diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index ad241c22eb64c..7c686b12e94f7 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,4 +1,4 @@ -FROM mcr.microsoft.com/devcontainers/typescript-node:16-bullseye +FROM mcr.microsoft.com/devcontainers/typescript-node:18-bookworm ADD install-vscode.sh /root/ RUN /root/install-vscode.sh diff --git a/.devcontainer/README.md b/.devcontainer/README.md index 6522e98aac95e..a5bde90d52746 100644 --- a/.devcontainer/README.md +++ b/.devcontainer/README.md @@ -19,13 +19,14 @@ This dev container includes configuration for a development container for workin > **Note:** The Dev Containers extension requires the Visual Studio Code distribution of Code - OSS. See the [FAQ](https://aka.ms/vscode-remote/faq/license) for details. 4. Due to the size of the repository we strongly recommend cloning it on a Linux filesystem for better bind mount performance. On macOS we recommend using a Docker volume (press F1 and select **Dev Containers: Clone Repository in Container Volume...**) and on Windows we recommend using a WSL folder: + - Make sure you are running a recent WSL version to get X11 and Wayland support. - Use the WSL extension for VS Code to open the cloned folder in WSL. - Press F1 and select **Dev Containers: Reopen in Container**. Next: **[Try it out!](#try-it)** -## Try it! +## Try it To start working with Code - OSS, follow these steps: @@ -50,6 +51,6 @@ Next, let's try debugging. Enjoy! -# Notes +## Notes The container comes with VS Code Insiders installed. To run it from an Integrated Terminal use `VSCODE_IPC_HOOK_CLI= /usr/bin/code-insiders .`. diff --git a/.devcontainer/install-vscode.sh b/.devcontainer/install-vscode.sh index 9d4b52755d9d2..cc70d527acdfb 100755 --- a/.devcontainer/install-vscode.sh +++ b/.devcontainer/install-vscode.sh @@ -9,4 +9,4 @@ sh -c 'echo "deb [arch=amd64,arm64,armhf signed-by=/etc/apt/keyrings/packages.mi rm -f packages.microsoft.gpg apt update -apt install -y code-insiders libsecret-1-dev libxkbfile-dev +apt install -y code-insiders libsecret-1-dev libxkbfile-dev libkrb5-dev diff --git a/.devcontainer/prebuilt/README.md b/.devcontainer/prebuilt/README.md index 82e731230c0d6..2ca4619ce1365 100644 --- a/.devcontainer/prebuilt/README.md +++ b/.devcontainer/prebuilt/README.md @@ -14,21 +14,21 @@ If you already have VS Code and Docker installed, you can click the badge above 2. **Important**: Docker needs at least **4 Cores and 8 GB of RAM** to run a full build with **9 GB of RAM** being recommended. If you are on macOS, or are using the old Hyper-V engine for Windows, update these values for Docker Desktop by right-clicking on the Docker status bar item and going to **Preferences/Settings > Resources > Advanced**. - > **Note:** The [Resource Monitor](https://marketplace.visualstudio.com/items?itemName=mutantdino.resourcemonitor) extension is included in the container so you can keep an eye on CPU/Memory in the status bar. + > **Note:** The [Resource Monitor](https://marketplace.visualstudio.com/items?itemName=mutantdino.resourcemonitor) extension is included in the container so you can keep an eye on CPU/Memory in the status bar. 3. Install [Visual Studio Code Stable](https://code.visualstudio.com/) or [Insiders](https://code.visualstudio.com/insiders/) and the [Dev Containers](https://aka.ms/vscode-remote/download/containers) extension. - ![Image of Dev Containers extension](https://microsoft.github.io/vscode-remote-release/images/dev-containers-extn.png) + ![Image of Dev Containers extension](https://microsoft.github.io/vscode-remote-release/images/dev-containers-extn.png) - > **Note:** The Dev Containers extension requires the Visual Studio Code distribution of Code - OSS. See the [FAQ](https://aka.ms/vscode-remote/faq/license) for details. + > **Note:** The Dev Containers extension requires the Visual Studio Code distribution of Code - OSS. See the [FAQ](https://aka.ms/vscode-remote/faq/license) for details. 4. Press Ctrl/Cmd + Shift + P or F1 and select **Dev Containers: Clone Repository in Container Volume...**. - > **Tip:** While you can use your local source tree instead, operations like `yarn install` can be slow on macOS or when using the Hyper-V engine on Windows. We recommend the "clone repository in container" approach instead since it uses "named volume" rather than the local filesystem. + > **Tip:** While you can use your local source tree instead, operations like `yarn install` can be slow on macOS or when using the Hyper-V engine on Windows. We recommend the "clone repository in container" approach instead since it uses "named volume" rather than the local filesystem. 5. Type `https://github.com/microsoft/vscode` (or a branch or PR URL) in the input box and press Enter. -6. After the container is running, open a web browser and go to [http://localhost:6080](http://localhost:6080), or use a [VNC Viewer](https://www.realvnc.com/en/connect/download/viewer/) to connect to `localhost:5901` and enter `vscode` as the password. +6. After the container is running, open a web browser and go to [http://localhost:6080](http://localhost:6080), or use a [VNC Viewer][def] to connect to `localhost:5901` and enter `vscode` as the password. Anything you start in VS Code, or the integrated terminal, will appear here. @@ -54,41 +54,42 @@ Next: **[Try it out!](#try-it)** ### Using VS Code with GitHub Codespaces -You may see improved VNC responsiveness when accessing a codespace from VS Code client since you can use a [VNC Viewer](https://www.realvnc.com/en/connect/download/viewer/). Here's how to do it. +You may see improved VNC responsiveness when accessing a codespace from VS Code client since you can use a [VNC Viewer][def]. Here's how to do it. -1. Install [Visual Studio Code Stable](https://code.visualstudio.com/) or [Insiders](https://code.visualstudio.com/insiders/) and the the [GitHub Codespaces extension](https://marketplace.visualstudio.com/items?itemName=GitHub.codespaces). +1. Install [Visual Studio Code Stable](https://code.visualstudio.com/) or [Insiders](https://code.visualstudio.com/insiders/) and the the [GitHub Codespaces extension](https://marketplace.visualstudio.com/items?itemName=GitHub.codespaces). - > **Note:** The GitHub Codespaces extension requires the Visual Studio Code distribution of Code - OSS. + > **Note:** The GitHub Codespaces extension requires the Visual Studio Code distribution of Code - OSS. 2. After the VS Code is up and running, press Ctrl/Cmd + Shift + P or F1, choose **Codespaces: Create New Codespace**, and use the following settings: - - `microsoft/vscode` for the repository. - - Select any branch (e.g. **main**) - you can select a different one later. - - Choose **Standard** (4-core, 8GB) as the size. -4. After you have connected to the codespace, you can use a [VNC Viewer](https://www.realvnc.com/en/connect/download/viewer/) to connect to `localhost:5901` and enter `vscode` as the password. +- `microsoft/vscode` for the repository. +- Select any branch (e.g. **main**) - you can select a different one later. +- Choose **Standard** (4-core, 8GB) as the size. + +3. After you have connected to the codespace, you can use a [VNC Viewer][def] to connect to `localhost:5901` and enter `vscode` as the password. > **Tip:** You may also need change your VNC client's **Picture Quality** setting to **High** to get a full color desktop. -5. Anything you start in VS Code, or the integrated terminal, will appear here. +4. Anything you start in VS Code, or the integrated terminal, will appear here. Next: **[Try it out!](#try-it)** -## Try it! +## Try it This container uses the [Fluxbox](http://fluxbox.org/) window manager to keep things lean. **Right-click on the desktop** to see menu options. It works with GNOME and GTK applications, so other tools can be installed if needed. -> **Note:** You can also set the resolution from the command line by typing `set-resolution`. + > **Note:** You can also set the resolution from the command line by typing `set-resolution`. To start working with Code - OSS, follow these steps: 1. In your local VS Code client, open a terminal (Ctrl/Cmd + Shift + \`) and type the following commands: - ```bash - yarn install - bash scripts/code.sh - ``` + ```bash + yarn install + bash scripts/code.sh + ``` -2. After the build is complete, open a web browser or a [VNC Viewer](https://www.realvnc.com/en/connect/download/viewer/) to connect to the desktop environment as described in the quick start and enter `vscode` as the password. +2. After the build is complete, open a web browser or a [VNC Viewer][def] to connect to the desktop environment as described in the quick start and enter `vscode` as the password. 3. You should now see Code - OSS! @@ -98,8 +99,10 @@ Next, let's try debugging. 2. Go to your local VS Code client, and use the **Run / Debug** view to launch the **VS Code** configuration. (Typically the default, so you can likely just press F5). - > **Note:** If launching times out, you can increase the value of `timeout` in the "VS Code", "Attach Main Process", "Attach Extension Host", and "Attach to Shared Process" configurations in [launch.json](../../.vscode/launch.json). However, running `scripts/code.sh` first will set up Electron which will usually solve timeout issues. + > **Note:** If launching times out, you can increase the value of `timeout` in the "VS Code", "Attach Main Process", "Attach Extension Host", and "Attach to Shared Process" configurations in [launch.json](../../.vscode/launch.json). However, running `scripts/code.sh` first will set up Electron which will usually solve timeout issues. 3. After a bit, Code - OSS will appear with the debugger attached! Enjoy! + +[def]: https://www.realvnc.com/en/connect/download/viewer/ diff --git a/.eslintplugin/code-no-test-async-suite.ts b/.eslintplugin/code-no-test-async-suite.ts new file mode 100644 index 0000000000000..41d15d286365e --- /dev/null +++ b/.eslintplugin/code-no-test-async-suite.ts @@ -0,0 +1,33 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { TSESTree } from '@typescript-eslint/experimental-utils'; +import * as eslint from 'eslint'; + +function isCallExpression(node: TSESTree.Node): node is TSESTree.CallExpression { + return node.type === 'CallExpression'; +} + +function isFunctionExpression(node: TSESTree.Node): node is TSESTree.FunctionExpression { + return node.type.includes('FunctionExpression'); +} + +export = new class NoAsyncSuite implements eslint.Rule.RuleModule { + + create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener { + function hasAsyncSuite(node: any) { + if (isCallExpression(node) && node.arguments.length >= 2 && isFunctionExpression(node.arguments[1]) && node.arguments[1].async) { + return context.report({ + node: node as any, + message: 'suite factory function should never be async' + }); + } + } + + return { + ['CallExpression[callee.name=/suite$/][arguments]']: hasAsyncSuite, + }; + } +}; diff --git a/.eslintrc.json b/.eslintrc.json index 2f52208fa18cb..e6011aeed862e 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -120,6 +120,7 @@ ], "rules": { "local/code-no-test-only": "error", + "local/code-no-test-async-suite": "warn", "local/code-no-unexternalized-strings": "off" } }, @@ -239,6 +240,7 @@ "console", "cookie", "crypto", + "dns", "electron", "events", "fs", diff --git a/.github/classifier.json b/.github/classifier.json index 388a50d8db91d..6710c3304dab2 100644 --- a/.github/classifier.json +++ b/.github/classifier.json @@ -281,7 +281,6 @@ "workbench-editor-resolver": {"assign": ["lramos15"]}, "workbench-editors": {"assign": ["bpasero"]}, "workbench-electron": {"assign": ["deepak1556"]}, - "workbench-feedback": {"assign": ["bpasero"]}, "workbench-fonts": {"assign": []}, "workbench-history": {"assign": ["bpasero"]}, "workbench-hot-exit": {"assign": ["bpasero"]}, diff --git a/.github/commands.json b/.github/commands.json index 15c6cd953c5a3..9d2ac7d70905b 100644 --- a/.github/commands.json +++ b/.github/commands.json @@ -486,7 +486,7 @@ ], "action": "comment", "addLabel": "info-needed", - "comment": "Please perform the following **three tasks** to diagnose the root cause of the issue:\n\n* [ ] **1.) Disable Extensions**\n * Select `View` and pick `Command Palette...`\n * Run `Developer: Reload With Extensions Disabled`\n * šŸ‘‰ See if the issue reproduces\n\n* [ ] **2.) Disable Configuration**\n * Select `View` and pick `Command Palette...`\n * Run `Profiles: Create a Temporary Profile`\n * šŸ‘‰ See if the issue reproduces\n\n* [ ] **3.) Try VS Code Insiders**\n * Download [VS Code Insiders](https://code.visualstudio.com/insiders/)\n * Install and Run it\n * šŸ‘‰ See if the issue reproduces\n \nThen pick one of the three resolutions depending on which step has helped:\n\n
\n Disabling my Extensions helped\n\nPlease run the command `Start Extension Bisect` and follow the instructions to find the extension that is causing this issue.\n\nimage\n\nPlease report the issue to the extension causing this.\n
\n\n
\n Disabling my configuration helped\nPlease report back more details about your configuration, including settings.\n
\n\n
\n Using VS Code Insiders has helped\nāœ… This likely means that the issue has been addressed already and will be available in an upcoming release. You can safely use VS Code Insiders until the new stable version is available.\n
" + "comment": "Please diagnose the root cause of the issue by running the command `F1 > Help: Troubleshoot Issue` and following the instructions. Once you have done that, please update the issue with the results.\n\nHappy Coding!" }, { "__comment__": "Allows folks on the team to label issues by commenting: `\\label My-Label` ", diff --git a/.github/workflows/basic.yml b/.github/workflows/basic.yml index 210b8058982aa..012c4247abe14 100644 --- a/.github/workflows/basic.yml +++ b/.github/workflows/basic.yml @@ -31,7 +31,7 @@ jobs: - uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 18 - name: Compute node modules cache key id: nodeModulesCacheKey @@ -83,7 +83,7 @@ jobs: - uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 18 - name: Compute node modules cache key id: nodeModulesCacheKey @@ -145,7 +145,7 @@ jobs: - uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 18 - name: Compute node modules cache key id: nodeModulesCacheKey diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dac5f9e073b79..cd32a2b50b9c5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,7 +25,7 @@ jobs: - uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 18 - uses: actions/setup-python@v4 with: @@ -107,7 +107,7 @@ jobs: - name: Setup Build Environment run: | sudo apt-get update - sudo apt-get install -y libxkbfile-dev pkg-config libsecret-1-dev libxss1 dbus xvfb libgtk-3-0 libgbm1 + sudo apt-get install -y libxkbfile-dev pkg-config libsecret-1-dev libkrb5-dev libxss1 dbus xvfb libgtk-3-0 libgbm1 sudo cp build/azure-pipelines/linux/xvfb.init /etc/init.d/xvfb sudo chmod +x /etc/init.d/xvfb sudo update-rc.d xvfb defaults @@ -115,7 +115,7 @@ jobs: - uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 18 - name: Compute node modules cache key id: nodeModulesCacheKey @@ -186,7 +186,7 @@ jobs: - uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 18 - name: Compute node modules cache key id: nodeModulesCacheKey @@ -259,7 +259,7 @@ jobs: - uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 18 - name: Compute node modules cache key id: nodeModulesCacheKey diff --git a/.github/workflows/monaco-editor.yml b/.github/workflows/monaco-editor.yml index a86f94bc331f9..a276604164e7e 100644 --- a/.github/workflows/monaco-editor.yml +++ b/.github/workflows/monaco-editor.yml @@ -22,7 +22,7 @@ jobs: - uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 18 - name: Compute node modules cache key id: nodeModulesCacheKey @@ -45,6 +45,9 @@ jobs: path: ${{ steps.yarnCacheDirPath.outputs.dir }} key: ${{ runner.os }}-yarnCacheDir-${{ steps.nodeModulesCacheKey.outputs.value }} restore-keys: ${{ runner.os }}-yarnCacheDir- + - name: Install libkrb5-dev + if: ${{ steps.cacheNodeModules.outputs.cache-hit != 'true' }} + run: sudo apt install -y libkrb5-dev - name: Execute yarn if: ${{ steps.cacheNodeModules.outputs.cache-hit != 'true' }} env: diff --git a/.github/workflows/rich-navigation.yml.off b/.github/workflows/rich-navigation.yml.off index c36c83dcb146d..a05130cbce45d 100644 --- a/.github/workflows/rich-navigation.yml.off +++ b/.github/workflows/rich-navigation.yml.off @@ -23,7 +23,7 @@ jobs: - uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 18 - name: Install dependencies if: steps.caching-stage.outputs.cache-hit != 'true' diff --git a/.gitignore b/.gitignore index 32f514ad07af6..0601e762dffb3 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,4 @@ vscode.db /cli/target /cli/openssl product.overrides.json +*.snap.actual diff --git a/.nvmrc b/.nvmrc index 5cb297e3e4897..0f9eb824458c8 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -16.17 +18.15 \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index baa3cfb0c8bdb..3bea8e7c076b5 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -244,11 +244,11 @@ "--disable-features=CalculateNativeWinOcclusion", "--disable-extension=vscode.vscode-api-tests" ], + "userDataDir": "${userHome}/.vscode-oss-dev", "webRoot": "${workspaceFolder}", "cascadeTerminateToConfigurations": [ "Attach to Extension Host" ], - "userDataDir": "${workspaceFolder}/.profile-oss", "pauseForSourceMap": false, "outFiles": [ "${workspaceFolder}/out/**/*.js" diff --git a/.vscode/notebooks/api.github-issues b/.vscode/notebooks/api.github-issues index 1d39b63dd9fa1..706cb4d5d38ea 100644 --- a/.vscode/notebooks/api.github-issues +++ b/.vscode/notebooks/api.github-issues @@ -7,7 +7,7 @@ { "kind": 2, "language": "github-issues", - "value": "$repo=repo:microsoft/vscode\n$milestone=milestone:\"July 2023\"" + "value": "$repo=repo:microsoft/vscode\n$milestone=milestone:\"August 2023\"" }, { "kind": 1, diff --git a/.vscode/notebooks/endgame.github-issues b/.vscode/notebooks/endgame.github-issues index 60c8c5a6aecfb..5bd52b7826ec7 100644 --- a/.vscode/notebooks/endgame.github-issues +++ b/.vscode/notebooks/endgame.github-issues @@ -7,7 +7,7 @@ { "kind": 2, "language": "github-issues", - "value": "$REPOS=repo:microsoft/vscode repo:microsoft/vscode-remote-release repo:microsoft/vscode-copilot repo:microsoft/vscode-copilot-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-unpkg repo:microsoft/vscode-references-view repo:microsoft/vscode-anycode repo:microsoft/vscode-hexeditor repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-livepreview repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-remote-repositories-github repo:microsoft/monaco-editor repo:microsoft/vscode-vsce repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-livepreview repo:microsoft/vscode-livepreview repo:microsoft/vscode-python repo:microsoft/vscode-python-debugger repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-l10n repo:microsoft/vscode-remote-tunnels\n\n$MILESTONE=milestone:\"July 2023\"" + "value": "$REPOS=repo:microsoft/vscode repo:microsoft/vscode-remote-release repo:microsoft/vscode-copilot repo:microsoft/vscode-copilot-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-unpkg repo:microsoft/vscode-references-view repo:microsoft/vscode-anycode repo:microsoft/vscode-hexeditor repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-livepreview repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-remote-repositories-github repo:microsoft/monaco-editor repo:microsoft/vscode-vsce repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-livepreview repo:microsoft/vscode-livepreview repo:microsoft/vscode-python repo:microsoft/vscode-python-debugger repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-l10n repo:microsoft/vscode-remote-tunnels\n\n$MILESTONE=milestone:\"August 2023\"" }, { "kind": 1, @@ -124,6 +124,16 @@ "language": "github-issues", "value": "$REPOS $MILESTONE is:issue is:closed reason:completed sort:updated-asc label:bug -label:verified -label:on-testplan -label:*duplicate -label:duplicate -label:invalid -label:*as-designed -label:error-telemetry -label:verification-steps-needed -label:z-author-verified label:unreleased" }, + { + "kind": 1, + "language": "markdown", + "value": "## All Unverified Fixes" + }, + { + "kind": 2, + "language": "github-issues", + "value": "$REPOS $MILESTONE is:issue is:closed reason:completed sort:updated-asc label:bug -label:verified -label:on-testplan -label:*duplicate -label:duplicate -label:invalid -label:*as-designed -label:error-telemetry -label:z-author-verified " + }, { "kind": 1, "language": "markdown", diff --git a/.vscode/notebooks/my-endgame.github-issues b/.vscode/notebooks/my-endgame.github-issues index 92fddeef220c2..96c780e5a6f48 100644 --- a/.vscode/notebooks/my-endgame.github-issues +++ b/.vscode/notebooks/my-endgame.github-issues @@ -7,7 +7,7 @@ { "kind": 2, "language": "github-issues", - "value": "$REPOS=repo:microsoft/vscode repo:microsoft/vscode-remote-release repo:microsoft/vscode-copilot repo:microsoft/vscode-copilot-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-unpkg repo:microsoft/vscode-references-view repo:microsoft/vscode-anycode repo:microsoft/vscode-hexeditor repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-livepreview repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-remote-repositories-github repo:microsoft/monaco-editor repo:microsoft/vscode-vsce repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-livepreview repo:microsoft/vscode-livepreview repo:microsoft/vscode-python repo:microsoft/vscode-python-debugger repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-l10n repo:microsoft/vscode-remote-tunnels\n\n$MILESTONE=milestone:\"July 2023\"\n\n$MINE=assignee:@me" + "value": "$REPOS=repo:microsoft/vscode repo:microsoft/vscode-remote-release repo:microsoft/vscode-copilot repo:microsoft/vscode-copilot-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-unpkg repo:microsoft/vscode-references-view repo:microsoft/vscode-anycode repo:microsoft/vscode-hexeditor repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-livepreview repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-remote-repositories-github repo:microsoft/monaco-editor repo:microsoft/vscode-vsce repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-livepreview repo:microsoft/vscode-livepreview repo:microsoft/vscode-python repo:microsoft/vscode-python-debugger repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-l10n repo:microsoft/vscode-remote-tunnels\r\n\r\n$MILESTONE=milestone:\"August 2023\"\r\n\r\n$MINE=assignee:@me" }, { "kind": 1, @@ -169,6 +169,16 @@ "language": "github-issues", "value": "$REPOS $MILESTONE -$MINE is:issue is:closed reason:completed -author:@me sort:updated-asc label:bug -label:unreleased -label:verified -label:z-author-verified -label:on-testplan -label:*duplicate -label:duplicate -label:invalid -label:*as-designed -label:error-telemetry -label:verification-steps-needed -label:verification-found" }, + { + "kind": 1, + "language": "markdown", + "value": "## Test steps needed from others" + }, + { + "kind": 2, + "language": "github-issues", + "value": "$REPOS $MILESTONE -$MINE is:issue label:bug label:verification-steps-needed" + }, { "kind": 1, "language": "markdown", @@ -177,6 +187,6 @@ { "kind": 2, "language": "github-issues", - "value": "repo:microsoft/vscode $MILESTONE $MINE is:issue is:closed reason:completed label:feature-request -label:on-release-notes\nrepo:microsoft/vscode $MILESTONE $MINE is:issue is:closed reason:completed label:engineering -label:on-release-notes\nrepo:microsoft/vscode $MILESTONE $MINE is:issue is:closed reason:completed label:plan-item -label:on-release-notes" + "value": "repo:microsoft/vscode $MILESTONE $MINE is:issue is:closed reason:completed label:feature-request -label:on-release-notes\r\nrepo:microsoft/vscode $MILESTONE $MINE is:issue is:closed reason:completed label:engineering -label:on-release-notes\r\nrepo:microsoft/vscode $MILESTONE $MINE is:issue is:closed reason:completed label:plan-item -label:on-release-notes" } ] \ No newline at end of file diff --git a/.vscode/notebooks/my-work.github-issues b/.vscode/notebooks/my-work.github-issues index 9f66c4771f6eb..06efd3450188d 100644 --- a/.vscode/notebooks/my-work.github-issues +++ b/.vscode/notebooks/my-work.github-issues @@ -7,7 +7,7 @@ { "kind": 2, "language": "github-issues", - "value": "// list of repos we work in\n$repos=repo:microsoft/vscode repo:microsoft/vscode-remote-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-unpkg repo:microsoft/vscode-references-view repo:microsoft/vscode-anycode repo:microsoft/vscode-hexeditor repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-livepreview repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-remote-repositories-github repo:microsoft/monaco-editor repo:microsoft/vscode-vsce repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-python repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-l10n repo:microsoft/vscode-remote-tunnels repo:microsoft/vscode-markdown-tm-grammar repo:microsoft/vscode-markdown-languageservice repo:microsoft/vscode-copilot repo:microsoft/vscode-copilot-release\n\n// current milestone name\n$milestone=milestone:\"July 2023\"" + "value": "// list of repos we work in\n$repos=repo:microsoft/vscode repo:microsoft/vscode-remote-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-unpkg repo:microsoft/vscode-references-view repo:microsoft/vscode-anycode repo:microsoft/vscode-hexeditor repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-livepreview repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-remote-repositories-github repo:microsoft/monaco-editor repo:microsoft/vscode-vsce repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-python repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-l10n repo:microsoft/vscode-remote-tunnels repo:microsoft/vscode-markdown-tm-grammar repo:microsoft/vscode-markdown-languageservice repo:microsoft/vscode-copilot repo:microsoft/vscode-copilot-release\n\n// current milestone name\n$milestone=milestone:\"August 2023\"" }, { "kind": 1, @@ -102,7 +102,7 @@ { "kind": 2, "language": "github-issues", - "value": "repo:microsoft/vscode assignee:@me is:open type:issue -label:\"info-needed\" -label:api -label:api-finalization -label:api-proposal -label:authentication -label:bisect-ext -label:bracket-pair-colorization -label:bracket-pair-guides -label:breadcrumbs -label:callhierarchy -label:chrome-devtools -label:cloud-changes -label:code-lens -label:command-center -label:comments -label:config -label:containers -label:context-keys -label:continue-working-on -label:css-less-scss -label:custom-editors -label:debug -label:debug-disassembly -label:dialogs -label:diff-editor -label:dropdown -label:editor-api -label:editor-autoclosing -label:editor-autoindent -label:editor-bracket-matching -label:editor-clipboard -label:editor-code-actions -label:editor-color-picker -label:editor-columnselect -label:editor-commands -label:editor-comments -label:editor-contrib -label:editor-core -label:editor-drag-and-drop -label:editor-error-widget -label:editor-find -label:editor-folding -label:editor-highlight -label:editor-hover -label:editor-indent-detection -label:editor-indent-guides -label:editor-input -label:editor-input-IME -label:editor-insets -label:editor-minimap -label:editor-multicursor -label:editor-parameter-hints -label:editor-render-whitespace -label:editor-rendering -label:editor-RTL -label:editor-scrollbar -label:editor-sorting -label:editor-sticky-scroll -label:editor-symbols -label:editor-synced-region -label:editor-textbuffer -label:editor-theming -label:editor-wordnav -label:editor-wrapping -label:emmet -label:emmet-parse -label:error-list -label:extension-activation -label:extension-host -label:extension-prerelease -label:extension-recommendations -label:extensions -label:extensions-development -label:file-decorations -label:file-encoding -label:file-explorer -label:file-glob -label:file-io -label:file-nesting -label:file-watcher -label:font-rendering -label:formatting -label:getting-started -label:ghost-text -label:git -label:github -label:github-repositories -label:gpu -label:grammar -label:grid-widget -label:html -label:icon-brand -label:icons-product -label:image-preview -label:inlay-hints -label:inline-completions -label:install-update -label:intellisense-config -label:interactive-playground -label:interactive-window -label:issue-bot -label:issue-reporter -label:javascript -label:json -label:keybindings -label:keybindings-editor -label:keybindings-json -label:keyboard-layout -label:L10N -label:l10n-platform -label:label-provider -label:languages-basic -label:languages-diagnostics -label:languages-guessing -label:layout -label:lcd-text-rendering -label:list-widget -label:live-preview -label:log -label:markdown -label:marketplace -label:menus -label:merge-conflict -label:merge-editor -label:merge-editor-workbench -label:monaco-editor -label:native-file-dialog -label:network -label:notebook -label:notebook-api -label:notebook-builtin-renderers -label:notebook-cell-editor -label:notebook-celltoolbar -label:notebook-clipboard -label:notebook-commenting -label:notebook-debugging -label:notebook-diff -label:notebook-dnd -label:notebook-execution -label:notebook-find -label:notebook-folding -label:notebook-getting-started -label:notebook-globaltoolbar -label:notebook-ipynb -label:notebook-kernel -label:notebook-kernel-picker -label:notebook-language -label:notebook-layout -label:notebook-markdown -label:notebook-math -label:notebook-minimap -label:notebook-multiselect -label:notebook-output -label:notebook-perf -label:notebook-remote -label:notebook-rendering -label:notebook-serialization -label:notebook-serverless-web -label:notebook-statusbar -label:notebook-toc-outline -label:notebook-undo-redo -label:notebook-variables -label:notebook-workbench-integration -label:notebook-workflow -label:open-editors -label:opener -label:outline -label:output -label:packaging -label:perf -label:perf-bloat -label:perf-startup -label:php -label:portable-mode -label:proxy -label:quick-open -label:quick-pick -label:references-viewlet -label:release-notes -label:remote -label:remote-connection -label:remote-explorer -label:remote-tunnel -label:rename -label:runCommands -label:sandbox -label:sash-widget -label:scm -label:screencast-mode -label:search -label:search-api -label:search-editor -label:search-replace -label:semantic-tokens -label:server -label:settings-editor -label:settings-sync -label:settings-sync-server -label:shared-process -label:simple-file-dialog -label:smart-select -label:snap -label:snippets -label:splitview-widget -label:ssh -label:suggest -label:table-widget -label:tasks -label:telemetry -label:terminal -label:terminal-accessibility -label:terminal-conpty -label:terminal-editors -label:terminal-external -label:terminal-find -label:terminal-input -label:terminal-layout -label:terminal-links -label:terminal-local-echo -label:terminal-persistence -label:terminal-process -label:terminal-profiles -label:terminal-quick-fix -label:terminal-rendering -label:terminal-shell-bash -label:terminal-shell-cmd -label:terminal-shell-fish -label:terminal-shell-git-bash -label:terminal-shell-integration -label:terminal-shell-pwsh -label:terminal-shell-zsh -label:terminal-tabs -label:terminal-winpty -label:testing -label:themes -label:timeline -label:timeline-git -label:timeline-local-history -label:titlebar -label:tokenization -label:touch/pointer -label:trackpad/scroll -label:tree-views -label:tree-widget -label:typescript -label:undo-redo -label:unicode-highlight -label:uri -label:user-profiles -label:ux -label:variable-resolving -label:VIM -label:virtual-workspaces -label:vscode-website -label:vscode.dev -label:web -label:webview -label:webview-views -label:workbench-actions -label:workbench-banner -label:workbench-cli -label:workbench-diagnostics -label:workbench-dnd -label:workbench-editor-grid -label:workbench-editor-groups -label:workbench-editor-resolver -label:workbench-editors -label:workbench-electron -label:workbench-feedback -label:workbench-fonts -label:workbench-history -label:workbench-hot-exit -label:workbench-hover -label:workbench-launch -label:workbench-link -label:workbench-multiroot -label:workbench-notifications -label:workbench-os-integration -label:workbench-rapid-render -label:workbench-run-as-admin -label:workbench-state -label:workbench-status -label:workbench-tabs -label:workbench-touchbar -label:workbench-untitled-editors -label:workbench-views -label:workbench-welcome -label:workbench-window -label:workbench-workspace -label:workbench-zen -label:workspace-edit -label:workspace-symbols -label:workspace-trust -label:zoom -label:inline-chat" + "value": "repo:microsoft/vscode assignee:@me is:open type:issue -label:\"info-needed\" -label:api -label:api-finalization -label:api-proposal -label:authentication -label:bisect-ext -label:bracket-pair-colorization -label:bracket-pair-guides -label:breadcrumbs -label:callhierarchy -label:chrome-devtools -label:cloud-changes -label:code-lens -label:command-center -label:comments -label:config -label:containers -label:context-keys -label:continue-working-on -label:css-less-scss -label:custom-editors -label:debug -label:debug-disassembly -label:dialogs -label:diff-editor -label:dropdown -label:editor-api -label:editor-autoclosing -label:editor-autoindent -label:editor-bracket-matching -label:editor-clipboard -label:editor-code-actions -label:editor-color-picker -label:editor-columnselect -label:editor-commands -label:editor-comments -label:editor-contrib -label:editor-core -label:editor-drag-and-drop -label:editor-error-widget -label:editor-find -label:editor-folding -label:editor-highlight -label:editor-hover -label:editor-indent-detection -label:editor-indent-guides -label:editor-input -label:editor-input-IME -label:editor-insets -label:editor-minimap -label:editor-multicursor -label:editor-parameter-hints -label:editor-render-whitespace -label:editor-rendering -label:editor-RTL -label:editor-scrollbar -label:editor-sorting -label:editor-sticky-scroll -label:editor-symbols -label:editor-synced-region -label:editor-textbuffer -label:editor-theming -label:editor-wordnav -label:editor-wrapping -label:emmet -label:emmet-parse -label:error-list -label:extension-activation -label:extension-host -label:extension-prerelease -label:extension-recommendations -label:extensions -label:extensions-development -label:file-decorations -label:file-encoding -label:file-explorer -label:file-glob -label:file-io -label:file-nesting -label:file-watcher -label:font-rendering -label:formatting -label:getting-started -label:ghost-text -label:git -label:github -label:github-repositories -label:gpu -label:grammar -label:grid-widget -label:html -label:icon-brand -label:icons-product -label:image-preview -label:inlay-hints -label:inline-completions -label:install-update -label:intellisense-config -label:interactive-playground -label:interactive-window -label:issue-bot -label:issue-reporter -label:javascript -label:json -label:keybindings -label:keybindings-editor -label:keybindings-json -label:keyboard-layout -label:L10N -label:l10n-platform -label:label-provider -label:languages-basic -label:languages-diagnostics -label:languages-guessing -label:layout -label:lcd-text-rendering -label:list-widget -label:live-preview -label:log -label:markdown -label:marketplace -label:menus -label:merge-conflict -label:merge-editor -label:merge-editor-workbench -label:monaco-editor -label:native-file-dialog -label:network -label:notebook -label:notebook-api -label:notebook-builtin-renderers -label:notebook-cell-editor -label:notebook-celltoolbar -label:notebook-clipboard -label:notebook-commenting -label:notebook-debugging -label:notebook-diff -label:notebook-dnd -label:notebook-execution -label:notebook-find -label:notebook-folding -label:notebook-getting-started -label:notebook-globaltoolbar -label:notebook-ipynb -label:notebook-kernel -label:notebook-kernel-picker -label:notebook-language -label:notebook-layout -label:notebook-markdown -label:notebook-math -label:notebook-minimap -label:notebook-multiselect -label:notebook-output -label:notebook-perf -label:notebook-remote -label:notebook-rendering -label:notebook-serialization -label:notebook-serverless-web -label:notebook-statusbar -label:notebook-toc-outline -label:notebook-undo-redo -label:notebook-variables -label:notebook-workbench-integration -label:notebook-workflow -label:open-editors -label:opener -label:outline -label:output -label:packaging -label:perf -label:perf-bloat -label:perf-startup -label:php -label:portable-mode -label:proxy -label:quick-open -label:quick-pick -label:references-viewlet -label:release-notes -label:remote -label:remote-connection -label:remote-explorer -label:remote-tunnel -label:rename -label:runCommands -label:sandbox -label:sash-widget -label:scm -label:screencast-mode -label:search -label:search-api -label:search-editor -label:search-replace -label:semantic-tokens -label:server -label:settings-editor -label:settings-sync -label:settings-sync-server -label:shared-process -label:simple-file-dialog -label:smart-select -label:snap -label:snippets -label:splitview-widget -label:ssh -label:suggest -label:table-widget -label:tasks -label:telemetry -label:terminal -label:terminal-accessibility -label:terminal-conpty -label:terminal-editors -label:terminal-external -label:terminal-find -label:terminal-input -label:terminal-layout -label:terminal-links -label:terminal-local-echo -label:terminal-persistence -label:terminal-process -label:terminal-profiles -label:terminal-quick-fix -label:terminal-rendering -label:terminal-shell-bash -label:terminal-shell-cmd -label:terminal-shell-fish -label:terminal-shell-git-bash -label:terminal-shell-integration -label:terminal-shell-pwsh -label:terminal-shell-zsh -label:terminal-tabs -label:terminal-winpty -label:testing -label:themes -label:timeline -label:timeline-git -label:timeline-local-history -label:titlebar -label:tokenization -label:touch/pointer -label:trackpad/scroll -label:tree-views -label:tree-widget -label:typescript -label:undo-redo -label:unicode-highlight -label:uri -label:user-profiles -label:ux -label:variable-resolving -label:VIM -label:virtual-workspaces -label:vscode-website -label:vscode.dev -label:web -label:webview -label:webview-views -label:workbench-actions -label:workbench-banner -label:workbench-cli -label:workbench-diagnostics -label:workbench-dnd -label:workbench-editor-grid -label:workbench-editor-groups -label:workbench-editor-resolver -label:workbench-editors -label:workbench-electron -label:workbench-fonts -label:workbench-history -label:workbench-hot-exit -label:workbench-hover -label:workbench-launch -label:workbench-link -label:workbench-multiroot -label:workbench-notifications -label:workbench-os-integration -label:workbench-rapid-render -label:workbench-run-as-admin -label:workbench-state -label:workbench-status -label:workbench-tabs -label:workbench-touchbar -label:workbench-untitled-editors -label:workbench-views -label:workbench-welcome -label:workbench-window -label:workbench-workspace -label:workbench-zen -label:workspace-edit -label:workspace-symbols -label:workspace-trust -label:zoom -label:inline-chat" }, { "kind": 1, diff --git a/.vscode/notebooks/verification.github-issues b/.vscode/notebooks/verification.github-issues index 43ff3912c72ec..1b81dcd0148cd 100644 --- a/.vscode/notebooks/verification.github-issues +++ b/.vscode/notebooks/verification.github-issues @@ -12,7 +12,7 @@ { "kind": 2, "language": "github-issues", - "value": "$repos=repo:microsoft/vscode repo:microsoft/vscode-remote-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-unpkg repo:microsoft/vscode-references-view repo:microsoft/vscode-anycode repo:microsoft/vscode-hexeditor repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-livepreview repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-remote-repositories-github repo:microsoft/monaco-editor repo:microsoft/vscode-vsce repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-livepreview repo:microsoft/vscode-livepreview repo:microsoft/vscode-python repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-l10n repo:microsoft/vscode-remote-tunnels\n$milestone=milestone:\"July 2023\"" + "value": "$repos=repo:microsoft/vscode repo:microsoft/vscode-remote-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-unpkg repo:microsoft/vscode-references-view repo:microsoft/vscode-anycode repo:microsoft/vscode-hexeditor repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-livepreview repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-remote-repositories-github repo:microsoft/monaco-editor repo:microsoft/vscode-vsce repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-livepreview repo:microsoft/vscode-livepreview repo:microsoft/vscode-python repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-l10n repo:microsoft/vscode-remote-tunnels\n$milestone=milestone:\"August 2023\"" }, { "kind": 1, diff --git a/.vscode/notebooks/vscode-dev.github-issues b/.vscode/notebooks/vscode-dev.github-issues index 65cfed180a597..013c3331dca08 100644 --- a/.vscode/notebooks/vscode-dev.github-issues +++ b/.vscode/notebooks/vscode-dev.github-issues @@ -2,7 +2,7 @@ { "kind": 2, "language": "github-issues", - "value": "$milestone=milestone:\"July 2023\"" + "value": "$milestone=milestone:\"August 2023\"" }, { "kind": 1, diff --git a/.vscode/settings.json b/.vscode/settings.json index 5d2930c5a923c..7eefe0c57f686 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -36,6 +36,7 @@ "files.readonlyInclude": { "**/node_modules/**": true, "**/yarn.lock": true, + "**/Cargo.lock": true, "src/vs/workbench/workbench.web.main.css": true, "src/vs/workbench/workbench.desktop.main.css": true, "src/vs/workbench/workbench.desktop.main.nls.js": true, diff --git a/.vscode/shared.code-snippets b/.vscode/shared.code-snippets index fb3df23dd42d2..f473425b76f0c 100644 --- a/.vscode/shared.code-snippets +++ b/.vscode/shared.code-snippets @@ -6,7 +6,7 @@ // Placeholders with the same ids are connected. // Example: "MSFT Copyright Header": { - "scope": "javascript,typescript,css", + "scope": "javascript,typescript,css,rust", "prefix": [ "header", "stub", diff --git a/.yarnrc b/.yarnrc index 3af2059dbd78d..8f658afd4a946 100644 --- a/.yarnrc +++ b/.yarnrc @@ -1,5 +1,5 @@ disturl "https://electronjs.org/headers" -target "22.3.14" -ms_build_id "21893604" +target "25.5.0" +ms_build_id "23084831" runtime "electron" build_from_source "true" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b96e077aa67ea..f17fa84364568 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -104,6 +104,6 @@ If you believe the bot got something wrong, please open a new issue and let us k If you are interested in writing code to fix issues, please see [How to Contribute](https://github.com/microsoft/vscode/wiki/How-to-Contribute) in the wiki. -# Thank You! +## Thank You Your contributions to open source, large or small, make great projects like this possible. Thank you for taking the time to contribute. diff --git a/CodeQL.yml b/CodeQL.yml index 9ef07560af34e..eecb813a96f9a 100644 --- a/CodeQL.yml +++ b/CodeQL.yml @@ -21,3 +21,9 @@ path_classifiers: - "out-build" - "out-vscode" - "**/out/**" + + # The default behavior is to tag library code as `library`. Results are hidden + # for library code. You can tag further files as being library code by adding them + # to the `library` section. + library: + - "**/node_modules/**" diff --git a/README.md b/README.md index 0c7c6236c42c6..61df8fc6bb44e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # Visual Studio Code - Open Source ("Code - OSS") + [![Feature Requests](https://img.shields.io/github/issues/microsoft/vscode/feature-request.svg)](https://github.com/microsoft/vscode/issues?q=is%3Aopen+is%3Aissue+label%3Afeature-request+sort%3Areactions-%2B1-desc) [![Bugs](https://img.shields.io/github/issues/microsoft/vscode/bug.svg)](https://github.com/microsoft/vscode/issues?utf8=āœ“&q=is%3Aissue+is%3Aopen+label%3Abug) [![Gitter](https://img.shields.io/badge/chat-on%20gitter-yellow.svg)](https://gitter.im/Microsoft/vscode) @@ -60,9 +61,10 @@ VS Code includes a set of built-in extensions located in the [extensions](extens This repository includes a Visual Studio Code Dev Containers / GitHub Codespaces development container. -- For [Dev Containers](https://aka.ms/vscode-remote/download/containers), use the **Dev Containers: Clone Repository in Container Volume...** command which creates a Docker volume for better disk I/O on macOS and Windows. - - If you already have VS Code and Docker installed, you can also click [here](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/microsoft/vscode) to get started. This will cause VS Code to automatically install the Dev Containers extension if needed, clone the source code into a container volume, and spin up a dev container for use. -- For Codespaces, install the [GitHub Codespaces](https://marketplace.visualstudio.com/items?itemName=GitHub.codespaces) extension in VS Code, and use the **Codespaces: Create New Codespace** command. +* For [Dev Containers](https://aka.ms/vscode-remote/download/containers), use the **Dev Containers: Clone Repository in Container Volume...** command which creates a Docker volume for better disk I/O on macOS and Windows. + * If you already have VS Code and Docker installed, you can also click [here](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/microsoft/vscode) to get started. This will cause VS Code to automatically install the Dev Containers extension if needed, clone the source code into a container volume, and spin up a dev container for use. + +* For Codespaces, install the [GitHub Codespaces](https://marketplace.visualstudio.com/items?itemName=GitHub.codespaces) extension in VS Code, and use the **Codespaces: Create New Codespace** command. Docker / the Codespace should have at least **4 Cores and 6 GB of RAM (8 GB recommended)** to run full build. See the [development container README](.devcontainer/README.md) for more information. diff --git a/SECURITY.md b/SECURITY.md index a050f362c1528..4fa5946a867c6 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -18,13 +18,13 @@ You should receive a response within 24 hours. If for some reason you do not, pl Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: - * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) - * Full paths of source file(s) related to the manifestation of the issue - * The location of the affected source code (tag/branch/commit or direct URL) - * Any special configuration required to reproduce the issue - * Step-by-step instructions to reproduce the issue - * Proof-of-concept or exploit code (if possible) - * Impact of the issue, including how an attacker might exploit the issue +* Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) +* Full paths of source file(s) related to the manifestation of the issue +* The location of the affected source code (tag/branch/commit or direct URL) +* Any special configuration required to reproduce the issue +* Step-by-step instructions to reproduce the issue +* Proof-of-concept or exploit code (if possible) +* Impact of the issue, including how an attacker might exploit the issue This information will help us triage your report more quickly. diff --git a/ThirdPartyNotices.txt b/ThirdPartyNotices.txt index d5a4c5f2193ca..cf52ca35c94f2 100644 --- a/ThirdPartyNotices.txt +++ b/ThirdPartyNotices.txt @@ -169,45 +169,6 @@ OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------- -atom/language-java 0.32.1 - MIT -https://github.com/atom/language-java - -The MIT License (MIT) - -Copyright (c) 2014 GitHub Inc. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -This package was derived from a TextMate bundle located at -https://github.com/textmate/java.tmbundle and distributed under the following -license, located in `README.mdown`: - -Permission to copy, use, modify, sell and distribute this -software is granted. This software is provided "as is" without -express or implied warranty, and with no claim as to its -suitability for any purpose. ---------------------------------------------------------- - ---------------------------------------------------------- - atom/language-sass 0.62.1 - MIT https://github.com/atom/language-sass @@ -493,17 +454,207 @@ b) the Mozilla Public License Version 2.0 ----------------------------------------------------------------------------- -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: - http://www.apache.org/licenses/LICENSE-2.0 + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. ----------------------------------------------------------------------------- Mozilla Public License, version 2.0 @@ -1275,7 +1426,7 @@ SOFTWARE. --------------------------------------------------------- -jeff-hykin/better-shell-syntax 1.5.4 - MIT +jeff-hykin/better-shell-syntax 1.6.2 - MIT https://github.com/jeff-hykin/better-shell-syntax MIT License @@ -1303,7 +1454,7 @@ SOFTWARE. --------------------------------------------------------- -jlelong/vscode-latex-basics 1.5.2 - MIT +jlelong/vscode-latex-basics 1.5.3 - MIT https://github.com/jlelong/vscode-latex-basics Copyright (c) vscode-latex-basics authors @@ -1986,6 +2137,46 @@ SOFTWARE. --------------------------------------------------------- +redhat-developer/vscode-java 1.21.0 - MIT +https://github.com/redhat-developer/vscode-java + +The MIT License (MIT) + +Copyright (c) 2014 GitHub Inc. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +-------------------------------------------------------------------- + +This package was derived from a TextMate bundle located at +https://github.com/textmate/java.tmbundle and distributed under the following +license, located in `README.mdown`: + +Permission to copy, use, modify, sell and distribute this +software is granted. This software is provided "as is" without +express or implied warranty, and with no claim as to its +suitability for any purpose. +--------------------------------------------------------- + +--------------------------------------------------------- + rust-syntax 0.5.0 - MIT https://github.com/dustypomerleau/rust-syntax diff --git a/build/.cachesalt b/build/.cachesalt index d63bdc3118947..26ad5de2bcab8 100644 --- a/build/.cachesalt +++ b/build/.cachesalt @@ -1 +1 @@ -2023-06-12T12:55:48.130Z +2023-07-20T13:31:34.746Z diff --git a/build/.moduleignore b/build/.moduleignore index abc37e3138c4c..e4a19bbb76280 100644 --- a/build/.moduleignore +++ b/build/.moduleignore @@ -73,6 +73,12 @@ windows-foreground-love/build/** windows-foreground-love/src/** !windows-foreground-love/**/*.node +kerberos/binding.gyp +kerberos/build/** +kerberos/src/** +kerberos/node_modules/** +!kerberos/**/*.node + keytar/binding.gyp keytar/build/** keytar/src/** @@ -108,14 +114,6 @@ vsda/SECURITY.md vsda/targets !vsda/build/Release/vsda.node -vscode-encrypt/build/** -vscode-encrypt/src/** -vscode-encrypt/vendor/** -vscode-encrypt/.gitignore -vscode-encrypt/binding.gyp -vscode-encrypt/README.md -!vscode-encrypt/build/Release/vscode-encrypt-native.node - @vscode/policy-watcher/build/** @vscode/policy-watcher/.husky/** @vscode/policy-watcher/src/** diff --git a/build/azure-pipelines/alpine/cli-build-alpine.yml b/build/azure-pipelines/alpine/cli-build-alpine.yml index 8aa191023daab..3fb6234cbcf67 100644 --- a/build/azure-pipelines/alpine/cli-build-alpine.yml +++ b/build/azure-pipelines/alpine/cli-build-alpine.yml @@ -11,11 +11,9 @@ parameters: steps: - task: NodeTool@0 inputs: - versionSpec: "16.x" + versionSpec: "18.x" - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - template: ../distro/download-distro.yml - # Install yarn as the ARM64 build agent is using vanilla Ubuntu - ${{ if eq(parameters.VSCODE_BUILD_ALPINE_ARM64, true) }}: - task: Npm@1 @@ -30,8 +28,7 @@ steps: workingDirectory: build displayName: Install pipeline build - - script: node .build/distro/cli-patches/index.js - displayName: Apply distro patches + - template: ../cli/cli-apply-patches.yml - task: Npm@1 displayName: Download openssl prebuilt @@ -56,13 +53,6 @@ steps: sudo ln -s "/usr/bin/g++" "/usr/bin/musl-g++" || echo "link exists" displayName: Install musl build dependencies - - script: node build/azure-pipelines/cli/prepare.js - displayName: Prepare CLI build - env: - VSCODE_CLI_PREPARE_ROOT: $(Build.SourcesDirectory)/.build/distro - VSCODE_QUALITY: ${{ parameters.VSCODE_QUALITY }} - GITHUB_TOKEN: "$(github-distro-mixin-password)" - - template: ../cli/install-rust-posix.yml parameters: targets: @@ -76,6 +66,7 @@ steps: parameters: VSCODE_CLI_TARGET: aarch64-unknown-linux-musl VSCODE_CLI_ARTIFACT: vscode_cli_alpine_arm64_cli + VSCODE_QUALITY: ${{ parameters.VSCODE_QUALITY }} VSCODE_CLI_ENV: CXX_aarch64-unknown-linux-musl: musl-g++ CC_aarch64-unknown-linux-musl: musl-gcc @@ -88,6 +79,7 @@ steps: parameters: VSCODE_CLI_TARGET: x86_64-unknown-linux-musl VSCODE_CLI_ARTIFACT: vscode_cli_alpine_x64_cli + VSCODE_QUALITY: ${{ parameters.VSCODE_QUALITY }} VSCODE_CLI_ENV: CXX_aarch64-unknown-linux-musl: musl-g++ CC_aarch64-unknown-linux-musl: musl-gcc diff --git a/build/azure-pipelines/alpine/product-build-alpine.yml b/build/azure-pipelines/alpine/product-build-alpine.yml index eed3623addcf1..20923b65b60d7 100644 --- a/build/azure-pipelines/alpine/product-build-alpine.yml +++ b/build/azure-pipelines/alpine/product-build-alpine.yml @@ -1,11 +1,7 @@ steps: - task: NodeTool@0 inputs: - versionSpec: "16.x" - - - script: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes - displayName: "Register Docker QEMU" - condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'arm64')) + versionSpec: "18.x" - template: ../distro/download-distro.yml @@ -46,7 +42,10 @@ steps: - script: | set -e npm config set registry "$NPM_REGISTRY" --location=project - npm config set always-auth=true --location=project + # npm >v7 deprecated the `always-auth` config option, refs npm/cli@72a7eeb + # following is a workaround for yarn to send authorization header + # for GET requests to the registry. + echo "always-auth=true" >> .npmrc yarn config set registry "$NPM_REGISTRY" condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM & Yarn @@ -67,6 +66,10 @@ steps: displayName: "Pull image" condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) + - script: sudo apt-get update && sudo apt-get install -y libkrb5-dev + displayName: Install build dependencies + condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) + - script: | set -e for i in {1..5}; do # try 5 times @@ -78,10 +81,12 @@ steps: echo "Yarn failed $i, trying again..." done env: + npm_config_arch: $(NPM_ARCH) ELECTRON_SKIP_BINARY_DOWNLOAD: 1 PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 GITHUB_TOKEN: "$(github-distro-mixin-password)" VSCODE_REMOTE_DEPENDENCIES_CONTAINER_NAME: vscodehub.azurecr.io/vscode-linux-build-agent:alpine-$(VSCODE_ARCH) + VSCODE_HOST_MOUNT: "/mnt/vss/_work/1/s" displayName: Install build dependencies condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) diff --git a/build/azure-pipelines/cli/cli-apply-patches.yml b/build/azure-pipelines/cli/cli-apply-patches.yml index 35b429375c02d..b96aa4ef7dd94 100644 --- a/build/azure-pipelines/cli/cli-apply-patches.yml +++ b/build/azure-pipelines/cli/cli-apply-patches.yml @@ -1,5 +1,8 @@ steps: - template: ../distro/download-distro.yml + - script: node build/azure-pipelines/distro/mixin-quality + displayName: Mixin distro quality + - script: node .build/distro/cli-patches/index.js displayName: Apply distro patches diff --git a/build/azure-pipelines/cli/cli-compile-and-publish.yml b/build/azure-pipelines/cli/cli-compile-and-publish.yml index a6468ad3ae966..37d68e2c51e82 100644 --- a/build/azure-pipelines/cli/cli-compile-and-publish.yml +++ b/build/azure-pipelines/cli/cli-compile-and-publish.yml @@ -1,4 +1,6 @@ parameters: + - name: VSCODE_QUALITY + type: string - name: VSCODE_CLI_TARGET type: string - name: VSCODE_CLI_ARTIFACT @@ -11,6 +13,21 @@ parameters: default: false steps: + - ${{ if contains(parameters.VSCODE_CLI_TARGET, '-windows-') }}: + - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: + - pwsh: Write-Host "##vso[task.setvariable variable=VSCODE_CLI_PRODUCT_JSON]$(Build.SourcesDirectory)/product.json" + displayName: Set product.json path + - ${{ else }}: + - pwsh: Write-Host "##vso[task.setvariable variable=VSCODE_CLI_PRODUCT_JSON]$(Build.SourcesDirectory)/.build/distro/mixin/${{ parameters.VSCODE_QUALITY }}/product.json" + displayName: Set product.json path + - ${{ else }}: + - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: + - script: echo "##vso[task.setvariable variable=VSCODE_CLI_PRODUCT_JSON]$(Build.SourcesDirectory)/product.json" + displayName: Set product.json path + - ${{ else }}: + - script: echo "##vso[task.setvariable variable=VSCODE_CLI_PRODUCT_JSON]$(Build.SourcesDirectory)/.build/distro/mixin/${{ parameters.VSCODE_QUALITY }}/product.json" + displayName: Set product.json path + - ${{ if parameters.VSCODE_CHECK_ONLY }}: - script: rustup component add clippy && cargo clippy --target ${{ parameters.VSCODE_CLI_TARGET }} --bin=code displayName: Lint ${{ parameters.VSCODE_CLI_TARGET }} @@ -26,6 +43,7 @@ steps: workingDirectory: $(Build.SourcesDirectory)/cli env: CARGO_NET_GIT_FETCH_WITH_CLI: true + VSCODE_CLI_COMMIT: $(Build.SourceVersion) ${{ each pair in parameters.VSCODE_CLI_ENV }}: ${{ pair.key }}: ${{ pair.value }} @@ -33,6 +51,11 @@ steps: - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" + $AppProductJson = Get-Content -Raw -Path "$env:VSCODE_CLI_PRODUCT_JSON" | ConvertFrom-Json + $env:VSCODE_CLI_APPLICATION_NAME = $AppProductJson.applicationName + + Write-Host "##vso[task.setvariable variable=VSCODE_CLI_APPLICATION_NAME]$env:VSCODE_CLI_APPLICATION_NAME" + Move-Item -Path $(Build.SourcesDirectory)/cli/target/${{ parameters.VSCODE_CLI_TARGET }}/release/code.exe -Destination "$(Build.ArtifactStagingDirectory)/${env:VSCODE_CLI_APPLICATION_NAME}.exe" - task: ArchiveFiles@2 @@ -49,7 +72,10 @@ steps: - ${{ else }}: - script: | set -e - mv $(Build.SourcesDirectory)/cli/target/${{ parameters.VSCODE_CLI_TARGET }}/release/code $(Build.ArtifactStagingDirectory)/$(VSCODE_CLI_APPLICATION_NAME) + VSCODE_CLI_APPLICATION_NAME=$(node -p "require(\"$VSCODE_CLI_PRODUCT_JSON\").applicationName") + echo "##vso[task.setvariable variable=VSCODE_CLI_APPLICATION_NAME]$VSCODE_CLI_APPLICATION_NAME" + + mv $(Build.SourcesDirectory)/cli/target/${{ parameters.VSCODE_CLI_TARGET }}/release/code $(Build.ArtifactStagingDirectory)/$VSCODE_CLI_APPLICATION_NAME - ${{ if contains(parameters.VSCODE_CLI_TARGET, '-darwin') }}: - task: ArchiveFiles@2 diff --git a/build/azure-pipelines/cli/install-rust-posix.yml b/build/azure-pipelines/cli/install-rust-posix.yml index ee1e26f3505f8..d6022a44f7a33 100644 --- a/build/azure-pipelines/cli/install-rust-posix.yml +++ b/build/azure-pipelines/cli/install-rust-posix.yml @@ -1,7 +1,7 @@ parameters: - name: channel type: string - default: 1.65.0 + default: 1.71.0 - name: targets default: [] type: object diff --git a/build/azure-pipelines/cli/install-rust-win32.yml b/build/azure-pipelines/cli/install-rust-win32.yml index 62ff0ce4ec5d2..373c41dd95ff4 100644 --- a/build/azure-pipelines/cli/install-rust-win32.yml +++ b/build/azure-pipelines/cli/install-rust-win32.yml @@ -1,7 +1,7 @@ parameters: - name: channel type: string - default: 1.65.0 + default: 1.71.0 - name: targets default: [] type: object diff --git a/build/azure-pipelines/cli/prepare.js b/build/azure-pipelines/cli/prepare.js deleted file mode 100644 index bd11bc6a0a4c1..0000000000000 --- a/build/azure-pipelines/cli/prepare.js +++ /dev/null @@ -1,93 +0,0 @@ -"use strict"; -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -Object.defineProperty(exports, "__esModule", { value: true }); -const getVersion_1 = require("../../lib/getVersion"); -const fs = require("fs"); -const path = require("path"); -const packageJson = require("../../../package.json"); -const root = process.env.VSCODE_CLI_PREPARE_ROOT || path.dirname(path.dirname(path.dirname(__dirname))); -const readJSON = (path) => JSON.parse(fs.readFileSync(path, 'utf8')); -let productJsonPath; -const isOSS = process.env.VSCODE_QUALITY === 'oss' || !process.env.VSCODE_QUALITY; -if (isOSS) { - productJsonPath = path.join(root, 'product.json'); -} -else { - productJsonPath = path.join(root, 'mixin', process.env.VSCODE_QUALITY, 'product.json'); -} -console.error('Loading product.json from', productJsonPath); -const product = readJSON(productJsonPath); -const allProductsAndQualities = isOSS ? [product] : fs.readdirSync(path.join(root, 'mixin')) - .map(quality => ({ quality, json: readJSON(path.join(root, 'mixin', quality, 'product.json')) })); -const commit = (0, getVersion_1.getVersion)(root); -const makeQualityMap = (m) => { - const output = {}; - for (const { quality, json } of allProductsAndQualities) { - output[quality] = m(json, quality); - } - return output; -}; -/** - * Sets build environment variables for the CLI for current contextual info. - */ -const setLauncherEnvironmentVars = () => { - const vars = new Map([ - ['VSCODE_CLI_ALREADY_PREPARED', 'true'], - ['VSCODE_CLI_REMOTE_LICENSE_TEXT', product.serverLicense?.join('\\n')], - ['VSCODE_CLI_REMOTE_LICENSE_PROMPT', product.serverLicensePrompt], - ['VSCODE_CLI_AI_KEY', product.aiConfig?.cliKey], - ['VSCODE_CLI_AI_ENDPOINT', product.aiConfig?.cliEndpoint], - ['VSCODE_CLI_VERSION', packageJson.version], - ['VSCODE_CLI_UPDATE_ENDPOINT', product.updateUrl], - ['VSCODE_CLI_QUALITY', product.quality], - ['VSCODE_CLI_NAME_SHORT', product.nameShort], - ['VSCODE_CLI_NAME_LONG', product.nameLong], - ['VSCODE_CLI_QUALITYLESS_PRODUCT_NAME', product.nameLong.replace(/ - [a-z]+$/i, '')], - ['VSCODE_CLI_DOCUMENTATION_URL', product.documentationUrl], - ['VSCODE_CLI_APPLICATION_NAME', product.applicationName], - ['VSCODE_CLI_EDITOR_WEB_URL', product.tunnelApplicationConfig?.editorWebUrl], - ['VSCODE_CLI_TUNNEL_SERVICE_MUTEX', product.win32TunnelServiceMutex], - ['VSCODE_CLI_TUNNEL_CLI_MUTEX', product.win32TunnelMutex], - ['VSCODE_CLI_COMMIT', commit], - ['VSCODE_CLI_DEFAULT_PARENT_DATA_DIR', product.dataFolderName], - [ - 'VSCODE_CLI_WIN32_APP_IDS', - !isOSS && JSON.stringify(makeQualityMap(json => Object.entries(json) - .filter(([key]) => /^win32.*AppId$/.test(key)) - .map(([, value]) => String(value).replace(/[{}]/g, '')))), - ], - [ - 'VSCODE_CLI_NAME_LONG_MAP', - !isOSS && JSON.stringify(makeQualityMap(json => json.nameLong)), - ], - [ - 'VSCODE_CLI_APPLICATION_NAME_MAP', - !isOSS && JSON.stringify(makeQualityMap(json => json.applicationName)), - ], - [ - 'VSCODE_CLI_SERVER_NAME_MAP', - !isOSS && JSON.stringify(makeQualityMap(json => json.serverApplicationName)), - ], - [ - 'VSCODE_CLI_QUALITY_DOWNLOAD_URIS', - !isOSS && JSON.stringify(makeQualityMap(json => json.downloadUrl)), - ], - ]); - if (process.env.VSCODE_CLI_PREPARE_OUTPUT === 'json') { - console.log(JSON.stringify([...vars].filter(([, v]) => !!v))); - } - else { - for (const [key, value] of vars) { - if (value) { - console.log(`##vso[task.setvariable variable=${key}]${value}`); - } - } - } -}; -if (require.main === module) { - setLauncherEnvironmentVars(); -} -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJlcGFyZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInByZXBhcmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Z0dBR2dHOztBQUVoRyxxREFBa0Q7QUFDbEQseUJBQXlCO0FBQ3pCLDZCQUE2QjtBQUM3QixxREFBcUQ7QUFFckQsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyx1QkFBdUIsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDeEcsTUFBTSxRQUFRLEdBQUcsQ0FBQyxJQUFZLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQztBQUU3RSxJQUFJLGVBQXVCLENBQUM7QUFDNUIsTUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLEtBQUssS0FBSyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUM7QUFDbEYsSUFBSSxLQUFLLEVBQUU7SUFDVixlQUFlLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsY0FBYyxDQUFDLENBQUM7Q0FDbEQ7S0FBTTtJQUNOLGVBQWUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxPQUFPLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFlLEVBQUUsY0FBYyxDQUFDLENBQUM7Q0FDeEY7QUFFRCxPQUFPLENBQUMsS0FBSyxDQUFDLDJCQUEyQixFQUFFLGVBQWUsQ0FBQyxDQUFDO0FBQzVELE1BQU0sT0FBTyxHQUFHLFFBQVEsQ0FBQyxlQUFlLENBQUMsQ0FBQztBQUMxQyxNQUFNLHVCQUF1QixHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztLQUMxRixHQUFHLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxjQUFjLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ25HLE1BQU0sTUFBTSxHQUFHLElBQUEsdUJBQVUsRUFBQyxJQUFJLENBQUMsQ0FBQztBQUVoQyxNQUFNLGNBQWMsR0FBRyxDQUFJLENBQTJDLEVBQXFCLEVBQUU7SUFDNUYsTUFBTSxNQUFNLEdBQXNCLEVBQUUsQ0FBQztJQUNyQyxLQUFLLE1BQU0sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLElBQUksdUJBQXVCLEVBQUU7UUFDeEQsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7S0FDbkM7SUFDRCxPQUFPLE1BQU0sQ0FBQztBQUNmLENBQUMsQ0FBQztBQUVGOztHQUVHO0FBQ0gsTUFBTSwwQkFBMEIsR0FBRyxHQUFHLEVBQUU7SUFDdkMsTUFBTSxJQUFJLEdBQUcsSUFBSSxHQUFHLENBQUM7UUFDcEIsQ0FBQyw2QkFBNkIsRUFBRSxNQUFNLENBQUM7UUFDdkMsQ0FBQyxnQ0FBZ0MsRUFBRSxPQUFPLENBQUMsYUFBYSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN0RSxDQUFDLGtDQUFrQyxFQUFFLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQztRQUNqRSxDQUFDLG1CQUFtQixFQUFFLE9BQU8sQ0FBQyxRQUFRLEVBQUUsTUFBTSxDQUFDO1FBQy9DLENBQUMsd0JBQXdCLEVBQUUsT0FBTyxDQUFDLFFBQVEsRUFBRSxXQUFXLENBQUM7UUFDekQsQ0FBQyxvQkFBb0IsRUFBRSxXQUFXLENBQUMsT0FBTyxDQUFDO1FBQzNDLENBQUMsNEJBQTRCLEVBQUUsT0FBTyxDQUFDLFNBQVMsQ0FBQztRQUNqRCxDQUFDLG9CQUFvQixFQUFFLE9BQU8sQ0FBQyxPQUFPLENBQUM7UUFDdkMsQ0FBQyx1QkFBdUIsRUFBRSxPQUFPLENBQUMsU0FBUyxDQUFDO1FBQzVDLENBQUMsc0JBQXNCLEVBQUUsT0FBTyxDQUFDLFFBQVEsQ0FBQztRQUMxQyxDQUFDLHFDQUFxQyxFQUFFLE9BQU8sQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLGFBQWEsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNwRixDQUFDLDhCQUE4QixFQUFFLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQztRQUMxRCxDQUFDLDZCQUE2QixFQUFFLE9BQU8sQ0FBQyxlQUFlLENBQUM7UUFDeEQsQ0FBQywyQkFBMkIsRUFBRSxPQUFPLENBQUMsdUJBQXVCLEVBQUUsWUFBWSxDQUFDO1FBQzVFLENBQUMsaUNBQWlDLEVBQUUsT0FBTyxDQUFDLHVCQUF1QixDQUFDO1FBQ3BFLENBQUMsNkJBQTZCLEVBQUUsT0FBTyxDQUFDLGdCQUFnQixDQUFDO1FBQ3pELENBQUMsbUJBQW1CLEVBQUUsTUFBTSxDQUFDO1FBQzdCLENBQUMsb0NBQW9DLEVBQUUsT0FBTyxDQUFDLGNBQWMsQ0FBQztRQUM5RDtZQUNDLDBCQUEwQjtZQUMxQixDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsU0FBUyxDQUN2QixjQUFjLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQztpQkFDekMsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2lCQUM3QyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FDekQ7U0FDRDtRQUNEO1lBQ0MsMEJBQTBCO1lBQzFCLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1NBQy9EO1FBQ0Q7WUFDQyxpQ0FBaUM7WUFDakMsQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7U0FDdEU7UUFDRDtZQUNDLDRCQUE0QjtZQUM1QixDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO1NBQzVFO1FBQ0Q7WUFDQyxrQ0FBa0M7WUFDbEMsQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7U0FDbEU7S0FDRCxDQUFDLENBQUM7SUFFSCxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMseUJBQXlCLEtBQUssTUFBTSxFQUFFO1FBQ3JELE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0tBQzlEO1NBQU07UUFDTixLQUFLLE1BQU0sQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLElBQUksSUFBSSxFQUFFO1lBQ2hDLElBQUksS0FBSyxFQUFFO2dCQUNWLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUNBQW1DLEdBQUcsSUFBSSxLQUFLLEVBQUUsQ0FBQyxDQUFDO2FBQy9EO1NBQ0Q7S0FDRDtBQUVGLENBQUMsQ0FBQztBQUVGLElBQUksT0FBTyxDQUFDLElBQUksS0FBSyxNQUFNLEVBQUU7SUFDNUIsMEJBQTBCLEVBQUUsQ0FBQztDQUM3QiJ9 \ No newline at end of file diff --git a/build/azure-pipelines/cli/prepare.ts b/build/azure-pipelines/cli/prepare.ts deleted file mode 100644 index 7157dae3ecd7c..0000000000000 --- a/build/azure-pipelines/cli/prepare.ts +++ /dev/null @@ -1,99 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { getVersion } from '../../lib/getVersion'; -import * as fs from 'fs'; -import * as path from 'path'; -import * as packageJson from '../../../package.json'; - -const root = process.env.VSCODE_CLI_PREPARE_ROOT || path.dirname(path.dirname(path.dirname(__dirname))); -const readJSON = (path: string) => JSON.parse(fs.readFileSync(path, 'utf8')); - -let productJsonPath: string; -const isOSS = process.env.VSCODE_QUALITY === 'oss' || !process.env.VSCODE_QUALITY; -if (isOSS) { - productJsonPath = path.join(root, 'product.json'); -} else { - productJsonPath = path.join(root, 'mixin', process.env.VSCODE_QUALITY!, 'product.json'); -} - -console.error('Loading product.json from', productJsonPath); -const product = readJSON(productJsonPath); -const allProductsAndQualities = isOSS ? [product] : fs.readdirSync(path.join(root, 'mixin')) - .map(quality => ({ quality, json: readJSON(path.join(root, 'mixin', quality, 'product.json')) })); -const commit = getVersion(root); - -const makeQualityMap = (m: (productJson: any, quality: string) => T): Record => { - const output: Record = {}; - for (const { quality, json } of allProductsAndQualities) { - output[quality] = m(json, quality); - } - return output; -}; - -/** - * Sets build environment variables for the CLI for current contextual info. - */ -const setLauncherEnvironmentVars = () => { - const vars = new Map([ - ['VSCODE_CLI_ALREADY_PREPARED', 'true'], - ['VSCODE_CLI_REMOTE_LICENSE_TEXT', product.serverLicense?.join('\\n')], - ['VSCODE_CLI_REMOTE_LICENSE_PROMPT', product.serverLicensePrompt], - ['VSCODE_CLI_AI_KEY', product.aiConfig?.cliKey], - ['VSCODE_CLI_AI_ENDPOINT', product.aiConfig?.cliEndpoint], - ['VSCODE_CLI_VERSION', packageJson.version], - ['VSCODE_CLI_UPDATE_ENDPOINT', product.updateUrl], - ['VSCODE_CLI_QUALITY', product.quality], - ['VSCODE_CLI_NAME_SHORT', product.nameShort], - ['VSCODE_CLI_NAME_LONG', product.nameLong], - ['VSCODE_CLI_QUALITYLESS_PRODUCT_NAME', product.nameLong.replace(/ - [a-z]+$/i, '')], - ['VSCODE_CLI_DOCUMENTATION_URL', product.documentationUrl], - ['VSCODE_CLI_APPLICATION_NAME', product.applicationName], - ['VSCODE_CLI_EDITOR_WEB_URL', product.tunnelApplicationConfig?.editorWebUrl], - ['VSCODE_CLI_TUNNEL_SERVICE_MUTEX', product.win32TunnelServiceMutex], - ['VSCODE_CLI_TUNNEL_CLI_MUTEX', product.win32TunnelMutex], - ['VSCODE_CLI_COMMIT', commit], - ['VSCODE_CLI_DEFAULT_PARENT_DATA_DIR', product.dataFolderName], - [ - 'VSCODE_CLI_WIN32_APP_IDS', - !isOSS && JSON.stringify( - makeQualityMap(json => Object.entries(json) - .filter(([key]) => /^win32.*AppId$/.test(key)) - .map(([, value]) => String(value).replace(/[{}]/g, ''))), - ), - ], - [ - 'VSCODE_CLI_NAME_LONG_MAP', - !isOSS && JSON.stringify(makeQualityMap(json => json.nameLong)), - ], - [ - 'VSCODE_CLI_APPLICATION_NAME_MAP', - !isOSS && JSON.stringify(makeQualityMap(json => json.applicationName)), - ], - [ - 'VSCODE_CLI_SERVER_NAME_MAP', - !isOSS && JSON.stringify(makeQualityMap(json => json.serverApplicationName)), - ], - [ - 'VSCODE_CLI_QUALITY_DOWNLOAD_URIS', - !isOSS && JSON.stringify(makeQualityMap(json => json.downloadUrl)), - ], - ]); - - if (process.env.VSCODE_CLI_PREPARE_OUTPUT === 'json') { - console.log(JSON.stringify([...vars].filter(([, v]) => !!v))); - } else { - for (const [key, value] of vars) { - if (value) { - console.log(`##vso[task.setvariable variable=${key}]${value}`); - } - } - } - -}; - -if (require.main === module) { - setLauncherEnvironmentVars(); -} diff --git a/build/azure-pipelines/common/createAsset.js b/build/azure-pipelines/common/createAsset.js index 0ac5646ebac58..e4ca63b65739d 100644 --- a/build/azure-pipelines/common/createAsset.js +++ b/build/azure-pipelines/common/createAsset.js @@ -194,12 +194,18 @@ async function main() { } } const promiseResults = await Promise.allSettled(uploadPromises); - for (const result of promiseResults) { - if (result.status === 'rejected') { - throw result.reason; - } + const rejectedPromiseResults = promiseResults.filter(result => result.status === 'rejected'); + if (rejectedPromiseResults.length === 0) { + console.log('All blobs successfully uploaded.'); + } + else if (rejectedPromiseResults[0]?.reason?.message?.includes('already exists')) { + console.warn(rejectedPromiseResults[0].reason.message); + console.log('Some blobs successfully uploaded.'); + } + else { + // eslint-disable-next-line no-throw-literal + throw rejectedPromiseResults[0]?.reason; } - console.log('All blobs successfully uploaded.'); const assetUrl = `${process.env['AZURE_CDN_URL']}/${quality}/${blobName}`; const blobPath = new URL(assetUrl).pathname; const mooncakeUrl = `${process.env['MOONCAKE_CDN_URL']}${blobPath}`; @@ -229,4 +235,4 @@ main().then(() => { console.error(err); process.exit(1); }); -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JlYXRlQXNzZXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJjcmVhdGVBc3NldC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7OztnR0FHZ0c7O0FBRWhHLHlCQUF5QjtBQUV6QixpQ0FBaUM7QUFDakMsc0RBQXdJO0FBQ3hJLDZCQUE2QjtBQUM3QiwwQ0FBNkM7QUFDN0MsOENBQXlEO0FBQ3pELG1DQUFnQztBQWFoQyxJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtJQUM5QixPQUFPLENBQUMsS0FBSyxDQUFDLDJEQUEyRCxDQUFDLENBQUM7SUFDM0UsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0NBQ2pCO0FBRUQsd0ZBQXdGO0FBQ3hGLFNBQVMsV0FBVyxDQUFDLE9BQWUsRUFBRSxFQUFVLEVBQUUsSUFBWSxFQUFFLElBQVk7SUFDM0UsUUFBUSxFQUFFLEVBQUU7UUFDWCxLQUFLLE9BQU87WUFDWCxRQUFRLE9BQU8sRUFBRTtnQkFDaEIsS0FBSyxRQUFRLENBQUMsQ0FBQztvQkFDZCxNQUFNLEtBQUssR0FBRyxJQUFJLEtBQUssTUFBTSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLFNBQVMsSUFBSSxFQUFFLENBQUM7b0JBQzFELFFBQVEsSUFBSSxFQUFFO3dCQUNiLEtBQUssU0FBUzs0QkFDYixPQUFPLEdBQUcsS0FBSyxVQUFVLENBQUM7d0JBQzNCLEtBQUssT0FBTzs0QkFDWCxPQUFPLEtBQUssQ0FBQzt3QkFDZCxLQUFLLFlBQVk7NEJBQ2hCLE9BQU8sR0FBRyxLQUFLLE9BQU8sQ0FBQzt3QkFDeEI7NEJBQ0MsTUFBTSxJQUFJLEtBQUssQ0FBQyxpQkFBaUIsT0FBTyxJQUFJLEVBQUUsSUFBSSxJQUFJLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQztxQkFDbkU7aUJBQ0Q7Z0JBQ0QsS0FBSyxRQUFRO29CQUNaLElBQUksSUFBSSxLQUFLLE9BQU8sRUFBRTt3QkFDckIsTUFBTSxJQUFJLEtBQUssQ0FBQyxpQkFBaUIsT0FBTyxJQUFJLEVBQUUsSUFBSSxJQUFJLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQztxQkFDbEU7b0JBQ0QsT0FBTyxJQUFJLEtBQUssTUFBTSxDQUFDLENBQUMsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixJQUFJLEVBQUUsQ0FBQztnQkFDbEUsS0FBSyxLQUFLO29CQUNULElBQUksSUFBSSxLQUFLLE9BQU8sRUFBRTt3QkFDckIsTUFBTSxJQUFJLEtBQUssQ0FBQyxpQkFBaUIsT0FBTyxJQUFJLEVBQUUsSUFBSSxJQUFJLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQztxQkFDbEU7b0JBQ0QsT0FBTyxJQUFJLEtBQUssTUFBTSxDQUFDLENBQUMsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLENBQUMsZ0JBQWdCLElBQUksTUFBTSxDQUFDO2dCQUMxRSxLQUFLLEtBQUs7b0JBQ1QsT0FBTyxhQUFhLElBQUksRUFBRSxDQUFDO2dCQUM1QjtvQkFDQyxNQUFNLElBQUksS0FBSyxDQUFDLGlCQUFpQixPQUFPLElBQUksRUFBRSxJQUFJLElBQUksSUFBSSxJQUFJLEVBQUUsQ0FBQyxDQUFDO2FBQ25FO1FBQ0YsS0FBSyxRQUFRO1lBQ1osUUFBUSxPQUFPLEVBQUU7Z0JBQ2hCLEtBQUssUUFBUTtvQkFDWixPQUFPLGlCQUFpQixJQUFJLEVBQUUsQ0FBQztnQkFDaEMsS0FBSyxLQUFLO29CQUNULE9BQU8saUJBQWlCLElBQUksTUFBTSxDQUFDO2dCQUNwQyxLQUFLLEtBQUs7b0JBQ1QsT0FBTyxjQUFjLElBQUksRUFBRSxDQUFDO2dCQUM3QjtvQkFDQyxNQUFNLElBQUksS0FBSyxDQUFDLGlCQUFpQixPQUFPLElBQUksRUFBRSxJQUFJLElBQUksSUFBSSxJQUFJLEVBQUUsQ0FBQyxDQUFDO2FBQ25FO1FBQ0YsS0FBSyxPQUFPO1lBQ1gsUUFBUSxJQUFJLEVBQUU7Z0JBQ2IsS0FBSyxNQUFNO29CQUNWLE9BQU8sY0FBYyxJQUFJLEVBQUUsQ0FBQztnQkFDN0IsS0FBSyxrQkFBa0I7b0JBQ3RCLFFBQVEsT0FBTyxFQUFFO3dCQUNoQixLQUFLLFFBQVE7NEJBQ1osT0FBTyxTQUFTLElBQUksRUFBRSxDQUFDO3dCQUN4QixLQUFLLFFBQVE7NEJBQ1osT0FBTyxnQkFBZ0IsSUFBSSxFQUFFLENBQUM7d0JBQy9CLEtBQUssS0FBSzs0QkFDVCxPQUFPLElBQUksS0FBSyxZQUFZLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxnQkFBZ0IsSUFBSSxNQUFNLENBQUM7d0JBQzlFOzRCQUNDLE1BQU0sSUFBSSxLQUFLLENBQUMsaUJBQWlCLE9BQU8sSUFBSSxFQUFFLElBQUksSUFBSSxJQUFJLElBQUksRUFBRSxDQUFDLENBQUM7cUJBQ25FO2dCQUNGLEtBQUssYUFBYTtvQkFDakIsT0FBTyxhQUFhLElBQUksRUFBRSxDQUFDO2dCQUM1QixLQUFLLGFBQWE7b0JBQ2pCLE9BQU8sYUFBYSxJQUFJLEVBQUUsQ0FBQztnQkFDNUIsS0FBSyxLQUFLO29CQUNULE9BQU8sYUFBYSxJQUFJLEVBQUUsQ0FBQztnQkFDNUI7b0JBQ0MsTUFBTSxJQUFJLEtBQUssQ0FBQyxpQkFBaUIsT0FBTyxJQUFJLEVBQUUsSUFBSSxJQUFJLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQzthQUNuRTtRQUNGLEtBQUssUUFBUTtZQUNaLFFBQVEsT0FBTyxFQUFFO2dCQUNoQixLQUFLLFFBQVE7b0JBQ1osSUFBSSxJQUFJLEtBQUssS0FBSyxFQUFFO3dCQUNuQixPQUFPLFFBQVEsQ0FBQztxQkFDaEI7b0JBQ0QsT0FBTyxVQUFVLElBQUksRUFBRSxDQUFDO2dCQUN6QixLQUFLLFFBQVE7b0JBQ1osSUFBSSxJQUFJLEtBQUssS0FBSyxFQUFFO3dCQUNuQixPQUFPLGVBQWUsQ0FBQztxQkFDdkI7b0JBQ0QsT0FBTyxpQkFBaUIsSUFBSSxFQUFFLENBQUM7Z0JBQ2hDLEtBQUssS0FBSztvQkFDVCxJQUFJLElBQUksS0FBSyxLQUFLLEVBQUU7d0JBQ25CLE9BQU8sbUJBQW1CLENBQUM7cUJBQzNCO29CQUNELE9BQU8saUJBQWlCLElBQUksTUFBTSxDQUFDO2dCQUNwQyxLQUFLLEtBQUs7b0JBQ1QsT0FBTyxjQUFjLElBQUksRUFBRSxDQUFDO2dCQUM3QjtvQkFDQyxNQUFNLElBQUksS0FBSyxDQUFDLGlCQUFpQixPQUFPLElBQUksRUFBRSxJQUFJLElBQUksSUFBSSxJQUFJLEVBQUUsQ0FBQyxDQUFDO2FBQ25FO1FBQ0Y7WUFDQyxNQUFNLElBQUksS0FBSyxDQUFDLGlCQUFpQixPQUFPLElBQUksRUFBRSxJQUFJLElBQUksSUFBSSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0tBQ25FO0FBQ0YsQ0FBQztBQUVELDhFQUE4RTtBQUM5RSxTQUFTLFdBQVcsQ0FBQyxJQUFZO0lBQ2hDLFFBQVEsSUFBSSxFQUFFO1FBQ2IsS0FBSyxZQUFZO1lBQ2hCLE9BQU8sT0FBTyxDQUFDO1FBQ2hCLEtBQUssYUFBYSxDQUFDO1FBQ25CLEtBQUssYUFBYTtZQUNqQixPQUFPLFNBQVMsQ0FBQztRQUNsQjtZQUNDLE9BQU8sSUFBSSxDQUFDO0tBQ2I7QUFDRixDQUFDO0FBRUQsU0FBUyxVQUFVLENBQUMsUUFBZ0IsRUFBRSxNQUFnQjtJQUNyRCxPQUFPLElBQUksT0FBTyxDQUFTLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFO1FBQ25DLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUM7UUFFM0MsTUFBTTthQUNKLEVBQUUsQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7YUFDdEMsRUFBRSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7YUFDZCxFQUFFLENBQUMsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM5QyxDQUFDLENBQUMsQ0FBQztBQUNKLENBQUM7QUFFRCxTQUFTLE1BQU0sQ0FBQyxJQUFZO0lBQzNCLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7SUFFakMsSUFBSSxPQUFPLE1BQU0sS0FBSyxXQUFXLEVBQUU7UUFDbEMsTUFBTSxJQUFJLEtBQUssQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDLENBQUM7S0FDeEM7SUFFRCxPQUFPLE1BQU0sQ0FBQztBQUNmLENBQUM7QUFFRCxLQUFLLFVBQVUsSUFBSTtJQUNsQixNQUFNLENBQUMsRUFBRSxBQUFELEVBQUcsT0FBTyxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsZUFBZSxFQUFFLFFBQVEsRUFBRSxRQUFRLENBQUMsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDO0lBQ2xGLHdDQUF3QztJQUN4QyxNQUFNLFFBQVEsR0FBRyxXQUFXLENBQUMsT0FBTyxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsZUFBZSxDQUFDLENBQUM7SUFDakUsTUFBTSxJQUFJLEdBQUcsV0FBVyxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQzFDLE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0lBQ3pDLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO0lBRTdDLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUJBQW1CLENBQUMsQ0FBQztJQUVqQyxNQUFNLElBQUksR0FBRyxNQUFNLElBQUksT0FBTyxDQUFXLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM3RyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDO0lBRXZCLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBRTNCLE1BQU0sTUFBTSxHQUFHLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUM3QyxNQUFNLENBQUMsUUFBUSxFQUFFLFVBQVUsQ0FBQyxHQUFHLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLEVBQUUsVUFBVSxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFN0csT0FBTyxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDL0IsT0FBTyxDQUFDLEdBQUcsQ0FBQyxTQUFTLEVBQUUsVUFBVSxDQUFDLENBQUM7SUFFbkMsTUFBTSxRQUFRLEdBQUcsTUFBTSxHQUFHLEdBQUcsR0FBRyxRQUFRLENBQUM7SUFFekMsTUFBTSxzQkFBc0IsR0FBMkIsRUFBRSxZQUFZLEVBQUUsRUFBRSxlQUFlLEVBQUUscUNBQXNCLENBQUMsV0FBVyxFQUFFLFFBQVEsRUFBRSxDQUFDLEVBQUUsY0FBYyxFQUFFLEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSSxFQUFFLEVBQUUsQ0FBQztJQUU5SyxNQUFNLFVBQVUsR0FBRyxJQUFJLGlDQUFzQixDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsaUJBQWlCLENBQUUsRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLGlCQUFpQixDQUFFLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxxQkFBcUIsQ0FBRSxDQUFDLENBQUM7SUFDckosTUFBTSxpQkFBaUIsR0FBRyxJQUFJLGdDQUFpQixDQUFDLHNDQUFzQyxFQUFFLFVBQVUsRUFBRSxzQkFBc0IsQ0FBQyxDQUFDO0lBQzVILE1BQU0sZUFBZSxHQUFHLGlCQUFpQixDQUFDLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3RFLE1BQU0sVUFBVSxHQUFHLGVBQWUsQ0FBQyxrQkFBa0IsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUVoRSxNQUFNLFdBQVcsR0FBbUM7UUFDbkQsZUFBZSxFQUFFO1lBQ2hCLGVBQWUsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQztZQUN0QyxzQkFBc0IsRUFBRSx5QkFBeUIsUUFBUSxHQUFHO1lBQzVELGdCQUFnQixFQUFFLDBCQUEwQjtTQUM1QztLQUNELENBQUM7SUFFRixNQUFNLGNBQWMsR0FBb0IsRUFBRSxDQUFDO0lBRTNDLElBQUksTUFBTSxVQUFVLENBQUMsTUFBTSxFQUFFLEVBQUU7UUFDOUIsY0FBYyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLFFBQVEsT0FBTyxLQUFLLFFBQVEsd0NBQXdDLENBQUMsQ0FBQyxDQUFDLENBQUM7S0FDckg7U0FBTTtRQUNOLGNBQWMsQ0FBQyxJQUFJLENBQUMsSUFBQSxhQUFLLEVBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxFQUFFO1lBQzNDLE9BQU8sQ0FBQyxHQUFHLENBQUMsNkNBQTZDLE9BQU8sTUFBTSxDQUFDLENBQUM7WUFDeEUsTUFBTSxVQUFVLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxXQUFXLENBQUMsQ0FBQztZQUNuRCxPQUFPLENBQUMsR0FBRyxDQUFDLDhDQUE4QyxDQUFDLENBQUM7UUFDN0QsQ0FBQyxDQUFDLENBQUMsQ0FBQztLQUNKO0lBRUQsTUFBTSxzQkFBc0IsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsNEJBQTRCLENBQUMsSUFBSSxNQUFNLENBQUMsQ0FBQztJQUVqRyxJQUFJLHNCQUFzQixFQUFFO1FBQzNCLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxpQ0FBc0IsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLDBCQUEwQixDQUFFLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQywwQkFBMEIsQ0FBRSxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsOEJBQThCLENBQUUsQ0FBQyxDQUFDO1FBQ3hMLE1BQU0seUJBQXlCLEdBQUcsSUFBSSxnQ0FBaUIsQ0FBQywyQ0FBMkMsRUFBRSxrQkFBa0IsRUFBRSxzQkFBc0IsQ0FBQyxDQUFDO1FBQ2pKLE1BQU0sdUJBQXVCLEdBQUcseUJBQXlCLENBQUMsa0JBQWtCLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDdEYsTUFBTSxrQkFBa0IsR0FBRyx1QkFBdUIsQ0FBQyxrQkFBa0IsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUVoRixJQUFJLE1BQU0sa0JBQWtCLENBQUMsTUFBTSxFQUFFLEVBQUU7WUFDdEMsY0FBYyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLGlCQUFpQixPQUFPLEtBQUssUUFBUSx3Q0FBd0MsQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUM5SDthQUFNO1lBQ04sY0FBYyxDQUFDLElBQUksQ0FBQyxJQUFBLGFBQUssRUFBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUU7Z0JBQzNDLE9BQU8sQ0FBQyxHQUFHLENBQUMsc0RBQXNELE9BQU8sTUFBTSxDQUFDLENBQUM7Z0JBQ2pGLE1BQU0sa0JBQWtCLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxXQUFXLENBQUMsQ0FBQztnQkFDM0QsT0FBTyxDQUFDLEdBQUcsQ0FBQyx1REFBdUQsQ0FBQyxDQUFDO1lBQ3RFLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDSjtLQUNEO0lBRUQsTUFBTSxjQUFjLEdBQUcsTUFBTSxPQUFPLENBQUMsVUFBVSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBRWhFLEtBQUssTUFBTSxNQUFNLElBQUksY0FBYyxFQUFFO1FBQ3BDLElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxVQUFVLEVBQUU7WUFDakMsTUFBTSxNQUFNLENBQUMsTUFBTSxDQUFDO1NBQ3BCO0tBQ0Q7SUFFRCxPQUFPLENBQUMsR0FBRyxDQUFDLGtDQUFrQyxDQUFDLENBQUM7SUFFaEQsTUFBTSxRQUFRLEdBQUcsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxJQUFJLE9BQU8sSUFBSSxRQUFRLEVBQUUsQ0FBQztJQUMxRSxNQUFNLFFBQVEsR0FBRyxJQUFJLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxRQUFRLENBQUM7SUFDNUMsTUFBTSxXQUFXLEdBQUcsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLGtCQUFrQixDQUFDLEdBQUcsUUFBUSxFQUFFLENBQUM7SUFFcEUsTUFBTSxLQUFLLEdBQVU7UUFDcEIsUUFBUTtRQUNSLElBQUk7UUFDSixHQUFHLEVBQUUsUUFBUTtRQUNiLElBQUksRUFBRSxRQUFRO1FBQ2QsV0FBVztRQUNYLFVBQVU7UUFDVixJQUFJO0tBQ0osQ0FBQztJQUVGLG1FQUFtRTtJQUNuRSxJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUU7UUFDM0IsS0FBSyxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQztLQUNoQztJQUVELE9BQU8sQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBRXpELE1BQU0sTUFBTSxHQUFHLElBQUkscUJBQVksQ0FBQyxFQUFFLFFBQVEsRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLDJCQUEyQixDQUFFLEVBQUUsY0FBYyxFQUFFLFVBQVUsRUFBRSxDQUFDLENBQUM7SUFDckgsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDO0lBQ3JFLE1BQU0sSUFBQSxhQUFLLEVBQUMsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLGVBQWUsQ0FBQyxhQUFhLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBRSxFQUFFLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFN0YsT0FBTyxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsQ0FBQztBQUMxQixDQUFDO0FBRUQsSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRTtJQUNoQixPQUFPLENBQUMsR0FBRyxDQUFDLDRCQUE0QixDQUFDLENBQUM7SUFDMUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNqQixDQUFDLEVBQUUsR0FBRyxDQUFDLEVBQUU7SUFDUixPQUFPLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ25CLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDakIsQ0FBQyxDQUFDLENBQUMifQ== \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JlYXRlQXNzZXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJjcmVhdGVBc3NldC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7OztnR0FHZ0c7O0FBRWhHLHlCQUF5QjtBQUV6QixpQ0FBaUM7QUFDakMsc0RBQXdJO0FBQ3hJLDZCQUE2QjtBQUM3QiwwQ0FBNkM7QUFDN0MsOENBQXlEO0FBQ3pELG1DQUFnQztBQWFoQyxJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtJQUM5QixPQUFPLENBQUMsS0FBSyxDQUFDLDJEQUEyRCxDQUFDLENBQUM7SUFDM0UsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0NBQ2pCO0FBRUQsd0ZBQXdGO0FBQ3hGLFNBQVMsV0FBVyxDQUFDLE9BQWUsRUFBRSxFQUFVLEVBQUUsSUFBWSxFQUFFLElBQVk7SUFDM0UsUUFBUSxFQUFFLEVBQUU7UUFDWCxLQUFLLE9BQU87WUFDWCxRQUFRLE9BQU8sRUFBRTtnQkFDaEIsS0FBSyxRQUFRLENBQUMsQ0FBQztvQkFDZCxNQUFNLEtBQUssR0FBRyxJQUFJLEtBQUssTUFBTSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLFNBQVMsSUFBSSxFQUFFLENBQUM7b0JBQzFELFFBQVEsSUFBSSxFQUFFO3dCQUNiLEtBQUssU0FBUzs0QkFDYixPQUFPLEdBQUcsS0FBSyxVQUFVLENBQUM7d0JBQzNCLEtBQUssT0FBTzs0QkFDWCxPQUFPLEtBQUssQ0FBQzt3QkFDZCxLQUFLLFlBQVk7NEJBQ2hCLE9BQU8sR0FBRyxLQUFLLE9BQU8sQ0FBQzt3QkFDeEI7NEJBQ0MsTUFBTSxJQUFJLEtBQUssQ0FBQyxpQkFBaUIsT0FBTyxJQUFJLEVBQUUsSUFBSSxJQUFJLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQztxQkFDbkU7aUJBQ0Q7Z0JBQ0QsS0FBSyxRQUFRO29CQUNaLElBQUksSUFBSSxLQUFLLE9BQU8s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 \ No newline at end of file diff --git a/build/azure-pipelines/common/createAsset.ts b/build/azure-pipelines/common/createAsset.ts index 32d9c847c120d..74c76407a78ca 100644 --- a/build/azure-pipelines/common/createAsset.ts +++ b/build/azure-pipelines/common/createAsset.ts @@ -227,15 +227,18 @@ async function main(): Promise { } const promiseResults = await Promise.allSettled(uploadPromises); + const rejectedPromiseResults = promiseResults.filter(result => result.status === 'rejected') as PromiseRejectedResult[]; - for (const result of promiseResults) { - if (result.status === 'rejected') { - throw result.reason; - } + if (rejectedPromiseResults.length === 0) { + console.log('All blobs successfully uploaded.'); + } else if (rejectedPromiseResults[0]?.reason?.message?.includes('already exists')) { + console.warn(rejectedPromiseResults[0].reason.message); + console.log('Some blobs successfully uploaded.'); + } else { + // eslint-disable-next-line no-throw-literal + throw rejectedPromiseResults[0]?.reason; } - console.log('All blobs successfully uploaded.'); - const assetUrl = `${process.env['AZURE_CDN_URL']}/${quality}/${blobName}`; const blobPath = new URL(assetUrl).pathname; const mooncakeUrl = `${process.env['MOONCAKE_CDN_URL']}${blobPath}`; diff --git a/build/azure-pipelines/common/releaseBuild.js b/build/azure-pipelines/common/releaseBuild.js index 5ba4e218ae069..752cb4db92c50 100644 --- a/build/azure-pipelines/common/releaseBuild.js +++ b/build/azure-pipelines/common/releaseBuild.js @@ -46,11 +46,12 @@ async function main(force) { await (0, retry_1.retry)(() => scripts.storedProcedure('releaseBuild').execute('', [commit])); } const [, , force] = process.argv; -main(force === 'true').then(() => { +console.log(process.argv); +main(/^true$/i.test(force)).then(() => { console.log('Build successfully released'); process.exit(0); }, err => { console.error(err); process.exit(1); }); -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVsZWFzZUJ1aWxkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsicmVsZWFzZUJ1aWxkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7O2dHQUdnRzs7QUFFaEcsOENBQXlEO0FBQ3pELDBDQUE2QztBQUM3QyxtQ0FBZ0M7QUFFaEMsU0FBUyxNQUFNLENBQUMsSUFBWTtJQUMzQixNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBRWpDLElBQUksT0FBTyxNQUFNLEtBQUssV0FBVyxFQUFFO1FBQ2xDLE1BQU0sSUFBSSxLQUFLLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQyxDQUFDO0tBQ3hDO0lBRUQsT0FBTyxNQUFNLENBQUM7QUFDZixDQUFDO0FBT0QsU0FBUyxtQkFBbUIsQ0FBQyxPQUFlO0lBQzNDLE9BQU87UUFDTixFQUFFLEVBQUUsT0FBTztRQUNYLE1BQU0sRUFBRSxLQUFLO0tBQ2IsQ0FBQztBQUNILENBQUM7QUFFRCxLQUFLLFVBQVUsU0FBUyxDQUFDLE1BQW9CLEVBQUUsT0FBZTtJQUM3RCxNQUFNLEtBQUssR0FBRyx1Q0FBdUMsT0FBTyxHQUFHLENBQUM7SUFFaEUsTUFBTSxHQUFHLEdBQUcsTUFBTSxNQUFNLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBRTlGLElBQUksR0FBRyxDQUFDLFNBQVMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO1FBQy9CLE9BQU8sbUJBQW1CLENBQUMsT0FBTyxDQUFDLENBQUM7S0FDcEM7SUFFRCxPQUFPLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFXLENBQUM7QUFDbkMsQ0FBQztBQUVELEtBQUssVUFBVSxJQUFJLENBQUMsS0FBYztJQUNqQyxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMscUJBQXFCLENBQUMsQ0FBQztJQUM3QyxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUV6QyxNQUFNLGNBQWMsR0FBRyxJQUFJLGlDQUFzQixDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsaUJBQWlCLENBQUUsRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLGlCQUFpQixDQUFFLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxxQkFBcUIsQ0FBRSxDQUFDLENBQUM7SUFDekosTUFBTSxNQUFNLEdBQUcsSUFBSSxxQkFBWSxDQUFDLEVBQUUsUUFBUSxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsMkJBQTJCLENBQUUsRUFBRSxjQUFjLEVBQUUsQ0FBQyxDQUFDO0lBRXpHLElBQUksQ0FBQyxLQUFLLEVBQUU7UUFDWCxNQUFNLE1BQU0sR0FBRyxNQUFNLFNBQVMsQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFFaEQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUV2QyxJQUFJLE1BQU0sQ0FBQyxNQUFNLEVBQUU7WUFDbEIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxvQ0FBb0MsT0FBTyxhQUFhLENBQUMsQ0FBQztZQUN0RSxPQUFPO1NBQ1A7S0FDRDtJQUVELE9BQU8sQ0FBQyxHQUFHLENBQUMsbUJBQW1CLE1BQU0sS0FBSyxDQUFDLENBQUM7SUFFNUMsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDO0lBQ3JFLE1BQU0sSUFBQSxhQUFLLEVBQUMsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLGVBQWUsQ0FBQyxjQUFjLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2xGLENBQUM7QUFFRCxNQUFNLENBQUMsRUFBRSxBQUFELEVBQUcsS0FBSyxDQUFDLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQztBQUVqQyxJQUFJLENBQUMsS0FBSyxLQUFLLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUU7SUFDaEMsT0FBTyxDQUFDLEdBQUcsQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDO0lBQzNDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDakIsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxFQUFFO0lBQ1IsT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNuQixPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLENBQUMsQ0FBQyxDQUFDIn0= \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVsZWFzZUJ1aWxkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsicmVsZWFzZUJ1aWxkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7O2dHQUdnRzs7QUFFaEcsOENBQXlEO0FBQ3pELDBDQUE2QztBQUM3QyxtQ0FBZ0M7QUFFaEMsU0FBUyxNQUFNLENBQUMsSUFBWTtJQUMzQixNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBRWpDLElBQUksT0FBTyxNQUFNLEtBQUssV0FBVyxFQUFFO1FBQ2xDLE1BQU0sSUFBSSxLQUFLLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQyxDQUFDO0tBQ3hDO0lBRUQsT0FBTyxNQUFNLENBQUM7QUFDZixDQUFDO0FBT0QsU0FBUyxtQkFBbUIsQ0FBQyxPQUFlO0lBQzNDLE9BQU87UUFDTixFQUFFLEVBQUUsT0FBTztRQUNYLE1BQU0sRUFBRSxLQUFLO0tBQ2IsQ0FBQztBQUNILENBQUM7QUFFRCxLQUFLLFVBQVUsU0FBUyxDQUFDLE1BQW9CLEVBQUUsT0FBZTtJQUM3RCxNQUFNLEtBQUssR0FBRyx1Q0FBdUMsT0FBTyxHQUFHLENBQUM7SUFFaEUsTUFBTSxHQUFHLEdBQUcsTUFBTSxNQUFNLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBRTlGLElBQUksR0FBRyxDQUFDLFNBQVMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO1FBQy9CLE9BQU8sbUJBQW1CLENBQUMsT0FBTyxDQUFDLENBQUM7S0FDcEM7SUFFRCxPQUFPLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFXLENBQUM7QUFDbkMsQ0FBQztBQUVELEtBQUssVUFBVSxJQUFJLENBQUMsS0FBYztJQUNqQyxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMscUJBQXFCLENBQUMsQ0FBQztJQUM3QyxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUV6QyxNQUFNLGNBQWMsR0FBRyxJQUFJLGlDQUFzQixDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsaUJBQWlCLENBQUUsRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLGlCQUFpQixDQUFFLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxxQkFBcUIsQ0FBRSxDQUFDLENBQUM7SUFDekosTUFBTSxNQUFNLEdBQUcsSUFBSSxxQkFBWSxDQUFDLEVBQUUsUUFBUSxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsMkJBQTJCLENBQUUsRUFBRSxjQUFjLEVBQUUsQ0FBQyxDQUFDO0lBRXpHLElBQUksQ0FBQyxLQUFLLEVBQUU7UUFDWCxNQUFNLE1BQU0sR0FBRyxNQUFNLFNBQVMsQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFFaEQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUV2QyxJQUFJLE1BQU0sQ0FBQyxNQUFNLEVBQUU7WUFDbEIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxvQ0FBb0MsT0FBTyxhQUFhLENBQUMsQ0FBQztZQUN0RSxPQUFPO1NBQ1A7S0FDRDtJQUVELE9BQU8sQ0FBQyxHQUFHLENBQUMsbUJBQW1CLE1BQU0sS0FBSyxDQUFDLENBQUM7SUFFNUMsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDO0lBQ3JFLE1BQU0sSUFBQSxhQUFLLEVBQUMsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLGVBQWUsQ0FBQyxjQUFjLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2xGLENBQUM7QUFFRCxNQUFNLENBQUMsRUFBRSxBQUFELEVBQUcsS0FBSyxDQUFDLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQztBQUVqQyxPQUFPLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUUxQixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUU7SUFDckMsT0FBTyxDQUFDLEdBQUcsQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDO0lBQzNDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDakIsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxFQUFFO0lBQ1IsT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNuQixPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLENBQUMsQ0FBQyxDQUFDIn0= \ No newline at end of file diff --git a/build/azure-pipelines/common/releaseBuild.ts b/build/azure-pipelines/common/releaseBuild.ts index fda389f345545..2e8fff04fb409 100644 --- a/build/azure-pipelines/common/releaseBuild.ts +++ b/build/azure-pipelines/common/releaseBuild.ts @@ -67,7 +67,9 @@ async function main(force: boolean): Promise { const [, , force] = process.argv; -main(force === 'true').then(() => { +console.log(process.argv); + +main(/^true$/i.test(force)).then(() => { console.log('Build successfully released'); process.exit(0); }, err => { diff --git a/build/azure-pipelines/darwin/cli-build-darwin.yml b/build/azure-pipelines/darwin/cli-build-darwin.yml index 8d98f0e93aace..ae8f0e846521b 100644 --- a/build/azure-pipelines/darwin/cli-build-darwin.yml +++ b/build/azure-pipelines/darwin/cli-build-darwin.yml @@ -14,7 +14,7 @@ parameters: steps: - task: NodeTool@0 inputs: - versionSpec: "16.x" + versionSpec: "18.x" - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - template: ../cli/cli-apply-patches.yml @@ -34,13 +34,6 @@ steps: tar -xvzf $(Build.ArtifactStagingDirectory)/vscode-internal-openssl-prebuilt-0.0.8.tgz --strip-components=1 --directory=$(Build.ArtifactStagingDirectory)/openssl displayName: Extract openssl prebuilt - - script: node build/azure-pipelines/cli/prepare.js - displayName: Prepare CLI build - env: - VSCODE_CLI_PREPARE_ROOT: $(Build.SourcesDirectory)/.build/distro - VSCODE_QUALITY: ${{ parameters.VSCODE_QUALITY }} - GITHUB_TOKEN: "$(github-distro-mixin-password)" - - template: ../cli/install-rust-posix.yml parameters: targets: @@ -52,6 +45,7 @@ steps: - ${{ if eq(parameters.VSCODE_BUILD_MACOS, true) }}: - template: ../cli/cli-compile-and-publish.yml parameters: + VSCODE_QUALITY: ${{ parameters.VSCODE_QUALITY }} VSCODE_CLI_TARGET: x86_64-apple-darwin VSCODE_CLI_ARTIFACT: unsigned_vscode_cli_darwin_x64_cli VSCODE_CHECK_ONLY: ${{ parameters.VSCODE_CHECK_ONLY }} @@ -62,6 +56,7 @@ steps: - ${{ if eq(parameters.VSCODE_BUILD_MACOS_ARM64, true) }}: - template: ../cli/cli-compile-and-publish.yml parameters: + VSCODE_QUALITY: ${{ parameters.VSCODE_QUALITY }} VSCODE_CLI_TARGET: aarch64-apple-darwin VSCODE_CLI_ARTIFACT: unsigned_vscode_cli_darwin_arm64_cli VSCODE_CHECK_ONLY: ${{ parameters.VSCODE_CHECK_ONLY }} diff --git a/build/azure-pipelines/darwin/product-build-darwin-cli-sign.yml b/build/azure-pipelines/darwin/product-build-darwin-cli-sign.yml index ec9ac07e606d4..0ee0d9be4a6a5 100644 --- a/build/azure-pipelines/darwin/product-build-darwin-cli-sign.yml +++ b/build/azure-pipelines/darwin/product-build-darwin-cli-sign.yml @@ -7,7 +7,7 @@ parameters: steps: - task: NodeTool@0 inputs: - versionSpec: "16.x" + versionSpec: "18.x" - script: node build/setup-npm-registry.js $NPM_REGISTRY build condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) @@ -16,7 +16,10 @@ steps: - script: | set -e npm config set registry "$NPM_REGISTRY" --location=project - npm config set always-auth=true --location=project + # npm >v7 deprecated the `always-auth` config option, refs npm/cli@72a7eeb + # following is a workaround for yarn to send authorization header + # for GET requests to the registry. + echo "always-auth=true" >> .npmrc yarn config set registry "$NPM_REGISTRY" workingDirectory: build condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) diff --git a/build/azure-pipelines/darwin/product-build-darwin-sign.yml b/build/azure-pipelines/darwin/product-build-darwin-sign.yml index 076788581c03a..3cbe9d329fb38 100644 --- a/build/azure-pipelines/darwin/product-build-darwin-sign.yml +++ b/build/azure-pipelines/darwin/product-build-darwin-sign.yml @@ -1,7 +1,7 @@ steps: - task: NodeTool@0 inputs: - versionSpec: "16.x" + versionSpec: "18.x" - task: UseDotNet@2 inputs: diff --git a/build/azure-pipelines/darwin/product-build-darwin-test.yml b/build/azure-pipelines/darwin/product-build-darwin-test.yml index 955b19749a61f..1ca8c9ec1a9ec 100644 --- a/build/azure-pipelines/darwin/product-build-darwin-test.yml +++ b/build/azure-pipelines/darwin/product-build-darwin-test.yml @@ -13,6 +13,7 @@ steps: env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Download Electron and Playwright + retryCountOnTaskFailure: 3 - ${{ if eq(parameters.VSCODE_RUN_UNIT_TESTS, true) }}: - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: diff --git a/build/azure-pipelines/darwin/product-build-darwin-universal.yml b/build/azure-pipelines/darwin/product-build-darwin-universal.yml index c52e8129a5585..3e4a2a8d8a2f5 100644 --- a/build/azure-pipelines/darwin/product-build-darwin-universal.yml +++ b/build/azure-pipelines/darwin/product-build-darwin-universal.yml @@ -1,7 +1,7 @@ steps: - task: NodeTool@0 inputs: - versionSpec: "16.x" + versionSpec: "18.x" - template: ../distro/download-distro.yml @@ -19,7 +19,10 @@ steps: - script: | set -e npm config set registry "$NPM_REGISTRY" --location=project - npm config set always-auth=true --location=project + # npm >v7 deprecated the `always-auth` config option, refs npm/cli@72a7eeb + # following is a workaround for yarn to send authorization header + # for GET requests to the registry. + echo "always-auth=true" >> .npmrc yarn config set registry "$NPM_REGISTRY" workingDirectory: build condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) diff --git a/build/azure-pipelines/darwin/product-build-darwin.yml b/build/azure-pipelines/darwin/product-build-darwin.yml index 3d8e6dc67b80d..dedc227caa777 100644 --- a/build/azure-pipelines/darwin/product-build-darwin.yml +++ b/build/azure-pipelines/darwin/product-build-darwin.yml @@ -18,7 +18,7 @@ steps: - task: NodeTool@0 inputs: - versionSpec: "16.x" + versionSpec: "18.x" - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - template: ../distro/download-distro.yml @@ -60,7 +60,10 @@ steps: - script: | set -e npm config set registry "$NPM_REGISTRY" --location=project - npm config set always-auth=true --location=project + # npm >v7 deprecated the `always-auth` config option, refs npm/cli@72a7eeb + # following is a workaround for yarn to send authorization header + # for GET requests to the registry. + echo "always-auth=true" >> .npmrc yarn config set registry "$NPM_REGISTRY" condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM & Yarn diff --git a/build/azure-pipelines/distro-build.yml b/build/azure-pipelines/distro-build.yml index fe05f56723b78..6aabd52c76ced 100644 --- a/build/azure-pipelines/distro-build.yml +++ b/build/azure-pipelines/distro-build.yml @@ -9,5 +9,5 @@ pr: none steps: - task: NodeTool@0 inputs: - versionSpec: "16.x" + versionSpec: "18.x" - template: ./distro/download-distro.yml diff --git a/build/azure-pipelines/linux/cli-build-linux.yml b/build/azure-pipelines/linux/cli-build-linux.yml index 4df126682cf5e..b77b78aa1a873 100644 --- a/build/azure-pipelines/linux/cli-build-linux.yml +++ b/build/azure-pipelines/linux/cli-build-linux.yml @@ -17,7 +17,7 @@ parameters: steps: - task: NodeTool@0 inputs: - versionSpec: "16.x" + versionSpec: "18.x" - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - template: ../cli/cli-apply-patches.yml @@ -45,13 +45,6 @@ steps: - bash: sudo apt-get install -yq gcc-aarch64-linux-gnu g++-aarch64-linux-gnu binutils-aarch64-linux-gnu displayName: Install arm64 toolchains - - script: node build/azure-pipelines/cli/prepare.js - displayName: Prepare CLI build - env: - VSCODE_CLI_PREPARE_ROOT: $(Build.SourcesDirectory)/.build/distro - VSCODE_QUALITY: ${{ parameters.VSCODE_QUALITY }} - GITHUB_TOKEN: "$(github-distro-mixin-password)" - - template: ../cli/install-rust-posix.yml parameters: targets: @@ -65,6 +58,7 @@ steps: - ${{ if eq(parameters.VSCODE_BUILD_LINUX_ARM64, true) }}: - template: ../cli/cli-compile-and-publish.yml parameters: + VSCODE_QUALITY: ${{ parameters.VSCODE_QUALITY }} VSCODE_CLI_TARGET: aarch64-unknown-linux-gnu VSCODE_CLI_ARTIFACT: vscode_cli_linux_arm64_cli VSCODE_CHECK_ONLY: ${{ parameters.VSCODE_CHECK_ONLY }} @@ -76,6 +70,7 @@ steps: - ${{ if eq(parameters.VSCODE_BUILD_LINUX, true) }}: - template: ../cli/cli-compile-and-publish.yml parameters: + VSCODE_QUALITY: ${{ parameters.VSCODE_QUALITY }} VSCODE_CLI_TARGET: x86_64-unknown-linux-gnu VSCODE_CLI_ARTIFACT: vscode_cli_linux_x64_cli VSCODE_CHECK_ONLY: ${{ parameters.VSCODE_CHECK_ONLY }} @@ -86,6 +81,7 @@ steps: - ${{ if eq(parameters.VSCODE_BUILD_LINUX_ARMHF, true) }}: - template: ../cli/cli-compile-and-publish.yml parameters: + VSCODE_QUALITY: ${{ parameters.VSCODE_QUALITY }} VSCODE_CLI_TARGET: armv7-unknown-linux-gnueabihf VSCODE_CLI_ARTIFACT: vscode_cli_linux_armhf_cli VSCODE_CHECK_ONLY: ${{ parameters.VSCODE_CHECK_ONLY }} diff --git a/build/azure-pipelines/linux/install.sh b/build/azure-pipelines/linux/install.sh new file mode 100755 index 0000000000000..c8d746870800f --- /dev/null +++ b/build/azure-pipelines/linux/install.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + +set -e + +# To workaround the issue of yarn not respecting the registry value from .npmrc +yarn config set registry "$NPM_REGISTRY" + +if [ -z "$CC" ] || [ -z "$CXX" ]; then + # Download clang based on chromium revision used by vscode + curl -s https://raw.githubusercontent.com/chromium/chromium/114.0.5735.199/tools/clang/scripts/update.py | python - --output-dir=$PWD/.build/CR_Clang --host-os=linux + + # Download libcxx headers and objects from upstream electron releases + DEBUG=libcxx-fetcher \ + VSCODE_LIBCXX_OBJECTS_DIR=$PWD/.build/libcxx-objects \ + VSCODE_LIBCXX_HEADERS_DIR=$PWD/.build/libcxx_headers \ + VSCODE_LIBCXXABI_HEADERS_DIR=$PWD/.build/libcxxabi_headers \ + VSCODE_ARCH="$npm_config_arch" \ + node build/linux/libcxx-fetcher.js + + # Set compiler toolchain + # Flags for the client build are based on + # https://source.chromium.org/chromium/chromium/src/+/refs/tags/114.0.5735.199:build/config/arm.gni + # https://source.chromium.org/chromium/chromium/src/+/refs/tags/114.0.5735.199:build/config/compiler/BUILD.gn + # https://source.chromium.org/chromium/chromium/src/+/refs/tags/114.0.5735.199:build/config/c++/BUILD.gn + export CC=$PWD/.build/CR_Clang/bin/clang + export CXX=$PWD/.build/CR_Clang/bin/clang++ + export CXXFLAGS="-nostdinc++ -D__NO_INLINE__ -I$PWD/.build/libcxx_headers -isystem$PWD/.build/libcxx_headers/include -isystem$PWD/.build/libcxxabi_headers/include -fPIC -flto=thin -fsplit-lto-unit -D_LIBCPP_ABI_NAMESPACE=Cr" + export LDFLAGS="-stdlib=libc++ -fuse-ld=lld -flto=thin -L$PWD/.build/libcxx-objects -lc++abi -Wl,--lto-O0" + export VSCODE_REMOTE_CC=$(which gcc) + export VSCODE_REMOTE_CXX=$(which g++) +fi + +for i in {1..5}; do # try 5 times + yarn --frozen-lockfile --check-files && break + if [ $i -eq 3 ]; then + echo "Yarn failed too many times" >&2 + exit 1 + fi + echo "Yarn failed $i, trying again..." +done diff --git a/build/azure-pipelines/linux/product-build-linux-test.yml b/build/azure-pipelines/linux/product-build-linux-test.yml index 7532c43c7c9b6..bb75be37e4b5b 100644 --- a/build/azure-pipelines/linux/product-build-linux-test.yml +++ b/build/azure-pipelines/linux/product-build-linux-test.yml @@ -13,17 +13,7 @@ steps: env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Download Electron and Playwright - - - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - sudo apt-get update - sudo apt-get install -y libxkbfile-dev pkg-config libsecret-1-dev libxss1 dbus xvfb libgtk-3-0 libgbm1 - sudo cp build/azure-pipelines/linux/xvfb.init /etc/init.d/xvfb - sudo chmod +x /etc/init.d/xvfb - sudo update-rc.d xvfb defaults - sudo service xvfb start - displayName: Setup build environment + retryCountOnTaskFailure: 3 - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - script: | diff --git a/build/azure-pipelines/linux/product-build-linux.yml b/build/azure-pipelines/linux/product-build-linux.yml index 99bbd4ca6bd98..2145e588b1cff 100644 --- a/build/azure-pipelines/linux/product-build-linux.yml +++ b/build/azure-pipelines/linux/product-build-linux.yml @@ -20,7 +20,7 @@ steps: - task: NodeTool@0 inputs: - versionSpec: "16.x" + versionSpec: "18.x" - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - template: ../distro/download-distro.yml @@ -41,15 +41,28 @@ steps: - script: tar -xzf $(Build.ArtifactStagingDirectory)/compilation.tar.gz displayName: Extract compilation output - - script: | - set -e - # Start X server - /etc/init.d/xvfb start - # Start dbus session - DBUS_LAUNCH_RESULT=$(sudo dbus-daemon --config-file=/usr/share/dbus-1/system.conf --print-address) - echo "##vso[task.setvariable variable=DBUS_SESSION_BUS_ADDRESS]$DBUS_LAUNCH_RESULT" - displayName: Setup system services - condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64')) + - script: | + set -e + # Start X server + sudo apt-get update + sudo apt-get install -y pkg-config \ + libxss1 \ + dbus \ + xvfb \ + libgtk-3-0 \ + libgbm1 \ + libxkbfile-dev \ + libsecret-1-dev \ + libkrb5-dev + sudo cp build/azure-pipelines/linux/xvfb.init /etc/init.d/xvfb + sudo chmod +x /etc/init.d/xvfb + sudo update-rc.d xvfb defaults + sudo service xvfb start + # Start dbus session + sudo mkdir -p /var/run/dbus + DBUS_LAUNCH_RESULT=$(sudo dbus-daemon --config-file=/usr/share/dbus-1/system.conf --print-address) + echo "##vso[task.setvariable variable=DBUS_SESSION_BUS_ADDRESS]$DBUS_LAUNCH_RESULT" + displayName: Setup system services - script: node build/setup-npm-registry.js $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) @@ -72,7 +85,10 @@ steps: - script: | set -e npm config set registry "$NPM_REGISTRY" --location=project - npm config set always-auth=true --location=project + # npm >v7 deprecated the `always-auth` config option, refs npm/cli@72a7eeb + # following is a workaround for yarn to send authorization header + # for GET requests to the registry. + echo "always-auth=true" >> .npmrc yarn config set registry "$NPM_REGISTRY" condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM & Yarn @@ -83,17 +99,6 @@ steps: condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Authentication - # TODO@joaomoreno TODO@deepak1556 this should be part of the base image - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - sudo apt-get update && sudo apt-get install -y ca-certificates curl gnupg - sudo mkdir -m 0755 -p /etc/apt/keyrings - curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg - echo "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null - sudo apt update && sudo apt install -y docker-ce-cli - displayName: Install Docker client - condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) - - ${{ if and(ne(parameters.VSCODE_QUALITY, 'oss'), or(eq(parameters.VSCODE_ARCH, 'x64'), eq(parameters.VSCODE_ARCH, 'arm64'))) }}: - task: Docker@1 displayName: "Pull Docker image" @@ -105,69 +110,72 @@ steps: containerCommand: uname condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) - - ${{ if and(ne(parameters.VSCODE_QUALITY, 'oss'), eq(parameters.VSCODE_ARCH, 'arm64')) }}: - - script: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes - displayName: Register Docker QEMU - condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), eq(variables['VSCODE_ARCH'], 'arm64')) - - - script: | - set -e + - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: + - script: | + set -e - for i in {1..5}; do # try 5 times - yarn --cwd build --frozen-lockfile --check-files && break - if [ $i -eq 3 ]; then - echo "Yarn failed too many times" >&2 - exit 1 - fi - echo "Yarn failed $i, trying again..." - done - - if [ -z "$CC" ] || [ -z "$CXX" ]; then - # Download clang based on chromium revision used by vscode - curl -s https://raw.githubusercontent.com/chromium/chromium/108.0.5359.215/tools/clang/scripts/update.py | python - --output-dir=$PWD/.build/CR_Clang --host-os=linux - # Download libcxx headers and objects from upstream electron releases - DEBUG=libcxx-fetcher \ - VSCODE_LIBCXX_OBJECTS_DIR=$PWD/.build/libcxx-objects \ - VSCODE_LIBCXX_HEADERS_DIR=$PWD/.build/libcxx_headers \ - VSCODE_LIBCXXABI_HEADERS_DIR=$PWD/.build/libcxxabi_headers \ - VSCODE_ARCH="$(NPM_ARCH)" \ - node build/linux/libcxx-fetcher.js - # Set compiler toolchain - # Flags for the client build are based on - # https://source.chromium.org/chromium/chromium/src/+/refs/tags/108.0.5359.215:build/config/arm.gni - # https://source.chromium.org/chromium/chromium/src/+/refs/tags/108.0.5359.215:build/config/compiler/BUILD.gn - # https://source.chromium.org/chromium/chromium/src/+/refs/tags/108.0.5359.215:build/config/c++/BUILD.gn - export CC=$PWD/.build/CR_Clang/bin/clang - export CXX=$PWD/.build/CR_Clang/bin/clang++ - export CXXFLAGS="-nostdinc++ -D__NO_INLINE__ -I$PWD/.build/libcxx_headers -isystem$PWD/.build/libcxx_headers/include -isystem$PWD/.build/libcxxabi_headers/include -fPIC -flto=thin -fsplit-lto-unit -D_LIBCPP_ABI_NAMESPACE=Cr" - export LDFLAGS="-stdlib=libc++ -fuse-ld=lld -flto=thin -L$PWD/.build/libcxx-objects -lc++abi -Wl,--lto-O0" - export VSCODE_REMOTE_CC=$(which gcc) - export VSCODE_REMOTE_CXX=$(which g++) - fi - - for i in {1..5}; do # try 5 times - yarn --frozen-lockfile --check-files && break - if [ $i -eq 3 ]; then - echo "Yarn failed too many times" >&2 - exit 1 - fi - echo "Yarn failed $i, trying again..." - done - env: - npm_config_arch: $(NPM_ARCH) - ELECTRON_SKIP_BINARY_DOWNLOAD: 1 - PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 - GITHUB_TOKEN: "$(github-distro-mixin-password)" - ${{ if and(ne(parameters.VSCODE_QUALITY, 'oss'), or(eq(parameters.VSCODE_ARCH, 'x64'), eq(parameters.VSCODE_ARCH, 'arm64'))) }}: - VSCODE_REMOTE_DEPENDENCIES_CONTAINER_NAME: vscodehub.azurecr.io/vscode-linux-build-agent:centos7-devtoolset8-$(VSCODE_ARCH) - displayName: Install dependencies - condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) + for i in {1..5}; do # try 5 times + yarn --cwd build --frozen-lockfile --check-files && break + if [ $i -eq 3 ]; then + echo "Yarn failed too many times" >&2 + exit 1 + fi + echo "Yarn failed $i, trying again..." + done + + docker run -e GITHUB_TOKEN -e npm_config_arch -e NPM_REGISTRY \ + -e VSCODE_REMOTE_DEPENDENCIES_CONTAINER_NAME -e VSCODE_HOST_MOUNT \ + -e ELECTRON_SKIP_BINARY_DOWNLOAD -e PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD \ + -e VSCODE_SKIP_NODE_VERSION_CHECK \ + -v /mnt/vss/_work/1/s:/home/builduser/vscode -v /mnt/vss/_work/1/s/.build/.netrc:/home/builduser/.netrc \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -u 1000:1000 \ + -w /home/builduser/vscode vscodehub.azurecr.io/vscode-linux-build-agent:bionic-$(VSCODE_ARCH) \ + /bin/bash -c "./build/azure-pipelines/linux/install.sh" + + sudo chown -R $USER:$USER /mnt/vss/_work/1/s + env: + npm_config_arch: $(NPM_ARCH) + NPM_REGISTRY: "$(NPM_REGISTRY)" + ELECTRON_SKIP_BINARY_DOWNLOAD: 1 + PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 + VSCODE_SKIP_NODE_VERSION_CHECK: 1 + GITHUB_TOKEN: "$(github-distro-mixin-password)" + VSCODE_HOST_MOUNT: "/mnt/vss/_work/1/s" + ${{ if or(eq(parameters.VSCODE_ARCH, 'x64'), eq(parameters.VSCODE_ARCH, 'arm64')) }}: + VSCODE_REMOTE_DEPENDENCIES_CONTAINER_NAME: vscodehub.azurecr.io/vscode-linux-build-agent:centos7-devtoolset8-$(VSCODE_ARCH) + displayName: Install dependencies + condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - script: node build/azure-pipelines/distro/mixin-npm condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) displayName: Mixin distro node modules + - ${{ else }}: + # Ref https://github.com/microsoft/vscode/issues/189019 + # for the node-gyp rebuild step + - script: | + set -e + + for i in {1..5}; do # try 5 times + yarn --frozen-lockfile --check-files && break + if [ $i -eq 3 ]; then + echo "Yarn failed too many times" >&2 + exit 1 + fi + echo "Yarn failed $i, trying again..." + done + + cd node_modules/native-keymap && npx node-gyp@9.4.0 -y rebuild --debug + cd ../.. && ./.github/workflows/check-clean-git-state.sh + env: + npm_config_arch: $(NPM_ARCH) + ELECTRON_SKIP_BINARY_DOWNLOAD: 1 + PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 + GITHUB_TOKEN: "$(github-distro-mixin-password)" + displayName: Install dependencies + condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) + - script: | set -e node build/azure-pipelines/common/listNodeModules.js .build/node_modules_list.txt @@ -188,12 +196,34 @@ steps: yarn gulp vscode-linux-$(VSCODE_ARCH)-min-ci ARCHIVE_PATH=".build/linux/client/code-${{ parameters.VSCODE_QUALITY }}-$(VSCODE_ARCH)-$(date +%s).tar.gz" mkdir -p $(dirname $ARCHIVE_PATH) - tar -czf $ARCHIVE_PATH -C .. VSCode-linux-$(VSCODE_ARCH) echo "##vso[task.setvariable variable=CLIENT_PATH]$ARCHIVE_PATH" env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Build client + - ${{ if ne(parameters.VSCODE_CIBUILD, true) }}: + - task: DownloadPipelineArtifact@2 + inputs: + artifact: $(ARTIFACT_PREFIX)vscode_cli_linux_$(VSCODE_ARCH)_cli + patterns: "**" + path: $(Build.ArtifactStagingDirectory)/cli + displayName: Download VS Code CLI + + - script: | + set -e + tar -xzvf $(Build.ArtifactStagingDirectory)/cli/*.tar.gz -C $(Build.ArtifactStagingDirectory)/cli + CLI_APP_NAME=$(node -p "require(\"$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)/resources/app/product.json\").tunnelApplicationName") + APP_NAME=$(node -p "require(\"$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)/resources/app/product.json\").applicationName") + mv $(Build.ArtifactStagingDirectory)/cli/$APP_NAME $(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)/bin/$CLI_APP_NAME + displayName: Mix in CLI + + - script: | + set -e + tar -czf $CLIENT_PATH -C .. VSCode-linux-$(VSCODE_ARCH) + env: + GITHUB_TOKEN: "$(github-distro-mixin-password)" + displayName: Archive client + - script: | set -e yarn gulp vscode-reh-linux-$(VSCODE_ARCH)-min-ci @@ -233,20 +263,15 @@ steps: VSCODE_RUN_SMOKE_TESTS: ${{ parameters.VSCODE_RUN_SMOKE_TESTS }} - ${{ if and(ne(parameters.VSCODE_CIBUILD, true), ne(parameters.VSCODE_QUALITY, 'oss')) }}: - - task: DownloadPipelineArtifact@2 - inputs: - artifact: $(ARTIFACT_PREFIX)vscode_cli_linux_$(VSCODE_ARCH)_cli - patterns: "**" - path: $(Build.ArtifactStagingDirectory)/cli - displayName: Download VS Code CLI - - - script: | + - script: | set -e - tar -xzvf $(Build.ArtifactStagingDirectory)/cli/*.tar.gz -C $(Build.ArtifactStagingDirectory)/cli - CLI_APP_NAME=$(node -p "require(\"$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)/resources/app/product.json\").tunnelApplicationName") - APP_NAME=$(node -p "require(\"$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)/resources/app/product.json\").applicationName") - mv $(Build.ArtifactStagingDirectory)/cli/$APP_NAME $(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)/bin/$CLI_APP_NAME - displayName: Make CLI executable + docker run -v /mnt/vss/_work/1/s:/home/builduser/vscode \ + -v /mnt/vss/_work/1/s/.build/.netrc:/home/builduser/.netrc \ + -v /mnt/vss/_work/1/VSCode-linux-$(VSCODE_ARCH):/home/builduser/VSCode-linux-$(VSCODE_ARCH) \ + -u 1000:1000 \ + -w /home/builduser/vscode vscodehub.azurecr.io/vscode-linux-build-agent:bionic-$(VSCODE_ARCH) \ + yarn gulp "vscode-linux-$(VSCODE_ARCH)-prepare-deb" + displayName: Prepare deb package - script: | set -e @@ -254,6 +279,16 @@ steps: echo "##vso[task.setvariable variable=DEB_PATH]$(ls .build/linux/deb/*/deb/*.deb)" displayName: Build deb package + - script: | + set -e + docker run -v /mnt/vss/_work/1/s:/home/builduser/vscode \ + -v /mnt/vss/_work/1/s/.build/.netrc:/home/builduser/.netrc \ + -v /mnt/vss/_work/1/VSCode-linux-$(VSCODE_ARCH):/home/builduser/VSCode-linux-$(VSCODE_ARCH) \ + -u 1000:1000 \ + -w /home/builduser/vscode vscodehub.azurecr.io/vscode-linux-build-agent:bionic-$(VSCODE_ARCH) \ + yarn gulp "vscode-linux-$(VSCODE_ARCH)-prepare-rpm" + displayName: Prepare rpm package + - script: | set -e yarn gulp "vscode-linux-$(VSCODE_ARCH)-build-rpm" diff --git a/build/azure-pipelines/linux/snap-build-linux.yml b/build/azure-pipelines/linux/snap-build-linux.yml index c028cc58e04e4..9146318cc1232 100644 --- a/build/azure-pipelines/linux/snap-build-linux.yml +++ b/build/azure-pipelines/linux/snap-build-linux.yml @@ -1,7 +1,7 @@ steps: - task: NodeTool@0 inputs: - versionSpec: "16.x" + versionSpec: "18.x" - task: DownloadPipelineArtifact@0 displayName: "Download Pipeline Artifact" diff --git a/build/azure-pipelines/oss/product-build-pr-cache-linux.yml b/build/azure-pipelines/oss/product-build-pr-cache-linux.yml index 97eba56abc3c7..2884ba79cd700 100644 --- a/build/azure-pipelines/oss/product-build-pr-cache-linux.yml +++ b/build/azure-pipelines/oss/product-build-pr-cache-linux.yml @@ -5,7 +5,7 @@ steps: - task: NodeTool@0 inputs: - versionSpec: "16.x" + versionSpec: "18.x" - script: node build/setup-npm-registry.js $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) @@ -28,7 +28,10 @@ steps: - script: | set -e npm config set registry "$NPM_REGISTRY" --location=project - npm config set always-auth=true --location=project + # npm >v7 deprecated the `always-auth` config option, refs npm/cli@72a7eeb + # following is a workaround for yarn to send authorization header + # for GET requests to the registry. + echo "always-auth=true" >> .npmrc yarn config set registry "$NPM_REGISTRY" condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM & Yarn @@ -39,6 +42,10 @@ steps: condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Authentication + - script: sudo apt-get update && sudo apt-get install -y libkrb5-dev + displayName: Install build dependencies + condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) + - script: | set -e for i in {1..5}; do # try 5 times diff --git a/build/azure-pipelines/oss/product-build-pr-cache-win32.yml b/build/azure-pipelines/oss/product-build-pr-cache-win32.yml index 61b0bf37d258b..2901d0f0f5e59 100644 --- a/build/azure-pipelines/oss/product-build-pr-cache-win32.yml +++ b/build/azure-pipelines/oss/product-build-pr-cache-win32.yml @@ -5,7 +5,7 @@ steps: - task: NodeTool@0 inputs: - versionSpec: "16.x" + versionSpec: "18.x" - powershell: node build/setup-npm-registry.js $env:NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) @@ -31,7 +31,10 @@ steps: . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" exec { npm config set registry "$env:NPM_REGISTRY" --location=project } - exec { npm config set always-auth=true --location=project } + # npm >v7 deprecated the `always-auth` config option, refs npm/cli@72a7eeb + # following is a workaround for yarn to send authorization header + # for GET requests to the registry. + exec { Add-Content -Path .npmrc -Value "always-auth=true" } exec { yarn config set registry "$env:NPM_REGISTRY" } condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM & Yarn diff --git a/build/azure-pipelines/product-build.yml b/build/azure-pipelines/product-build.yml index 1be2db3b5fa3c..2d4ad8aa84a0e 100644 --- a/build/azure-pipelines/product-build.yml +++ b/build/azure-pipelines/product-build.yml @@ -143,18 +143,6 @@ name: "$(Date:yyyyMMdd).$(Rev:r) (${{ parameters.VSCODE_QUALITY }})" resources: containers: - - container: vscode-bionic-x64 - image: vscodehub.azurecr.io/vscode-linux-build-agent:bionic-x64 - endpoint: VSCodeHub - options: --user 0:0 --cap-add SYS_ADMIN - - container: vscode-arm64 - image: vscodehub.azurecr.io/vscode-linux-build-agent:bionic-arm64 - endpoint: VSCodeHub - options: --user 0:0 --cap-add SYS_ADMIN - - container: vscode-armhf - image: vscodehub.azurecr.io/vscode-linux-build-agent:bionic-armhf - endpoint: VSCodeHub - options: --user 0:0 --cap-add SYS_ADMIN - container: snapcraft image: vscodehub.azurecr.io/vscode-linux-build-agent:snapcraft-x64 endpoint: VSCodeHub @@ -382,7 +370,6 @@ stages: - ${{ if eq(variables['VSCODE_CIBUILD'], true) }}: - job: Linuxx64UnitTest displayName: Unit Tests - container: vscode-bionic-x64 variables: VSCODE_ARCH: x64 NPM_ARCH: x64 @@ -398,7 +385,6 @@ stages: VSCODE_RUN_SMOKE_TESTS: false - job: Linuxx64IntegrationTest displayName: Integration Tests - container: vscode-bionic-x64 variables: VSCODE_ARCH: x64 NPM_ARCH: x64 @@ -414,7 +400,6 @@ stages: VSCODE_RUN_SMOKE_TESTS: false - job: Linuxx64SmokeTest displayName: Smoke Tests - container: vscode-bionic-x64 variables: VSCODE_ARCH: x64 NPM_ARCH: x64 @@ -431,7 +416,6 @@ stages: - ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_LINUX, true)) }}: - job: Linuxx64 - container: vscode-bionic-x64 variables: VSCODE_ARCH: x64 NPM_ARCH: x64 @@ -458,7 +442,6 @@ stages: - ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_LINUX_ARMHF, true)) }}: - job: LinuxArmhf - container: vscode-armhf variables: VSCODE_ARCH: armhf NPM_ARCH: arm @@ -474,7 +457,6 @@ stages: - ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_LINUX_ARM64, true)) }}: - job: LinuxArm64 - container: vscode-arm64 variables: VSCODE_ARCH: arm64 NPM_ARCH: arm64 @@ -499,6 +481,7 @@ stages: - job: LinuxAlpine variables: VSCODE_ARCH: x64 + NPM_ARCH: x64 steps: - template: alpine/product-build-alpine.yml @@ -507,6 +490,7 @@ stages: timeoutInMinutes: 120 variables: VSCODE_ARCH: arm64 + NPM_ARCH: arm64 steps: - template: alpine/product-build-alpine.yml diff --git a/build/azure-pipelines/product-compile.yml b/build/azure-pipelines/product-compile.yml index 8471cfdec3dea..4bcf3fd911432 100644 --- a/build/azure-pipelines/product-compile.yml +++ b/build/azure-pipelines/product-compile.yml @@ -5,7 +5,7 @@ parameters: steps: - task: NodeTool@0 inputs: - versionSpec: "16.x" + versionSpec: "18.x" - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - template: ./distro/download-distro.yml @@ -38,7 +38,10 @@ steps: - script: | set -e npm config set registry "$NPM_REGISTRY" --location=project - npm config set always-auth=true --location=project + # npm >v7 deprecated the `always-auth` config option, refs npm/cli@72a7eeb + # following is a workaround for yarn to send authorization header + # for GET requests to the registry. + echo "always-auth=true" >> .npmrc yarn config set registry "$NPM_REGISTRY" condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM & Yarn @@ -49,7 +52,7 @@ steps: condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Authentication - - script: sudo apt update -y && sudo apt install -y build-essential pkg-config libx11-dev libx11-xcb-dev libxkbfile-dev libsecret-1-dev libnotify-bin + - script: sudo apt update -y && sudo apt install -y build-essential pkg-config libx11-dev libx11-xcb-dev libxkbfile-dev libsecret-1-dev libnotify-bin libkrb5-dev displayName: Install build tools condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) diff --git a/build/azure-pipelines/product-publish.yml b/build/azure-pipelines/product-publish.yml index 2e2d735da054d..db4424735e969 100644 --- a/build/azure-pipelines/product-publish.yml +++ b/build/azure-pipelines/product-publish.yml @@ -1,7 +1,7 @@ steps: - task: NodeTool@0 inputs: - versionSpec: "16.x" + versionSpec: "18.x" - task: AzureKeyVault@1 displayName: "Azure Key Vault: Get Secrets" diff --git a/build/azure-pipelines/product-release.yml b/build/azure-pipelines/product-release.yml index 8be900a9b4126..498d7c586072e 100644 --- a/build/azure-pipelines/product-release.yml +++ b/build/azure-pipelines/product-release.yml @@ -5,7 +5,7 @@ parameters: steps: - task: NodeTool@0 inputs: - versionSpec: "16.x" + versionSpec: "18.x" - task: AzureCLI@2 inputs: diff --git a/build/azure-pipelines/publish-types/publish-types.yml b/build/azure-pipelines/publish-types/publish-types.yml index 031fafd4c7581..db0d5ce1894d8 100644 --- a/build/azure-pipelines/publish-types/publish-types.yml +++ b/build/azure-pipelines/publish-types/publish-types.yml @@ -12,7 +12,7 @@ pool: steps: - task: NodeTool@0 inputs: - versionSpec: "16.x" + versionSpec: "18.x" - bash: | TAG_VERSION=$(git describe --tags `git rev-list --tags --max-count=1`) diff --git a/build/azure-pipelines/sdl-scan.yml b/build/azure-pipelines/sdl-scan.yml index 8c81ee204015a..16304177c7c5e 100644 --- a/build/azure-pipelines/sdl-scan.yml +++ b/build/azure-pipelines/sdl-scan.yml @@ -52,7 +52,7 @@ stages: outputFormat: "pre" - task: NodeTool@0 inputs: - versionSpec: "16.x" + versionSpec: "18.x" - template: ./distro/download-distro.yml @@ -67,7 +67,10 @@ stages: . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" exec { npm config set registry "$env:NPM_REGISTRY" --location=project } - exec { npm config set always-auth=true --location=project } + # npm >v7 deprecated the `always-auth` config option, refs npm/cli@72a7eeb + # following is a workaround for yarn to send authorization header + # for GET requests to the registry. + exec { Add-Content -Path .npmrc -Value "always-auth=true" } exec { yarn config set registry "$env:NPM_REGISTRY" } condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM & Yarn @@ -176,7 +179,7 @@ stages: toolMajorVersion: "V2" - task: NodeTool@0 inputs: - versionSpec: "16.x" + versionSpec: "18.x" - template: ./distro/download-distro.yml @@ -190,7 +193,10 @@ stages: - script: | set -e npm config set registry "$NPM_REGISTRY" --location=project - npm config set always-auth=true --location=project + # npm >v7 deprecated the `always-auth` config option, refs npm/cli@72a7eeb + # following is a workaround for yarn to send authorization header + # for GET requests to the registry. + echo "always-auth=true" >> .npmrc yarn config set registry "$NPM_REGISTRY" condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM & Yarn diff --git a/build/azure-pipelines/web/product-build-web.yml b/build/azure-pipelines/web/product-build-web.yml index a941ae9adfe66..afaf43c55c282 100644 --- a/build/azure-pipelines/web/product-build-web.yml +++ b/build/azure-pipelines/web/product-build-web.yml @@ -1,7 +1,7 @@ steps: - task: NodeTool@0 inputs: - versionSpec: "16.x" + versionSpec: "18.x" - template: ../distro/download-distro.yml @@ -42,7 +42,10 @@ steps: - script: | set -e npm config set registry "$NPM_REGISTRY" --location=project - npm config set always-auth=true --location=project + # npm >v7 deprecated the `always-auth` config option, refs npm/cli@72a7eeb + # following is a workaround for yarn to send authorization header + # for GET requests to the registry. + echo "always-auth=true" >> .npmrc yarn config set registry "$NPM_REGISTRY" condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM & Yarn @@ -53,6 +56,10 @@ steps: condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Authentication + - script: sudo apt-get update && sudo apt-get install -y libkrb5-dev + displayName: Install build dependencies + condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) + - script: | set -e for i in {1..5}; do # try 5 times diff --git a/build/azure-pipelines/win32/cli-build-win32.yml b/build/azure-pipelines/win32/cli-build-win32.yml index 9a155a0c0be09..6eb5ac41f5c49 100644 --- a/build/azure-pipelines/win32/cli-build-win32.yml +++ b/build/azure-pipelines/win32/cli-build-win32.yml @@ -17,7 +17,7 @@ parameters: steps: - task: NodeTool@0 inputs: - versionSpec: "16.x" + versionSpec: "18.x" - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - template: ../cli/cli-apply-patches.yml @@ -36,13 +36,6 @@ steps: tar -xvzf $(Build.ArtifactStagingDirectory)/vscode-internal-openssl-prebuilt-0.0.8.tgz --strip-components=1 --directory=$(Build.ArtifactStagingDirectory)/openssl displayName: Extract openssl prebuilt - - powershell: node build/azure-pipelines/cli/prepare.js - displayName: Prepare CLI build - env: - VSCODE_CLI_PREPARE_ROOT: $(Build.SourcesDirectory)/.build/distro - VSCODE_QUALITY: ${{ parameters.VSCODE_QUALITY }} - GITHUB_TOKEN: "$(github-distro-mixin-password)" - - template: ../cli/install-rust-win32.yml parameters: targets: @@ -56,6 +49,7 @@ steps: - ${{ if eq(parameters.VSCODE_BUILD_WIN32, true) }}: - template: ../cli/cli-compile-and-publish.yml parameters: + VSCODE_QUALITY: ${{ parameters.VSCODE_QUALITY }} VSCODE_CLI_TARGET: x86_64-pc-windows-msvc VSCODE_CLI_ARTIFACT: unsigned_vscode_cli_win32_x64_cli VSCODE_CHECK_ONLY: ${{ parameters.VSCODE_CHECK_ONLY }} @@ -67,6 +61,7 @@ steps: - ${{ if eq(parameters.VSCODE_BUILD_WIN32_ARM64, true) }}: - template: ../cli/cli-compile-and-publish.yml parameters: + VSCODE_QUALITY: ${{ parameters.VSCODE_QUALITY }} VSCODE_CLI_TARGET: aarch64-pc-windows-msvc VSCODE_CLI_ARTIFACT: unsigned_vscode_cli_win32_arm64_cli VSCODE_CHECK_ONLY: ${{ parameters.VSCODE_CHECK_ONLY }} @@ -78,6 +73,7 @@ steps: - ${{ if eq(parameters.VSCODE_BUILD_WIN32_32BIT, true) }}: - template: ../cli/cli-compile-and-publish.yml parameters: + VSCODE_QUALITY: ${{ parameters.VSCODE_QUALITY }} VSCODE_CLI_TARGET: i686-pc-windows-msvc VSCODE_CLI_ARTIFACT: unsigned_vscode_cli_win32_ia32_cli VSCODE_CHECK_ONLY: ${{ parameters.VSCODE_CHECK_ONLY }} diff --git a/build/azure-pipelines/win32/product-build-win32-cli-sign.yml b/build/azure-pipelines/win32/product-build-win32-cli-sign.yml index 31bffda478895..61b7197328040 100644 --- a/build/azure-pipelines/win32/product-build-win32-cli-sign.yml +++ b/build/azure-pipelines/win32/product-build-win32-cli-sign.yml @@ -10,7 +10,7 @@ steps: - task: NodeTool@0 displayName: "Use Node.js" inputs: - versionSpec: "16.x" + versionSpec: "18.x" - powershell: node build/setup-npm-registry.js $env:NPM_REGISTRY build condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) @@ -20,7 +20,10 @@ steps: . azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" exec { npm config set registry "$env:NPM_REGISTRY" --location=project } - exec { npm config set always-auth=true --location=project } + # npm >v7 deprecated the `always-auth` config option, refs npm/cli@72a7eeb + # following is a workaround for yarn to send authorization header + # for GET requests to the registry. + exec { Add-Content -Path .npmrc -Value "always-auth=true" } exec { yarn config set registry "$env:NPM_REGISTRY" } workingDirectory: build condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) diff --git a/build/azure-pipelines/win32/product-build-win32-test.yml b/build/azure-pipelines/win32/product-build-win32-test.yml index 630e226a742ac..3a24e95657ad6 100644 --- a/build/azure-pipelines/win32/product-build-win32-test.yml +++ b/build/azure-pipelines/win32/product-build-win32-test.yml @@ -15,6 +15,7 @@ steps: env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Download Electron and Playwright + retryCountOnTaskFailure: 3 - ${{ if eq(parameters.VSCODE_RUN_UNIT_TESTS, true) }}: - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: diff --git a/build/azure-pipelines/win32/product-build-win32.yml b/build/azure-pipelines/win32/product-build-win32.yml index 6356978d40bef..8b61ee5201517 100644 --- a/build/azure-pipelines/win32/product-build-win32.yml +++ b/build/azure-pipelines/win32/product-build-win32.yml @@ -20,7 +20,7 @@ steps: - task: NodeTool@0 inputs: - versionSpec: "16.x" + versionSpec: "18.x" - task: UsePythonVersion@0 inputs: @@ -73,7 +73,10 @@ steps: . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" exec { npm config set registry "$env:NPM_REGISTRY" --location=project } - exec { npm config set always-auth=true --location=project } + # npm >v7 deprecated the `always-auth` config option, refs npm/cli@72a7eeb + # following is a workaround for yarn to send authorization header + # for GET requests to the registry. + exec { Add-Content -Path .npmrc -Value "always-auth=true" } exec { yarn config set registry "$env:NPM_REGISTRY" } condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM & Yarn @@ -94,9 +97,12 @@ steps: $ErrorActionPreference = "Stop" # TODO: Should be replaced with upstream URL once https://github.com/nodejs/node-gyp/pull/2825 # gets merged. - exec { git clone https://github.com/rzhao271/node-gyp.git . } "Cloning rzhao271/node-gyp failed" - exec { git checkout 102b347da0c92c29f9c67df22e864e70249cf086 } "Checking out 102b347 failed" - exec { npm install } "Building rzhao271/node-gyp failed" + exec { git config --global user.email "vscode@microsoft.com" } "git config user.email failed" + exec { git config --global user.name "VSCode" } "git config user.name failed" + exec { git clone https://github.com/nodejs/node-gyp.git . } "Cloning nodejs/node-gyp failed" + exec { git checkout v9.4.0 } "Checking out v9.4.0 failed" + exec { git am --3way --whitespace=fix ../../build/npm/gyp/patches/gyp_spectre_mitigation_support.patch } "Apply spectre patch failed" + exec { npm install } "Building node-gyp failed" displayName: Install custom node-gyp workingDirectory: .build/node-gyp condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) @@ -136,7 +142,7 @@ steps: - template: ../common/install-builtin-extensions.yml - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: + - ${{ if and(ne(parameters.VSCODE_CIBUILD, true), ne(parameters.VSCODE_QUALITY, 'oss')) }}: - powershell: node build\lib\policies displayName: Generate Group Policy definitions retryCountOnTaskFailure: 3 @@ -148,7 +154,7 @@ steps: displayName: Transpile - ${{ else }}: - - ${{ if eq(parameters.VSCODE_QUALITY, 'insider') }}: + - ${{ if and(ne(parameters.VSCODE_CIBUILD, true), eq(parameters.VSCODE_QUALITY, 'insider')) }}: - powershell: node build/win32/explorer-appx-fetcher .build/win32/appx displayName: Download Explorer Sparse Package @@ -263,7 +269,7 @@ steps: $ErrorActionPreference = "Stop" $ArchivePath = ".build\win32-$(VSCODE_ARCH)\vscode-server-win32-$(VSCODE_ARCH).zip" New-Item -ItemType Directory -Path .build\win32-$(VSCODE_ARCH) -Force - exec { 7z.exe a -tzip $ArchivePath ..\vscode-server-win32-$(VSCODE_ARCH)\* -r } + exec { 7z.exe a -tzip $ArchivePath ..\vscode-server-win32-$(VSCODE_ARCH) -r } echo "##vso[task.setvariable variable=SERVER_PATH]$ArchivePath" condition: and(succeededOrFailed(), eq(variables['BUILT_SERVER'], 'true')) displayName: Package server @@ -273,7 +279,7 @@ steps: $ErrorActionPreference = "Stop" $ArchivePath = ".build\win32-$(VSCODE_ARCH)\vscode-server-win32-$(VSCODE_ARCH)-web.zip" New-Item -ItemType Directory -Path .build\win32-$(VSCODE_ARCH) -Force - exec { 7z.exe a -tzip $ArchivePath ..\vscode-server-win32-$(VSCODE_ARCH)-web\* -r } + exec { 7z.exe a -tzip $ArchivePath ..\vscode-server-win32-$(VSCODE_ARCH)-web -r } echo "##vso[task.setvariable variable=WEB_PATH]$ArchivePath" condition: and(succeededOrFailed(), eq(variables['BUILT_WEB'], 'true')) displayName: Package server (web) diff --git a/build/checksums/electron.txt b/build/checksums/electron.txt index beb2b9730b077..f5c22bc1c23f4 100644 --- a/build/checksums/electron.txt +++ b/build/checksums/electron.txt @@ -1,27 +1,27 @@ -3ba067c6f338f9a525c4b697e9cf8e3c3b3d9f6abfdfb11fba47e053da0f3496 *electron-v22.3.14-darwin-arm64-symbols.zip -c08bf19e11c006346b210585cf0803cd0b07107a362a2414cc185f6a228afbf2 *electron-v22.3.14-darwin-arm64.zip -72ced94e7230d3138dd84acbf38dc593d4a93ec796a3a478f99aa6974030d79c *electron-v22.3.14-darwin-x64-symbols.zip -77c1c96411326b00d3ef7c9f6af96a3b4c2fa2314196fce3374fcf734dd8dc67 *electron-v22.3.14-darwin-x64.zip -d847c59f3835749dcdd5376daefb3a5992f1ed5d7693f871328296e1388fb69d *electron-v22.3.14-linux-arm64-symbols.zip -95bb9ee160c60b50ff25b307fb8bc36bdb5297d43c6e366f0b835f36c4f327c9 *electron-v22.3.14-linux-arm64.zip -38a51d81f9ffe6e2ebf25844999fddbeb4edc63ae22136af1502db373bb024ab *electron-v22.3.14-linux-armv7l-symbols.zip -bf589c74f07fe11586ffcf8c122d34b91c5ced08d54532ee883d1e025b6d1b02 *electron-v22.3.14-linux-armv7l.zip -28d0eda61ea736375c549d0955f36b7d3e3c2019453ef83d793dae8b0d74f461 *electron-v22.3.14-linux-x64-symbols.zip -89b72e40fb8b9106deda3e6ffa30dd80beaa8f2e2a9d037b55c034a5a27a7b60 *electron-v22.3.14-linux-x64.zip -b9ba15fcf7c60cf57e95fae731bc0c336e131ed4fac91b4c59d50a28407ca0b0 *electron-v22.3.14-win32-arm64-pdb.zip -9f375d01feeb9e28f9c0913a4e22be900c0a7ff4e51449bb9b859ce1bd18f9f3 *electron-v22.3.14-win32-arm64-symbols.zip -17e354aca0683f79d79f7fa7ecfa8a4381b356d04fa45ec0aa85b5f048151c10 *electron-v22.3.14-win32-arm64.zip -900ca316ce939547ab62847c8833a78c1002a69b936be7e9af328a3518a7d379 *electron-v22.3.14-win32-ia32-pdb.zip -90af7a48b4e722a3436b6a8893540fb746d99b4832ca48c355a63fa0930f6446 *electron-v22.3.14-win32-ia32-symbols.zip -487d811c7cf3282f4c3a17b5ab7ab1fd71dbc585449d77da3a9bf052657ac4ad *electron-v22.3.14-win32-ia32.zip -41ce6c3d87c89f6b48aac74649657a120c28c78513908996dc20e57a640d4653 *electron-v22.3.14-win32-x64-pdb.zip -57b35bfa186b64a9dd1eb2bb85141bb998d0378bb20ac8038718b41d16deb978 *electron-v22.3.14-win32-x64-symbols.zip -f45eba3faa7e10fb1c6e5cf044dd42733a7c8cb455de57647b74e7510b0b94b6 *electron-v22.3.14-win32-x64.zip -16a75de6e3e4643589237e6e1c680c43b4e77fe04918bfbe4408775b7e616afc *ffmpeg-v22.3.14-darwin-arm64.zip -92db0c163c326d33a516ebfc56c7bd4faae9456f4238dde916c580b459b8dc8d *ffmpeg-v22.3.14-darwin-x64.zip -59d2e2b2f2cc515a86a4e0cfd1116d10a8b25a8d58d45bb04de3512e156c944b *ffmpeg-v22.3.14-linux-arm64.zip -b9d3b227bee17666d395ee7882ef477a733c3eeef3f1d9f2e3616d2d02eb3376 *ffmpeg-v22.3.14-linux-armv7l.zip -fa07ef910b23a4ef4b6761bc16d20c0e70ff0259325c4d523129e2d9c5084174 *ffmpeg-v22.3.14-linux-x64.zip -7f744b657ae7c26f80cae0f2771a00edd368350229b85118a246573987dd6ff1 *ffmpeg-v22.3.14-win32-arm64.zip -562e04d2cf1c970b6128d66d08dfe8d88a28e54adf599293eee2bd6c292fd16b *ffmpeg-v22.3.14-win32-ia32.zip -f69510384ef912fd9b4961f97357789a4a36e8df6ff382aeeab23fbb063def9a *ffmpeg-v22.3.14-win32-x64.zip +c3fb8cb4804143eb25fce55a179a6f2df8c215ed709104ec235c96e357b20f42 *electron-v25.5.0-darwin-arm64-symbols.zip +e6d2a09348d4fe7c9fbd92bf796489a95e625642f0f1ce96169212554cfa6841 *electron-v25.5.0-darwin-arm64.zip +15c28e613dfee0f7e46a296bb4aed64e17f9644d7ef19129aeb6480b8da230ab *electron-v25.5.0-darwin-x64-symbols.zip +a5c5c0b621daf8242258c89edb2387fbdf1c69125c984f8564d89b87927373e3 *electron-v25.5.0-darwin-x64.zip +69d60a69b7f692b9069cdf9e518bcbaca9cec561f40199cc87196929936a34ce *electron-v25.5.0-linux-arm64-symbols.zip +adec2ba09faf5f8d8af8997c8bed43c7712eba5546db1e7d06f8357bf4613921 *electron-v25.5.0-linux-arm64.zip +0fe7a5d152c9c401671e02ebcd9da34ab9bb0c28598ede3657077a79f8b3e70a *electron-v25.5.0-linux-armv7l-symbols.zip +eccb66e4a308a0bd2d90474894370e3d687e32f78672e6b5077c1822c7bc526b *electron-v25.5.0-linux-armv7l.zip +82bd9bc9e66f8ae802fe48a51b8d7e2fb599403e9715fa4b859190200a7376b1 *electron-v25.5.0-linux-x64-symbols.zip +485cbeb206fccfb4ed42f694100eebb80c9db6639b3537a95823c4fcb7f210cd *electron-v25.5.0-linux-x64.zip +ed2c2a7da571b53bcb336b9a2a024753a272df82ece45df83df888df51bf1912 *electron-v25.5.0-win32-arm64-pdb.zip +c316f6364e9b4cd61e19d4763c96abda7247a2c31ae7d30e81219c9a7754f11a *electron-v25.5.0-win32-arm64-symbols.zip +582ccbfc5a85a093f5639ee476bb5fef18c2d25dab4a60e5f5cb47e64c99f7fb *electron-v25.5.0-win32-arm64.zip +5776e650c23e3847b0c52d850f61c57a84a4fa30943c3cc82197250112911b5b *electron-v25.5.0-win32-ia32-pdb.zip +730b429ad2c4cae0fe3ba9600a6ee86c79dada77976bac1c75ca2404993495bc *electron-v25.5.0-win32-ia32-symbols.zip +7e6e68aa33a89c0d647575b06daf415a2401feb170ebb9cd795e221af321f751 *electron-v25.5.0-win32-ia32.zip +0792665fda9255b340a829cdd24601887a2ca8f04cc49f9a6d4557db0c0cd2f2 *electron-v25.5.0-win32-x64-pdb.zip +dc2459546951f8418e866857e9111dd83a0789d401906b2200c2f8dd59d9146b *electron-v25.5.0-win32-x64-symbols.zip +9bf7980fbc024ba77ea8ab3e2d32088a5f69bf32506a7d2db72ede17028abdf4 *electron-v25.5.0-win32-x64.zip +5b1ea601b737842eacf88d7456c4d14e697822753e9a08ede889cce9e20bafb2 *ffmpeg-v25.5.0-darwin-arm64.zip +37bf5c75edefc0b6735b44d0b5b06fdd427179a8501f6e93df9840283cdb4a95 *ffmpeg-v25.5.0-darwin-x64.zip +bd52d57ff97fb56ac01a3482af905d04f0d4e9c13c53858c6d9f99957eca82da *ffmpeg-v25.5.0-linux-arm64.zip +9b3d09177fa1e63e2a6beecfa70aeec30aeb5c1873ff21128a68051c4e23f95d *ffmpeg-v25.5.0-linux-armv7l.zip +edc7b1c9f1a0733f109a2c0375a4e40c5bfe0bf28b7f06dcc76e1ada0aa2f125 *ffmpeg-v25.5.0-linux-x64.zip +2e28767b3570ea247869a20988cddd23af710eb994d6099404f123390cedeba6 *ffmpeg-v25.5.0-win32-arm64.zip +715568eefd7267573a30186ade3de901587baeb1f013200d8ae50b35941b613f *ffmpeg-v25.5.0-win32-ia32.zip +29876504452aaa505f696642178968e24b8dc8cc4b055071e6f0f3f073088acc *ffmpeg-v25.5.0-win32-x64.zip diff --git a/build/checksums/nodejs.txt b/build/checksums/nodejs.txt index 5229a5bc80a38..de9f8f071500c 100644 --- a/build/checksums/nodejs.txt +++ b/build/checksums/nodejs.txt @@ -1,7 +1,7 @@ -f9f02f7872e2e8ee54320fce13deb9d56904f32bb0615b6e21aa3371d8899150 node-v16.17.1-darwin-arm64.tar.gz -3db26761ad8493b894d42260d7e65094b7af9bc473588739e61bc1c32d6ff955 node-v16.17.1-darwin-x64.tar.gz -adc7032888d4e672a4aac886baede8c04fccdd1a2e7ab4bcf325e3f336f44a3d node-v16.17.1-linux-arm64.tar.gz -aeab05e35f1d2824ecfb88ca321f1408b44d292b2775f2890972c828e00216d0 node-v16.17.1-linux-armv7l.tar.gz -da5658693243b3ecf6a4cba6751a71df1eb9e9703ca93b42a9404aed85f58ad0 node-v16.17.1-linux-x64.tar.gz -f518a70dcab7c3fac5b2e1ef100b4f628edfb160f4fafa9a94ef222da8a6e9ab win-x64/node.exe -2393aff88be19dbe0205cbde4ff0c1d89911b15de5c99c80f6e5e29604eecd12 win-x86/node.exe +bd302a689c3c34e2b61d86b97de66d26a335881a17af09b6a0a4bb1019df56e4 node-v18.15.0-darwin-arm64.tar.gz +76add174d2d3f98da08907412e82add7352b8cb6f639324d352a65c084b99c7e node-v18.15.0-darwin-x64.tar.gz +8ef7aa7a679360ddbf0c7c8511881030b3de9d1f54451d92ba5c8d59a91c7073 node-v18.15.0-linux-arm64.tar.gz +ca2186313d3cbe5c67d0c08e931a6d290906f4f13c584e63fefa05a04dee9c58 node-v18.15.0-linux-armv7l.tar.gz +b298a73a9fc07badfa9e4a2e86ed48824fc9201327cdc43e3f3f58b273c535e7 node-v18.15.0-linux-x64.tar.gz +17fd75d8a41bf9b4c475143e19ff2808afa7a92f7502ede731537d9da674d5e8 win-x64/node.exe +d78b2f981465a40a23b964b2db32a390db1970a0dd5371682e121ae2b7422697 win-x86/node.exe diff --git a/build/filters.js b/build/filters.js index 6cac25cde1674..0e0c5fcabb8ca 100644 --- a/build/filters.js +++ b/build/filters.js @@ -32,6 +32,7 @@ module.exports.unicodeFilter = [ '**', '!**/ThirdPartyNotices.txt', + '!**/ThirdPartyNotices.cli.txt', '!**/LICENSE.{txt,rtf}', '!LICENSES.chromium.html', '!**/LICENSE', @@ -65,6 +66,7 @@ module.exports.indentationFilter = [ // except specific files '!**/ThirdPartyNotices.txt', + '!**/ThirdPartyNotices.cli.txt', '!**/LICENSE.{txt,rtf}', '!LICENSES.chromium.html', '!**/LICENSE', @@ -78,6 +80,7 @@ module.exports.indentationFilter = [ '!test/unit/assert.js', '!resources/linux/snap/electron-launch', '!build/ext.js', + '!build/npm/gyp/patches/gyp_spectre_mitigation_support.patch', // except specific folders '!test/automation/out/**', diff --git a/build/gulpfile.extensions.js b/build/gulpfile.extensions.js index e2c9e3d9abaf4..bcdb206606b24 100644 --- a/build/gulpfile.extensions.js +++ b/build/gulpfile.extensions.js @@ -64,6 +64,7 @@ const compilations = [ 'search-result/tsconfig.json', 'references-view/tsconfig.json', 'simple-browser/tsconfig.json', + 'tunnel-forwarding/tsconfig.json', 'typescript-language-features/test-workspace/tsconfig.json', 'typescript-language-features/web/tsconfig.json', 'typescript-language-features/tsconfig.json', diff --git a/build/gulpfile.vscode.linux.js b/build/gulpfile.vscode.linux.js index 90f75ccfabd7f..0d7d3c5b7f80c 100644 --- a/build/gulpfile.vscode.linux.js +++ b/build/gulpfile.vscode.linux.js @@ -297,12 +297,14 @@ const BUILD_TARGETS = [ BUILD_TARGETS.forEach(({ arch }) => { const debArch = getDebPackageArch(arch); const prepareDebTask = task.define(`vscode-linux-${arch}-prepare-deb`, task.series(util.rimraf(`.build/linux/deb/${debArch}`), prepareDebPackage(arch))); - const buildDebTask = task.define(`vscode-linux-${arch}-build-deb`, task.series(prepareDebTask, buildDebPackage(arch))); + gulp.task(prepareDebTask); + const buildDebTask = task.define(`vscode-linux-${arch}-build-deb`, buildDebPackage(arch)); gulp.task(buildDebTask); const rpmArch = getRpmPackageArch(arch); const prepareRpmTask = task.define(`vscode-linux-${arch}-prepare-rpm`, task.series(util.rimraf(`.build/linux/rpm/${rpmArch}`), prepareRpmPackage(arch))); - const buildRpmTask = task.define(`vscode-linux-${arch}-build-rpm`, task.series(prepareRpmTask, buildRpmPackage(arch))); + gulp.task(prepareRpmTask); + const buildRpmTask = task.define(`vscode-linux-${arch}-build-rpm`, buildRpmPackage(arch)); gulp.task(buildRpmTask); const prepareSnapTask = task.define(`vscode-linux-${arch}-prepare-snap`, task.series(util.rimraf(`.build/linux/snap/${arch}`), prepareSnapPackage(arch))); diff --git a/build/gulpfile.vscode.win32.js b/build/gulpfile.vscode.win32.js index 2d6f14551b33b..674eb41a5032c 100644 --- a/build/gulpfile.vscode.win32.js +++ b/build/gulpfile.vscode.win32.js @@ -98,6 +98,7 @@ function buildWin32Setup(arch, target) { AppMutex: product.win32MutexName, TunnelMutex: product.win32TunnelMutex, TunnelServiceMutex: product.win32TunnelServiceMutex, + TunnelApplicationName: product.tunnelApplicationName, ApplicationName: product.applicationName, Arch: arch, AppId: { 'ia32': ia32AppId, 'x64': x64AppId, 'arm64': arm64AppId }[arch], diff --git a/build/hygiene.js b/build/hygiene.js index b8881081b2eab..2c01b1f4d754d 100644 --- a/build/hygiene.js +++ b/build/hygiene.js @@ -150,10 +150,12 @@ function hygiene(some, linting = true) { } const productJsonFilter = filter('product.json', { restore: true }); + const snapshotFilter = filter(['**', '!**/*.snap', '!**/*.snap.actual']); const unicodeFilterStream = filter(unicodeFilter, { restore: true }); const result = input .pipe(filter((f) => !f.stat.isDirectory())) + .pipe(snapshotFilter) .pipe(productJsonFilter) .pipe(process.env['BUILD_SOURCEVERSION'] ? es.through() : productJson) .pipe(productJsonFilter.restore) diff --git a/build/lib/compilation.js b/build/lib/compilation.js index 2270e054ba55e..8e82e1cd234ad 100644 --- a/build/lib/compilation.js +++ b/build/lib/compilation.js @@ -82,17 +82,19 @@ function createCompile(src, build, emitError, transpileOnly) { return pipeline; } function transpileTask(src, out, swc) { - return function () { + const task = () => { const transpile = createCompile(src, false, true, { swc }); const srcPipe = gulp.src(`${src}/**`, { base: `${src}` }); return srcPipe .pipe(transpile()) .pipe(gulp.dest(out)); }; + task.taskName = `transpile-${path.basename(src)}`; + return task; } exports.transpileTask = transpileTask; function compileTask(src, out, build, options = {}) { - return function () { + const task = () => { if (os.totalmem() < 4000000000) { throw new Error('compilation requires 4GB of RAM'); } @@ -128,10 +130,12 @@ function compileTask(src, out, build, options = {}) { .pipe(compile()) .pipe(gulp.dest(out)); }; + task.taskName = `compile-${path.basename(src)}`; + return task; } exports.compileTask = compileTask; function watchTask(out, build) { - return function () { + const task = () => { const compile = createCompile('src', build, false, false); const src = gulp.src('src/**', { base: 'src' }); const watchSrc = watch('src/**', { base: 'src', readDelay: 200 }); @@ -142,6 +146,8 @@ function watchTask(out, build) { .pipe(util.incremental(compile, src, true)) .pipe(gulp.dest(out)); }; + task.taskName = `watch-${path.basename(out)}`; + return task; } exports.watchTask = watchTask; const REPO_SRC_FOLDER = path.join(__dirname, '../../src'); @@ -281,4 +287,4 @@ exports.watchApiProposalNamesTask = task.define('watch-api-proposal-names', () = .pipe(util.debounce(task)) .pipe(gulp.dest('src')); }); -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcGlsYXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJjb21waWxhdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7OztnR0FHZ0c7OztBQUVoRyxtQ0FBbUM7QUFDbkMseUJBQXlCO0FBQ3pCLDZCQUE2QjtBQUM3Qiw2QkFBNkI7QUFDN0IsMENBQTBDO0FBQzFDLDZCQUE2QjtBQUM3Qix5Q0FBNEM7QUFDNUMsK0JBQStCO0FBQy9CLHNDQUFzQztBQUN0QywwQ0FBMEM7QUFDMUMseUJBQXlCO0FBQ3pCLGlDQUFrQztBQUNsQyw4QkFBOEI7QUFDOUIsK0JBQStCO0FBQy9CLDBDQUF5QztBQUV6QyxNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7QUFHakMsdUVBQXVFO0FBRXZFLE1BQU0sUUFBUSxHQUFHLElBQUEseUJBQWMsR0FBRSxDQUFDO0FBRWxDLFNBQVMsNEJBQTRCLENBQUMsR0FBVztJQUNoRCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxTQUFTLEdBQUcsRUFBRSxDQUFDLENBQUM7SUFDckQsTUFBTSxPQUFPLEdBQXVCLEVBQUUsQ0FBQztJQUN2QyxPQUFPLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQztJQUN4QixPQUFPLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztJQUN6QixJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMscUJBQXFCLENBQUMsRUFBRSxFQUFFLHNDQUFzQztRQUMvRSxPQUFPLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztLQUMxQjtJQUNELE9BQU8sQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO0lBQzFCLE9BQU8sQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO0lBQzFCLE9BQU8sQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUM3QyxPQUFPLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQyxJQUFJ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 \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcGlsYXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJjb21waWxhdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7OztnR0FHZ0c7OztBQUVoRyxtQ0FBbUM7QUFDbkMseUJBQXlCO0FBQ3pCLDZCQUE2QjtBQUM3Qiw2QkFBNkI7QUFDN0IsMENBQTBDO0FBQzFDLDZCQUE2QjtBQUM3Qix5Q0FBNEM7QUFDNUMsK0JBQStCO0FBQy9CLHNDQUFzQztBQUN0QywwQ0FBMEM7QUFDMUMseUJBQXlCO0FBQ3pCLGlDQUFrQztBQUNsQyw4QkFBOEI7QUFDOUIsK0JBQStCO0FBQy9CLDBDQUF5QztBQUV6QyxNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7QUFHakMsdUVBQXVFO0FBRXZFLE1BQU0sUUFBUSxHQUFHLElBQUEseUJBQWMsR0FBRSxDQUFDO0FBRWxDLFNBQVMsNEJBQTRCLENBQUMsR0FBVztJQUNoRCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxTQUFTLEdBQUcsRUFBRSxDQUFDLENBQUM7SUFDckQsTUFBTSxPQUFPLEdBQXVCLEVBQUUsQ0FBQztJQUN2QyxPQUFPLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQztJQUN4QixPQUFPLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztJQUN6QixJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMscUJBQXFCLENBQUMsRUFBRSxFQUFFLHNDQUFzQztRQUMvRSxPQUFPLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztLQUMxQjtJQUNELE9BQU8sQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO0lBQzFCLE9BQU8sQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO0lBQzFCLE9BQU8sQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUM3QyxPQUFPLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQyxJQUFJ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 \ No newline at end of file diff --git a/build/lib/compilation.ts b/build/lib/compilation.ts index d5da3f1cd89df..cf2ab921f1c4c 100644 --- a/build/lib/compilation.ts +++ b/build/lib/compilation.ts @@ -93,9 +93,9 @@ function createCompile(src: string, build: boolean, emitError: boolean, transpil return pipeline; } -export function transpileTask(src: string, out: string, swc: boolean): () => NodeJS.ReadWriteStream { +export function transpileTask(src: string, out: string, swc: boolean): task.StreamTask { - return function () { + const task = () => { const transpile = createCompile(src, false, true, { swc }); const srcPipe = gulp.src(`${src}/**`, { base: `${src}` }); @@ -104,11 +104,14 @@ export function transpileTask(src: string, out: string, swc: boolean): () => Nod .pipe(transpile()) .pipe(gulp.dest(out)); }; + + task.taskName = `transpile-${path.basename(src)}`; + return task; } -export function compileTask(src: string, out: string, build: boolean, options: { disableMangle?: boolean } = {}): () => NodeJS.ReadWriteStream { +export function compileTask(src: string, out: string, build: boolean, options: { disableMangle?: boolean } = {}): task.StreamTask { - return function () { + const task = () => { if (os.totalmem() < 4_000_000_000) { throw new Error('compilation requires 4GB of RAM'); @@ -150,11 +153,14 @@ export function compileTask(src: string, out: string, build: boolean, options: { .pipe(compile()) .pipe(gulp.dest(out)); }; + + task.taskName = `compile-${path.basename(src)}`; + return task; } -export function watchTask(out: string, build: boolean): () => NodeJS.ReadWriteStream { +export function watchTask(out: string, build: boolean): task.StreamTask { - return function () { + const task = () => { const compile = createCompile('src', build, false, false); const src = gulp.src('src/**', { base: 'src' }); @@ -168,6 +174,8 @@ export function watchTask(out: string, build: boolean): () => NodeJS.ReadWriteSt .pipe(util.incremental(compile, src, true)) .pipe(gulp.dest(out)); }; + task.taskName = `watch-${path.basename(out)}`; + return task; } const REPO_SRC_FOLDER = path.join(__dirname, '../../src'); diff --git a/build/lib/electron.js b/build/lib/electron.js index f06445d87fafa..6d315b386adf5 100644 --- a/build/lib/electron.js +++ b/build/lib/electron.js @@ -212,4 +212,4 @@ if (require.main === module) { process.exit(1); }); } -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWxlY3Ryb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJlbGVjdHJvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7OztnR0FHZ0c7OztBQUVoRyx5QkFBeUI7QUFDekIsNkJBQTZCO0FBQzdCLGdDQUFnQztBQUNoQyxzQ0FBc0M7QUFDdEMsZ0NBQWdDO0FBQ2hDLCtCQUErQjtBQUMvQiw2Q0FBMEM7QUFZMUMsU0FBUyxnQkFBZ0IsQ0FBQyxHQUFZO0lBQ3JDLE9BQU8sR0FBRyxLQUFLLFVBQVUsSUFBSSxHQUFHLEtBQUssUUFBUSxJQUFJLEdBQUcsS0FBSyxNQUFNLElBQUksR0FBRyxLQUFLLGFBQWEsQ0FBQztBQUMxRixDQUFDO0FBRUQsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7QUFDbkQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLGNBQWMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUM7QUFDckYsTUFBTSxNQUFNLEdBQUcsSUFBQSx1QkFBVSxFQUFDLElBQUksQ0FBQyxDQUFDO0FBRWhDLE1BQU0scUJBQXFCLEdBQUcsT0FBTyxDQUFDLGFBQWEsSUFBSSxDQUFDLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLGFBQWEsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUM7QUFFbkk7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWtCRztBQUNILFNBQVMsd0JBQXdCLENBQUMsVUFBb0IsRUFBRSxJQUFZLEVBQUUsWUFBNEMsRUFBRSxJQUFlO0lBQ2xJLDJGQUEyRjtJQUMzRixJQUFJLGdCQUFnQixDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsWUFB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 \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWxlY3Ryb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJlbGVjdHJvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7OztnR0FHZ0c7OztBQUVoRyx5QkFBeUI7QUFDekIsNkJBQTZCO0FBQzdCLGdDQUFnQztBQUNoQyxzQ0FBc0M7QUFDdEMsZ0NBQWdDO0FBQ2hDLCtCQUErQjtBQUMvQiw2Q0FBMEM7QUFZMUMsU0FBUyxnQkFBZ0IsQ0FBQyxHQUFZO0lBQ3JDLE9BQU8sR0FBRyxLQUFLLFVBQVUsSUFBSSxHQUFHLEtBQUssUUFBUSxJQUFJLEdBQUcsS0FBSyxNQUFNLElBQUksR0FBRyxLQUFLLGFBQWEsQ0FBQztBQUMxRixDQUFDO0FBRUQsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7QUFDbkQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLGNBQWMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUM7QUFDckYsTUFBTSxNQUFNLEdBQUcsSUFBQSx1QkFBVSxFQUFDLElBQUksQ0FBQyxDQUFDO0FBRWhDLE1BQU0scUJBQXFCLEdBQUcsT0FBTyxDQUFDLGFBQWEsSUFBSSxDQUFDLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLGFBQWEsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUM7QUFFbkk7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWtCRztBQUNILFNBQVMsd0JBQXdCLENBQUMsVUFBb0IsRUFBRSxJQUFZLEVBQUUsWUFBNEMsRUFBRSxJQUFlO0lBQ2xJLDJGQUEyRjtJQUMzRixJQUFJLGdCQUFnQixDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFO1FBQ3BELFlBQVksR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsWUFBWSxJQUFJLFVBQVUsQ0FBQyxDQUFDO0tBQ2pHO0lBRUQsT0FBTztRQUNOLElBQUksRUFBRSxZQUFZO1FBQ2xCLElBQUksRUFBRSxRQUFRO1FBQ2QsT0FBTyxFQUFFLENBQUMsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDO1FBQ3pDLFVBQVU7UUFDVixRQUFRLEVBQUUsbUJBQW1CLEdBQUcsSUFBSSxHQUFHLE9BQU87UUFDOUMsSUFBSTtLQUNKLENBQUM7QUFDSCxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7R0FVRztBQUNILFNBQVMseUJBQXlCLENBQUMsS0FBNEMsRUFBRSxJQUFZO0lBQzVGLE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFZLEVBQXNCLEVBQUU7UUFDbEUsTUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQy9CLE9BQU87WUFDTixJQUFJO1lBQ0osSUFBSSxFQUFFLFFBQVE7WUFDZCxPQUFPLEVBQUUsQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUM7WUFDekMsVUFBVSxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUM7WUFDakUsUUFBUSxFQUFFLG1CQUFtQixHQUFHLElBQUksR0FBRyxPQUFPO1NBQ3hCLENBQUM7SUFDekIsQ0FBQyxDQUFDLENBQUM7QUFDSixDQUFDO0FBRUQsTUFBTSxFQUFFLGVBQWUsRUFBRSxTQUFTLEVBQUUsR0FBRyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztBQUVwRCxRQUFBLE1BQU0sR0FBRztJQUNyQixPQUFPLEVBQUUsZUFBZTtJQUN4QixHQUFHLEVBQUUsT0FBTyxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxJQUFJLGVBQWUsSUFBSSxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUMsU0FBUztJQUNoRixjQUFjLEVBQUUsT0FBTyxDQUFDLFFBQVE7SUFDaEMsV0FBVyxFQUFFLHVCQUF1QjtJQUNwQyxTQUFTLEVBQUUsbURBQW1EO0lBQzlELFVBQVUsRUFBRSw0QkFBNEI7SUFDeEMsc0JBQXNCLEVBQUUsT0FBTyxDQUFDLHNCQUFzQjtJQUN0RCw2QkFBNkIsRUFBRSxxQ0FBcUM7SUFDcEUsb0JBQW9CLEVBQUUsa0JBQWtCO0lBQ3hDLGtCQUFrQixFQUFFLGtCQUFrQjtJQUN0Qyx5QkFBeUIsRUFBRTtRQUMxQixHQUFHLHlCQUF5QixDQUFDLEVBQUUsZUFBZSxFQUFFLEdBQUcsRUFBRSxlQUFlLEVBQUUsR0FBRyxFQUFFLEVBQUUsR0FBRyxDQUFDO1FBQ2pGLEdBQUcseUJBQXlCLENBQUMsRUFBRSx3QkFBd0IsRUFBRSxDQUFDLGVBQWUsRUFBRSxXQUFXLEVBQUUsV0FBVyxDQUFDLEVBQUUsRUFBRSxRQUFRLENBQUM7UUFDakgsR0FBRyx5QkFBeUIsQ0FBQyxFQUFFLHdCQUF3QixFQUFFLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsT0FBTyxDQUFDLEVBQUUsRUFBRSxNQUFNLENBQUM7UUFDL0gsd0JBQXdCLENBQUMsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLEVBQUUsS0FBSyxFQUFFLHdCQUF3QixDQUFDO1FBQ3pFLHdCQUF3QixDQUFDLENBQUMsU0FBUyxDQUFDLEVBQUUsT0FBTyxDQUFDO1FBQzlDLHdCQUF3QixDQUFDLENBQUMsUUFBUSxFQUFFLGNBQWMsRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLEVBQUUsUUFBUSxFQUFFLG9CQUFvQixDQUFDO1FBQ2xHLHdCQUF3QixDQUFDLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLEVBQUUsS0FBSyxFQUFFLGlCQUFpQixDQUFDO1FBQy9FLHdCQUF3QixDQUFDLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLEVBQUUsS0FBSyxFQUFFLGlCQUFpQixDQUFDO1FBQy9FLHdCQUF3QixDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsU0FBUyxFQUFFLHlCQUF5QixDQUFDO1FBQ3JFLHdCQUF3QixDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLDJCQUEyQixDQUFDO1FBQ3BFLHdCQUF3QixDQUFDLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxFQUFFLFFBQVEsRUFBRSxnQkFBZ0IsQ0FBQztRQUNuRSx3QkFBd0IsQ0FBQyxDQUFDLEtBQUssQ0FBQyxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUM7UUFDL0Msd0JBQXdCLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLEVBQUUsZ0JBQWdCLENBQUM7UUFDeEQsd0JBQXdCLENBQUMsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxFQUFFLE1BQU0sQ0FBQztRQUMxRCx3QkFBd0IsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLE1BQU0sQ0FBQztRQUMxQyx3QkFBd0IsQ0FBQyxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsRUFBRSxNQUFNLENBQUM7UUFDakQsd0JBQXdCLENBQUMsQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLEVBQUUsWUFBWSxFQUFFLE1BQU0sQ0FBQztRQUMxRix3QkFBd0IsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLE1BQU0sQ0FBQztRQUMxQyx3QkFBd0IsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLE1BQU0sQ0FBQztRQUMxQyx3QkFBd0IsQ0FBQyxDQUFDLFVBQVUsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLEVBQUUsVUFBVSxDQUFDO1FBQ25ILHdCQUF3QixDQUFDLENBQUMsS0FBSyxDQUFDLEVBQUUsS0FBSyxFQUFFLGFBQWEsQ0FBQztRQUN2RCx3QkFBd0IsQ0FBQyxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDLEVBQUUsWUFBWSxFQUFFLFFBQVEsQ0FBQztRQUN6RSx3QkFBd0IsQ0FBQyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsRUFBRSxRQUFRLEVBQUUsUUFBUSxDQUFDO1FBQzNELHdCQUF3QixDQUFDLENBQUMsU0FBUyxFQUFFLElBQUksRUFBRSxLQUFLLENBQUMsRUFBRSxNQUFNLEVBQUUsYUFBYSxDQUFDO1FBQ3pFLHdCQUF3QixDQUFDLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUM7UUFDMUQsd0JBQXdCLENBQUMsQ0FBQyxLQUFLLENBQUMsRUFBRSxLQUFLLEVBQUUsUUFBUSxDQUFDO1FBQ2xELHdCQUF3QixDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsWUFBWSxFQUFFLE1BQU0sQ0FBQztRQUN0RCx3QkFBd0IsQ0FBQyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsRUFBRSxPQUFPLEVBQUUsYUFBYSxDQUFDO1FBQ2hFLHdCQUF3QixDQUFDLENBQUMsS0FBSyxDQUFDLEVBQUUsS0FBSyxFQUFFLGFBQWEsQ0FBQztRQUN2RCx3QkFBd0IsQ0FBQyxDQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLEVBQUUsS0FBSyxDQUFDO1FBQ3ZHLHdCQUF3QixDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsS0FBSyxDQUFDLEVBQUUsTUFBTSxDQUFDO1FBQ2xFLHdCQUF3QixDQUFDO1lBQ3hCLE1BQU0sRUFBRSxZQUFZLEVBQUUsYUFBYSxFQUFFLGNBQWMsRUFBRSxRQUFRO1lBQzdELFNBQVMsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsU0FBUztZQUM1RCxVQUFVLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxPQUFPO1NBQ3BDLEVBQUUsT0FBTyxFQUFFLFFBQVEsQ0FBQztRQUNyQixvQ0FBb0M7UUFDcEMsR0FBRyx5QkFBeUIsQ0FBQztZQUM1QixxQkFBcUIsRUFBRSxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLFNBQVMsQ0FBQztZQUN6RCx3QkFBd0IsRUFBRSxnQkFBZ0I7WUFDMUMsMEJBQTBCLEVBQUUsUUFBUTtZQUNwQyx3QkFBd0IsRUFBRSxLQUFLO1lBQy9CLGNBQWMsRUFBRSxPQUFPO1lBQ3ZCLGFBQWEsRUFBRSxNQUFNO1lBQ3JCLFdBQVcsRUFBRSxNQUFNO1lBQ25CLFlBQVksRUFBRSxZQUFZO1lBQzFCLGFBQWEsRUFBRSxRQUFRO1lBQ3ZCLGVBQWUsRUFBRSxRQUFRO1lBQ3pCLFVBQVUsRUFBRSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUM7WUFDOUIsWUFBWSxFQUFFLEtBQUs7WUFDbkIsY0FBYyxFQUFFLEtBQUs7WUFDckIsU0FBUyxFQUFFLE9BQU87WUFDbEIsVUFBVSxFQUFFLE1BQU07WUFDbEIsVUFBVSxFQUFFLEtBQUs7WUFDakIsaUJBQWlCLEVBQUUsS0FBSztZQUN4QixvQkFBb0IsRUFBRSxXQUFXO1lBQ2pDLHNCQUFzQixFQUFFLGFBQWE7WUFDckMscUJBQXFCLEVBQUUsSUFBSTtZQUMzQixlQUFlLEVBQUUsR0FBRztZQUNwQixrQkFBa0IsRUFBRSxJQUFJO1lBQ3hCLDRCQUE0QixFQUFFLEtBQUs7WUFDbkMsZ0JBQWdCLEVBQUUsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDO1lBQ2hDLGdCQUFnQixFQUFFLElBQUk7WUFDdEIsbUJBQW1CLEVBQUUsS0FBSztZQUMxQixXQUFXLEVBQUUsQ0FBQyxLQUFLLEVBQUUsVUFBVSxDQUFDO1lBQ2hDLGNBQWMsRUFBRSxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUM7WUFDL0IsZUFBZSxFQUFFLE1BQU07WUFDdkIsbUJBQW1CLEVBQUUsT0FBTztTQUM1QixFQUFFLFNBQVMsQ0FBQztRQUNiLGlDQUFpQztRQUNqQyx3QkFBd0IsQ0FBQztZQUN4QixlQUFlLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsS0FBSztZQUN0RSxJQUFJLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxHQUFHO1NBQ3RFLEVBQUUsU0FBUyxFQUFFLE9BQU8sQ0FBQyxRQUFRLEdBQUcsV0FBVyxDQUFDO1FBQzdDLG9CQUFvQjtRQUNwQix3QkFBd0IsQ0FBQyxFQUFFLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxDQUFDLGVBQWUsQ0FBQyxDQUFDO0tBQ3BFO0lBQ0Qsb0JBQW9CLEVBQUUsQ0FBQztZQUN0QixJQUFJLEVBQUUsUUFBUTtZQUNkLElBQUksRUFBRSxPQUFPLENBQUMsUUFBUTtZQUN0QixVQUFVLEVBQUUsQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDO1NBQ2pDLENBQUM7SUFDRiwwQkFBMEIsRUFBRSxJQUFJO0lBQ2hDLGFBQWEsRUFBRSxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLElBQUksSUFBSSxFQUFFLENBQUMsV0FBVyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVM7SUFDekksbUJBQW1CLEVBQUUsT0FBTyxDQUFDLGVBQWU7SUFDNUMsT0FBTyxFQUFFLDBCQUEwQjtJQUNuQyxLQUFLLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUM7SUFDbEMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxrQkFBa0IsSUFBSSxTQUFTO0lBQzdDLGdCQUFnQixFQUFFLElBQUk7SUFDdEIsWUFBWSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRSxXQUFXLEVBQUUsY0FBYyxDQUFDO0NBQ25FLENBQUM7QUFFRixTQUFTLFdBQVcsQ0FBQyxJQUFZO0lBQ2hDLE9BQU8sR0FBRyxFQUFFO1FBQ1gsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLHVCQUF1QixDQUFDLENBQUM7UUFDbEQsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixDQUFzQyxDQUFDO1FBRTlFLE1BQU0sWUFBWSxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLGNBQU0sRUFBRTtZQUN6QyxRQUFRLEVBQUUsT0FBTyxDQUFDLFFBQVE7WUFDMUIsSUFBSSxFQUFFLElBQUksS0FBSyxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSTtZQUNyQyxjQUFjLEVBQUUsS0FBSztZQUNyQixjQUFjLEVBQUUsSUFBSTtTQUNwQixDQUFDLENBQUM7UUFFSCxPQUFPLEdBQUcsQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDO2FBQzVCLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLEVBQUUsT0FBTyxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUM7YUFDdkMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQzthQUM1QixJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLHNCQUFzQixDQUFDLENBQUMsQ0FBQzthQUM1QyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUM7SUFDckMsQ0FBQyxDQUFDO0FBQ0gsQ0FBQztBQUVELEtBQUssVUFBVSxJQUFJLENBQUMsT0FBZSxPQUFPLENBQUMsSUFBSTtJQUM5QyxNQUFNLE9BQU8sR0FBRyxlQUFlLENBQUM7SUFDaEMsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBQzNELE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLFNBQVMsQ0FBQyxDQUFDO0lBQ3ZELE1BQU0sVUFBVSxHQUFHLEVBQUUsQ0FBQyxVQUFVLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxDQUFDLFlBQVksQ0FBQyxXQUFXLEVBQUUsTUFBTSxDQUFDLEtBQUssR0FBRyxPQUFPLEVBQUUsQ0FBQztJQUV2RyxJQUFJLENBQUMsVUFBVSxFQUFFO1FBQ2hCLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDO1FBQ2xDLE1BQU0sSUFBSSxDQUFDLGVBQWUsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0tBQ2hEO0FBQ0YsQ0FBQztBQUVELElBQUksT0FBTyxDQUFDLElBQUksS0FBSyxNQUFNLEVBQUU7SUFDNUIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEVBQUU7UUFDakMsT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNuQixPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2pCLENBQUMsQ0FBQyxDQUFDO0NBQ0gifQ== \ No newline at end of file diff --git a/build/lib/electron.ts b/build/lib/electron.ts index 0c3df8cfd7156..592708cc3857d 100644 --- a/build/lib/electron.ts +++ b/build/lib/electron.ts @@ -216,7 +216,7 @@ function getElectron(arch: string): () => NodeJS.ReadWriteStream { }; } -async function main(arch = process.arch): Promise { +async function main(arch: string = process.arch): Promise { const version = electronVersion; const electronPath = path.join(root, '.build', 'electron'); const versionFile = path.join(electronPath, 'version'); diff --git a/build/lib/i18n.resources.json b/build/lib/i18n.resources.json index 50d9b271d95ed..f7f313371241b 100644 --- a/build/lib/i18n.resources.json +++ b/build/lib/i18n.resources.json @@ -58,6 +58,10 @@ "name": "vs/workbench/contrib/commands", "project": "vscode-workbench" }, + { + "name": "vs/workbench/contrib/mappedEdits", + "project": "vscode-workbench" + }, { "name": "vs/workbench/contrib/comments", "project": "vscode-workbench" @@ -86,10 +90,6 @@ "name": "vs/workbench/contrib/externalTerminal", "project": "vscode-workbench" }, - { - "name": "vs/workbench/contrib/feedback", - "project": "vscode-workbench" - }, { "name": "vs/workbench/contrib/files", "project": "vscode-workbench" diff --git a/build/lib/layersChecker.js b/build/lib/layersChecker.js index f52680fd9da91..618c736b30a7f 100644 --- a/build/lib/layersChecker.js +++ b/build/lib/layersChecker.js @@ -58,6 +58,11 @@ const CORE_TYPES = [ 'URL', 'URLSearchParams', 'ReadonlyArray', + 'Event', + 'EventTarget', + 'BroadcastChannel', + 'performance', + 'Blob' ]; // Types that are defined in a common layer but are known to be only // available in native environments should not be allowed in browser @@ -283,4 +288,4 @@ for (const sourceFile of program.getSourceFiles()) { if (hasErrors) { process.exit(1); } -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGF5ZXJzQ2hlY2tlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImxheWVyc0NoZWNrZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Z0dBR2dHOztBQUVoRyxpQ0FBaUM7QUFDakMsMkJBQThDO0FBQzlDLCtCQUE4QztBQUM5Qyx5Q0FBa0M7QUFFbEMsRUFBRTtBQUNGLGdHQUFnRztBQUNoRyxFQUFFO0FBQ0YsK0ZBQStGO0FBQy9GLG1EQUFtRDtBQUNuRCw0RUFBNEU7QUFDNUUsaUVBQWlFO0FBQ2pFLEVBQUU7QUFDRixnR0FBZ0c7QUFDaEcsRUFBRTtBQUNGLGdHQUFnRztBQUNoRyxFQUFFO0FBRUYsbUZBQW1GO0FBQ25GLHdGQUF3RjtBQUN4RixNQUFNLFVBQVUsR0FBRztJQUNsQixTQUFTO0lBQ1QsWUFBWTtJQUNaLGNBQWM7SUFDZCxhQUFhO0lBQ2IsZUFBZTtJQUNmLFNBQVM7SUFDVCxTQUFTO0lBQ1QsT0FBTztJQUNQLGtCQUFrQjtJQUNsQixRQUFRO0lBQ1IsYUFBYTtJQUNiLGFBQWE7SUFDYixNQUFNO0lBQ04sZ0JBQWdCO0lBQ2hCLE9BQU87SUFDUCxZQUFZO0lBQ1osYUFBYTtJQUNiLGFBQWE7SUFDYixXQUFXO0lBQ1gsWUFBWTtJQUNaLFlBQVk7SUFDWixjQUFjO0lBQ2QsY0FBYztJQUNkLG1CQUFtQjtJQUNuQixnQkFBZ0I7SUFDaEIsZUFBZTtJQUNmLE1BQU07SUFDTixNQUFNO0lBQ04saUJBQWlCO0lBQ2pCLGFBQWE7SUFDYixnQkFBZ0I7SUFDaEIsYUFBYTtJQUNiLEtBQUs7SUFDTCxpQkFBaUI7SUFDakIsZUFBZTtDQUNmLENBQUM7QUFFRixvRUFBb0U7QUFDcEUsb0VBQW9FO0FBQ3BFLE1BQU0sWUFBWSxHQUFHO0lBQ3BCLGtCQUFrQjtJQUNsQiwyQkFBMkI7SUFDM0Isa0NBQWtDO0lBQ2xDLDRCQUE0QjtJQUM1QiwwQkFBMEI7SUFDMUIsb0JBQW9CO0lBQ3BCLHFCQUFxQjtDQUNyQixDQUFDO0FBRUYs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 \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGF5ZXJzQ2hlY2tlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImxheWVyc0NoZWNrZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Z0dBR2dHOztBQUVoRyxpQ0FBaUM7QUFDakMsMkJBQThDO0FBQzlDLCtCQUE4QztBQUM5Qyx5Q0FBa0M7QUFFbEMsRUFBRTtBQUNGLGdHQUFnRztBQUNoRyxFQUFFO0FBQ0YsK0ZBQStGO0FBQy9GLG1EQUFtRDtBQUNuRCw0RUFBNEU7QUFDNUUsaUVBQWlFO0FBQ2pFLEVBQUU7QUFDRixnR0FBZ0c7QUFDaEcsRUFBRTtBQUNGLGdHQUFnRztBQUNoRyxFQUFFO0FBRUYsbUZBQW1GO0FBQ25GLHdGQUF3RjtBQUN4RixNQUFNLFVBQVUsR0FBRztJQUNsQixTQUFTO0lBQ1QsWUFBWTtJQUNaLGNBQWM7SUFDZCxhQUFhO0lBQ2IsZUFBZTtJQUNmLFNBQVM7SUFDVCxTQUFTO0lBQ1QsT0FBTztJQUNQLGtCQUFrQjtJQUNsQixRQUFRO0lBQ1IsYUFBYTtJQUNiLGFBQWE7SUFDYixNQUFNO0lBQ04sZ0JBQWdCO0lBQ2hCLE9BQU87SUFDUCxZQUFZO0lBQ1osYUFBYTtJQUNiLGFBQWE7SUFDYixXQUFXO0lBQ1gsWUFBWTtJQUNaLFlBQVk7SUFDWixjQUFjO0lBQ2QsY0FBYztJQUNkLG1CQUFtQjtJQUNuQixnQkFBZ0I7SUFDaEIsZUFBZTtJQUNmLE1BQU07SUFDTixNQUFNO0lBQ04saUJBQWlCO0lBQ2pCLGFBQWE7SUFDYixnQkFBZ0I7SUFDaEIsYUFBYTtJQUNiLEtBQUs7SUFDTCxpQkFBaUI7SUFDakIsZUFBZTtJQUNmLE9BQU87SUFDUCxhQUFhO0lBQ2Isa0JBQWtCO0lBQ2xCLGFBQWE7SUFDYixNQUFNO0NBQ04sQ0FBQztBQUVGLG9FQUFvRTtBQUNwRSxvRUFBb0U7QUFDcEUsTUFBTSxZQUFZLEdBQUc7SUFDcEIsa0JBQWtCO0lBQ2xCLDJCQUEyQjtJQUMzQixrQ0FBa0M7SUFDbEMsNEJBQTRCO0lB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 \ No newline at end of file diff --git a/build/lib/layersChecker.ts b/build/lib/layersChecker.ts index 95f88735bf80e..e7fdfd4214e22 100644 --- a/build/lib/layersChecker.ts +++ b/build/lib/layersChecker.ts @@ -59,6 +59,11 @@ const CORE_TYPES = [ 'URL', 'URLSearchParams', 'ReadonlyArray', + 'Event', + 'EventTarget', + 'BroadcastChannel', + 'performance', + 'Blob' ]; // Types that are defined in a common layer but are known to be only diff --git a/build/lib/mangle/index.js b/build/lib/mangle/index.js index 75981c79d06e3..27281954b748e 100644 --- a/build/lib/mangle/index.js +++ b/build/lib/mangle/index.js @@ -246,12 +246,6 @@ function isNameTakenInFile(node, name) { } return false; } -const fileIdents = new class { - idents = new ShortIdent('$'); - next() { - return this.idents.next(); - } -}; const skippedExportMangledFiles = [ // Build 'css.build', @@ -301,7 +295,7 @@ class DeclarationData { node; service; replacementName; - constructor(fileName, node, service) { + constructor(fileName, node, service, fileIdents) { this.fileName = fileName; this.node = node; this.service = service; @@ -368,6 +362,7 @@ class Mangler { // STEP: // - Find all classes and their field info. // - Find exported symbols. + const fileIdents = new ShortIdent('$'); const visit = (node) => { if (this.config.manglePrivateFields) { if (ts.isClassDeclaration(node) || ts.isClassExpression(node)) { @@ -410,7 +405,7 @@ class Mangler { if (isInAmbientContext(node)) { return; } - this.allExportedSymbols.add(new DeclarationData(node.getSourceFile().fileName, node, this.service)); + this.allExportedSymbols.add(new DeclarationData(node.getSourceFile().fileName, node, this.service, fileIdents)); } } ts.forEachChild(node, visit); @@ -662,4 +657,4 @@ async function _run() { if (__filename === process_1.argv[1]) { _run(); } -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7OztnR0FHZ0c7OztBQUVoRyx5QkFBeUI7QUFDekIsNkJBQTZCO0FBQzdCLHFDQUErQjtBQUMvQiwyQ0FBeUQ7QUFDekQsaUNBQWlDO0FBQ2pDLDZCQUFvQztBQUNwQyx5Q0FBeUM7QUFDekMsMkVBQXdFO0FBQ3hFLE1BQU0sU0FBUyxHQUFHLE9BQU8sQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO0FBRXBELE1BQU0sVUFBVTtJQVlHO0lBVlYsTUFBTSxDQUFDLFNBQVMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxVQUFVO1FBQzlHLFNBQVMsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRSxJQUFJO1FBQ25HLFFBQVEsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsT0FBTztRQUMxRyxNQUFNLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztJQUU1RCxNQUFNLENBQUMsU0FBUyxHQUFHLGtFQUFrRSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUVoRyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBRW5CLFlBQ2tCLE1BQWM7UUFBZCxXQUFNLEdBQU4sTUFBTSxDQUFRO0lBQzVCLENBQUM7SUFFTCxJQUFJLENBQUMsV0FBdUM7UUFDM0MsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLE1BQU0sR0FBRyxVQUFVLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNoRSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDZCxJQUFJLFVBQVUsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxJQUFJLFNBQVMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksV0FBVyxFQUFFLENBQUMsU0FBUyxDQUFDLEVBQUU7WUFDakcsWUFBWTtZQUNaLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztTQUM5QjtRQUNELE9BQU8sU0FBUyxDQUFDO0lBQ2xCLENBQUM7SUFFTyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQVM7UUFDL0IsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUM7UUFDbkMsSUFBSSxNQUFNLEdBQUcsRUFBRSxDQUFDO1FBQ2hCLEdBQUc7WUFDRixNQUFNLElBQUksR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDO1lBQ3RCLE1BQU0sSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQy9CLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7U0FDbkIsUUFBUSxDQUFDLEdBQUcsQ0FBQyxFQUFFO1FBQ2hCLE9BQU8sTUFBTSxDQUFDO0lBQ2YsQ0FBQzs7QUFHRixJQUFXLFNBSVY7QUFKRCxXQUFXLFNBQVM7SUFDbkIsNkNBQU0sQ0FBQTtJQUNOLG1EQUFTLENBQUE7SUFDVCwrQ0FBTyxDQUFBO0FBQ1IsQ0FBQyxFQUpVLFNBQVMsS0FBVCxTQUFTLFFBSW5CO0FBRUQsTUFBTSxTQUFTO0lBVUo7SUFDQTtJQVRWLE1BQU0sR0FBRyxJQUFJLEdBQUcsRUFBNEMsQ0FBQztJQUVyRCxZQUFZLENBQWtDO0lBRXRELE1BQU0sQ0FBd0I7SUFDOUIsUUFBUSxDQUEwQjtJQUVsQyxZQUNVLFFBQWdCLEVBQ2hCLElBQThDO1FBRXZELGdGQUFnRjtRQUNoRixnRkFBZ0Y7UUFKdkUsYUFBUSxHQUFSLFFBQVEsQ0FBUTtRQUNoQixTQUFJLEdBQUosSUFBSSxDQUEwQztRQUt2RCxNQUFNLFVBQVUsR0FBNEIsRUFBRSxDQUFDO1FBQy9DLEtBQUssTUFBTSxNQUFNLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtZQUNsQyxJQUFJLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLENBQUMsRUFBRTtnQkFDbkMsb0JBQW9CO2dCQUNwQixVQUFVLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2FBRXhCO2lCQUFNLElBQUksRUFBRSxDQUFDLHFCQUFxQixDQUFDLE1BQU0sQ0FBQyxFQUFFO2dCQUM1Qyx1QkFBdUI7Z0JBQ3ZCLFVBQVUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7YUFFeEI7aUJBQU0sSUFBSSxFQUFFLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxFQUFFO2dCQUNwQyw4QkFBOEI7Z0JBQzlCLFVBQVUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7YUFFeEI7aUJBQU0sSUFBSSxFQUFFLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxFQUFFO2dCQUNwQyw4QkFBOEI7Z0JBQzlCLFVBQVUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7YUFFeEI7aUJBQU0sSUFBSSxFQUFFLENBQUMsd0JBQXdCLENBQUMsTUFBTSxDQUFDLEVBQUU7Z0JBQy9DLGlEQUFpRDtnQkFDakQsS0FBSyxNQUFNLEtBQUssSUFBSSxNQUFNLENBQUMsVUFBVSxFQUFFO29CQUN0QyxJQUFJLFdBQVcsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxjQUFjLENBQUM7MkJBQ2hELFdBQVcsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQzsyQkFDbEQsV0FBVyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQzsyQkFDL0MsV0FBVyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsVUFBVSxDQUFDLGVBQWUsQ0FBQyxFQUNuRDt3QkFDRCxVQUFVLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO3FCQUN2QjtpQkFDRDthQUNEO1NBQ0Q7UUFDRCxLQUFLLE1BQU0sTUFBTSxJQUFJLFVBQVUsRUFBRTtZQUNoQyxNQUFNLEtBQUssR0FBRyxTQUFTLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQy9DLElBQUksQ0FBQyxLQUFLLEVBQUU7Z0JBQ1gsU0FBUzthQUNUO1lBQ0QsTUFBTSxJQUFJLEdBQUcsU0FBUyxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUM3QyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLE1BQU0sQ0FBQyxJQUFLLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1NBQy9EO0lBQ0YsQ0FBQztJQUVPLE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBeUI7UUFDdEQsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUU7WUFDZixPQUFPLFNBQVMsQ0FBQztTQUNqQjtRQUNELE1BQU0sRUFBRSxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUM7UUFDdEIsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQzNCLElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxFQUFFLENBQUMsVUFBVSxDQUFDLG9CQUFvQixFQUFFO1lBQ3JELElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEtBQUssRUFBRSxDQUFDLFVBQVUsQ0FBQyxhQUFhLEVBQUU7Z0JBQ3pELCtDQUErQztnQkFDL0MsT0FBTzthQUNQO1lBQ0QsVUFBVTtZQUNWLEtBQUssR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUMvQztRQUVELE9BQU8sS0FBSyxDQUFDO0lBQ2QsQ0FBQztJQUVPLE1BQU0sQ0FBQyxhQUFhLENBQUMsSUFBYTtRQUN6QyxJQUFJLFdBQVcsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxjQUFjLENBQUMsRUFBRTtZQUNwRCxpQ0FBeUI7U0FDekI7YUFBTSxJQUFJLFdBQVcsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFO1lBQzdELG1DQUEyQjtTQUMzQjthQUFNO1lBQ04sZ0NBQXdCO1NBQ3hCO0lBQ0YsQ0FBQztJQUVELE1BQU0sQ0FBQyxhQUFhLENBQUMsSUFBZTtRQUNuQyxPQUFPLElBQUksOEJBQXNCO2VBQzdCLElBQUksZ0NBQXdCLENBQzlCO0lBQ0gsQ0FBQztJQUVELE1BQU0sQ0FBQyxnQ0FBZ0MsQ0FBQyxJQUFlLEVBQUUsZUFBa0U7UUFDMUgsVUFBVTtRQUNWLGlGQUFpRjtRQUNqRixpRkFBaUY7UUFDakYsS0FBSyxNQUFNLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUU7WUFDdkMsSUFBSSxJQUFJLENBQUMsSUFBSSw2QkFBcUIsRUFBRTtnQkFDbkMsU0FBUzthQUNUO1lBQ0QsSUFBSSxNQUFNLEdBQTBCLElBQUksQ0FBQyxNQUFNLENBQUM7WUFDaEQsT0FBTyxNQUFNLEVBQUU7Z0JBQ2QsSUFBSSxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLGdDQUF3QixFQUFFO29CQUMxRCxNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDLDZCQUE2QixDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO29CQUMxRyxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDLDZCQUE2QixDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztvQkFDbEYsZUFBZSxDQUFDLElBQUksRUFBRSxJQUFJLElBQUksVUFBVSxNQUFNLENBQUMsUUFBUSxJQUFJLFNBQVMsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxFQUFFLEVBQUUsR0FBRyxJQUFJLENBQUMsUUFBUSxJQUFJLE9BQU8sQ0FBQyxJQUFJLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztvQkFFekgsTUFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFFLENBQUMsSUFBSSwyQkFBbUIsQ0FBQztpQkFDakQ7Z0JBQ0QsTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7YUFDdkI7U0FDRDtJQUNGLENBQUM7SUFFRCxNQUFNLENBQUMsaUJBQWlCLENBQUMsSUFBZTtRQUV2QyxJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUU7WUFDdEIsZUFBZTtZQUNmLE9BQU87U0FDUDtRQUVELHdCQUF3QjtRQUN4QixJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUU7WUFDaEIsU0FBUyxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztTQUN6QztRQUVELElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUU5QixNQUFNLFdBQVcsR0FBRyxDQUFDLElBQVksRUFBRSxFQUFFO1lBQ3BDLGdCQUFnQjtZQUNoQixJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLEVBQUU7Z0JBQzVCLE9BQU8sSUFBSSxDQUFDO2FBQ1o7WUFFRCxVQUFVO1lBQ1YsSUFBSSxNQUFNLEdBQTBCLElBQUksQ0FBQyxNQUFNLENBQUM7WUFDaEQsT0FBTyxNQUFNLEVBQUU7Z0JBQ2QsSUFBSSxNQUFNLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxFQUFFO29CQUM5QixPQUFPLElBQUksQ0FBQztpQkFDWjtnQkFDRCxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQzthQUN2QjtZQUVELFdBQVc7WUFDWCxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUU7Z0JBQ2xCLE1BQU0sS0FBSyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ2pDLE9BQU8sS0FBSyxDQUFDLE1BQU0sRUFBRTtvQkFDcEIsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLEdBQUcsRUFBRyxDQUFDO29CQUMxQixJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLEVBQUU7d0JBQzVCLE9BQU8sSUFBSSxDQUFDO3FCQUNaO29CQUNELElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRTt3QkFDbEIsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztxQkFDN0I7aUJBQ0Q7YUFDRDtZQUVELE9BQU8sS0FBSyxDQUFDO1FBQ2QsQ0FBQyxDQUFDO1FBQ0YsTUFBTSxTQUFTLEdBQUcsSUFBSSxVQUFVLENBQUMsRUFBRSxDQUFDLENBQUM7UUFFckMsS0FBSyxNQUFNLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUU7WUFDdkMsSUFBSSxTQUFTLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRTtnQkFDdkMsTUFBTSxTQUFTLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztnQkFDOUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFDO2FBQ3ZDO1NBQ0Q7SUFDRixDQUFDO0lBRUQsa0VBQWtFO0lBQ2xFLGtEQUFrRDtJQUMxQyxZQUFZLENBQUMsSUFBWTtRQUNoQyxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRTtZQUNuRixlQUFlO1lBQ2YsT0FBTyxJQUFJLENBQUM7U0FDWjtRQUNELElBQUksSUFBSSxDQUFDLFlBQVksRUFBRTtZQUN0QixLQUFLLE1BQU0sU0FBUyxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLEVBQUU7Z0JBQ25ELElBQUksU0FBUyxLQUFLLElBQUksRUFBRTtvQkFDdkIsNkNBQTZDO29CQUM3QyxPQUFPLElBQUksQ0FBQztpQkFDWjthQUNEO1NBQ0Q7UUFFRCxJQUFJLGlCQUFpQixDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEVBQUU7WUFDdkMsT0FBTyxJQUFJLENBQUM7U0FDWjtRQUVELE9BQU8sS0FBSyxDQUFDO0lBQ2QsQ0FBQztJQUVELGVBQWUsQ0FBQyxJQUFZO1FBQzNCLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxZQUFhLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBRSxDQUFDO1FBQzFDLElBQUksTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7UUFDekIsT0FBTyxNQUFNLEVBQUU7WUFDZCxJQUFJLE1BQU0sQ0FBQyxZQUFhLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksZ0NBQXdCLEVBQUU7Z0JBQzVGLEtBQUssR0FBRyxNQUFNLENBQUMsWUFBYSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUUsSUFBSSxLQUFLLENBQUM7YUFDakQ7WUFDRCxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztTQUN2QjtRQUNELE9BQU8sS0FBSyxDQUFDO0lBQ2QsQ0FBQztJQUVELHNCQUFzQjtJQUV0QixRQUFRLENBQUMsS0FBZ0I7UUFDeEIsSUFBSSxDQUFDLFFBQVEsS0FBSyxFQUFFLENBQUM7UUFDckIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDMUIsS0FBSyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUM7SUFDckIsQ0FBQztDQUNEO0FBRUQsU0FBUyxpQkFBaUIsQ0FBQyxJQUFhLEVBQUUsSUFBWTtJQUNyRCxNQUFNLFdBQVcsR0FBUyxJQUFJLENBQUMsYUFBYSxFQUFHLENBQUMsV0FBVyxDQUFDO0lBQzVELElBQUksV0FBVyxZQUFZLEdBQUcsRUFBRTtRQUMvQixJQUFJLFdBQVcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDMUIsT0FBTyxJQUFJLENBQUM7U0FDWjtLQUNEO0lBQ0QsT0FBTyxLQUFLLENBQUM7QUFDZCxDQUFDO0FBRUQsTUFBTSxVQUFVLEdBQUcsSUFBSTtJQUNMLE1BQU0sR0FBRyxJQUFJLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUU5QyxJQUFJO1FBQ0gsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDO0lBQzNCLENBQUM7Q0FDRCxDQUFDO0FBRUYsTUFBTSx5QkFBeUIsR0FBRztJQUNqQyxRQUFRO0lBQ1IsV0FBVztJQUNYLFdBQVc7SUFFWCxTQUFTO0lBQ1QsY0FBYztJQUNkLGVBQWU7SUFDZixZQUFZO0lBQ1osa0JBQWtCO0lBQ2xCLGlCQUFpQjtJQUNqQixxQkFBcUI7SUFFckIsWUFBWTtJQUNaLHdCQUF3QjtJQUV4QiwrQkFBK0I7SUFDL0IsS0FBSztJQUVMLGVBQWU7SUFDZixHQUFHO1FBQ0YsU0FBUyxDQUFDLFVBQVUsQ0FBQyw0QkFBNEIsRUFBRSxFQUFFLENBQUM7UUFDdEQsU0FBUyxDQUFDLFVBQVUsQ0FBQyxxQ0FBcUMsRUFBRSxFQUFFLENBQUM7UUFDL0QsU0FBUyxDQUFDLElBQUk7UUFDZCxTQUFTLENBQUMsbUJBQW1CO1FBQzdCLFNBQVMsQ0FBQyxjQUFjO1FBQ3hCLFNBQVMsQ0FBQyx1QkFBdUI7UUFDakMsU0FBUyxDQUFDLHFCQUFxQjtRQUMvQixTQUFTLENBQUMscUJBQXFCO1FBQy9CLFNBQVMsQ0FBQyxnQkFBZ0I7UUFDMUIsU0FBUyxDQUFDLFlBQVk7UUFDdEIsU0FBUyxDQUFDLElBQUk7S0FDZCxDQUFDLElBQUksRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7Q0FDekIsQ0FBQztBQUVGLE1BQU0sNEJBQTRCLEdBQUc7SUFDcEMsZ0JBQWdCO0lBQ2hCLGtCQUFrQjtJQUVsQiwwRkFBMEY7SUFDMUYsdUJBQXVCO0lBQ3ZCLDBCQUEwQjtJQUMxQix1QkFBdUI7SUFDdkIsK0JBQStCO0NBQy9CLENBQUM7QUFFRixNQUFNLDJCQUEyQixHQUFHO0lBQ25DLHNDQUFzQztJQUN0QyxVQUFVO0lBQ1YsWUFBWTtDQUNaLENBQUM7QUFFRixNQUFNLGVBQWU7SUFLVjtJQUNBO0lBQ1E7SUFMVCxlQUFlLENBQVM7SUFFakMsWUFDVSxRQUFnQixFQUNoQixJQUFnRyxFQUN4RixPQUEyQjtRQUZuQyxhQUFRLEdBQVIsUUFBUSxDQUFRO1FBQ2hCLFNBQUksR0FBSixJQUFJLENBQTRGO1FBQ3hGLFlBQU8sR0FBUCxPQUFPLENBQW9CO1FBRTVDLDBHQUEwRztRQUMxRyxJQUFJLENBQUMsZUFBZSxHQUFHLFVBQVUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUMxQyxDQUFDO0lBRUQsSUFBSSxTQUFTO1FBQ1osSUFBSSxFQUFFLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFO1lBQ3hDLDhEQUE4RDtZQUM5RCxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMseUJBQXlCLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO1lBQzFHLElBQUksZ0JBQWdCLEVBQUUsV0FBVyxJQUFJLGdCQUFnQixDQUFDLFdBQVcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO2dCQUM3RSxPQUFPLGdCQUFnQixDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQyxRQUFRLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO2FBQ25HO1NBQ0Q7UUFFRCxPQUFPLENBQUM7Z0JBQ1AsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRO2dCQUN2QixNQUFNLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFLLENBQUMsUUFBUSxFQUFFO2FBQ2xDLENBQUMsQ0FBQztJQUNKLENBQUM7SUFFRCxZQUFZLENBQUMsT0FBZTtRQUMzQixNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUM5QyxJQUFJLFdBQVcsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLElBQUksMkJBQTJCLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxFQUFFO1lBQ3JGLE9BQU8sS0FBSyxDQUFDO1NBQ2I7UUFFRCwwQ0FBMEM7UUFDMUMsSUFBSSxPQUFPLENBQUMsTUFBTSxJQUFJLFdBQVcsQ0FBQyxNQUFNLEVBQUU7WUFDekMsT0FBTyxLQUFLLENBQUM7U0FDYjtRQUVELG9EQUFvRDtRQUNwRCxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxFQUFFO1lBQ3BELE9BQU8sS0FBSyxDQUFDO1NBQ2I7UUFFRCxPQUFPLElBQUksQ0FBQztJQUNiLENBQUM7Q0FDRDtBQU9EOzs7Ozs7OztHQVFHO0FBQ0gsTUFBYSxPQUFPO0lBU0Q7SUFDQTtJQUNBO0lBVEQsaUJBQWlCLEdBQUcsSUFBSSxHQUFHLEVBQXFCLENBQUM7SUFDakQsa0JBQWtCLEdBQUcsSUFBSSxHQUFHLEVBQW1CLENBQUM7SUFFaEQsT0FBTyxDQUFxQjtJQUM1QixnQkFBZ0IsQ0FBd0I7SUFFekQsWUFDa0IsV0FBbUIsRUFDbkIsTUFBMEIsR0FBRyxFQUFFLEdBQUcsQ0FBQyxFQUNuQyxNQUFrRjtRQUZsRixnQkFBVyxHQUFYLFdBQVcsQ0FBUTtRQUNuQixRQUFHLEdBQUgsR0FBRyxDQUFnQztRQUNuQyxXQUFNLEdBQU4sTUFBTSxDQUE0RTtRQUVuRyxJQUFJLENBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLHFEQUF5QixDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUM7UUFFcEYsSUFBSSxDQUFDLGdCQUFnQixHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsaUJBQWlCLENBQUMsRUFBRTtZQUNoRixVQUFVLEVBQUUsQ0FBQztZQUNiLFVBQVUsRUFBRSxLQUFLO1NBQ2pCLENBQUMsQ0FBQztJQUNKLENBQUM7SUFFRCxLQUFLLENBQUMsc0JBQXNCLENBQUMsNEJBQTBDO1FBRXRFLFFBQVE7UUFDUiwyQ0FBMkM7UUFDM0MsMkJBQTJCO1FBRTNCLE1BQU0sS0FBSyxHQUFHLENBQUMsSUFBYSxFQUFRLEVBQUU7WUFDckMsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLG1CQUFtQixFQUFFO2dCQUNwQyxJQUFJLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLEVBQUU7b0JBQzlELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDO29CQUNqQyxNQUFNLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQyxRQUFRLElBQUksTUFBTSxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUM7b0JBQ3BFLElBQUksSUFBSSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRTt3QkFDcEMsTUFBTSxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztxQkFDekI7b0JBQ0QsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO2lCQUNwRjthQUNEO1lBRUQsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsRUFBRTtnQkFDOUIsNkNBQTZDO2dCQUM3QyxJQUNDO2dCQUNDLGlCQUFpQjtnQkFDakIsRUFBRSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQzt1QkFDeEIsV0FBVyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQzt1QkFDOUMsSUFBSSxDQUFDLElBQUksQ0FDWixJQUFJO2dCQUNKLG9CQUFvQjtnQkFDcEIsRUFBRSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQzt1QkFDM0IsRUFBRSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDO3VCQUM1QixXQUFXLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDO3VCQUM5QyxJQUFJLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsNENBQTRDO2lCQUN0RSxJQUFJO2dCQUNKLG9CQUFvQjtnQkFDcEIsRUFBRSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQzt1QkFDM0IsV0FBVyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLENBQUMsaUNBQWlDO3VCQUM5RixFQUFFLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUM3QztnQkFFRCwrREFBK0Q7Z0JBQy9ELHVEQUF1RDtnQkFDdkQ7Ozs7Ozs7a0JBT0U7a0JBQ0Q7b0JBQ0QsSUFBSSxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsRUFBRTt3QkFDN0IsT0FBTztxQkFDUDtvQkFFRCxJQUFJLENBQUMsa0JBQWtCLENBQUMsR0FBRyxDQUFDLElBQUksZUFBZSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQyxRQUFRLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO2lCQUNwRzthQUNEO1lBRUQsRUFBRSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDOUIsQ0FBQyxDQUFDO1FBRUYsS0FBSyxNQUFNLElBQUksSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRyxDQUFDLGNBQWMsRUFBRSxFQUFFO1lBQy9ELElBQUksQ0FBQyxJQUFJLENBQUMsaUJBQWlCLEVBQUU7Z0JBQzVCLEVBQUUsQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO2FBQzdCO1NBQ0Q7UUFDRCxJQUFJLENBQUMsR0FBRyxDQUFDLDZCQUE2QixJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSx1QkFBdUIsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7UUFHeEgscUNBQXFDO1FBRXJDLE1BQU0sWUFBWSxHQUFHLENBQUMsSUFBZSxFQUFFLEVBQUU7WUFDeEMsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssS0FBSyxFQUFFLENBQUMsVUFBVSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1lBQ3JHLElBQUksQ0FBQyxhQUFhLEVBQUU7Z0JBQ25CLG9CQUFvQjtnQkFDcEIsT0FBTzthQUNQO1lBRUQsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7WUFDN0csSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtnQkFDL0IsMkNBQTJDO2dCQUMzQyxPQUFPO2FBQ1A7WUFFRCxJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO2dCQUN0QixzQ0FBc0M7Z0JBQ3RDLE9BQU87YUFDUDtZQUVELE1BQU0sQ0FBQyxVQUFVLENBQUMsR0FBRyxJQUFJLENBQUM7WUFDMUIsTUFBTSxHQUFHLEdBQUcsR0FBRyxVQUFVLENBQUMsUUFBUSxJQUFJLFVBQVUsQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDbEUsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUMvQyxJQUFJLENBQUMsTUFBTSxFQUFFO2dCQUNaLG1EQUFtRDtnQkFDbkQsT0FBTzthQUNQO1lBQ0QsTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN2QixDQUFDLENBQUM7UUFDRixLQUFLLE1BQU0sSUFBSSxJQUFJLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLEVBQUUsRUFBRTtZQUNuRCxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUM7U0FDbkI7UUFFRCx1RUFBdUU7UUFDdkUsTUFBTSxVQUFVLEdBQUcsSUFBSSxHQUFHLEVBQW9CLENBQUM7UUFDL0MsSUFBSSxzQkFBc0IsR0FBRyxLQUFLLENBQUM7UUFDbkMsS0FBSyxNQUFNLElBQUksSUFBSSxJQUFJLENBQUMsaUJBQWlCLENBQUMsTUFBTSxFQUFFLEVBQUU7WUFDbkQsU0FBUyxDQUFDLGdDQUFnQyxDQUFDLElBQUksRUFBRSxDQUFDLElBQVksRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLEVBQUU7Z0JBQzVFLE1BQU0sR0FBRyxHQUFHLFVBQVUsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQ2pDLElBQUksR0FBRyxFQUFFO29CQUNSLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7aUJBQ2Q7cUJBQU07b0JBQ04sVUFBVSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO2lCQUM1QjtnQkFFRCxJQUFJLDRCQUE0QixJQUFJLENBQUMsNEJBQTRCLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFO29CQUM1RSxzQkFBc0IsR0FBRyxJQUFJLENBQUM7aUJBQzlCO1lBQ0YsQ0FBQyxDQUFDLENBQUM7U0FDSDtRQUNELEtBQUssTUFBTSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsSUFBSSxVQUFVLEVBQUU7WUFDckMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLEdBQUcsOEJBQThCLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1NBQ3ZFO1FBQ0QsSUFBSSxzQkFBc0IsRUFBRTtZQUMzQixNQUFNLE9BQU8sR0FBRyxzSUFBc0ksQ0FBQztZQUN2SixJQUFJLENBQUMsR0FBRyxDQUFDLFVBQVUsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUM5QixNQUFNLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1NBQ3pCO1FBRUQsaURBQWlEO1FBQ2pELEtBQUssTUFBTSxJQUFJLElBQUksSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sRUFBRSxFQUFFO1lBQ25ELFNBQVMsQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUNsQztRQUNELElBQUksQ0FBQyxHQUFHLENBQUMsa0NBQWtDLENBQUMsQ0FBQztRQUU3Qyw2QkFBNkI7UUFDN0IsSUFBSSxDQUFDLEdBQUcsQ0FBQywrQkFBK0IsQ0FBQyxDQUFDO1FBRzFDLE1BQU0sV0FBVyxHQUFHLElBQUksR0FBRyxFQUFrQixDQUFDO1FBRTlDLE1BQU0sVUFBVSxHQUFHLENBQUMsUUFBZ0IsRUFBRSxJQUFVLEVBQUUsRUFBRTtZQUNuRCxNQUFNLEtBQUssR0FBRyxXQUFXLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3hDLElBQUksQ0FBQyxLQUFLLEVBQUU7Z0JBQ1gsV0FBVyxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO2FBQ2xDO2lCQUFNO2dCQUNOLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7YUFDakI7UUFDRixDQUFDLENBQUM7UUFDRixNQUFNLFlBQVksR0FBRyxDQUFDLE9BQWUsRUFBRSxHQUFzQixFQUFFLEVBQUU7WUFDaEUsVUFBVSxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUU7Z0JBQ3hCLE9BQU8sRUFBRSxDQUFDLEdBQUcsQ0FBQyxVQUFVLElBQUksRUFBRSxDQUFDLEdBQUcsT0FBTyxHQUFHLENBQUMsR0FBRyxDQUFDLFVBQVUsSUFBSSxFQUFFLENBQUM7Z0JBQ2xFLE1BQU0sRUFBRSxHQUFHLENBQUMsUUFBUSxDQUFDLEtBQUs7Z0JBQzFCLE1BQU0sRUFBRSxHQUFHLENBQUMsUUFBUSxDQUFDLE1BQU07YUFDM0IsQ0FBQyxDQUFDO1FBQ0osQ0FBQyxDQUFDO1FBSUYsTUFBTSxhQUFhLEdBQW1HLEVBQUUsQ0FBQztRQUV6SCxNQUFNLFdBQVcsR0FBRyxDQUFDLFFBQWdCLEVBQUUsR0FBVyxFQUFFLE9BQWUsRUFBRSxFQUFFO1lBQ3RFLGFBQWEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFXLHFCQUFxQixFQUFFLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxRQUFRLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztpQkFDaEksSUFBSSxDQUFDLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2xELENBQUMsQ0FBQztRQUVGLEtBQUssTUFBTSxJQUFJLElBQUksSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sRUFBRSxFQUFFO1lBQ25ELElBQUksV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxjQUFjLENBQUMsRUFBRTtnQkFDekQsU0FBUzthQUNUO1lBRUQsTUFBTSxFQUFFLEtBQUssTUFBTSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFO2dCQUMvQyxJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUU7b0JBQ3hDLFNBQVMsTUFBTSxDQUFDO2lCQUNoQjtnQkFFRCxvREFBb0Q7Z0JBQ3BELHVEQUF1RDtnQkFDdkQsSUFBSSxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztnQkFDekIsT0FBTyxNQUFNLEVBQUU7b0JBQ2QsSUFBSSxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLDZCQUFxQixFQUFFO3dCQUN2RCxTQUFTLE1BQU0sQ0FBQztxQkFDaEI7b0JBQ0QsTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7aUJBQ3ZCO2dCQUVELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQzNDLFdBQVcsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUUsT0FBTyxDQUFDLENBQUM7YUFDOUM7U0FDRDtRQUVELEtBQUssTUFBTSxJQUFJLElBQUksSUFBSSxDQUFDLGtCQUFrQixDQUFDLE1BQU0sRUFBRSxFQUFFO1lBQ3BELElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDO21CQUMvQiw0QkFBNEIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQzttQkFDdkUseUJBQXlCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFDLEVBQzlFO2dCQUNELFNBQVM7YUFDVDtZQUVELElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsRUFBRTtnQkFDN0MsU0FBUzthQUNUO1lBRUQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQztZQUNyQyxLQUFLLE1BQU0sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRTtnQkFDbEQsV0FBVyxDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUM7YUFDdkM7U0FDRDtRQUVELE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRTtZQUNoRCxLQUFLLE1BQU0sRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLElBQUksTUFBTSxFQUFFO2dCQUM1QyxLQUFLLE1BQU0sR0FBRyxJQUFJLFNBQVMsRUFBRTtvQkFDNUIsWUFBWSxDQUFDLE9BQU8sRUFBRSxHQUFHLENBQUMsQ0FBQztpQkFDM0I7YUFDRDtRQUNGLENBQUMsQ0FBQyxDQUFDO1FBRUgsTUFBTSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxFQUFFLENBQUM7UUFFeEMsSUFBSSxDQUFDLEdBQUcsQ0FBQyx5QkFBeUIsV0FBVyxDQUFDLElBQUksUUFBUSxDQUFDLENBQUM7UUFFNUQsMENBQTBDO1FBQzFDLE1BQU0sTUFBTSxHQUFHLElBQUksR0FBRyxFQUF3QixDQUFDO1FBQy9DLElBQUksVUFBVSxHQUFHLENBQUMsQ0FBQztRQUVuQixLQUFLLE1BQU0sSUFBSSxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFHLENBQUMsY0FBYyxFQUFFLEVBQUU7WUFFL0QsTUFBTSxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRyxDQUFDLGtCQUFrQixFQUFFLENBQUM7WUFDaEYsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDbEQsTUFBTSxhQUFhLEdBQUcsT0FBTyxJQUFJLElBQUEsbUJBQWEsRUFBQyxVQUFVLElBQUksVUFBVSxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7WUFFcEYsY0FBYztZQUNkLElBQUksU0FBeUMsQ0FBQztZQUU5QyxJQUFJLFdBQW1CLENBQUM7WUFDeEIsTUFBTSxLQUFLLEdBQUcsV0FBVyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDN0MsSUFBSSxDQUFDLEtBQUssRUFBRTtnQkFDWCxZQUFZO2dCQUNaLFdBQVcsR0FBRyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7YUFFakM7aUJBQU07Z0JBQ04sdUJBQXVCO2dCQUN2QixNQUFNLGdCQUFnQixHQUFHLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztnQkFDN0UsTUFBTSxjQUFjLEdBQUcsSUFBSSxHQUFHLEVBQXFCLENBQUM7Z0JBRXBELGdCQUFnQjtnQkFDaEIsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUMxQyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUVoRCxJQUFJLFFBQTBCLENBQUM7Z0JBRS9CLEtBQUssTUFBTSxJQUFJLElBQUksS0FBSyxFQUFFO29CQUN6QixJQUFJLFFBQVEsSUFBSSxRQUFRLENBQUMsTUFBTSxLQUFLLElBQUksQ0FBQyxNQUFNLEVBQUU7d0JBQ2hELEVBQUU7d0JBQ0YsSUFBSSxRQUFRLENBQUMsTUFBTSxLQUFLLElBQUksQ0FBQyxNQUFNLElBQUksUUFBUSxDQUFDLE9BQU8sS0FBSyxJQUFJLENBQUMsT0FBTyxFQUFFOzRCQUN6RSxJQUFJLENBQUMsR0FBRyxDQUFDLHlCQUF5QixFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FBQzs0QkFDdkUsTUFBTSxJQUFJLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO3lCQUNwQzs2QkFBTTs0QkFDTixTQUFTO3lCQUNUO3FCQUNEO29CQUNELFFBQVEsR0FBRyxJQUFJLENBQUM7b0JBQ2hCLE1BQU0sV0FBVyxHQUFHLFVBQVUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7b0JBQ3ZGLFVBQVUsSUFBSSxXQUFXLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDO29CQUV2RCxjQUFjO29CQUNkLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyw2QkFBNkIsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7b0JBRzVELElBQUksUUFBUSxHQUFHLGNBQWMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO29CQUM1QyxJQUFJLENBQUMsUUFBUSxFQUFFO3dCQUNkLFFBQVEsR0FBRyxFQUFFLENBQUM7d0JBQ2QsY0FBYyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDO3FCQUN2QztvQkFDRCxRQUFRLENBQUMsT0FBTyxDQUFDO3dCQUNoQixNQUFNLEVBQUUsZ0JBQWdCO3dCQUN4QixRQUFRLEVBQUUsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLElBQUksR0FBRyxDQUFDLEVBQUUsTUFBTSxFQUFFLEdBQUcsQ0FBQyxTQUFTLEVBQUU7d0JBQ3ZELFNBQVMsRUFBRSxFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsSUFBSSxHQUFHLENBQUMsRUFBRSxNQUFNLEVBQUUsR0FBRyxDQUFDLFNBQVMsRUFBRTt3QkFDeEQsSUFBSSxFQUFFLFdBQVc7cUJBQ2pCLEVBQUU7d0JBQ0YsTUFBTSxFQUFFLGdCQUFnQjt3QkFDeEIsUUFBUSxFQUFFLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxFQUFFLE1BQU0sRUFBRSxHQUFHLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUU7d0JBQ3JFLFNBQVMsRUFBRSxFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsSUFBSSxHQUFHLENBQUMsRUFBRSxNQUFNLEVBQUUsR0FBRyxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRTtxQkFDOUUsQ0FBQyxDQUFDO2lCQUNIO2dCQUVELG9FQUFvRTtnQkFDcEUsU0FBUyxHQUFHLElBQUksK0JBQWtCLENBQUMsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsVUFBVSxFQUFFLGFBQWEsRUFBRSxDQUFDLENBQUM7Z0JBQ3RHLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxnQkFBZ0IsRUFBRSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztnQkFDakUsS0FBSyxNQUFNLENBQUMsRUFBRSxRQUFRLENBQUMsSUFBSSxjQUFjLEVBQUU7b0JBQzFDLElBQUksU0FBUyxHQUFHLENBQUMsQ0FBQztvQkFDbEIsS0FBSyxNQUFNLE9BQU8sSUFBSSxRQUFRLEVBQUU7d0JBQy9CLFNBQVMsQ0FBQyxVQUFVLENBQUM7NEJBQ3BCLEdBQUcsT0FBTzs0QkFDVixTQUFTLEVBQUUsRUFBRSxJQUFJLEVBQUUsT0FBTyxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxTQUFTLENBQUMsTUFBTSxHQUFHLFNBQVMsRUFBRTt5QkFDekYsQ0FBQyxDQUFDO3dCQUNILFNBQVMsSUFBSSxPQUFPLENBQUMsUUFBUSxDQUFDLE1BQU0sR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQztxQkFDaEU7aUJBQ0Q7Z0JBRUQsV0FBVyxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7YUFDbEM7WUFDRCxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsRUFBRSxHQUFHLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1NBQ2xGO1FBRUQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLFVBQVUsR0FBRyxJQUFJLFVBQVUsQ0FBQyxDQUFDO1FBQy9DLE9BQU8sTUFBTSxDQUFDO0lBQ2YsQ0FBQztDQUNEO0FBeFVELDBCQXdVQztBQUVELGdCQUFnQjtBQUVoQixTQUFTLFdBQVcsQ0FBQyxJQUFhLEVBQUUsSUFBbUI7SUFDdEQsTUFBTSxTQUFTLEdBQUcsRUFBRSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7SUFDaEYsT0FBTyxPQUFPLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQztBQUM3RCxDQUFDO0FBRUQsU0FBUyxrQkFBa0IsQ0FBQyxJQUFhO0lBQ3hDLEtBQUssSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUU7UUFDMUMsSUFBSSxFQUFFLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDOUIsT0FBTyxJQUFJLENBQUM7U0FDWjtLQUNEO0lBQ0QsT0FBTyxLQUFLLENBQUM7QUFDZCxDQUFDO0FBRUQsU0FBUyxTQUFTLENBQUMsSUFBWTtJQUM5QixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQ2pDLENBQUM7QUFFRCxLQUFLLFVBQVUsSUFBSTtJQUNsQixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ3BELE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQzNDLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLGVBQWUsQ0FBQyxDQUFDO0lBQzVELE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDO0lBRTlGLEVBQUUsQ0FBQyxNQUFNLENBQUMsV0FBVyxFQUFFLGNBQWMsRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBRTVELE1BQU0sT0FBTyxHQUFHLElBQUksT0FBTyxDQUFDLFdBQVcsRUFBRSxPQUFPLENBQUMsR0FBRyxFQUFFO1FBQ3JELGFBQWEsRUFBRSxJQUFJO1FBQ25CLG1CQUFtQixFQUFFLElBQUk7S0FDekIsQ0FBQyxDQUFDO0lBQ0gsS0FBSyxNQUFNLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxJQUFJLE1BQU0sT0FBTyxDQUFDLHNCQUFzQixDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFO1FBQ2hHLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFDcEYsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFDeEUsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxXQUFXLEVBQUUsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3ZELElBQUksUUFBUSxDQUFDLFNBQVMsRUFBRTtZQUN2QixNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLFdBQVcsR0FBRyxNQUFNLEVBQUUsUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1NBQ3RFO0tBQ0Q7QUFDRixDQUFDO0FBRUQsSUFBSSxVQUFVLEtBQUssY0FBSSxDQUFDLENBQUMsQ0FBQyxFQUFFO0lBQzNCLElBQUksRUFBRSxDQUFDO0NBQ1AifQ== \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7OztnR0FHZ0c7OztBQUVoRyx5QkFBeUI7QUFDekIsNkJBQTZCO0FBQzdCLHFDQUErQjtBQUMvQiwyQ0FBeUQ7QUFDekQsaUNBQWlDO0FBQ2pDLDZCQUFvQztBQUNwQyx5Q0FBeUM7QUFDekMsMkVBQXdFO0FBQ3hFLE1BQU0sU0FBUyxHQUFHLE9BQU8sQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO0FBRXBELE1BQU0sVUFBVTtJQVlHO0lBVlYsTUFBTSxDQUFDLFNBQVMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxVQUFVO1FBQzlHLFNBQVMsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRSxJQUFJO1FBQ25HLFFBQVEsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsT0FBTztRQUMxRyxNQUFNLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztJQUU1RCxNQUFNLENBQUMsU0FBUyxHQUFHLGtFQUFrRSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUVoRyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBRW5CLFlBQ2tCLE1BQWM7UUFBZCxXQUFNLEdBQU4sTUFBTSxDQUFRO0lBQzVCLENBQUM7SUFFTCxJQUFJLENBQUMsV0FBdUM7UUFDM0MsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLE1BQU0sR0FBRyxVQUFVLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNoRSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDZCxJQUFJLFVBQVUsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxJQUFJLFNBQVMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksV0FBVyxFQUFFLENBQUMsU0FBUyxDQUFDLEVBQUU7WUFDakcsWUFBWTtZQUNaLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztTQUM5QjtRQUNELE9BQU8sU0FBUyxDQUFDO0lBQ2xCLENBQUM7SUFFTyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQVM7UUFDL0IsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUM7UUFDbkMsSUFBSSxNQUFNLEdBQUcsRUFBRSxDQUFDO1FBQ2hCLEdBQUc7WUFDRixNQUFNLElBQUksR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDO1lBQ3RCLE1BQU0sSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQy9CLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7U0FDbkIsUUFBUSxDQUFDLEdBQUcsQ0FBQyxFQUFFO1FBQ2hCLE9BQU8sTUFBTSxDQUFDO0lBQ2YsQ0FBQzs7QUFHRixJQUFXLFNBSVY7QUFKRCxXQUFXLFNBQVM7SUFDbkIsNkNBQU0sQ0FBQTtJQUNOLG1EQUFTLENBQUE7SUFDVCwrQ0FBTyxDQUFBO0FBQ1IsQ0FBQyxFQUpVLFNBQVMsS0FBVCxTQUFTLFFBSW5CO0FBRUQsTUFBTSxTQUFTO0lBVUo7SUFDQTtJQVRWLE1BQU0sR0FBRyxJQUFJLEdBQUcsRUFBNEMsQ0FBQztJQUVyRCxZQUFZLENBQWtDO0lBRXRELE1BQU0sQ0FBd0I7SUFDOUIsUUFBUSxDQUEwQjtJQUVsQyxZQUNVLFFBQWdCLEVBQ2hCLElBQThDO1FBRXZELGdGQUFnRjtRQUNoRixnRkFBZ0Y7UUFKdkUsYUFBUSxHQUFSLFFBQVEsQ0FBUTtRQUNoQixTQUFJLEdBQUosSUFBSSxDQUEwQztRQUt2RCxNQUFNLFVBQVUsR0FBNEIsRUFBRSxDQUFDO1FBQy9DLEtBQUssTUFBTSxNQUFNLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtZQUNsQyxJQUFJLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLENBQUMsRUFBRTtnQkFDbkMsb0JBQW9CO2dCQUNwQixVQUFVLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2FBRXhCO2lCQUFNLElBQUksRUFBRSxDQUFDLHFCQUFxQixDQUFDLE1BQU0sQ0FBQyxFQUFFO2dCQUM1Qyx1QkFBdUI7Z0JBQ3ZCLFVBQVUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7YUFFeEI7aUJBQU0sSUFBSSxFQUFFLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxFQUFFO2dCQUNwQyw4QkFBOEI7Z0JBQzlCLFVBQVUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7YUFFeEI7aUJBQU0sSUFBSSxFQUFFLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxFQUFFO2dCQUNwQyw4QkFBOEI7Z0JBQzlCLFVBQVUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7YUFFeEI7aUJBQU0sSUFBSSxFQUFFLENBQUMsd0JBQXdCLENBQUMsTUFBTSxDQUFDLEVBQUU7Z0JBQy9DLGlEQUFpRDtnQkFDakQsS0FBSyxNQUFNLEtBQUssSUFBSSxNQUFNLENBQUMsVUFBVSxFQUFFO29CQUN0QyxJQUFJLFdBQVcsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxjQUFjLENBQUM7MkJBQ2hELFdBQVcsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQzsyQkFDbEQsV0FBVyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQzsyQkFDL0MsV0FBVyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsVUFBVSxDQUFDLGVBQWUsQ0FBQyxFQUNuRDt3QkFDRCxVQUFVLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO3FCQUN2QjtpQkFDRDthQUNEO1NBQ0Q7UUFDRCxLQUFLLE1BQU0sTUFBTSxJQUFJLFVBQVUsRUFBRTtZQUNoQyxNQUFNLEtBQUssR0FBRyxTQUFTLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQy9DLElBQUksQ0FBQyxLQUFLLEVBQUU7Z0JBQ1gsU0FBUzthQUNUO1lBQ0QsTUFBTSxJQUFJLEdBQUcsU0FBUyxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUM3QyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLE1BQU0sQ0FBQyxJQUFLLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1NBQy9EO0lBQ0YsQ0FBQztJQUVPLE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBeUI7UUFDdEQsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUU7WUFDZixPQUFPLFNBQVMsQ0FBQztTQUNqQjtRQUNELE1BQU0sRUFBRSxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUM7UUFDdEIsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQzNCLElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxFQUFFLENBQUMsVUFBVSxDQUFDLG9CQUFvQixFQUFFO1lBQ3JELElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEtBQUssRUFBRSxDQUFDLFVBQVUsQ0FBQyxhQUFhLEVBQUU7Z0JBQ3pELCtDQUErQztnQkFDL0MsT0FBTzthQUNQO1lBQ0QsVUFBVTtZQUNWLEtBQUssR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUMvQztRQUVELE9BQU8sS0FBSyxDQUFDO0lBQ2QsQ0FBQztJQUVPLE1BQU0sQ0FBQyxhQUFhLENBQUMsSUFBYTtRQUN6QyxJQUFJLFdBQVcsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxjQUFjLENBQUMsRUFBRTtZQUNwRCxpQ0FBeUI7U0FDekI7YUFBTSxJQUFJLFdBQVcsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFO1lBQzdELG1DQUEyQjtTQUMzQjthQUFNO1lBQ04sZ0NBQXdCO1NBQ3hCO0lBQ0YsQ0FBQztJQUVELE1BQU0sQ0FBQyxhQUFhLENBQUMsSUFBZTtRQUNuQyxPQUFPLElBQUksOEJBQXNCO2VBQzdCLElBQUksZ0NBQXdCLENBQzlCO0lBQ0gsQ0FBQztJQUVELE1BQU0sQ0FBQyxnQ0FBZ0MsQ0FBQyxJQUFlLEVBQUUsZUFBa0U7UUFDMUgsVUFBVTtRQUNWLGlGQUFpRjtRQUNqRixpRkFBaUY7UUFDakYsS0FBSyxNQUFNLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUU7WUFDdkMsSUFBSSxJQUFJLENBQUMsSUFBSSw2QkFBcUIsRUFBRTtnQkFDbkMsU0FBUzthQUNUO1lBQ0QsSUFBSSxNQUFNLEdBQTBCLElBQUksQ0FBQyxNQUFNLENBQUM7WUFDaEQsT0FBTyxNQUFNLEVBQUU7Z0JBQ2QsSUFBSSxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLGdDQUF3QixFQUFFO29CQUMxRCxNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDLDZCQUE2QixDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO29CQUMxRyxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDLDZCQUE2QixDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztvQkFDbEYsZUFBZSxDQUFDLElBQUksRUFBRSxJQUFJLElBQUksVUFBVSxNQUFNLENBQUMsUUFBUSxJQUFJLFNBQVMsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxFQUFFLEVBQUUsR0FBRyxJQUFJLENBQUMsUUFBUSxJQUFJLE9BQU8sQ0FBQyxJQUFJLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztvQkFFekgsTUFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFFLENBQUMsSUFBSSwyQkFBbUIsQ0FBQztpQkFDakQ7Z0JBQ0QsTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7YUFDdkI7U0FDRDtJQUNGLENBQUM7SUFFRCxNQUFNLENBQUMsaUJBQWlCLENBQUMsSUFBZTtRQUV2QyxJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUU7WUFDdEIsZUFBZTtZQUNmLE9BQU87U0FDUDtRQUVELHdCQUF3QjtRQUN4QixJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUU7WUFDaEIsU0FBUyxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztTQUN6QztRQUVELElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUU5QixNQUFNLFdBQVcsR0FBRyxDQUFDLElBQVksRUFBRSxFQUFFO1lBQ3BDLGdCQUFnQjtZQUNoQixJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLEVBQUU7Z0JBQzVCLE9BQU8sSUFBSSxDQUFDO2FBQ1o7WUFFRCxVQUFVO1lBQ1YsSUFBSSxNQUFNLEdBQTBCLElBQUksQ0FBQyxNQUFNLENBQUM7WUFDaEQsT0FBTyxNQUFNLEVBQUU7Z0JBQ2QsSUFBSSxNQUFNLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxFQUFFO29CQUM5QixPQUFPLElBQUksQ0FBQztpQkFDWjtnQkFDRCxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQzthQUN2QjtZQUVELFdBQVc7WUFDWCxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUU7Z0JBQ2xCLE1BQU0sS0FBSyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ2pDLE9BQU8sS0FBSyxDQUFDLE1BQU0sRUFBRTtvQkFDcEIsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLEdBQUcsRUFBRyxDQUFDO29CQUMxQixJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLEVBQUU7d0JBQzVCLE9BQU8sSUFBSSxDQUFDO3FCQUNaO29CQUNELElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRTt3QkFDbEIsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztxQkFDN0I7aUJBQ0Q7YUFDRDtZQUVELE9BQU8sS0FBSyxDQUFDO1FBQ2QsQ0FBQyxDQUFDO1FBQ0YsTUFBTSxTQUFTLEdBQUcsSUFBSSxVQUFVLENBQUMsRUFBRSxDQUFDLENBQUM7UUFFckMsS0FBSyxNQUFNLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUU7WUFDdkMsSUFBSSxTQUFTLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRTtnQkFDdkMsTUFBTSxTQUFTLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztnQkFDOUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFDO2FBQ3ZDO1NBQ0Q7SUFDRixDQUFDO0lBRUQsa0VBQWtFO0lBQ2xFLGtEQUFrRDtJQUMxQyxZQUFZLENBQUMsSUFBWTtRQUNoQyxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRTtZQUNuRixlQUFlO1lBQ2YsT0FBTyxJQUFJLENBQUM7U0FDWjtRQUNELElBQUksSUFBSSxDQUFDLFlBQVksRUFBRTtZQUN0QixLQUFLLE1BQU0sU0FBUyxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLEVBQUU7Z0JBQ25ELElBQUksU0FBUyxLQUFLLElBQUksRUFBRTtvQkFDdkIsNkNBQTZDO29CQUM3QyxPQUFPLElBQUksQ0FBQztpQkFDWjthQUNEO1NBQ0Q7UUFFRCxJQUFJLGlCQUFpQixDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEVBQUU7WUFDdkMsT0FBTyxJQUFJLENBQUM7U0FDWjtRQUVELE9BQU8sS0FBSyxDQUFDO0lBQ2QsQ0FBQztJQUVELGVBQWUsQ0FBQyxJQUFZO1FBQzNCLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxZQUFhLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBRSxDQUFDO1FBQzFDLElBQUksTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7UUFDekIsT0FBTyxNQUFNLEVBQUU7WUFDZCxJQUFJLE1BQU0sQ0FBQyxZQUFhLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksZ0NBQXdCLEVBQUU7Z0JBQzVGLEtBQUssR0FBRyxNQUFNLENBQUMsWUFBYSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUUsSUFBSSxLQUFLLENBQUM7YUFDakQ7WUFDRCxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztTQUN2QjtRQUNELE9BQU8sS0FBSyxDQUFDO0lBQ2QsQ0FBQztJQUVELHNCQUFzQjtJQUV0QixRQUFRLENBQUMsS0FBZ0I7UUFDeEIsSUFBSSxDQUFDLFFBQVEsS0FBSyxFQUFFLENBQUM7UUFDckIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDMUIsS0FBSyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUM7SUFDckIsQ0FBQztDQUNEO0FBRUQsU0FBUyxpQkFBaUIsQ0FBQyxJQUFhLEVBQUUsSUFBWTtJQUNyRCxNQUFNLFdBQVcsR0FBUyxJQUFJLENBQUMsYUFBYSxFQUFHLENBQUMsV0FBVyxDQUFDO0lBQzVELElBQUksV0FBVyxZQUFZLEdBQUcsRUFBRTtRQUMvQixJQUFJLFdBQVcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDMUIsT0FBTyxJQUFJLENBQUM7U0FDWjtLQUNEO0lBQ0QsT0FBTyxLQUFLLENBQUM7QUFDZCxDQUFDO0FBR0QsTUFBTSx5QkFBeUIsR0FBRztJQUNqQyxRQUFRO0lBQ1IsV0FBVztJQUNYLFdBQVc7SUFFWCxTQUFTO0lBQ1QsY0FBYztJQUNkLGVBQWU7SUFDZixZQUFZO0lBQ1osa0JBQWtCO0lBQ2xCLGlCQUFpQjtJQUNqQixxQkFBcUI7SUFFckIsWUFBWTtJQUNaLHdCQUF3QjtJQUV4QiwrQkFBK0I7SUFDL0IsS0FBSztJQUVMLGVBQWU7SUFDZixHQUFHO1FBQ0YsU0FBUyxDQUFDLFVBQVUsQ0FBQyw0QkFBNEIsRUFBRSxFQUFFLENBQUM7UUFDdEQsU0FBUyxDQUFDLFVBQVUsQ0FBQyxxQ0FBcUMsRUFBRSxFQUFFLENBQUM7UUFDL0QsU0FBUyxDQUFDLElBQUk7UUFDZCxTQUFTLENBQUMsbUJBQW1CO1FBQzdCLFNBQVMsQ0FBQyxjQUFjO1FBQ3hCLFNBQVMsQ0FBQyx1QkFBdUI7UUFDakMsU0FBUyxDQUFDLHFCQUFxQjtRQUMvQixTQUFTLENBQUMscUJBQXFCO1FBQy9CLFNBQVMsQ0FBQyxnQkFBZ0I7UUFDMUIsU0FBUyxDQUFDLFlBQVk7UUFDdEIsU0FBUyxDQUFDLElBQUk7S0FDZCxDQUFDLElBQUksRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7Q0FDekIsQ0FBQztBQUVGLE1BQU0sNEJBQTRCLEdBQUc7SUFDcEMsZ0JBQWdCO0lBQ2hCLGtCQUFrQjtJQUVsQiwwRkFBMEY7SUFDMUYsdUJBQXVCO0lBQ3ZCLDBCQUEwQjtJQUMxQix1QkFBdUI7SUFDdkIsK0JBQStCO0NBQy9CLENBQUM7QUFFRixNQUFNLDJCQUEyQixHQUFHO0lBQ25DLHNDQUFzQztJQUN0QyxVQUFVO0lBQ1YsWUFBWTtDQUNaLENBQUM7QUFFRixNQUFNLGVBQWU7SUFLVjtJQUNBO0lBQ1E7SUFMVCxlQUFlLENBQVM7SUFFakMsWUFDVSxRQUFnQixFQUNoQixJQUFnRyxFQUN4RixPQUEyQixFQUM1QyxVQUFzQjtRQUhiLGFBQVEsR0FBUixRQUFRLENBQVE7UUFDaEIsU0FBSSxHQUFKLElBQUksQ0FBNEY7UUFDeEYsWUFBTyxHQUFQLE9BQU8sQ0FBb0I7UUFHNUMsMEdBQTBHO1FBQzFHLElBQUksQ0FBQyxlQUFlLEdBQUcsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDO0lBQzFDLENBQUM7SUFFRCxJQUFJLFNBQVM7UUFDWixJQUFJLEVBQUUsQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDeEMsOERBQThEO1lBQzlELE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyx5QkFBeUIsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7WUFDMUcsSUFBSSxnQkFBZ0IsRUFBRSxXQUFXLElBQUksZ0JBQWdCLENBQUMsV0FBVyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7Z0JBQzdFLE9BQU8sZ0JBQWdCLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUM7YUFDbkc7U0FDRDtRQUVELE9BQU8sQ0FBQztnQkFDUCxRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVE7Z0JBQ3ZCLE1BQU0sRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUssQ0FBQyxRQUFRLEVBQUU7YUFDbEMsQ0FBQyxDQUFDO0lBQ0osQ0FBQztJQUVELFlBQVksQ0FBQyxPQUFlO1FBQzNCLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQzlDLElBQUksV0FBVyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsSUFBSSwyQkFBMkIsQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLEVBQUU7WUFDckYsT0FBTyxLQUFLLENBQUM7U0FDYjtRQUVELDBDQUEwQztRQUMxQyxJQUFJLE9BQU8sQ0FBQyxNQUFNLElBQUksV0FBVyxDQUFDLE1BQU0sRUFBRTtZQUN6QyxPQUFPLEtBQUssQ0FBQztTQUNiO1FBRUQsb0RBQW9EO1FBQ3BELElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLEVBQUU7WUFDcEQsT0FBTyxLQUFLLENBQUM7U0FDYjtRQUVELE9BQU8sSUFBSSxDQUFDO0lBQ2IsQ0FBQztDQUNEO0FBT0Q7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFhLE9BQU87SUFTRDtJQUNBO0lBQ0E7SUFURCxpQkFBaUIsR0FBRyxJQUFJLEdBQUcsRUFBcUIsQ0FBQztJQUNqRCxrQkFBa0IsR0FBRyxJQUFJLEdBQUcsRUFBbUIsQ0FBQztJQUVoRCxPQUFPLENBQXFCO0lBQzVCLGdCQUFnQixDQUF3QjtJQUV6RCxZQUNrQixXQUFtQixFQUNuQixNQUEwQixHQUFHLEVBQUUsR0FBRyxDQUFDLEVBQ25DLE1BQWtGO1FBRmxGLGdCQUFXLEdBQVgsV0FBVyxDQUFRO1FBQ25CLFFBQUcsR0FBSCxHQUFHLENBQWdDO1FBQ25DLFdBQU0sR0FBTixNQUFNLENBQTRFO1FBRW5HLElBQUksQ0FBQyxPQUFPLEdBQUcsRUFBRSxDQUFDLHFCQUFxQixDQUFDLElBQUkscURBQXlCLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQztRQUVwRixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxpQkFBaUIsQ0FBQyxFQUFFO1lBQ2hGLFVBQVUsRUFBRSxDQUFDO1lBQ2IsVUFBVSxFQUFFLEtBQUs7U0FDakIsQ0FBQyxDQUFDO0lBQ0osQ0FBQztJQUVELEtBQUssQ0FBQyxzQkFBc0IsQ0FBQyw0QkFBMEM7UUFFdEUsUUFBUTtRQUNSLDJDQUEyQztRQUMzQywyQkFBMkI7UUFFM0IsTUFBTSxVQUFVLEdBQUcsSUFBSSxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUM7UUFFdkMsTUFBTSxLQUFLLEdBQUcsQ0FBQyxJQUFhLEVBQVEsRUFBRTtZQUNyQyxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsbUJBQW1CLEVBQUU7Z0JBQ3BDLElBQUksRUFBRSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsRUFBRTtvQkFDOUQsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLENBQUM7b0JBQ2pDLE1BQU0sR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDLFFBQVEsSUFBSSxNQUFNLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQztvQkFDcEUsSUFBSSxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFO3dCQUNwQyxNQUFNLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO3FCQUN6QjtvQkFDRCxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxJQUFJLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7aUJBQ3BGO2FBQ0Q7WUFFRCxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxFQUFFO2dCQUM5Qiw2Q0FBNkM7Z0JBQzdDLElBQ0M7Z0JBQ0MsaUJBQWlCO2dCQUNqQixFQUFFLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDO3VCQUN4QixXQUFXLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDO3VCQUM5QyxJQUFJLENBQUMsSUFBSSxDQUNaLElBQUk7Z0JBQ0osb0JBQW9CO2dCQUNwQixFQUFFLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDO3VCQUMzQixFQUFFLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUM7dUJBQzVCLFdBQVcsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUM7dUJBQzlDLElBQUksQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyw0Q0FBNEM7aUJBQ3RFLElBQUk7Z0JBQ0osb0JBQW9CO2dCQUNwQixFQUFFLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDO3VCQUMzQixXQUFXLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsQ0FBQyxpQ0FBaUM7dUJBQzlGLEVBQUUsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQzdDO2dCQUVELCtEQUErRDtnQkFDL0QsdURBQXVEO2dCQUN2RDs7Ozs7OztrQkFPRTtrQkFDRDtvQkFDRCxJQUFJLGtCQUFrQixDQUFDLElBQUksQ0FBQyxFQUFFO3dCQUM3QixPQUFPO3FCQUNQO29CQUVELElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsSUFBSSxlQUFlLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDLFFBQVEsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLE9BQU8sRUFBRSxVQUFVLENBQUMsQ0FBQyxDQUFDO2lCQUNoSDthQUNEO1lBRUQsRUFBRSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDOUIsQ0FBQyxDQUFDO1FBRUYsS0FBSyxNQUFNLElBQUksSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRyxDQUFDLGNBQWMsRUFBRSxFQUFFO1lBQy9ELElBQUksQ0FBQyxJQUFJLENBQUMsaUJBQWlCLEVBQUU7Z0JBQzVCLEVBQUUsQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO2FBQzdCO1NBQ0Q7UUFDRCxJQUFJLENBQUMsR0FBRyxDQUFDLDZCQUE2QixJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSx1QkFBdUIsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7UUFHeEgscUNBQXFDO1FBRXJDLE1BQU0sWUFBWSxHQUFHLENBQUMsSUFBZSxFQUFFLEVBQUU7WUFDeEMsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssS0FBSyxFQUFFLENBQUMsVUFBVSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1lBQ3JHLElBQUksQ0FBQyxhQUFhLEVBQUU7Z0JBQ25CLG9CQUFvQjtnQkFDcEIsT0FBTzthQUNQO1lBRUQsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7WUFDN0csSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtnQkFDL0IsMkNBQTJDO2dCQUMzQyxPQUFPO2FBQ1A7WUFFRCxJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO2dCQUN0QixzQ0FBc0M7Z0JBQ3RDLE9BQU87YUFDUDtZQUVELE1BQU0sQ0FBQyxVQUFVLENBQUMsR0FBRyxJQUFJLENBQUM7WUFDMUIsTUFBTSxHQUFHLEdBQUcsR0FBRyxVQUFVLENBQUMsUUFBUSxJQUFJLFVBQVUsQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDbEUsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUMvQyxJQUFJLENBQUMsTUFBTSxFQUFFO2dCQUNaLG1EQUFtRDtnQkFDbkQsT0FBTzthQUNQO1lBQ0QsTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN2QixDQUFDLENBQUM7UUFDRixLQUFLLE1BQU0sSUFBSSxJQUFJLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLEVBQUUsRUFBRTtZQUNuRCxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUM7U0FDbkI7UUFFRCx1RUFBdUU7UUFDdkUsTUFBTSxVQUFVLEdBQUcsSUFBSSxHQUFHLEVBQW9CLENBQUM7UUFDL0MsSUFBSSxzQkFBc0IsR0FBRyxLQUFLLENBQUM7UUFDbkMsS0FBSyxNQUFNLElBQUksSUFBSSxJQUFJLENBQUMsaUJBQWlCLENBQUMsTUFBTSxFQUFFLEVBQUU7WUFDbkQsU0FBUyxDQUFDLGdDQUFnQyxDQUFDLElBQUksRUFBRSxDQUFDLElBQVksRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLEVBQUU7Z0JBQzVFLE1BQU0sR0FBRyxHQUFHLFVBQVUsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQ2pDLElBQUksR0FBRyxFQUFFO29CQUNSLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7aUJBQ2Q7cUJBQU07b0JBQ04sVUFBVSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO2lCQUM1QjtnQkFFRCxJQUFJLDRCQUE0QixJQUFJLENBQUMsNEJBQTRCLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFO29CQUM1RSxzQkFBc0IsR0FBRyxJQUFJLENBQUM7aUJBQzlCO1lBQ0YsQ0FBQyxDQUFDLENBQUM7U0FDSDtRQUNELEtBQUssTUFBTSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsSUFBSSxVQUFVLEVBQUU7WUFDckMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLEdBQUcsOEJBQThCLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1NBQ3ZFO1FBQ0QsSUFBSSxzQkFBc0IsRUFBRTtZQUMzQixNQUFNLE9BQU8sR0FBRyxzSUFBc0ksQ0FBQztZQUN2SixJQUFJLENBQUMsR0FBRyxDQUFDLFVBQVUsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUM5QixNQUFNLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1NBQ3pCO1FBRUQsaURBQWlEO1FBQ2pELEtBQUssTUFBTSxJQUFJLElBQUksSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sRUFBRSxFQUFFO1lBQ25ELFNBQVMsQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUNsQztRQUNELElBQUksQ0FBQyxHQUFHLENBQUMsa0NBQWtDLENBQUMsQ0FBQztRQUU3Qyw2QkFBNkI7UUFDN0IsSUFBSSxDQUFDLEdBQUcsQ0FBQywrQkFBK0IsQ0FBQyxDQUFDO1FBRzFDLE1BQU0sV0FBVyxHQUFHLElBQUksR0FBRyxFQUFrQixDQUFDO1FBRTlDLE1BQU0sVUFBVSxHQUFHLENBQUMsUUFBZ0IsRUFBRSxJQUFVLEVBQUUsRUFBRTtZQUNuRCxNQUFNLEtBQUssR0FBRyxXQUFXLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3hDLElBQUksQ0FBQyxLQUFLLEVBQUU7Z0JBQ1gsV0FBVyxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO2FBQ2xDO2lCQUFNO2dCQUNOLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7YUFDakI7UUFDRixDQUFDLENBQUM7UUFDRixNQUFNLFlBQVksR0FBRyxDQUFDLE9BQWUsRUFBRSxHQUFzQixFQUFFLEVBQUU7WUFDaEUsVUFBVSxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUU7Z0JBQ3hCLE9BQU8sRUFBRSxDQUFDLEdBQUcsQ0FBQyxVQUFVLElBQUksRUFBRSxDQUFDLEdBQUcsT0FBTyxHQUFHLENBQUMsR0FBRyxDQUFDLFVBQVUsSUFBSSxFQUFFLENBQUM7Z0JBQ2xFLE1BQU0sRUFBRSxHQUFHLENBQUMsUUFBUSxDQUFDLEtBQUs7Z0JBQzFCLE1BQU0sRUFBRSxHQUFHLENBQUMsUUFBUSxDQUFDLE1BQU07YUFDM0IsQ0FBQyxDQUFDO1FBQ0osQ0FBQyxDQUFDO1FBSUYsTUFBTSxhQUFhLEdBQW1HLEVBQUUsQ0FBQztRQUV6SCxNQUFNLFdBQVcsR0FBRyxDQUFDLFFBQWdCLEVBQUUsR0FBVyxFQUFFLE9BQWUsRUFBRSxFQUFFO1lBQ3RFLGFBQWEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFXLHFCQUFxQixFQUFFLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxRQUFRLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztpQkFDaEksSUFBSSxDQUFDLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2xELENBQUMsQ0FBQztRQUVGLEtBQUssTUFBTSxJQUFJLElBQUksSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sRUFBRSxFQUFFO1lBQ25ELElBQUksV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxjQUFjLENBQUMsRUFBRTtnQkFDekQsU0FBUzthQUNUO1lBRUQsTUFBTSxFQUFFLEtBQUssTUFBTSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFO2dCQUMvQyxJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUU7b0JBQ3hDLFNBQVMsTUFBTSxDQUFDO2lCQUNoQjtnQkFFRCxvREFBb0Q7Z0JBQ3BELHVEQUF1RDtnQkFDdkQsSUFBSSxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztnQkFDekIsT0FBTyxNQUFNLEVBQUU7b0JBQ2QsSUFBSSxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLDZCQUFxQixFQUFFO3dCQUN2RCxTQUFTLE1BQU0sQ0FBQztxQkFDaEI7b0JBQ0QsTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7aUJBQ3ZCO2dCQUVELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQzNDLFdBQVcsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUUsT0FBTyxDQUFDLENBQUM7YUFDOUM7U0FDRDtRQUVELEtBQUssTUFBTSxJQUFJLElBQUksSUFBSSxDQUFDLGtCQUFrQixDQUFDLE1BQU0sRUFBRSxFQUFFO1lBQ3BELElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDO21CQUMvQiw0QkFBNEIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQzttQkFDdkUseUJBQXlCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFDLEVBQzlFO2dCQUNELFNBQVM7YUFDVDtZQUVELElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsRUFBRTtnQkFDN0MsU0FBUzthQUNUO1lBRUQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQztZQUNyQyxLQUFLLE1BQU0sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRTtnQkFDbEQsV0FBVyxDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUM7YUFDdkM7U0FDRDtRQUVELE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRTtZQUNoRCxLQUFLLE1BQU0sRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLElBQUksTUFBTSxFQUFFO2dCQUM1QyxLQUFLLE1BQU0sR0FBRyxJQUFJLFNBQVMsRUFBRTtvQkFDNUIsWUFBWSxDQUFDLE9BQU8sRUFBRSxHQUFHLENBQUMsQ0FBQztpQkFDM0I7YUFDRDtRQUNGLENBQUMsQ0FBQyxDQUFDO1FBRUgsTUFBTSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxFQUFFLENBQUM7UUFFeEMsSUFBSSxDQUFDLEdBQUcsQ0FBQyx5QkFBeUIsV0FBVyxDQUFDLElBQUksUUFBUSxDQUFDLENBQUM7UUFFNUQsMENBQTBDO1FBQzFDLE1BQU0sTUFBTSxHQUFHLElBQUksR0FBRyxFQUF3QixDQUFDO1FBQy9DLElBQUksVUFBVSxHQUFHLENBQUMsQ0FBQztRQUVuQixLQUFLLE1BQU0sSUFBSSxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFHLENBQUMsY0FBYyxFQUFFLEVBQUU7WUFFL0QsTUFBTSxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRyxDQUFDLGtCQUFrQixFQUFFLENBQUM7WUFDaEYsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDbEQsTUFBTSxhQUFhLEdBQUcsT0FBTyxJQUFJLElBQUEsbUJBQWEsRUFBQyxVQUFVLElBQUksVUFBVSxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7WUFFcEYsY0FBYztZQUNkLElBQUksU0FBeUMsQ0FBQztZQUU5QyxJQUFJLFdBQW1CLENBQUM7WUFDeEIsTUFBTSxLQUFLLEdBQUcsV0FBVyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDN0MsSUFBSSxDQUFDLEtBQUssRUFBRTtnQkFDWCxZQUFZO2dCQUNaLFdBQVcsR0FBRyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7YUFFakM7aUJBQU07Z0JBQ04sdUJBQXVCO2dCQUN2QixNQUFNLGdCQUFnQixHQUFHLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztnQkFDN0UsTUFBTSxjQUFjLEdBQUcsSUFBSSxHQUFHLEVBQXFCLENBQUM7Z0JBRXBELGdCQUFnQjtnQkFDaEIsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUMxQyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUVoRCxJQUFJLFFBQTBCLENBQUM7Z0JBRS9CLEtBQUssTUFBTSxJQUFJLElBQUksS0FBSyxFQUFFO29CQUN6QixJQUFJLFFBQVEsSUFBSSxRQUFRLENBQUMsTUFBTSxLQUFLLElBQUksQ0FBQyxNQUFNLEVBQUU7d0JBQ2hELEVBQUU7d0JBQ0YsSUFBSSxRQUFRLENBQUMsTUFBTSxLQUFLLElBQUksQ0FBQyxNQUFNLElBQUksUUFBUSxDQUFDLE9BQU8sS0FBSyxJQUFJLENBQUMsT0FBTyxFQUFFOzRCQUN6RSxJQUFJLENBQUMsR0FBRyxDQUFDLHlCQUF5QixFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FBQzs0QkFDdkUsTUFBTSxJQUFJLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO3lCQUNwQzs2QkFBTTs0QkFDTixTQUFTO3lCQUNUO3FCQUNEO29CQUNELFFBQVEsR0FBRyxJQUFJLENBQUM7b0JBQ2hCLE1BQU0sV0FBVyxHQUFHLFVBQVUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7b0JBQ3ZGLFVBQVUsSUFBSSxXQUFXLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDO29CQUV2RCxjQUFjO29CQUNkLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyw2QkFBNkIsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7b0JBRzVELElBQUksUUFBUSxHQUFHLGNBQWMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO29CQUM1QyxJQUFJLENBQUMsUUFBUSxFQUFFO3dCQUNkLFFBQVEsR0FBRyxFQUFFLENBQUM7d0JBQ2QsY0FBYyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDO3FCQUN2QztvQkFDRCxRQUFRLENBQUMsT0FBTyxDQUFDO3dCQUNoQixNQUFNLEVBQUUsZ0JBQWdCO3dCQUN4QixRQUFRLEVBQUUsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLElBQUksR0FBRyxDQUFDLEVBQUUsTUFBTSxFQUFFLEdBQUcsQ0FBQyxTQUFTLEVBQUU7d0JBQ3ZELFNBQVMsRUFBRSxFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsSUFBSSxHQUFHLENBQUMsRUFBRSxNQUFNLEVBQUUsR0FBRyxDQUFDLFNBQVMsRUFBRTt3QkFDeEQsSUFBSSxFQUFFLFdBQVc7cUJBQ2pCLEVBQUU7d0JBQ0YsTUFBTSxFQUFFLGdCQUFnQjt3QkFDeEIsUUFBUSxFQUFFLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxFQUFFLE1BQU0sRUFBRSxHQUFHLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUU7d0JBQ3JFLFNBQVMsRUFBRSxFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsSUFBSSxHQUFHLENBQUMsRUFBRSxNQUFNLEVBQUUsR0FBRyxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRTtxQkFDOUUsQ0FBQyxDQUFDO2lCQUNIO2dCQUVELG9FQUFvRTtnQkFDcEUsU0FBUyxHQUFHLElBQUksK0JBQWtCLENBQUMsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsVUFBVSxFQUFFLGFBQWEsRUFBRSxDQUFDLENBQUM7Z0JBQ3RHLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxnQkFBZ0IsRUFBRSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztnQkFDakUsS0FBSyxNQUFNLENBQUMsRUFBRSxRQUFRLENBQUMsSUFBSSxjQUFjLEVBQUU7b0JBQzFDLElBQUksU0FBUyxHQUFHLENBQUMsQ0FBQztvQkFDbEIsS0FBSyxNQUFNLE9BQU8sSUFBSSxRQUFRLEVBQUU7d0JBQy9CLFNBQVMsQ0FBQyxVQUFVLENBQUM7NEJBQ3BCLEdBQUcsT0FBTzs0QkFDVixTQUFTLEVBQUUsRUFBRSxJQUFJLEVBQUUsT0FBTyxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxTQUFTLENBQUMsTUFBTSxHQUFHLFNBQVMsRUFBRTt5QkFDekYsQ0FBQyxDQUFDO3dCQUNILFNBQVMsSUFBSSxPQUFPLENBQUMsUUFBUSxDQUFDLE1BQU0sR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQztxQkFDaEU7aUJBQ0Q7Z0JBRUQsV0FBVyxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7YUFDbEM7WUFDRCxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsRUFBRSxHQUFHLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1NBQ2xGO1FBRUQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLFVBQVUsR0FBRyxJQUFJLFVBQVUsQ0FBQyxDQUFDO1FBQy9DLE9BQU8sTUFBTSxDQUFDO0lBQ2YsQ0FBQztDQUNEO0FBMVVELDBCQTBVQztBQUVELGdCQUFnQjtBQUVoQixTQUFTLFdBQVcsQ0FBQyxJQUFhLEVBQUUsSUFBbUI7SUFDdEQsTUFBTSxTQUFTLEdBQUcsRUFBRSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7SUFDaEYsT0FBTyxPQUFPLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQztBQUM3RCxDQUFDO0FBRUQsU0FBUyxrQkFBa0IsQ0FBQyxJQUFhO0lBQ3hDLEtBQUssSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUU7UUFDMUMsSUFBSSxFQUFFLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDOUIsT0FBTyxJQUFJLENBQUM7U0FDWjtLQUNEO0lBQ0QsT0FBTyxLQUFLLENBQUM7QUFDZCxDQUFDO0FBRUQsU0FBUyxTQUFTLENBQUMsSUFBWTtJQUM5QixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQ2pDLENBQUM7QUFFRCxLQUFLLFVBQVUsSUFBSTtJQUNsQixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ3BELE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQzNDLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLGVBQWUsQ0FBQyxDQUFDO0lBQzVELE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDO0lBRTlGLEVBQUUsQ0FBQyxNQUFNLENBQUMsV0FBVyxFQUFFLGNBQWMsRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBRTVELE1BQU0sT0FBTyxHQUFHLElBQUksT0FBTyxDQUFDLFdBQVcsRUFBRSxPQUFPLENBQUMsR0FBRyxFQUFFO1FBQ3JELGFBQWEsRUFBRSxJQUFJO1FBQ25CLG1CQUFtQixFQUFFLElBQUk7S0FDekIsQ0FBQyxDQUFDO0lBQ0gsS0FBSyxNQUFNLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxJQUFJLE1BQU0sT0FBTyxDQUFDLHNCQUFzQixDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFO1FBQ2hHLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFDcEYsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFDeEUsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxXQUFXLEVBQUUsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3ZELElBQUksUUFBUSxDQUFDLFNBQVMsRUFBRTtZQUN2QixNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLFdBQVcsR0FBRyxNQUFNLEVBQUUsUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1NBQ3RFO0tBQ0Q7QUFDRixDQUFDO0FBRUQsSUFBSSxVQUFVLEtBQUssY0FBSSxDQUFDLENBQUMsQ0FBQyxFQUFFO0lBQzNCLElBQUksRUFBRSxDQUFDO0NBQ1AifQ== \ No newline at end of file diff --git a/build/lib/mangle/index.ts b/build/lib/mangle/index.ts index a87fe97f45662..035653c6f5b5b 100644 --- a/build/lib/mangle/index.ts +++ b/build/lib/mangle/index.ts @@ -278,13 +278,6 @@ function isNameTakenInFile(node: ts.Node, name: string): boolean { return false; } -const fileIdents = new class { - private readonly idents = new ShortIdent('$'); - - next() { - return this.idents.next(); - } -}; const skippedExportMangledFiles = [ // Build @@ -346,6 +339,7 @@ class DeclarationData { readonly fileName: string, readonly node: ts.FunctionDeclaration | ts.ClassDeclaration | ts.EnumDeclaration | ts.VariableDeclaration, private readonly service: ts.LanguageService, + fileIdents: ShortIdent, ) { // Todo: generate replacement names based on usage count, with more used names getting shorter identifiers this.replacementName = fileIdents.next(); @@ -427,6 +421,8 @@ export class Mangler { // - Find all classes and their field info. // - Find exported symbols. + const fileIdents = new ShortIdent('$'); + const visit = (node: ts.Node): void => { if (this.config.manglePrivateFields) { if (ts.isClassDeclaration(node) || ts.isClassExpression(node)) { @@ -475,7 +471,7 @@ export class Mangler { return; } - this.allExportedSymbols.add(new DeclarationData(node.getSourceFile().fileName, node, this.service)); + this.allExportedSymbols.add(new DeclarationData(node.getSourceFile().fileName, node, this.service, fileIdents)); } } diff --git a/build/lib/stylelint/vscode-known-variables.json b/build/lib/stylelint/vscode-known-variables.json index 67ec595ed30d8..a7d22a17b85a2 100644 --- a/build/lib/stylelint/vscode-known-variables.json +++ b/build/lib/stylelint/vscode-known-variables.json @@ -1,5 +1,6 @@ { "colors": [ + "--vscode-actionBar-toggledBackground", "--vscode-activityBar-activeBackground", "--vscode-activityBar-activeBorder", "--vscode-activityBar-activeFocusBorder", @@ -36,8 +37,9 @@ "--vscode-charts-purple", "--vscode-charts-red", "--vscode-charts-yellow", - "--vscode-chat-requestBackground", "--vscode-chat-requestBorder", + "--vscode-chat-slashCommandBackground", + "--vscode-chat-slashCommandForeground", "--vscode-checkbox-background", "--vscode-checkbox-border", "--vscode-checkbox-foreground", @@ -97,6 +99,7 @@ "--vscode-diffEditor-insertedTextBackground", "--vscode-diffEditor-insertedTextBorder", "--vscode-diffEditor-move-border", + "--vscode-diffEditor-moveActive-border", "--vscode-diffEditor-removedLineBackground", "--vscode-diffEditor-removedTextBackground", "--vscode-diffEditor-removedTextBorder", @@ -211,12 +214,14 @@ "--vscode-editorHoverWidget-foreground", "--vscode-editorHoverWidget-highlightForeground", "--vscode-editorHoverWidget-statusBarBackground", + "--vscode-editorIndentGuide-activeBackground", "--vscode-editorIndentGuide-activeBackground1", "--vscode-editorIndentGuide-activeBackground2", "--vscode-editorIndentGuide-activeBackground3", "--vscode-editorIndentGuide-activeBackground4", "--vscode-editorIndentGuide-activeBackground5", "--vscode-editorIndentGuide-activeBackground6", + "--vscode-editorIndentGuide-background", "--vscode-editorIndentGuide-background1", "--vscode-editorIndentGuide-background2", "--vscode-editorIndentGuide-background3", @@ -312,11 +317,11 @@ "--vscode-inlineChat-regionHighlight", "--vscode-inlineChat-shadow", "--vscode-inlineChatDiff-inserted", + "--vscode-inlineChatDiff-removed", "--vscode-inlineChatInput-background", "--vscode-inlineChatInput-border", "--vscode-inlineChatInput-focusBorder", "--vscode-inlineChatInput-placeholderForeground", - "--vscode-inlineChatrDiff-removed", "--vscode-input-background", "--vscode-input-border", "--vscode-input-foreground", @@ -530,6 +535,7 @@ "--vscode-sideBarTitle-foreground", "--vscode-sideBySideEditor-horizontalBorder", "--vscode-sideBySideEditor-verticalBorder", + "--vscode-simpleFindWidget-sashBorder", "--vscode-statusBar-background", "--vscode-statusBar-border", "--vscode-statusBar-debuggingBackground", @@ -540,21 +546,31 @@ "--vscode-statusBar-noFolderBackground", "--vscode-statusBar-noFolderBorder", "--vscode-statusBar-noFolderForeground", - "--vscode-statusBar-offlineBackground", - "--vscode-statusBar-offlineForeground", + "--vscode-statusBarItem-offlineBackground", + "--vscode-statusBarItem-offlineForeground", + "--vscode-statusBarItem-offlineHoverBackground", + "--vscode-statusBarItem-offlineHoverForeground", "--vscode-statusBarItem-activeBackground", "--vscode-statusBarItem-compactHoverBackground", "--vscode-statusBarItem-errorBackground", "--vscode-statusBarItem-errorForeground", + "--vscode-statusBarItem-errorHoverBackground", + "--vscode-statusBarItem-errorHoverForeground", "--vscode-statusBarItem-focusBorder", "--vscode-statusBarItem-hoverBackground", + "--vscode-statusBarItem-hoverForeground", "--vscode-statusBarItem-prominentBackground", "--vscode-statusBarItem-prominentForeground", "--vscode-statusBarItem-prominentHoverBackground", + "--vscode-statusBarItem-prominentHoverForeground", "--vscode-statusBarItem-remoteBackground", "--vscode-statusBarItem-remoteForeground", + "--vscode-statusBarItem-remoteHoverBackground", + "--vscode-statusBarItem-remoteHoverForeground", "--vscode-statusBarItem-warningBackground", "--vscode-statusBarItem-warningForeground", + "--vscode-statusBarItem-warningHoverBackground", + "--vscode-statusBarItem-warningHoverForeground", "--vscode-symbolIcon-arrayForeground", "--vscode-symbolIcon-booleanForeground", "--vscode-symbolIcon-classForeground", @@ -727,6 +743,9 @@ "--vscode-editorCodeLens-fontSize", "--vscode-editorCodeLens-lineHeight", "--vscode-explorer-align-offset-margin-left", + "--vscode-hover-maxWidth", + "--vscode-hover-sourceWhiteSpace", + "--vscode-hover-whiteSpace", "--vscode-inline-chat-cropped", "--vscode-inline-chat-expanded", "--vscode-interactive-session-foreground", @@ -737,6 +756,7 @@ "--vscode-repl-line-height", "--vscode-sash-hover-size", "--vscode-sash-size", + "--vscode-editorStickyScroll-scrollableWidth", "--window-border-color", "--workspace-trust-check-color", "--workspace-trust-selected-color", @@ -756,6 +776,7 @@ "--z-index-notebook-progress-bar", "--z-index-notebook-scrollbar", "--z-index-run-button-container", + "--z-index-notebook-sticky-scroll", "--zoom-factor" ] -} +} \ No newline at end of file diff --git a/build/linux/debian/calculate-deps.js b/build/linux/debian/calculate-deps.js index d9839581a8f1d..80146ba40e2a9 100644 --- a/build/linux/debian/calculate-deps.js +++ b/build/linux/debian/calculate-deps.js @@ -71,10 +71,18 @@ function calculatePackageDeps(binaryPath, arch, sysroot) { // on the newer package, this hack skips the dep. This is safe because // libgcc-s1 is a dependency of libc6. This hack can be removed once // support for Debian Buster and Ubuntu Bionic are dropped. + // + // Remove kerberos native module related dependencies as the versions + // computed from sysroot will not satisfy the minimum supported distros + // Refs https://github.com/microsoft/vscode/issues/188881. + // TODO(deepak1556): remove this workaround in favor of computing the + // versions from build container for native modules. const filteredDeps = depsStr.split(', ').filter(dependency => { - return !dependency.startsWith('libgcc-s1'); + return !dependency.startsWith('libgcc-s1') && + !dependency.startsWith('libgssapi-krb5-2') && + !dependency.startsWith('libkrb5-3'); }).sort(); const requires = new Set(filteredDeps); return requires; } -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsY3VsYXRlLWRlcHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJjYWxjdWxhdGUtZGVwcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7OztnR0FHZ0c7OztBQUVoRyxpREFBMEM7QUFDMUMsMkJBQXlDO0FBQ3pDLDJCQUE0QjtBQUM1Qiw2QkFBOEI7QUFDOUIsc0RBQXNEO0FBQ3RELDJDQUE2QztBQUc3QyxTQUFnQixtQkFBbUIsQ0FBQyxLQUFlLEVBQUUsSUFBc0IsRUFBRSxPQUFlO0lBQzNGLE1BQU0sWUFBWSxHQUFrQixLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsb0JBQW9CLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDO0lBQ2pHLE1BQU0saUJBQWlCLEdBQUcsSUFBSSxHQUFHLENBQUMsMEJBQWMsQ0FBQyxDQUFDO0lBQ2xELFlBQVksQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQztJQUNyQyxPQUFPLFlBQVksQ0FBQztBQUNyQixDQUFDO0FBTEQsa0RBS0M7QUFFRCw2SEFBNkg7QUFDN0gsU0FBUyxvQkFBb0IsQ0FBQyxVQUFrQixFQUFFLElBQXNCLEVBQUUsT0FBZTtJQUN4RixJQUFJO1FBQ0gsSUFBSSxDQUFDLENBQUMsSUFBQSxhQUFRLEVBQUMsVUFBVSxDQUFDLENBQUMsSUFBSSxHQUFHLGNBQVMsQ0FBQyxPQUFPLENBQUMsRUFBRTtZQUNyRCxNQUFNLElBQUksS0FBSyxDQUFDLFVBQVUsVUFBVSx1Q0FBdUMsQ0FBQyxDQUFDO1NBQzdFO0tBQ0Q7SUFBQyxPQUFPLENBQUMsRUFBRTtRQUNYLDhEQUE4RDtRQUM5RCxPQUFPLENBQUMsS0FBSyxDQUFDLGdCQUFnQixHQUFHLFVBQVUsR0FBRyxjQUFjLENBQUMsQ0FBQztLQUM5RDtJQUVELHdDQUF3QztJQUN4QyxNQUFNLGdCQUFnQixHQUFHLFNBQVMsQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLFlB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 \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsY3VsYXRlLWRlcHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJjYWxjdWxhdGUtZGVwcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7OztnR0FHZ0c7OztBQUVoRyxpREFBMEM7QUFDMUMsMkJBQXlDO0FBQ3pDLDJCQUE0QjtBQUM1Qiw2QkFBOEI7QUFDOUIsc0RBQXNEO0FBQ3RELDJDQUE2QztBQUc3QyxTQUFnQixtQkFBbUIsQ0FBQyxLQUFlLEVBQUUsSUFBc0IsRUFBRSxPQUFlO0lBQzNGLE1BQU0sWUFBWSxHQUFrQixLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsb0JBQW9CLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDO0lBQ2pHLE1BQU0saUJBQWlCLEdBQUcsSUFBSSxHQUFHLENBQUMsMEJBQWMsQ0FBQyxDQUFDO0lBQ2xELFlBQVksQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQztJQUNyQyxPQUFPLFlBQVksQ0FBQztBQUNyQixDQUFDO0FBTEQsa0RBS0M7QUFFRCw2SEFBNkg7QUFDN0gsU0FBUyxvQkFBb0IsQ0FBQyxVQUFrQixFQUFFLElBQXNCLEVBQUUsT0FBZTtJQUN4RixJQUFJO1FBQ0gsSUFBSSxDQUFDLENBQUMsSUFBQSxhQUFRLEVBQUMsVUFBVSxDQUFDLENBQUMsSUFBSSxHQUFHLGNBQVMsQ0FBQyxPQUFPLENBQUMsRUFBRTtZQUNyRCxNQUFNLElBQUksS0FBSyxDQUFDLFVBQVUsVUFBVSx1Q0FBdUMsQ0FBQyxDQUFDO1NBQzdFO0tBQ0Q7SUFBQyxPQUFPLENBQUMsRUFBRTtRQUNYLDhEQUE4RDtRQUM5RCxPQUFPLENBQUMsS0FBSyxDQUFDLGdCQUFnQixHQUFHLFVBQVUsR0FBRyxjQUFjLENBQUMsQ0FBQztLQUM5RDtJQUVELHdDQUF3QztJQUN4QyxNQUFNLGdCQUFnQixHQUFHLFNBQVMsQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLFlB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 \ No newline at end of file diff --git a/build/linux/debian/calculate-deps.ts b/build/linux/debian/calculate-deps.ts index b13d3cdfaaf6b..a23c41ace2471 100644 --- a/build/linux/debian/calculate-deps.ts +++ b/build/linux/debian/calculate-deps.ts @@ -76,8 +76,16 @@ function calculatePackageDeps(binaryPath: string, arch: DebianArchString, sysroo // on the newer package, this hack skips the dep. This is safe because // libgcc-s1 is a dependency of libc6. This hack can be removed once // support for Debian Buster and Ubuntu Bionic are dropped. + // + // Remove kerberos native module related dependencies as the versions + // computed from sysroot will not satisfy the minimum supported distros + // Refs https://github.com/microsoft/vscode/issues/188881. + // TODO(deepak1556): remove this workaround in favor of computing the + // versions from build container for native modules. const filteredDeps = depsStr.split(', ').filter(dependency => { - return !dependency.startsWith('libgcc-s1'); + return !dependency.startsWith('libgcc-s1') && + !dependency.startsWith('libgssapi-krb5-2') && + !dependency.startsWith('libkrb5-3'); }).sort(); const requires = new Set(filteredDeps); return requires; diff --git a/build/linux/debian/dep-lists.js b/build/linux/debian/dep-lists.js index 2444e401703de..bd2ce4fa3d7db 100644 --- a/build/linux/debian/dep-lists.js +++ b/build/linux/debian/dep-lists.js @@ -12,7 +12,9 @@ exports.additionalDeps = [ 'libgtk-3-0 (>= 3.9.10) | libgtk-4-1', 'libnss3 (>= 3.26)', 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', - 'xdg-utils (>= 1.0.2)' // OS integration + 'xdg-utils (>= 1.0.2)', + 'libgssapi-krb5-2', + 'libkrb5-3', ]; // Based on https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/debian/manual_recommends // Dependencies that we can only recommend @@ -28,20 +30,23 @@ exports.referenceGeneratedDepsByArch = { 'libatk1.0-0 (>= 2.2.0)', 'libatspi2.0-0 (>= 2.9.90)', 'libc6 (>= 2.14)', + 'libc6 (>= 2.16)', 'libc6 (>= 2.17)', 'libc6 (>= 2.2.5)', 'libcairo2 (>= 1.6.0)', 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', 'libdbus-1-3 (>= 1.5.12)', - 'libdrm2 (>= 2.4.60)', + 'libdrm2 (>= 2.4.75)', 'libexpat1 (>= 2.0.1)', 'libgbm1 (>= 17.1.0~rc2)', 'libglib2.0-0 (>= 2.16.0)', - 'libglib2.0-0 (>= 2.39.4)', + 'libglib2.0-0 (>= 2.37.3)', + 'libgssapi-krb5-2', 'libgtk-3-0 (>= 3.9.10)', 'libgtk-3-0 (>= 3.9.10) | libgtk-4-1', + 'libkrb5-3', 'libnspr4 (>= 2:4.9-2~)', - 'libnss3 (>= 2:3.22)', + 'libnss3 (>= 2:3.30)', 'libnss3 (>= 3.26)', 'libpango-1.0-0 (>= 1.14.0)', 'libsecret-1-0 (>= 0.18)', @@ -64,6 +69,7 @@ exports.referenceGeneratedDepsByArch = { 'libatk1.0-0 (>= 2.2.0)', 'libatspi2.0-0 (>= 2.9.90)', 'libc6 (>= 2.15)', + 'libc6 (>= 2.16)', 'libc6 (>= 2.17)', 'libc6 (>= 2.4)', 'libc6 (>= 2.8)', @@ -71,15 +77,17 @@ exports.referenceGeneratedDepsByArch = { 'libcairo2 (>= 1.6.0)', 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', 'libdbus-1-3 (>= 1.5.12)', - 'libdrm2 (>= 2.4.60)', + 'libdrm2 (>= 2.4.75)', 'libexpat1 (>= 2.0.1)', 'libgbm1 (>= 17.1.0~rc2)', 'libglib2.0-0 (>= 2.12.0)', - 'libglib2.0-0 (>= 2.39.4)', + 'libglib2.0-0 (>= 2.37.3)', + 'libgssapi-krb5-2', 'libgtk-3-0 (>= 3.9.10)', 'libgtk-3-0 (>= 3.9.10) | libgtk-4-1', + 'libkrb5-3', 'libnspr4 (>= 2:4.9-2~)', - 'libnss3 (>= 2:3.22)', + 'libnss3 (>= 2:3.30)', 'libnss3 (>= 3.26)', 'libpango-1.0-0 (>= 1.14.0)', 'libsecret-1-0 (>= 0.18)', @@ -108,15 +116,17 @@ exports.referenceGeneratedDepsByArch = { 'libcairo2 (>= 1.6.0)', 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', 'libdbus-1-3 (>= 1.0.2)', - 'libdrm2 (>= 2.4.60)', + 'libdrm2 (>= 2.4.75)', 'libexpat1 (>= 2.0.1)', 'libgbm1 (>= 17.1.0~rc2)', 'libglib2.0-0 (>= 2.12.0)', - 'libglib2.0-0 (>= 2.39.4)', + 'libglib2.0-0 (>= 2.37.3)', + 'libgssapi-krb5-2', 'libgtk-3-0 (>= 3.9.10)', 'libgtk-3-0 (>= 3.9.10) | libgtk-4-1', + 'libkrb5-3', 'libnspr4 (>= 2:4.9-2~)', - 'libnss3 (>= 2:3.22)', + 'libnss3 (>= 2:3.30)', 'libnss3 (>= 3.26)', 'libpango-1.0-0 (>= 1.14.0)', 'libsecret-1-0 (>= 0.18)', @@ -136,4 +146,4 @@ exports.referenceGeneratedDepsByArch = { 'xdg-utils (>= 1.0.2)' ] }; -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVwLWxpc3RzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZGVwLWxpc3RzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7O2dHQUdnRzs7O0FBRWhHLGtIQUFrSDtBQUNsSCw0REFBNEQ7QUFDL0MsUUFBQSxjQUFjLEdBQUc7SUFDN0IsaUJBQWlCO0lBQ2pCLHFDQUFxQztJQUNyQyxtQkFBbUI7SUFDbkIsc0RBQXNEO0lBQ3RELHNCQUFzQixDQUFDLGlCQUFpQjtDQUN4QyxDQUFDO0FBRUYsb0hBQW9IO0FBQ3BILDBDQUEwQztBQUMxQyw4REFBOEQ7QUFDakQsUUFBQSxlQUFlLEdBQUc7SUFDOUIsWUFBWSxDQUFDLHlFQUF5RTtDQUN0RixDQUFDO0FBRVcsUUFBQSw0QkFBNEIsR0FBRztJQUMzQyxPQUFPLEVBQUU7UUFDUixpQkFBaUI7UUFDakIsd0JBQXdCO1FBQ3hCLCtCQUErQjtRQUMvQix3QkFBd0I7UUFDeEIsMkJBQTJCO1FBQzNCLGlCQUFpQjtRQUNqQixpQkFBaUI7UUFDakIsa0JBQWtCO1FBQ2xCLHNCQUFzQjtRQUN0QixzREFBc0Q7UUFDdEQseUJBQXlCO1FBQ3pCLHFCQUFxQjtRQUNyQixzQkFBc0I7UUFDdEIseUJBQXlCO1FBQ3pCLDBCQUEwQjtRQUMxQiwwQkFBMEI7UUFDMUIsd0JBQXdCO1FBQ3hCLHFDQUFxQztRQUNyQyx3QkFBd0I7UUFDeEIscUJBQXFCO1FBQ3JCLG1CQUFtQjtRQUNuQiw0QkFBNEI7UUFDNUIseUJBQXlCO1FBQ3pCLFVBQVU7UUFDViwwQkFBMEI7UUFDMUIsb0JBQW9CO1FBQ3BCLCtCQUErQjtRQUMvQix3QkFBd0I7UUFDeEIsVUFBVTtRQUNWLFlBQVk7UUFDWiwwQkFBMEI7UUFDMUIsYUFBYTtRQUNiLFlBQVk7UUFDWixzQkFBc0I7S0FDdEI7SUFDRCxPQUFPLEVBQUU7UUFDUixpQkFBaUI7UUFDakIsd0JBQXdCO1FBQ3hCLCtCQUErQjtRQUMvQix3QkFBd0I7UUFDeEIsMkJBQTJCO1FBQzNCLGlCQUFpQjtRQUNqQixpQkFBaUI7UUFDakIsZ0JBQWdCO1FBQ2hCLGdCQUFnQjtRQUNoQixnQkFBZ0I7UUFDaEIsc0JBQXNCO1FBQ3RCLHNEQUFzRDtRQUN0RCx5QkFBeUI7UUFDekIscUJBQXFCO1FBQ3JCLHNCQUFzQjtRQUN0Qix5QkFBeUI7UUFDekIsMEJBQTBCO1FBQzFCLDBCQUEwQjtRQUMxQix3QkFBd0I7UUFDeEIscUNBQXFDO1FBQ3JDLHdCQUF3QjtRQUN4QixxQkFBcUI7UUFDckIsbUJBQW1CO1FBQ25CLDRCQUE0QjtRQUM1Qix5QkFBeUI7UUFDekIsbUJBQW1CO1FBQ25CLHFCQUFxQjtRQUNyQixtQkFBbUI7UUFDbkIsVUFBVTtRQUNWLDBCQUEwQjtRQUMxQixvQkFBb0I7UUFDcEIsK0JBQStCO1FBQy9CLHdCQUF3QjtRQUN4QixVQUFVO1FBQ1YsWUFBWTtRQUNaLDBCQUEwQjtRQUMxQixhQUFhO1FBQ2IsWUFBWTtRQUNaLHNCQUFzQjtLQUN0QjtJQUNELE9BQU8sRUFBRTtRQUNSLGlCQUFpQjtRQUNqQix3QkFBd0I7UUFDeEIsK0JBQStCO1FBQy9CLHdCQUF3QjtRQUN4QiwyQkFBMkI7UUFDM0IsaUJBQWlCO1FBQ2pCLHNCQUFzQjtRQUN0QixzREFBc0Q7UUFDdEQsd0JBQXdCO1FBQ3hCLHFCQUFxQjtRQUNyQixzQkFBc0I7UUFDdEIseUJBQXlCO1FBQ3pCLDBCQUEwQjtRQUMxQiwwQkFBMEI7UUFDMUIsd0JBQXdCO1FBQ3hCLHFDQUFxQztRQUNyQyx3QkFBd0I7UUFDeEIscUJBQXFCO1FBQ3JCLG1CQUFtQjtRQUNuQiw0QkFBNEI7UUFDNUIseUJBQXlCO1FBQ3pCLG1CQUFtQjtRQUNuQixxQkFBcUI7UUFDckIsbUJBQW1CO1FBQ25CLFVBQVU7UUFDViwwQkFBMEI7UUFDMUIsb0JBQW9CO1FBQ3BCLCtCQUErQjtRQUMvQix3QkFBd0I7UUFDeEIsVUFBVTtRQUNWLFlBQVk7UUFDWiwwQkFBMEI7UUFDMUIsYUFBYTtRQUNiLFlBQVk7UUFDWixzQkFBc0I7S0FDdEI7Q0FDRCxDQUFDIn0= \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVwLWxpc3RzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZGVwLWxpc3RzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7O2dHQUdnRzs7O0FBRWhHLGtIQUFrSDtBQUNsSCw0REFBNEQ7QUFDL0MsUUFBQSxjQUFjLEdBQUc7SUFDN0IsaUJBQWlCO0lBQ2pCLHFDQUFxQztJQUNyQyxtQkFBbUI7SUFDbkIsc0RBQXNEO0lBQ3RELHNCQUFzQjtJQUN0QixrQkFBa0I7SUFDbEIsV0FBVztDQUNYLENBQUM7QUFFRixvSEFBb0g7QUFDcEgsMENBQTBDO0FBQzFDLDhEQUE4RDtBQUNqRCxRQUFBLGVBQWUsR0FBRztJQUM5QixZQUFZLENBQUMseUVBQXlFO0NBQ3RGLENBQUM7QUFFVyxRQUFBLDRCQUE0QixHQUFHO0lBQzNDLE9BQU8sRUFBRTtRQUNSLGlCQUFpQjtRQUNqQix3QkFBd0I7UUFDeEIsK0JBQStCO1FBQy9CLHdCQUF3QjtRQUN4QiwyQkFBMkI7UUFDM0IsaUJBQWlCO1FBQ2pCLGlCQUFpQjtRQUNqQixpQkFBaUI7UUFDakIsa0JBQWtCO1FBQ2xCLHNCQUFzQjtRQUN0QixzREFBc0Q7UUFDdEQseUJBQXlCO1FBQ3pCLHFCQUFxQjtRQUNyQixzQkFBc0I7UUFDdEIseUJBQXlCO1FBQ3pCLDBCQUEwQjtRQUMxQiwwQkFBMEI7UUFDMUIsa0JBQWtCO1FBQ2xCLHdCQUF3QjtRQUN4QixxQ0FBcUM7UUFDckMsV0FBVztRQUNYLHdCQUF3QjtRQUN4QixxQkFBcUI7UUFDckIsbUJBQW1CO1FBQ25CLDRCQUE0QjtRQUM1Qix5QkFBeUI7UUFDekIsVUFBVTtRQUNWLDBCQUEwQjtRQUMxQixvQkFBb0I7UUFDcEIsK0JBQStCO1FBQy9CLHdCQUF3QjtRQUN4QixVQUFVO1FBQ1YsWUFBWTtRQUNaLDBCQUEwQjtRQUMxQixhQUFhO1FBQ2IsWUFBWTtRQUNaLHNCQUFzQjtLQUN0QjtJQUNELE9BQU8sRUFBRTtRQUNSLGlCQUFpQjtRQUNqQix3QkFBd0I7UUFDeEIsK0JBQStCO1FBQy9CLHdCQUF3QjtRQUN4QiwyQkFBMkI7UUFDM0IsaUJBQWlCO1FBQ2pCLGlCQUFpQjtRQUNqQixpQkFBaUI7UUFDakIsZ0JBQWdCO1FBQ2hCLGdCQUFnQjtRQUNoQixnQkFBZ0I7UUFDaEIsc0JBQXNCO1FBQ3RCLHNEQUFzRDtRQUN0RCx5QkFBeUI7UUFDekIscUJBQXFCO1FBQ3JCLHNCQUFzQjtRQUN0Qix5QkFBeUI7UUFDekIsMEJBQTBCO1FBQzFCLDBCQUEwQjtRQUMxQixrQkFBa0I7UUFDbEIsd0JBQXdCO1FBQ3hCLHFDQUFxQztRQUNyQyxXQUFXO1FBQ1gsd0JBQXdCO1FBQ3hCLHFCQUFxQjtRQUNyQixtQkFBbUI7UUFDbkIsNEJBQTRCO1FBQzVCLHlCQUF5QjtRQUN6QixtQkFBbUI7UUFDbkIscUJBQXFCO1FBQ3JCLG1CQUFtQjtRQUNuQixVQUFVO1FBQ1YsMEJBQTBCO1FBQzFCLG9CQUFvQjtRQUNwQiwrQkFBK0I7UUFDL0Isd0JBQXdCO1FBQ3hCLFVBQVU7UUFDVixZQUFZO1FBQ1osMEJBQTBCO1FBQzFCLGFBQWE7UUFDYixZQUFZO1FBQ1osc0JBQXNCO0tBQ3RCO0lBQ0QsT0FBTyxFQUFFO1FBQ1IsaUJBQWlCO1FBQ2pCLHdCQUF3QjtRQUN4QiwrQkFBK0I7UUFDL0Isd0JBQXdCO1FBQ3hCLDJCQUEyQjtRQUMzQixpQkFBaUI7UUFDakIsc0JBQXNCO1FBQ3RCLHNEQUFzRDtRQUN0RCx3QkFBd0I7UUFDeEIscUJBQXFCO1FBQ3JCLHNCQUFzQjtRQUN0Qix5QkFBeUI7UUFDekIsMEJBQTBCO1FBQzFCLDBCQUEwQjtRQUMxQixrQkFBa0I7UUFDbEIsd0JBQXdCO1FBQ3hCLHFDQUFxQztRQUNyQyxXQUFXO1FBQ1gsd0JBQXdCO1FBQ3hCLHFCQUFxQjtRQUNyQixtQkFBbUI7UUFDbkIsNEJBQTRCO1FBQzVCLHlCQUF5QjtRQUN6QixtQkFBbUI7UUFDbkIscUJBQXFCO1FBQ3JCLG1CQUFtQjtRQUNuQixVQUFVO1FBQ1YsMEJBQTBCO1FBQzFCLG9CQUFvQjtRQUNwQiwrQkFBK0I7UUFDL0Isd0JBQXdCO1FBQ3hCLFVBQVU7UUFDVixZQUFZO1FBQ1osMEJBQTBCO1FBQzFCLGFBQWE7UUFDYixZQUFZO1FBQ1osc0JBQXNCO0tBQ3RCO0NBQ0QsQ0FBQyJ9 \ No newline at end of file diff --git a/build/linux/debian/dep-lists.ts b/build/linux/debian/dep-lists.ts index 7f6cd6ca8ccfb..842eaac27cc80 100644 --- a/build/linux/debian/dep-lists.ts +++ b/build/linux/debian/dep-lists.ts @@ -10,7 +10,9 @@ export const additionalDeps = [ 'libgtk-3-0 (>= 3.9.10) | libgtk-4-1', 'libnss3 (>= 3.26)', 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', // For Breakpad crash reports. - 'xdg-utils (>= 1.0.2)' // OS integration + 'xdg-utils (>= 1.0.2)', // OS integration + 'libgssapi-krb5-2', + 'libkrb5-3', ]; // Based on https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/debian/manual_recommends @@ -28,20 +30,23 @@ export const referenceGeneratedDepsByArch = { 'libatk1.0-0 (>= 2.2.0)', 'libatspi2.0-0 (>= 2.9.90)', 'libc6 (>= 2.14)', + 'libc6 (>= 2.16)', 'libc6 (>= 2.17)', 'libc6 (>= 2.2.5)', 'libcairo2 (>= 1.6.0)', 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', 'libdbus-1-3 (>= 1.5.12)', - 'libdrm2 (>= 2.4.60)', + 'libdrm2 (>= 2.4.75)', 'libexpat1 (>= 2.0.1)', 'libgbm1 (>= 17.1.0~rc2)', 'libglib2.0-0 (>= 2.16.0)', - 'libglib2.0-0 (>= 2.39.4)', + 'libglib2.0-0 (>= 2.37.3)', + 'libgssapi-krb5-2', 'libgtk-3-0 (>= 3.9.10)', 'libgtk-3-0 (>= 3.9.10) | libgtk-4-1', + 'libkrb5-3', 'libnspr4 (>= 2:4.9-2~)', - 'libnss3 (>= 2:3.22)', + 'libnss3 (>= 2:3.30)', 'libnss3 (>= 3.26)', 'libpango-1.0-0 (>= 1.14.0)', 'libsecret-1-0 (>= 0.18)', @@ -64,6 +69,7 @@ export const referenceGeneratedDepsByArch = { 'libatk1.0-0 (>= 2.2.0)', 'libatspi2.0-0 (>= 2.9.90)', 'libc6 (>= 2.15)', + 'libc6 (>= 2.16)', 'libc6 (>= 2.17)', 'libc6 (>= 2.4)', 'libc6 (>= 2.8)', @@ -71,15 +77,17 @@ export const referenceGeneratedDepsByArch = { 'libcairo2 (>= 1.6.0)', 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', 'libdbus-1-3 (>= 1.5.12)', - 'libdrm2 (>= 2.4.60)', + 'libdrm2 (>= 2.4.75)', 'libexpat1 (>= 2.0.1)', 'libgbm1 (>= 17.1.0~rc2)', 'libglib2.0-0 (>= 2.12.0)', - 'libglib2.0-0 (>= 2.39.4)', + 'libglib2.0-0 (>= 2.37.3)', + 'libgssapi-krb5-2', 'libgtk-3-0 (>= 3.9.10)', 'libgtk-3-0 (>= 3.9.10) | libgtk-4-1', + 'libkrb5-3', 'libnspr4 (>= 2:4.9-2~)', - 'libnss3 (>= 2:3.22)', + 'libnss3 (>= 2:3.30)', 'libnss3 (>= 3.26)', 'libpango-1.0-0 (>= 1.14.0)', 'libsecret-1-0 (>= 0.18)', @@ -108,15 +116,17 @@ export const referenceGeneratedDepsByArch = { 'libcairo2 (>= 1.6.0)', 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', 'libdbus-1-3 (>= 1.0.2)', - 'libdrm2 (>= 2.4.60)', + 'libdrm2 (>= 2.4.75)', 'libexpat1 (>= 2.0.1)', 'libgbm1 (>= 17.1.0~rc2)', 'libglib2.0-0 (>= 2.12.0)', - 'libglib2.0-0 (>= 2.39.4)', + 'libglib2.0-0 (>= 2.37.3)', + 'libgssapi-krb5-2', 'libgtk-3-0 (>= 3.9.10)', 'libgtk-3-0 (>= 3.9.10) | libgtk-4-1', + 'libkrb5-3', 'libnspr4 (>= 2:4.9-2~)', - 'libnss3 (>= 2:3.22)', + 'libnss3 (>= 2:3.30)', 'libnss3 (>= 3.26)', 'libpango-1.0-0 (>= 1.14.0)', 'libsecret-1-0 (>= 0.18)', diff --git a/build/linux/dependencies-generator.js b/build/linux/dependencies-generator.js index 0ea66992dd38f..381539dd67ae5 100644 --- a/build/linux/dependencies-generator.js +++ b/build/linux/dependencies-generator.js @@ -21,7 +21,7 @@ const types_2 = require("./rpm/types"); // The reference dependencies, which one has to update when the new dependencies // are valid, are in dep-lists.ts const FAIL_BUILD_FOR_NEW_DEPENDENCIES = true; -// Based on https://source.chromium.org/chromium/chromium/src/+/refs/tags/108.0.5359.215:chrome/installer/linux/BUILD.gn;l=64-80 +// Based on https://source.chromium.org/chromium/chromium/src/+/refs/tags/114.0.5735.199:chrome/installer/linux/BUILD.gn;l=64-80 // and the Linux Archive build // Shared library dependencies that we already bundle. const bundledDeps = [ diff --git a/build/linux/dependencies-generator.ts b/build/linux/dependencies-generator.ts index c0d811253d2ba..5c4b9d240dcac 100644 --- a/build/linux/dependencies-generator.ts +++ b/build/linux/dependencies-generator.ts @@ -23,7 +23,7 @@ import { isRpmArchString, RpmArchString } from './rpm/types'; // are valid, are in dep-lists.ts const FAIL_BUILD_FOR_NEW_DEPENDENCIES: boolean = true; -// Based on https://source.chromium.org/chromium/chromium/src/+/refs/tags/108.0.5359.215:chrome/installer/linux/BUILD.gn;l=64-80 +// Based on https://source.chromium.org/chromium/chromium/src/+/refs/tags/114.0.5735.199:chrome/installer/linux/BUILD.gn;l=64-80 // and the Linux Archive build // Shared library dependencies that we already bundle. const bundledDeps = [ diff --git a/build/linux/rpm/dep-lists.js b/build/linux/rpm/dep-lists.js index c836348ef5105..5e2749a50be46 100644 --- a/build/linux/rpm/dep-lists.js +++ b/build/linux/rpm/dep-lists.js @@ -65,7 +65,11 @@ exports.referenceGeneratedDepsByArch = { 'libgio-2.0.so.0()(64bit)', 'libglib-2.0.so.0()(64bit)', 'libgobject-2.0.so.0()(64bit)', + 'libgssapi_krb5.so.2()(64bit)', + 'libgssapi_krb5.so.2(gssapi_krb5_2_MIT)(64bit)', 'libgtk-3.so.0()(64bit)', + 'libkrb5.so.3()(64bit)', + 'libkrb5.so.3(krb5_3_MIT)(64bit)', 'libm.so.6()(64bit)', 'libm.so.6(GLIBC_2.2.5)(64bit)', 'libnspr4.so()(64bit)', @@ -73,9 +77,11 @@ exports.referenceGeneratedDepsByArch = { 'libnss3.so(NSS_3.11)(64bit)', 'libnss3.so(NSS_3.12)(64bit)', 'libnss3.so(NSS_3.12.1)(64bit)', + 'libnss3.so(NSS_3.13)(64bit)', 'libnss3.so(NSS_3.2)(64bit)', 'libnss3.so(NSS_3.22)(64bit)', 'libnss3.so(NSS_3.3)(64bit)', + 'libnss3.so(NSS_3.30)(64bit)', 'libnss3.so(NSS_3.4)(64bit)', 'libnss3.so(NSS_3.5)(64bit)', 'libnss3.so(NSS_3.9.2)(64bit)', @@ -126,7 +132,6 @@ exports.referenceGeneratedDepsByArch = { 'libc.so.6(GLIBC_2.15)', 'libc.so.6(GLIBC_2.16)', 'libc.so.6(GLIBC_2.17)', - 'libc.so.6(GLIBC_2.25)', 'libc.so.6(GLIBC_2.4)', 'libc.so.6(GLIBC_2.6)', 'libc.so.6(GLIBC_2.7)', @@ -146,8 +151,12 @@ exports.referenceGeneratedDepsByArch = { 'libgio-2.0.so.0', 'libglib-2.0.so.0', 'libgobject-2.0.so.0', + 'libgssapi_krb5.so.2', + 'libgssapi_krb5.so.2(gssapi_krb5_2_MIT)', 'libgtk-3.so.0', 'libgtk-3.so.0()(64bit)', + 'libkrb5.so.3', + 'libkrb5.so.3(krb5_3_MIT)', 'libm.so.6', 'libm.so.6(GLIBC_2.4)', 'libnspr4.so', @@ -155,10 +164,12 @@ exports.referenceGeneratedDepsByArch = { 'libnss3.so(NSS_3.11)', 'libnss3.so(NSS_3.12)', 'libnss3.so(NSS_3.12.1)', + 'libnss3.so(NSS_3.13)', 'libnss3.so(NSS_3.2)', 'libnss3.so(NSS_3.22)', 'libnss3.so(NSS_3.22)(64bit)', 'libnss3.so(NSS_3.3)', + 'libnss3.so(NSS_3.30)', 'libnss3.so(NSS_3.4)', 'libnss3.so(NSS_3.5)', 'libnss3.so(NSS_3.9.2)', @@ -219,7 +230,6 @@ exports.referenceGeneratedDepsByArch = { 'libatspi.so.0()(64bit)', 'libc.so.6()(64bit)', 'libc.so.6(GLIBC_2.17)(64bit)', - 'libc.so.6(GLIBC_2.25)(64bit)', 'libcairo.so.2()(64bit)', 'libcurl.so.4()(64bit)', 'libdbus-1.so.3()(64bit)', @@ -236,7 +246,11 @@ exports.referenceGeneratedDepsByArch = { 'libgio-2.0.so.0()(64bit)', 'libglib-2.0.so.0()(64bit)', 'libgobject-2.0.so.0()(64bit)', + 'libgssapi_krb5.so.2()(64bit)', + 'libgssapi_krb5.so.2(gssapi_krb5_2_MIT)(64bit)', 'libgtk-3.so.0()(64bit)', + 'libkrb5.so.3()(64bit)', + 'libkrb5.so.3(krb5_3_MIT)(64bit)', 'libm.so.6()(64bit)', 'libm.so.6(GLIBC_2.17)(64bit)', 'libnspr4.so()(64bit)', @@ -244,9 +258,11 @@ exports.referenceGeneratedDepsByArch = { 'libnss3.so(NSS_3.11)(64bit)', 'libnss3.so(NSS_3.12)(64bit)', 'libnss3.so(NSS_3.12.1)(64bit)', + 'libnss3.so(NSS_3.13)(64bit)', 'libnss3.so(NSS_3.2)(64bit)', 'libnss3.so(NSS_3.22)(64bit)', 'libnss3.so(NSS_3.3)(64bit)', + 'libnss3.so(NSS_3.30)(64bit)', 'libnss3.so(NSS_3.4)(64bit)', 'libnss3.so(NSS_3.5)(64bit)', 'libnss3.so(NSS_3.9.2)(64bit)', @@ -289,4 +305,4 @@ exports.referenceGeneratedDepsByArch = { 'xdg-utils' ] }; -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVwLWxpc3RzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZGVwLWxpc3RzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7O2dHQUdnRzs7O0FBRWhHLCtHQUErRztBQUMvRywrREFBK0Q7QUFDbEQsUUFBQSxjQUFjLEdBQUc7SUFDN0IsaUJBQWlCO0lBQ2pCLHdCQUF3QjtJQUN4Qiw2QkFBNkI7SUFDN0IsNkJBQTZCO0lBQzdCLGdDQUFnQztJQUNoQyx5QkFBeUI7SUFDekIsdUJBQXVCO0lBQ3ZCLFdBQVcsQ0FBQyxpQkFBaUI7Q0FDN0IsQ0FBQztBQUVXLFFBQUEsNEJBQTRCLEdBQUc7SUFDM0MsUUFBUSxFQUFFO1FBQ1QsaUJBQWlCO1FBQ2pCLCtCQUErQjtRQUMvQiwwQ0FBMEM7UUFDMUMsd0NBQXdDO1FBQ3hDLHNCQUFzQjtRQUN0Qiw2QkFBNkI7UUFDN0IsMEJBQTBCO1FBQzFCLHVCQUF1QjtRQUN2Qix5QkFBeUI7UUFDekIseUJBQXlCO1FBQ3pCLHlCQUF5QjtRQUN6QixpQ0FBaUM7UUFDakMsc0NBQXNDO1FBQ3RDLDBCQUEwQjtRQUMxQixpQ0FBaUM7UUFDakMsd0JBQXdCO1FBQ3hCLG9CQUFvQjtRQUNwQiw4QkFBOEI7UUFDOUIsOEJBQThCO1FBQzlCLDhCQUE4QjtRQUM5Qiw4QkFBOEI7UUFDOUIsOEJBQThCO1FBQzlCLDhCQUE4QjtRQUM5QiwrQkFBK0I7UUFDL0IsNkJBQTZCO1FBQzdCLCtCQUErQjtRQUMvQiwrQkFBK0I7UUFDL0IsK0JBQStCO1FBQy9CLDZCQUE2QjtRQUM3Qiw2QkFBNkI7UUFDN0IsNkJBQTZCO1FBQzdCLDZCQUE2QjtRQUM3Qiw2QkFBNkI7UUFDN0Isd0JBQXdCO1FBQ3hCLHVCQUF1QjtRQUN2Qix5QkFBeUI7UUFDekIscUJBQXFCO1FBQ3JCLGdDQUFnQztRQUNoQyxzQkFBc0I7UUFDdEIsd0JBQXdCO1FBQ3hCLHNCQUFzQjtRQUN0Qix3QkFBd0I7UUFDeEIsK0JBQStCO1FBQy9CLDBCQUEwQjtRQUMxQiwyQkFBMkI7UUFDM0IsOEJBQThCO1FBQzlCLHdCQUF3QjtRQUN4QixvQkFBb0I7UUFDcEIsK0JBQStCO1FBQy9CLHNCQUFzQjtRQUN0QixxQkFBcUI7UUFDckIsNkJBQTZCO1FBQzdCLDZCQUE2QjtRQUM3QiwrQkFBK0I7UUFDL0IsNEJBQTRCO1FBQzVCLDZCQUE2QjtRQUM3Qiw0QkFBNEI7UUFDNUIsNEJBQTRCO1FBQzVCLDRCQUE0QjtRQUM1Qiw4QkFBOEI7UUFDOUIseUJBQXlCO1FBQ3pCLHVDQUF1QztRQUN2Qyw0QkFBNEI7UUFDNUIsMEJBQTBCO1FBQzFCLG9DQUFvQztRQUNwQyxxQ0FBcUM7UUFDckMscUNBQXFDO1FBQ3JDLHFDQUFxQztRQUNyQyxxQ0FBcUM7UUFDckMscUJBQXFCO1FBQ3JCLGdDQUFnQztRQUNoQywyQkFBMkI7UUFDM0IsdUJBQXVCO1FBQ3ZCLCtCQUErQjtRQUMvQiw4QkFBOEI7UUFDOUIsNkJBQTZCO1FBQzdCLHVCQUF1QjtRQUN2QixrQ0FBa0M7UUFDbEMsc0JBQXNCO1FBQ3RCLDRCQUE0QjtRQUM1QiwwQkFBMEI7UUFDMUIsZ0NBQWdDO1FBQ2hDLGdCQUFnQjtRQUNoQixXQUFXO0tBQ1g7SUFDRCxTQUFTLEVBQUU7UUFDVixpQkFBaUI7UUFDakIscUJBQXFCO1FBQ3JCLGdDQUFnQztRQUNoQyxhQUFhO1FBQ2Isb0JBQW9CO1FBQ3BCLGlCQUFpQjtRQUNqQixjQUFjO1FBQ2QsZ0JBQWdCO1FBQ2hCLGdCQUFnQjtRQUNoQixnQkFBZ0I7UUFDaEIsMEJBQTBCO1FBQzFCLCtCQUErQjtRQUMvQixpQkFBaUI7UUFDakIsd0JBQXdCO1FBQ3hCLGVBQWU7UUFDZixXQUFXO1FBQ1gsdUJBQXVCO1FBQ3ZCLHVCQUF1QjtRQUN2Qix1QkFBdUI7UUFDdkIsdUJBQXVCO1FBQ3ZCLHVCQUF1QjtRQUN2Qix1QkFBdUI7UUFDdkIsc0JBQXNCO1FBQ3RCLHNCQUFzQjtRQUN0QixzQkFBc0I7UUFDdEIsc0JBQXNCO1FBQ3RCLHNCQUFzQjtRQUN0QixlQUFlO1FBQ2YsdUJBQXVCO1FBQ3ZCLGdCQUFnQjtRQUNoQixZQUFZO1FBQ1osdUJBQXVCO1FBQ3ZCLGFBQWE7UUFDYixlQUFlO1FBQ2YsYUFBYTtRQUNiLGVBQWU7UUFDZix3QkFBd0I7UUFDeEIsd0JBQXdCO1FBQ3hCLGlCQUFpQjtRQUNqQixrQkFBa0I7UUFDbEIscUJBQXFCO1FBQ3JCLGVBQWU7UUFDZix3QkFBd0I7UUFDeEIsV0FBVztRQUNYLHNCQUFzQjtRQUN0QixhQUFhO1FBQ2IsWUFBWTtRQUNaLHNCQUFzQjtRQUN0QixzQkFBc0I7UUFDdEIsd0JBQXdCO1FBQ3hCLHFCQUFxQjtRQUNyQixzQkFBc0I7UUFDdEIsNkJBQTZCO1FBQzdCLHFCQUFxQjtRQUNyQixxQkFBcUI7UUFDckIscUJBQXFCO1FBQ3JCLHVCQUF1QjtRQUN2QixnQkFBZ0I7UUFDaEIsZ0NBQWdDO1FBQ2hDLG1CQUFtQjtRQUNuQixpQkFBaUI7UUFDakIsNkJBQTZCO1FBQzdCLDRCQUE0QjtRQUM1QixZQUFZO1FBQ1osdUJBQXVCO1FBQ3ZCLGtCQUFrQjtRQUNsQixjQUFjO1FBQ2Qsd0JBQXdCO1FBQ3hCLHVCQUF1QjtRQUN2Qiw2QkFBNkI7UUFDN0IsZ0JBQWdCO1FBQ2hCLDRCQUE0QjtRQUM1Qiw4QkFBOEI7UUFDOUIsOEJBQThCO1FBQzlCLDhCQUE4QjtRQUM5QixrQ0FBa0M7UUFDbEMsNkJBQTZCO1FBQzdCLGdDQUFnQztRQUNoQyxnQ0FBZ0M7UUFDaEMsZ0NBQWdDO1FBQ2hDLGdDQUFnQztRQUNoQyxnQ0FBZ0M7UUFDaEMsZ0NBQWdDO1FBQ2hDLGdDQUFnQztRQUNoQyxnQ0FBZ0M7UUFDaEMsK0JBQStCO1FBQy9CLCtCQUErQjtRQUMvQixjQUFjO1FBQ2QseUJBQXlCO1FBQ3pCLGFBQWE7UUFDYixtQkFBbUI7UUFDbkIsaUJBQWlCO1FBQ2pCLGdDQUFnQztRQUNoQyxnQkFBZ0I7UUFDaEIsV0FBVztLQUNYO0lBQ0QsU0FBUyxFQUFFO1FBQ1YsaUJBQWlCO1FBQ2pCLGdDQUFnQztRQUNoQywwQ0FBMEM7UUFDMUMsc0JBQXNCO1FBQ3RCLDZCQUE2QjtRQUM3QiwwQkFBMEI7UUFDMUIsdUJBQXVCO1FBQ3ZCLHlCQUF5QjtRQUN6Qix5QkFBeUI7UUFDekIseUJBQXlCO1FBQ3pCLGlDQUFpQztRQUNqQyxzQ0FBc0M7UUFDdEMsMEJBQTBCO1FBQzFCLGlDQUFpQztRQUNqQyx3QkFBd0I7UUFDeEIsb0JBQW9CO1FBQ3BCLDhCQUE4QjtRQUM5Qiw4QkFBOEI7UUFDOUIsd0JBQXdCO1FBQ3hCLHVCQUF1QjtRQUN2Qix5QkFBeUI7UUFDekIsb0NBQW9DO1FBQ3BDLHFCQUFxQjtRQUNyQiwrQkFBK0I7UUFDL0Isc0JBQXNCO1FBQ3RCLHdCQUF3QjtRQUN4QixzQkFBc0I7UUFDdEIsd0JBQXdCO1FBQ3hCLCtCQUErQjtRQUMvQixpQ0FBaUM7UUFDakMsaUNBQWlDO1FBQ2pDLDBCQUEwQjtRQUMxQiwyQkFBMkI7UUFDM0IsOEJBQThCO1FBQzlCLHdCQUF3QjtRQUN4QixvQkFBb0I7UUFDcEIsOEJBQThCO1FBQzlCLHNCQUFzQjtRQUN0QixxQkFBcUI7UUFDckIsNkJBQTZCO1FBQzdCLDZCQUE2QjtRQUM3QiwrQkFBK0I7UUFDL0IsNEJBQTRCO1FBQzVCLDZCQUE2QjtRQUM3Qiw0QkFBNEI7UUFDNUIsNEJBQTRCO1FBQzVCLDRCQUE0QjtRQUM1Qiw4QkFBOEI7UUFDOUIseUJBQXlCO1FBQ3pCLHVDQUF1QztRQUN2Qyw0QkFBNEI7UUFDNUIsMEJBQTBCO1FBQzFCLG9DQUFvQztRQUNwQyxxQkFBcUI7UUFDckIsK0JBQStCO1FBQy9CLDJCQUEyQjtRQUMzQix1QkFBdUI7UUFDdkIsK0JBQStCO1FBQy9CLDhCQUE4QjtRQUM5Qiw2QkFBNkI7UUFDN0IseUJBQXlCO1FBQ3pCLG1DQUFtQztRQUNuQyxxQ0FBcUM7UUFDckMscUNBQXFDO1FBQ3JDLHFDQUFxQztRQUNyQyxvQ0FBb0M7UUFDcEMsdUNBQXVDO1FBQ3ZDLHVDQUF1QztRQUN2Qyx1Q0FBdUM7UUFDdkMsdUNBQXVDO1FBQ3ZDLHVDQUF1QztRQUN2Qyx1Q0FBdUM7UUFDdkMsdUNBQXVDO1FBQ3ZDLHVDQUF1QztRQUN2QyxzQ0FBc0M7UUFDdEMsc0NBQXNDO1FBQ3RDLHVCQUF1QjtRQUN2QixpQ0FBaUM7UUFDakMsc0JBQXNCO1FBQ3RCLDRCQUE0QjtRQUM1QixtQ0FBbUM7UUFDbkMsMEJBQTBCO1FBQzFCLGdDQUFnQztRQUNoQyxnQkFBZ0I7UUFDaEIsV0FBVztLQUNYO0NBQ0QsQ0FBQyJ9 \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVwLWxpc3RzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZGVwLWxpc3RzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7O2dHQUdnRzs7O0FBRWhHLCtHQUErRztBQUMvRywrREFBK0Q7QUFDbEQsUUFBQSxjQUFjLEdBQUc7SUFDN0IsaUJBQWlCO0lBQ2pCLHdCQUF3QjtJQUN4Qiw2QkFBNkI7SUFDN0IsNkJBQTZCO0lBQzdCLGdDQUFnQztJQUNoQyx5QkFBeUI7SUFDekIsdUJBQXVCO0lBQ3ZCLFdBQVcsQ0FBQyxpQkFBaUI7Q0FDN0IsQ0FBQztBQUVXLFFBQUEsNEJBQTRCLEdBQUc7SUFDM0MsUUFBUSxFQUFFO1FBQ1QsaUJBQWlCO1FBQ2pCLCtCQUErQjtRQUMvQiwwQ0FBMEM7UUFDMUMsd0NBQXdDO1FBQ3hDLHNCQUFzQjtRQUN0Qiw2QkFBNkI7UUFDN0IsMEJBQTBCO1FBQzFCLHVCQUF1QjtRQUN2Qix5QkFBeUI7UUFDekIseUJBQXlCO1FBQ3pCLHlCQUF5QjtRQUN6QixpQ0FBaUM7UUFDakMsc0NBQXNDO1FBQ3RDLDBCQUEwQjtRQUMxQixpQ0FBaUM7UUFDakMsd0JBQXdCO1FBQ3hCLG9CQUFvQjtRQUNwQiw4QkFBOEI7UUFDOUIsOEJBQThCO1FBQzlCLDhCQUE4QjtRQUM5Qiw4QkFBOEI7UUFDOUIsOEJBQThCO1FBQzlCLDhCQUE4QjtRQUM5QiwrQkFBK0I7UUFDL0IsNkJBQTZCO1FBQzdCLCtCQUErQjtRQUMvQiwrQkFBK0I7UUFDL0IsK0JBQStCO1FBQy9CLDZCQUE2QjtRQUM3Qiw2QkFBNkI7UUFDN0IsNkJBQTZCO1FBQzdCLDZCQUE2QjtRQUM3Qiw2QkFBNkI7UUFDN0Isd0JBQXdCO1FBQ3hCLHVCQUF1QjtRQUN2Qix5QkFBeUI7UUFDekIscUJBQXFCO1FBQ3JCLGdDQUFnQztRQUNoQyxzQkFBc0I7UUFDdEIsd0JBQXdCO1FBQ3hCLHNCQUFzQjtRQUN0Qix3QkFBd0I7UUFDeEIsK0JBQStCO1FBQy9CLDBCQUEwQjtR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 \ No newline at end of file diff --git a/build/linux/rpm/dep-lists.ts b/build/linux/rpm/dep-lists.ts index c262448c318e8..4e5f64dc20b03 100644 --- a/build/linux/rpm/dep-lists.ts +++ b/build/linux/rpm/dep-lists.ts @@ -64,7 +64,11 @@ export const referenceGeneratedDepsByArch = { 'libgio-2.0.so.0()(64bit)', 'libglib-2.0.so.0()(64bit)', 'libgobject-2.0.so.0()(64bit)', + 'libgssapi_krb5.so.2()(64bit)', + 'libgssapi_krb5.so.2(gssapi_krb5_2_MIT)(64bit)', 'libgtk-3.so.0()(64bit)', + 'libkrb5.so.3()(64bit)', + 'libkrb5.so.3(krb5_3_MIT)(64bit)', 'libm.so.6()(64bit)', 'libm.so.6(GLIBC_2.2.5)(64bit)', 'libnspr4.so()(64bit)', @@ -72,9 +76,11 @@ export const referenceGeneratedDepsByArch = { 'libnss3.so(NSS_3.11)(64bit)', 'libnss3.so(NSS_3.12)(64bit)', 'libnss3.so(NSS_3.12.1)(64bit)', + 'libnss3.so(NSS_3.13)(64bit)', 'libnss3.so(NSS_3.2)(64bit)', 'libnss3.so(NSS_3.22)(64bit)', 'libnss3.so(NSS_3.3)(64bit)', + 'libnss3.so(NSS_3.30)(64bit)', 'libnss3.so(NSS_3.4)(64bit)', 'libnss3.so(NSS_3.5)(64bit)', 'libnss3.so(NSS_3.9.2)(64bit)', @@ -125,7 +131,6 @@ export const referenceGeneratedDepsByArch = { 'libc.so.6(GLIBC_2.15)', 'libc.so.6(GLIBC_2.16)', 'libc.so.6(GLIBC_2.17)', - 'libc.so.6(GLIBC_2.25)', 'libc.so.6(GLIBC_2.4)', 'libc.so.6(GLIBC_2.6)', 'libc.so.6(GLIBC_2.7)', @@ -145,8 +150,12 @@ export const referenceGeneratedDepsByArch = { 'libgio-2.0.so.0', 'libglib-2.0.so.0', 'libgobject-2.0.so.0', + 'libgssapi_krb5.so.2', + 'libgssapi_krb5.so.2(gssapi_krb5_2_MIT)', 'libgtk-3.so.0', 'libgtk-3.so.0()(64bit)', + 'libkrb5.so.3', + 'libkrb5.so.3(krb5_3_MIT)', 'libm.so.6', 'libm.so.6(GLIBC_2.4)', 'libnspr4.so', @@ -154,10 +163,12 @@ export const referenceGeneratedDepsByArch = { 'libnss3.so(NSS_3.11)', 'libnss3.so(NSS_3.12)', 'libnss3.so(NSS_3.12.1)', + 'libnss3.so(NSS_3.13)', 'libnss3.so(NSS_3.2)', 'libnss3.so(NSS_3.22)', 'libnss3.so(NSS_3.22)(64bit)', 'libnss3.so(NSS_3.3)', + 'libnss3.so(NSS_3.30)', 'libnss3.so(NSS_3.4)', 'libnss3.so(NSS_3.5)', 'libnss3.so(NSS_3.9.2)', @@ -218,7 +229,6 @@ export const referenceGeneratedDepsByArch = { 'libatspi.so.0()(64bit)', 'libc.so.6()(64bit)', 'libc.so.6(GLIBC_2.17)(64bit)', - 'libc.so.6(GLIBC_2.25)(64bit)', 'libcairo.so.2()(64bit)', 'libcurl.so.4()(64bit)', 'libdbus-1.so.3()(64bit)', @@ -235,7 +245,11 @@ export const referenceGeneratedDepsByArch = { 'libgio-2.0.so.0()(64bit)', 'libglib-2.0.so.0()(64bit)', 'libgobject-2.0.so.0()(64bit)', + 'libgssapi_krb5.so.2()(64bit)', + 'libgssapi_krb5.so.2(gssapi_krb5_2_MIT)(64bit)', 'libgtk-3.so.0()(64bit)', + 'libkrb5.so.3()(64bit)', + 'libkrb5.so.3(krb5_3_MIT)(64bit)', 'libm.so.6()(64bit)', 'libm.so.6(GLIBC_2.17)(64bit)', 'libnspr4.so()(64bit)', @@ -243,9 +257,11 @@ export const referenceGeneratedDepsByArch = { 'libnss3.so(NSS_3.11)(64bit)', 'libnss3.so(NSS_3.12)(64bit)', 'libnss3.so(NSS_3.12.1)(64bit)', + 'libnss3.so(NSS_3.13)(64bit)', 'libnss3.so(NSS_3.2)(64bit)', 'libnss3.so(NSS_3.22)(64bit)', 'libnss3.so(NSS_3.3)(64bit)', + 'libnss3.so(NSS_3.30)(64bit)', 'libnss3.so(NSS_3.4)(64bit)', 'libnss3.so(NSS_3.5)(64bit)', 'libnss3.so(NSS_3.9.2)(64bit)', diff --git a/build/monaco/README-npm.md b/build/monaco/README-npm.md index ca5592e0fe1f6..ec8eb5a40376e 100644 --- a/build/monaco/README-npm.md +++ b/build/monaco/README-npm.md @@ -10,4 +10,5 @@ The Monaco Editor is the code editor that powers [VS Code](https://github.com/mi This npm module contains the core editor functionality, as it comes from the [vscode repository](https://github.com/microsoft/vscode). ## License + [MIT](https://github.com/microsoft/vscode/blob/main/LICENSE.txt) diff --git a/build/monaco/monaco.d.ts.recipe b/build/monaco/monaco.d.ts.recipe index ff4febe8ce66b..89c884f18a01f 100644 --- a/build/monaco/monaco.d.ts.recipe +++ b/build/monaco/monaco.d.ts.recipe @@ -107,7 +107,7 @@ export interface ICommandHandler { #include(vs/editor/common/core/editOperation): ISingleEditOperation #include(vs/editor/common/core/wordHelper): IWordAtPosition #includeAll(vs/editor/common/model): IScrollEvent -#include(vs/editor/common/diff/smartLinesDiffComputer): IChange, ICharChange, ILineChange +#include(vs/editor/common/diff/legacyLinesDiffComputer): IChange, ICharChange, ILineChange #include(vs/editor/common/diff/documentDiffProvider): IDocumentDiffProvider, IDocumentDiffProviderOptions, IDocumentDiff #include(vs/editor/common/core/lineRange): LineRange #include(vs/editor/common/diff/linesDiffComputer): LineRangeMapping, RangeMapping, MovedText, SimpleLineRangeMapping diff --git a/build/npm/dirs.js b/build/npm/dirs.js index 875390550dadf..faf3a6577a5d8 100644 --- a/build/npm/dirs.js +++ b/build/npm/dirs.js @@ -41,6 +41,7 @@ const dirs = [ 'extensions/references-view', 'extensions/search-result', 'extensions/simple-browser', + 'extensions/tunnel-forwarding', 'extensions/typescript-language-features', 'extensions/vscode-api-tests', 'extensions/vscode-colorize-tests', diff --git a/build/npm/gyp/package.json b/build/npm/gyp/package.json index 0efaa499b9d36..3961e955a5f84 100644 --- a/build/npm/gyp/package.json +++ b/build/npm/gyp/package.json @@ -4,7 +4,7 @@ "private": true, "license": "MIT", "devDependencies": { - "node-gyp": "^8.4.1" + "node-gyp": "^9.4.0" }, "scripts": {} } diff --git a/build/npm/gyp/patches/gyp_spectre_mitigation_support.patch b/build/npm/gyp/patches/gyp_spectre_mitigation_support.patch new file mode 100644 index 0000000000000..e64f42e2b04ec --- /dev/null +++ b/build/npm/gyp/patches/gyp_spectre_mitigation_support.patch @@ -0,0 +1,51 @@ +From 853e4643b6737224a5aa0720a4108461a0230991 Mon Sep 17 00:00:00 2001 +From: Raymond Zhao <7199958+rzhao271@users.noreply.github.com> +Date: Thu, 30 Mar 2023 05:23:36 -0700 +Subject: [PATCH] feat(msvs): add SpectreMitigation attribute (#190) + +Backports https://github.com/nodejs/gyp-next/commit/853e4643b6737224a5aa0720a4108461a0230991 + +diff --git a/gyp/pylib/gyp/easy_xml_test.py b/gyp/pylib/gyp/easy_xml_test.py +index 342f693..c5808b8 100755 +--- a/gyp/pylib/gyp/easy_xml_test.py ++++ b/gyp/pylib/gyp/easy_xml_test.py +@@ -76,6 +76,7 @@ def test_EasyXml_complex(self): + '\'Debug|Win32\'" Label="Configuration">' + "Application" + "Unicode" ++ "SpectreLoadCF" + "" + "" + ) +@@ -99,6 +100,7 @@ def test_EasyXml_complex(self): + }, + ["ConfigurationType", "Application"], + ["CharacterSet", "Unicode"], ++ ["SpectreMitigation", "SpectreLoadCF"] + ], + ] + ) +diff --git a/gyp/pylib/gyp/generator/msvs.py b/gyp/pylib/gyp/generator/msvs.py +index 72269bd..85c354f 100644 +--- a/gyp/pylib/gyp/generator/msvs.py ++++ b/gyp/pylib/gyp/generator/msvs.py +@@ -3006,6 +3006,10 @@ def _GetMSBuildConfigurationDetails(spec, build_file): + character_set = msbuild_attributes.get("CharacterSet") + config_type = msbuild_attributes.get("ConfigurationType") + _AddConditionalProperty(properties, condition, "ConfigurationType", config_type) ++ spectre_mitigation = msbuild_attributes.get('SpectreMitigation') ++ if spectre_mitigation: ++ _AddConditionalProperty(properties, condition, "SpectreMitigation", ++ spectre_mitigation) + if config_type == "Driver": + _AddConditionalProperty(properties, condition, "DriverType", "WDM") + _AddConditionalProperty( +@@ -3094,6 +3098,8 @@ def _ConvertMSVSBuildAttributes(spec, config, build_file): + msbuild_attributes[a] = _ConvertMSVSCharacterSet(msvs_attributes[a]) + elif a == "ConfigurationType": + msbuild_attributes[a] = _ConvertMSVSConfigurationType(msvs_attributes[a]) ++ elif a == "SpectreMitigation": ++ msbuild_attributes[a] = msvs_attributes[a] + else: + print("Warning: Do not know how to convert MSVS attribute " + a) + return msbuild_attributes diff --git a/build/npm/gyp/yarn.lock b/build/npm/gyp/yarn.lock index 10514f566bb62..3716071611c37 100644 --- a/build/npm/gyp/yarn.lock +++ b/build/npm/gyp/yarn.lock @@ -2,33 +2,36 @@ # yarn lockfile v1 -"@gar/promisify@^1.0.1": - version "1.1.3" - resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" - integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== - -"@npmcli/fs@^1.0.0": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-1.1.1.tgz#72f719fe935e687c56a4faecf3c03d06ba593257" - integrity sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ== +"@isaacs/cliui@^8.0.2": + version "8.0.2" + resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" + integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== + dependencies: + string-width "^5.1.2" + string-width-cjs "npm:string-width@^4.2.0" + strip-ansi "^7.0.1" + strip-ansi-cjs "npm:strip-ansi@^6.0.1" + wrap-ansi "^8.1.0" + wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" + +"@npmcli/fs@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-3.1.0.tgz#233d43a25a91d68c3a863ba0da6a3f00924a173e" + integrity sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w== dependencies: - "@gar/promisify" "^1.0.1" semver "^7.3.5" -"@npmcli/move-file@^1.0.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-1.1.2.tgz#1a82c3e372f7cae9253eb66d72543d6b8685c674" - integrity sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg== - dependencies: - mkdirp "^1.0.4" - rimraf "^3.0.2" +"@pkgjs/parseargs@^0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" + integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== -"@tootallnate/once@1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" - integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== +"@tootallnate/once@2": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" + integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== -abbrev@1: +abbrev@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== @@ -40,13 +43,13 @@ agent-base@6, agent-base@^6.0.2: dependencies: debug "4" -agentkeepalive@^4.1.3: - version "4.2.1" - resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.2.1.tgz#a7975cbb9f83b367f06c90cc51ff28fe7d499717" - integrity sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA== +agentkeepalive@^4.2.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.3.0.tgz#bb999ff07412653c1803b3ced35e50729830a255" + integrity sha512-7Epl1Blf4Sy37j4v9f9FjICCh4+KAQOyXgHEwlyBiAQLbhKdq/i2QQU3amQalS/wPhdPzDXPL5DMR5bkn+YeWg== dependencies: debug "^4.1.0" - depd "^1.1.2" + depd "^2.0.0" humanize-ms "^1.2.1" aggregate-error@^3.0.0: @@ -62,6 +65,23 @@ ansi-regex@^5.0.1: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== +ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + +ansi-styles@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-styles@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + "aproba@^1.0.3 || ^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" @@ -88,29 +108,30 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" -cacache@^15.2.0: - version "15.3.0" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.3.0.tgz#dc85380fb2f556fe3dda4c719bfa0ec875a7f1eb" - integrity sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ== +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== dependencies: - "@npmcli/fs" "^1.0.0" - "@npmcli/move-file" "^1.0.1" - chownr "^2.0.0" - fs-minipass "^2.0.0" - glob "^7.1.4" - infer-owner "^1.0.4" - lru-cache "^6.0.0" - minipass "^3.1.1" + balanced-match "^1.0.0" + +cacache@^17.0.0: + version "17.1.3" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-17.1.3.tgz#c6ac23bec56516a7c0c52020fd48b4909d7c7044" + integrity sha512-jAdjGxmPxZh0IipMdR7fK/4sDSrHMLUV0+GvVUsjwyGNKHsh79kW/otg+GkbXwl6Uzvy9wsvHOX4nUoWldeZMg== + dependencies: + "@npmcli/fs" "^3.1.0" + fs-minipass "^3.0.0" + glob "^10.2.2" + lru-cache "^7.7.1" + minipass "^5.0.0" minipass-collect "^1.0.2" minipass-flush "^1.0.5" - minipass-pipeline "^1.2.2" - mkdirp "^1.0.3" + minipass-pipeline "^1.2.4" p-map "^4.0.0" - promise-inflight "^1.0.1" - rimraf "^3.0.2" - ssri "^8.0.1" - tar "^6.0.2" - unique-filename "^1.1.1" + ssri "^10.0.0" + tar "^6.1.11" + unique-filename "^3.0.0" chownr@^2.0.0: version "2.0.0" @@ -122,6 +143,18 @@ clean-stack@^2.0.0: resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + color-support@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" @@ -137,6 +170,15 @@ console-control-strings@^1.1.0: resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== +cross-spawn@^7.0.0: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + debug@4, debug@^4.1.0, debug@^4.3.3: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" @@ -149,17 +191,27 @@ delegates@^1.0.0: resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== -depd@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== +depd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== -encoding@^0.1.12: +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + +encoding@^0.1.13: version "0.1.13" resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== @@ -176,6 +228,19 @@ err-code@^2.0.2: resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== +exponential-backoff@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.1.tgz#64ac7526fe341ab18a39016cd22c787d01e00bf6" + integrity sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw== + +foreground-child@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" + integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== + dependencies: + cross-spawn "^7.0.0" + signal-exit "^4.0.1" + fs-minipass@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" @@ -183,6 +248,13 @@ fs-minipass@^2.0.0: dependencies: minipass "^3.0.0" +fs-minipass@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-3.0.2.tgz#5b383858efa8c1eb8c33b39e994f7e8555b8b3a3" + integrity sha512-2GAfyfoaCDRrM6jaOS3UsBts8yJ55VioXdWcOL7dK9zdAuKT71+WBA4ifnNYqVjYv+4SsPxjK0JT4yIIn4cA/g== + dependencies: + minipass "^5.0.0" + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -202,6 +274,17 @@ gauge@^4.0.3: strip-ansi "^6.0.1" wide-align "^1.1.5" +glob@^10.2.2: + version "10.3.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.3.tgz#8360a4ffdd6ed90df84aa8d52f21f452e86a123b" + integrity sha512-92vPiMb/iqpmEgsOoIDvTjc50wf9CCCvMzsi6W0JLPeUKE8TWP1a73PgqSrqy7iAZxaSD1YdzU7QZR5LF51MJw== + dependencies: + foreground-child "^3.1.0" + jackspeak "^2.0.3" + minimatch "^9.0.1" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-scurry "^1.10.1" + glob@^7.1.3, glob@^7.1.4: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" @@ -224,17 +307,17 @@ has-unicode@^2.0.1: resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== -http-cache-semantics@^4.1.0: +http-cache-semantics@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== -http-proxy-agent@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" - integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== +http-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" + integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w== dependencies: - "@tootallnate/once" "1" + "@tootallnate/once" "2" agent-base "6" debug "4" @@ -270,11 +353,6 @@ indent-string@^4.0.0: resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== -infer-owner@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" - integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== - inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -308,6 +386,15 @@ isexe@^2.0.0: resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== +jackspeak@^2.0.3: + version "2.2.2" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.2.2.tgz#707c62733924b8dc2a0a629dc6248577788b5385" + integrity sha512-mgNtVv4vUuaKA97yxUHoA3+FkuhtxkjdXEWOyB/N76fjy0FjezEt34oy3epBtvCvS+7DyKwqCFWx/oJLV5+kCg== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -315,27 +402,36 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -make-fetch-happen@^9.1.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz#53085a09e7971433e6765f7971bf63f4e05cb968" - integrity sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg== - dependencies: - agentkeepalive "^4.1.3" - cacache "^15.2.0" - http-cache-semantics "^4.1.0" - http-proxy-agent "^4.0.1" +lru-cache@^7.7.1: + version "7.18.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" + integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== + +"lru-cache@^9.1.1 || ^10.0.0": + version "10.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.0.tgz#b9e2a6a72a129d81ab317202d93c7691df727e61" + integrity sha512-svTf/fzsKHffP42sujkO/Rjs37BCIsQVRCeNYIm9WN8rgT7ffoUnRtZCqU+6BqcSBdv8gwJeTz8knJpgACeQMw== + +make-fetch-happen@^11.0.3: + version "11.1.1" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz#85ceb98079584a9523d4bf71d32996e7e208549f" + integrity sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w== + dependencies: + agentkeepalive "^4.2.1" + cacache "^17.0.0" + http-cache-semantics "^4.1.1" + http-proxy-agent "^5.0.0" https-proxy-agent "^5.0.0" is-lambda "^1.0.1" - lru-cache "^6.0.0" - minipass "^3.1.3" - minipass-collect "^1.0.2" - minipass-fetch "^1.3.2" + lru-cache "^7.7.1" + minipass "^5.0.0" + minipass-fetch "^3.0.0" minipass-flush "^1.0.5" minipass-pipeline "^1.2.4" - negotiator "^0.6.2" + negotiator "^0.6.3" promise-retry "^2.0.1" - socks-proxy-agent "^6.0.0" - ssri "^8.0.0" + socks-proxy-agent "^7.0.0" + ssri "^10.0.0" minimatch@^3.1.1: version "3.1.2" @@ -344,6 +440,13 @@ minimatch@^3.1.1: dependencies: brace-expansion "^1.1.7" +minimatch@^9.0.1: + version "9.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" + integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== + dependencies: + brace-expansion "^2.0.1" + minipass-collect@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" @@ -351,16 +454,16 @@ minipass-collect@^1.0.2: dependencies: minipass "^3.0.0" -minipass-fetch@^1.3.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-1.4.1.tgz#d75e0091daac1b0ffd7e9d41629faff7d0c1f1b6" - integrity sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw== +minipass-fetch@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-3.0.3.tgz#d9df70085609864331b533c960fd4ffaa78d15ce" + integrity sha512-n5ITsTkDqYkYJZjcRWzZt9qnZKCT7nKCosJhHoj7S7zD+BP4jVbWs+odsniw5TA3E0sLomhTKOKjF86wf11PuQ== dependencies: - minipass "^3.1.0" + minipass "^5.0.0" minipass-sized "^1.0.3" - minizlib "^2.0.0" + minizlib "^2.1.2" optionalDependencies: - encoding "^0.1.12" + encoding "^0.1.13" minipass-flush@^1.0.5: version "1.0.5" @@ -369,7 +472,7 @@ minipass-flush@^1.0.5: dependencies: minipass "^3.0.0" -minipass-pipeline@^1.2.2, minipass-pipeline@^1.2.4: +minipass-pipeline@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== @@ -383,7 +486,7 @@ minipass-sized@^1.0.3: dependencies: minipass "^3.0.0" -minipass@^3.0.0, minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3: +minipass@^3.0.0: version "3.3.6" resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== @@ -395,7 +498,17 @@ minipass@^4.0.0: resolved "https://registry.yarnpkg.com/minipass/-/minipass-4.0.3.tgz#00bfbaf1e16e35e804f4aa31a7c1f6b8d9f0ee72" integrity sha512-OW2r4sQ0sI+z5ckEt5c1Tri4xTgZwYDxpE54eqWlQloQRoWtXjqt9udJ5Z4dSv7wK+nfFI7FRXyCpBSft+gpFw== -minizlib@^2.0.0, minizlib@^2.1.1: +minipass@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" + integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== + +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0": + version "7.0.2" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.2.tgz#58a82b7d81c7010da5bd4b2c0c85ac4b4ec5131e" + integrity sha512-eL79dXrE1q9dBbDCLg7xfn/vl7MS4F1gvJAgjJrQli/jbQWdUttuVawphqpffoIYfRdq78LHx6GP4bU/EQ2ATA== + +minizlib@^2.1.1, minizlib@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== @@ -403,7 +516,7 @@ minizlib@^2.0.0, minizlib@^2.1.1: minipass "^3.0.0" yallist "^4.0.0" -mkdirp@^1.0.3, mkdirp@^1.0.4: +mkdirp@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== @@ -418,33 +531,34 @@ ms@^2.0.0: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -negotiator@^0.6.2: +negotiator@^0.6.3: version "0.6.3" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== -node-gyp@^8.4.1: - version "8.4.1" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-8.4.1.tgz#3d49308fc31f768180957d6b5746845fbd429937" - integrity sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w== +node-gyp@^9.4.0: + version "9.4.0" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-9.4.0.tgz#2a7a91c7cba4eccfd95e949369f27c9ba704f369" + integrity sha512-dMXsYP6gc9rRbejLXmTbVRYjAHw7ppswsKyMxuxJxxOHzluIO1rGp9TOQgjFJ+2MCqcOcQTOPB/8Xwhr+7s4Eg== dependencies: env-paths "^2.2.0" + exponential-backoff "^3.1.1" glob "^7.1.4" graceful-fs "^4.2.6" - make-fetch-happen "^9.1.0" - nopt "^5.0.0" + make-fetch-happen "^11.0.3" + nopt "^6.0.0" npmlog "^6.0.0" rimraf "^3.0.2" semver "^7.3.5" tar "^6.1.2" which "^2.0.2" -nopt@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" - integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== +nopt@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-6.0.0.tgz#245801d8ebf409c6df22ab9d95b65e1309cdb16d" + integrity sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g== dependencies: - abbrev "1" + abbrev "^1.0.0" npmlog@^6.0.0: version "6.0.2" @@ -475,10 +589,18 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== -promise-inflight@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" - integrity sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g== +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-scurry@^1.10.1: + version "1.10.1" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.1.tgz#9ba6bf5aa8500fe9fd67df4f0d9483b2b0bfc698" + integrity sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ== + dependencies: + lru-cache "^9.1.1 || ^10.0.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" promise-retry@^2.0.1: version "2.0.1" @@ -531,20 +653,37 @@ set-blocking@^2.0.0: resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + signal-exit@^3.0.7: version "3.0.7" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== +signal-exit@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== + smart-buffer@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== -socks-proxy-agent@^6.0.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz#2687a31f9d7185e38d530bef1944fe1f1496d6ce" - integrity sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ== +socks-proxy-agent@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz#dc069ecf34436621acb41e3efa66ca1b5fed15b6" + integrity sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww== dependencies: agent-base "^6.0.2" debug "^4.3.3" @@ -558,14 +697,14 @@ socks@^2.6.2: ip "^2.0.0" smart-buffer "^4.2.0" -ssri@^8.0.0, ssri@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" - integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ== +ssri@^10.0.0: + version "10.0.4" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-10.0.4.tgz#5a20af378be586df139ddb2dfb3bf992cf0daba6" + integrity sha512-12+IR2CB2C28MMAw0Ncqwj5QbTcs0nGIhgJzYWzDkb21vWmfNI83KS4f3Ci6GI98WreIfG7o9UXp3C0qbpA8nQ== dependencies: - minipass "^3.1.1" + minipass "^5.0.0" -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -574,6 +713,15 @@ ssri@^8.0.0, ssri@^8.0.1: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" +string-width@^5.0.1, string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== + dependencies: + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" + string_decoder@^1.1.1: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" @@ -581,14 +729,33 @@ string_decoder@^1.1.1: dependencies: safe-buffer "~5.2.0" -strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: ansi-regex "^5.0.1" -tar@^6.0.2, tar@^6.1.2: +strip-ansi@^7.0.1: + version "7.1.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== + dependencies: + ansi-regex "^6.0.1" + +tar@^6.1.11: + version "6.1.15" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.15.tgz#c9738b0b98845a3b344d334b8fa3041aaba53a69" + integrity sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A== + dependencies: + chownr "^2.0.0" + fs-minipass "^2.0.0" + minipass "^5.0.0" + minizlib "^2.1.1" + mkdirp "^1.0.3" + yallist "^4.0.0" + +tar@^6.1.2: version "6.1.13" resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.13.tgz#46e22529000f612180601a6fe0680e7da508847b" integrity sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw== @@ -600,17 +767,17 @@ tar@^6.0.2, tar@^6.1.2: mkdirp "^1.0.3" yallist "^4.0.0" -unique-filename@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" - integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== +unique-filename@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-3.0.0.tgz#48ba7a5a16849f5080d26c760c86cf5cf05770ea" + integrity sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g== dependencies: - unique-slug "^2.0.0" + unique-slug "^4.0.0" -unique-slug@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" - integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== +unique-slug@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-4.0.0.tgz#6bae6bb16be91351badd24cdce741f892a6532e3" + integrity sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ== dependencies: imurmurhash "^0.1.4" @@ -619,7 +786,7 @@ util-deprecate@^1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== -which@^2.0.2: +which@^2.0.1, which@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== @@ -633,6 +800,24 @@ wide-align@^1.1.5: dependencies: string-width "^1.0.2 || 2 || 3 || 4" +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== + dependencies: + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" diff --git a/build/npm/postinstall.js b/build/npm/postinstall.js index d9280ffb1eb87..09df602a3bf5d 100644 --- a/build/npm/postinstall.js +++ b/build/npm/postinstall.js @@ -53,7 +53,10 @@ function yarnInstall(dir, opts) { console.log(`Installing dependencies in ${dir} inside container ${process.env['VSCODE_REMOTE_DEPENDENCIES_CONTAINER_NAME']}...`); opts.cwd = root; - run('docker', ['run', '-e', 'GITHUB_TOKEN', '-e', 'npm_config_arch', '-v', `/mnt/vss/_work/1/s:/root/vscode`, '-v', `/mnt/vss/_work/1/s/.build/.netrc:/root/.netrc`, process.env['VSCODE_REMOTE_DEPENDENCIES_CONTAINER_NAME'], 'yarn', '--cwd', dir, ...args], opts); + if (process.env['npm_config_arch'] === 'arm64') { + run('sudo', ['docker', 'run', '--rm', '--privileged', 'multiarch/qemu-user-static', '--reset', '-p', 'yes'], opts); + } + run('sudo', ['docker', 'run', '-e', 'GITHUB_TOKEN', '-e', 'npm_config_arch', '-v', `${process.env['VSCODE_HOST_MOUNT']}:/root/vscode`, '-v', `${process.env['VSCODE_HOST_MOUNT']}/.build/.netrc:/root/.netrc`, process.env['VSCODE_REMOTE_DEPENDENCIES_CONTAINER_NAME'], 'yarn', '--cwd', dir, ...args], opts); run('sudo', ['chown', '-R', `${userinfo.uid}:${userinfo.gid}`, `${dir}/node_modules`], opts); } else { console.log(`Installing dependencies in ${dir}...`); diff --git a/build/npm/preinstall.js b/build/npm/preinstall.js index 79f2b629c5db9..b6a0a74678078 100644 --- a/build/npm/preinstall.js +++ b/build/npm/preinstall.js @@ -9,12 +9,14 @@ const majorNodeVersion = parseInt(nodeVersion[1]); const minorNodeVersion = parseInt(nodeVersion[2]); const patchNodeVersion = parseInt(nodeVersion[3]); -if (majorNodeVersion < 16 || (majorNodeVersion === 16 && minorNodeVersion < 17)) { - console.error('\033[1;31m*** Please use node.js versions >=16.17.x and <17.\033[0;0m'); - err = true; -} -if (majorNodeVersion >= 17) { - console.warn('\033[1;31m*** Warning: Versions of node.js >= 17 have not been tested.\033[0;0m') +if (!process.env['VSCODE_SKIP_NODE_VERSION_CHECK']) { + if (majorNodeVersion < 18 || (majorNodeVersion === 18 && minorNodeVersion < 15)) { + console.error('\033[1;31m*** Please use node.js versions >=18.15.x and <19.\033[0;0m'); + err = true; + } + if (majorNodeVersion >= 19) { + console.warn('\033[1;31m*** Warning: Versions of node.js >= 19 have not been tested.\033[0;0m') + } } const path = require('path'); @@ -123,7 +125,19 @@ function installHeaders() { cp.execFileSync(node_gyp, ['install', '--dist-url', local.disturl, local.target]); } - if (remote !== undefined && !versions.has(remote.target)) { + // Avoid downloading headers for Windows arm64 till we move to Nodejs v19 in remote + // which is the first official release with support for the architecture. Downloading + // the headers for older versions now redirect to https://origin.nodejs.org/404.html + // which causes checksum validation error in node-gyp. + // + // gyp http 200 https://origin.nodejs.org/404.html + // gyp WARN install got an error, rolling back install + // gyp ERR! install error + // gyp ERR! stack Error: win-arm64/node.lib local checksum 4c62bed7a032f7b36984321b7ffdd60b596fac870672037ff879ae9ac9548fb7 not match remote undefined + // + if (remote !== undefined && !versions.has(remote.target) && + process.env['npm_config_arch'] !== "arm64" && + process.arch !== "arm64") { // Both disturl and target come from a file checked into our repository cp.execFileSync(node_gyp, ['install', '--dist-url', remote.disturl, remote.target]); } diff --git a/build/package.json b/build/package.json index b1b4256942538..98d4b6578d18c 100644 --- a/build/package.json +++ b/build/package.json @@ -28,7 +28,7 @@ "@types/minimist": "^1.2.1", "@types/mkdirp": "^1.0.1", "@types/mocha": "^9.1.1", - "@types/node": "16.x", + "@types/node": "18.x", "@types/p-limit": "^2.2.0", "@types/pump": "^1.0.1", "@types/rimraf": "^2.0.4", diff --git a/build/win32/Cargo.lock b/build/win32/Cargo.lock index f83ae22dfc260..fb5217556906a 100644 --- a/build/win32/Cargo.lock +++ b/build/win32/Cargo.lock @@ -109,7 +109,7 @@ dependencies = [ [[package]] name = "inno_updater" -version = "0.10.0" +version = "0.10.1" dependencies = [ "byteorder", "crc", diff --git a/build/win32/Cargo.toml b/build/win32/Cargo.toml index faf7e7fe6d1a1..cf3cc9de80be5 100644 --- a/build/win32/Cargo.toml +++ b/build/win32/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "inno_updater" -version = "0.10.0" +version = "0.10.1" authors = ["Microsoft "] build = "build.rs" diff --git a/build/win32/code.iss b/build/win32/code.iss index 44c9f2f1f0b29..b7336831374b6 100644 --- a/build/win32/code.iss +++ b/build/win32/code.iss @@ -1362,12 +1362,6 @@ begin end; end; - if IsNotBackgroundUpdate() and CheckForMutexes('{#TunnelMutex}') then - begin - MsgBox('{#NameShort} is still running a tunnel. Please stop the tunnel before installing.', mbInformation, MB_OK); - Result := false - end; - end; function WizardNotSilent(): Boolean; @@ -1380,6 +1374,31 @@ end; var ShouldRestartTunnelService: Boolean; +function StopTunnelOtherProcesses(): Boolean; +var + WaitCounter: Integer; + TaskKilled: Integer; +begin + Log('Stopping all tunnel services (at ' + ExpandConstant('"{app}\bin\{#TunnelApplicationName}.exe"') + ')'); + ShellExec('', 'powershell.exe', '-Command "Get-WmiObject Win32_Process | Where-Object { $_.ExecutablePath -eq ' + ExpandConstant('''{app}\bin\{#TunnelApplicationName}.exe''') + ' } | Select @{Name=''Id''; Expression={$_.ProcessId}} | Stop-Process -Force"', '', SW_HIDE, ewWaitUntilTerminated, TaskKilled) + + WaitCounter := 10; + while (WaitCounter > 0) and CheckForMutexes('{#TunnelMutex}') do + begin + Log('Tunnel process is is still running, waiting'); + Sleep(500); + WaitCounter := WaitCounter - 1 + end; + + if CheckForMutexes('{#TunnelMutex}') then + begin + Log('Unable to stop tunnel processes'); + Result := False; + end + else + Result := True; +end; + procedure StopTunnelServiceIfNeeded(); var StopServiceResultCode: Integer; @@ -1413,7 +1432,11 @@ function PrepareToInstall(var NeedsRestart: Boolean): String; begin if IsNotBackgroundUpdate() then StopTunnelServiceIfNeeded(); - Result := '' + + if IsNotBackgroundUpdate() and not StopTunnelOtherProcesses() then + Result := '{#NameShort} is still running a tunnel process. Please stop the tunnel before installing.' + else + Result := ''; end; // VS Code will create a flag file before the update starts (/update=C:\foo\bar) @@ -1607,4 +1630,4 @@ begin #endif Exec(ExpandConstant('{sys}\icacls.exe'), ExpandConstant('"{app}" /inheritancelevel:r ') + Permissions, '', SW_HIDE, ewWaitUntilTerminated, ResultCode); -end; \ No newline at end of file +end; diff --git a/build/win32/inno_updater.exe b/build/win32/inno_updater.exe index 941ebfe408145..fa2fd26a466de 100644 Binary files a/build/win32/inno_updater.exe and b/build/win32/inno_updater.exe differ diff --git a/build/yarn.lock b/build/yarn.lock index 66ff004f40b48..0b3f151633bb8 100644 --- a/build/yarn.lock +++ b/build/yarn.lock @@ -546,10 +546,10 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.51.tgz#b31d716fb8d58eeb95c068a039b9b6292817d5fb" integrity sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ== -"@types/node@16.x": - version "16.18.3" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.3.tgz#d7f7ba828ad9e540270f01ce00d391c54e6e0abc" - integrity sha512-jh6m0QUhIRcZpNv7Z/rpN+ZWXOicUUQbSoWks7Htkbb9IjFQj4kzcX/xFCkjstCj5flMsN8FiSvt+q+Tcs4Llg== +"@types/node@18.x": + version "18.15.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" + integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== "@types/p-limit@^2.2.0": version "2.2.0" diff --git a/cglicenses.json b/cglicenses.json index 585a819df1e34..121cbc30c502e 100644 --- a/cglicenses.json +++ b/cglicenses.json @@ -530,5 +530,11 @@ "IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN", "CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." ] + }, + { + "name": "cacheable-request", + "prependLicenseText": [ + "Copyright (c) cacheable-request authors" + ] } ] diff --git a/cgmanifest.json b/cgmanifest.json index d5669cdf185e9..574ec75d24df9 100644 --- a/cgmanifest.json +++ b/cgmanifest.json @@ -6,7 +6,7 @@ "git": { "name": "chromium", "repositoryUrl": "https://chromium.googlesource.com/chromium/src", - "commitHash": "513ac8b2c47c7e1ac6b9f4fb5ea98e965cf29b66" + "commitHash": "88c0a3606e1a856ad43651130d27bb880e1833d6" } }, "licenseDetail": [ @@ -40,7 +40,7 @@ "SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ], "isOnlyProductionDependency": true, - "version": "108.0.5359.215" + "version": "114.0.5735.289" }, { "component": { @@ -48,7 +48,7 @@ "git": { "name": "ffmpeg", "repositoryUrl": "https://chromium.googlesource.com/chromium/third_party/ffmpeg", - "commitHash": "b9f01c3c54576330b2cf8918c54d5ee5be8faefe" + "commitHash": "8d21d41d8bec5c0b266ee305d1a708dc5c23b594" } }, "isOnlyProductionDependency": true, @@ -516,11 +516,11 @@ "git": { "name": "nodejs", "repositoryUrl": "https://github.com/nodejs/node", - "commitHash": "6b06e89c7dfccec6792008302af1cee57649445c" + "commitHash": "a94966ffc114e831d4a917a97f9958d3385ab6f7" } }, "isOnlyProductionDependency": true, - "version": "16.17.1" + "version": "18.15.0" }, { "component": { @@ -528,12 +528,12 @@ "git": { "name": "electron", "repositoryUrl": "https://github.com/electron/electron", - "commitHash": "4ade2a6fb65e4b723feb7c09a5df765e5006b378" + "commitHash": "34be316c404e84cdd967fa0e10fceeb6424eed90" } }, "isOnlyProductionDependency": true, "license": "MIT", - "version": "22.3.14" + "version": "25.5.0" }, { "component": { diff --git a/cli/Cargo.lock b/cli/Cargo.lock index 8e6e477991fc9..34627da135bbf 100644 --- a/cli/Cargo.lock +++ b/cli/Cargo.lock @@ -183,17 +183,6 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1181e1e0d1fce796a03db1ae795d67167da795f9cf4a39c37589e85ef57f26d3" -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", -] - [[package]] name = "autocfg" version = "1.1.0" @@ -301,11 +290,8 @@ checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" dependencies = [ "android-tzdata", "iana-time-zone", - "js-sys", "num-traits", "serde", - "time 0.1.44", - "wasm-bindgen", "winapi", ] @@ -356,7 +342,6 @@ name = "code-cli" version = "0.1.0" dependencies = [ "async-trait", - "atty", "base64 0.21.2", "bytes", "cfg-if", @@ -517,9 +502,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.12" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edbafec5fa1f196ca66527c1b12c2ec4745ca14b50f1ad8f9f6f720b55d11fac" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" dependencies = [ "cfg-if", ] @@ -536,9 +521,9 @@ dependencies = [ [[package]] name = "cxx" -version = "1.0.78" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19f39818dcfc97d45b03953c1292efc4e80954e1583c4aa770bac1383e2310a4" +checksum = "e88abab2f5abbe4c56e8f1fb431b784d710b709888f35755a160e62e33fe38e8" dependencies = [ "cc", "cxxbridge-flags", @@ -548,9 +533,9 @@ dependencies = [ [[package]] name = "cxx-build" -version = "1.0.78" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e580d70777c116df50c390d1211993f62d40302881e54d4b79727acb83d0199" +checksum = "5c0c11acd0e63bae27dcd2afced407063312771212b7a823b4fd72d633be30fb" dependencies = [ "cc", "codespan-reporting", @@ -558,24 +543,24 @@ dependencies = [ "proc-macro2", "quote", "scratch", - "syn 1.0.103", + "syn 2.0.18", ] [[package]] name = "cxxbridge-flags" -version = "1.0.78" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56a46460b88d1cec95112c8c363f0e2c39afdb237f60583b0b36343bf627ea9c" +checksum = "8d3816ed957c008ccd4728485511e3d9aaf7db419aa321e3d2c5a2f3411e36c8" [[package]] name = "cxxbridge-macro" -version = "1.0.78" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "747b608fecf06b0d72d440f27acc99288207324b793be2c17991839f3d4995ea" +checksum = "a26acccf6f445af85ea056362561a24ef56cdc15fcc685f03aec50b9c702cb6d" dependencies = [ "proc-macro2", "quote", - "syn 1.0.103", + "syn 2.0.18", ] [[package]] @@ -998,9 +983,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" dependencies = [ "bytes", "fnv", @@ -1069,23 +1054,23 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.51" +version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5a6ef98976b22b3b7f2f3a806f858cb862044cfa66805aa3ad84cb3d3b785ed" +checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "winapi", + "windows", ] [[package]] name = "iana-time-zone-haiku" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fde6edd6cef363e9359ed3c98ba64590ba9eecba2293eb5a723ab32aee8926aa" +checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" dependencies = [ "cxx", "cxx-build", @@ -1234,9 +1219,9 @@ checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" [[package]] name = "link-cplusplus" -version = "1.0.7" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369" +checksum = "9d240c6f7e1ba3a28b0249f774e6a9dd0175054b52dfbb61b16eb8505c3785c9" dependencies = [ "cc", ] @@ -1996,9 +1981,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "scratch" -version = "1.0.2" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" +checksum = "a3cf7c11c38cb994f3d40e8a8cde3bbd1f72a435e4c49e85d6553d8312306152" [[package]] name = "secret-service" @@ -2271,9 +2256,9 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.1.3" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" dependencies = [ "winapi-util", ] @@ -2298,17 +2283,6 @@ dependencies = [ "syn 2.0.18", ] -[[package]] -name = "time" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" -dependencies = [ - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi", -] - [[package]] name = "time" version = "0.3.21" @@ -2497,7 +2471,7 @@ dependencies = [ [[package]] name = "tunnels" version = "0.1.0" -source = "git+https://github.com/microsoft/dev-tunnels?rev=2621784a9ad72aa39500372391332a14bad581a3#2621784a9ad72aa39500372391332a14bad581a3" +source = "git+https://github.com/microsoft/dev-tunnels?rev=3141ad7be00e18c4231f7c4fb6c11f9219ac49af#3141ad7be00e18c4231f7c4fb6c11f9219ac49af" dependencies = [ "async-trait", "chrono", @@ -2649,12 +2623,6 @@ version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" -[[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -2790,6 +2758,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +dependencies = [ + "windows-targets 0.48.0", +] + [[package]] name = "windows-sys" version = "0.36.1" @@ -3100,7 +3077,7 @@ dependencies = [ "crc32fast", "crossbeam-utils", "flate2", - "time 0.3.21", + "time", ] [[package]] diff --git a/cli/Cargo.toml b/cli/Cargo.toml index d685d9efcbbe1..50fad68a8a46a 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -29,16 +29,15 @@ rmp-serde = "1.1.1" uuid = { version = "1.3.3", features = ["serde", "v4"] } dirs = "5.0.1" rand = "0.8.5" -atty = "0.2.14" opentelemetry = { version = "0.19.0", features = ["rt-tokio"] } serde_bytes = "0.11.9" -chrono = { version = "0.4.26", features = ["serde"] } +chrono = { version = "0.4.26", features = ["serde", "std", "clock"], default-features = false } gethostname = "0.4.3" libc = "0.2.144" -tunnels = { git = "https://github.com/microsoft/dev-tunnels", rev = "2621784a9ad72aa39500372391332a14bad581a3", default-features = false, features = ["connections"] } +tunnels = { git = "https://github.com/microsoft/dev-tunnels", rev = "3141ad7be00e18c4231f7c4fb6c11f9219ac49af", default-features = false, features = ["connections"] } keyring = { version = "2.0.3", default-features = false, features = ["linux-secret-service-rt-tokio-crypto-openssl"] } dialoguer = "0.10.4" -hyper = "0.14.26" +hyper = { version = "0.14.26", features = ["server", "http1", "runtime"] } indicatif = "0.17.4" tempfile = "3.5.0" clap_lex = "0.5.0" @@ -57,7 +56,7 @@ bytes = "1.4.0" tar = "0.4.38" [build-dependencies] -serde = "1.0.163" +serde = { version="1.0.163", features = ["derive"] } serde_json = "1.0.96" [target.'cfg(windows)'.dependencies] diff --git a/cli/ThirdPartyNotices.txt b/cli/ThirdPartyNotices.txt new file mode 100644 index 0000000000000..ba85a27096c6c --- /dev/null +++ b/cli/ThirdPartyNotices.txt @@ -0,0 +1,10946 @@ +NOTICES AND INFORMATION +Do Not Translate or Localize + +This software incorporates material from third parties. +Microsoft makes certain open source code available at https://3rdpartysource.microsoft.com, +or you may send a check or money order for US $5.00, including the product name, +the open source component name, platform, and version number, to: + +Source Code Compliance Team +Microsoft Corporation +One Microsoft Way +Redmond, WA 98052 +USA + +Notwithstanding any other terms, you may reverse engineer this software to the extent +required to debug changes to any libraries licensed under the GNU Lesser General Public License. + + + +--------------------------------------------------------- + +adler 1.0.2 - 0BSD OR MIT OR Apache-2.0 +https://github.com/jonas-schievink/adler + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +aho-corasick 1.0.1 - Unlicense OR MIT +https://github.com/BurntSushi/aho-corasick + +The MIT License (MIT) + +Copyright (c) 2015 Andrew Gallant + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +android-tzdata 0.1.1 - MIT OR Apache-2.0 +https://github.com/RumovZ/android-tzdata + +MIT License + +Copyright (c) [year] [fullname] + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +android_system_properties 0.1.5 - MIT/Apache-2.0 +https://github.com/nical/android_system_properties + +The MIT License (MIT) + +Copyright (c) 2013 Nicolas Silva + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +anstream 0.3.2 - MIT OR Apache-2.0 +https://github.com/rust-cli/anstyle + +This software is released under the MIT license: + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +anstyle 1.0.0 - MIT OR Apache-2.0 +https://github.com/rust-cli/anstyle + +This software is released under the MIT license: + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +anstyle-parse 0.2.0 - MIT OR Apache-2.0 +https://github.com/rust-cli/anstyle + +This software is released under the MIT license: + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +anstyle-query 1.0.0 - MIT OR Apache-2.0 +https://github.com/rust-cli/anstyle + +This software is released under the MIT license: + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +anstyle-wincon 1.0.1 - MIT OR Apache-2.0 +https://github.com/rust-cli/anstyle + +This software is released under the MIT license: + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +async-broadcast 0.5.1 - MIT OR Apache-2.0 +https://github.com/smol-rs/async-broadcast + +The MIT License (MIT) + +Copyright (c) 2020 Yoshua Wuyts + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +async-channel 1.8.0 - Apache-2.0 OR MIT +https://github.com/smol-rs/async-channel + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +async-io 1.9.0 - Apache-2.0 OR MIT +https://github.com/smol-rs/async-io + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +async-lock 2.7.0 - Apache-2.0 OR MIT +https://github.com/smol-rs/async-lock + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +async-process 1.7.0 - Apache-2.0 OR MIT +https://github.com/smol-rs/async-process + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +async-recursion 1.0.0 - MIT OR Apache-2.0 +https://github.com/dcchut/async-recursion + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +async-task 4.4.0 - Apache-2.0 OR MIT +https://github.com/smol-rs/async-task + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +async-trait 0.1.68 - MIT OR Apache-2.0 +https://github.com/dtolnay/async-trait + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +atomic-waker 1.1.1 - Apache-2.0 OR MIT +https://github.com/smol-rs/atomic-waker + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +atty 0.2.14 - MIT +https://github.com/softprops/atty + +The MIT License (MIT) + +Copyright (c) 2015-2019 Doug Tangren + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +autocfg 1.1.0 - Apache-2.0 OR MIT +https://github.com/cuviper/autocfg + +Copyright (c) 2018 Josh Stone + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +base64 0.13.0 - MIT/Apache-2.0 +base64 0.21.2 - MIT OR Apache-2.0 +https://github.com/marshallpierce/rust-base64 + +The MIT License (MIT) + +Copyright (c) 2015 Alice Maz + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +bit-vec 0.6.3 - MIT/Apache-2.0 +https://github.com/contain-rs/bit-vec + +Copyright (c) 2023 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +bitflags 1.3.2 - MIT/Apache-2.0 +https://github.com/bitflags/bitflags + +Copyright (c) 2014 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +block-buffer 0.10.3 - MIT OR Apache-2.0 +https://github.com/RustCrypto/utils + +All crates licensed under either of + + * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) + * [MIT license](http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. + +[//]: # (badges) + +[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg +[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260052-utils +[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg +[deps-image]: https://deps.rs/repo/github/RustCrypto/utils/status.svg +[deps-link]: https://deps.rs/repo/github/RustCrypto/utils + +[msrv-1.39]: https://img.shields.io/badge/rustc-1.39.0+-blue.svg +[msrv-1.40]: https://img.shields.io/badge/rustc-1.40.0+-blue.svg +[msrv-1.41]: https://img.shields.io/badge/rustc-1.41.0+-blue.svg +[msrv-1.45]: https://img.shields.io/badge/rustc-1.45.0+-blue.svg +[msrv-1.51]: https://img.shields.io/badge/rustc-1.51.0+-blue.svg +[msrv-1.56]: https://img.shields.io/badge/rustc-1.56.0+-blue.svg +[msrv-1.57]: https://img.shields.io/badge/rustc-1.57.0+-blue.svg +[msrv-1.59]: https://img.shields.io/badge/rustc-1.59.0+-blue.svg +[msrv-1.60]: https://img.shields.io/badge/rustc-1.60.0+-blue.svg + +[//]: # (crates) + +[`blobby`]: ./blobby +[`block-buffer`]: ./block-buffer +[`blockā€‘padding`]: ./block-padding +[`cmov`]: ./cmov +[`collectable`]: ./collectable +[`cpufeatures`]: ./cpufeatures +[`dbl`]: ./dbl +[`hex-literal`]: ./hex-literal +[`inout`]: ./inout +[`opaque-debug`]: ./opaque-debug +[`wycheproof2blb`]: ./wycheproof2blb +[`zeroize`]: ./zeroize + +[//]: # (misc) + +[Wycheproof]: https://github.com/google/wycheproof +--------------------------------------------------------- + +--------------------------------------------------------- + +block-padding 0.3.2 - MIT OR Apache-2.0 +https://github.com/RustCrypto/utils + +All crates licensed under either of + + * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) + * [MIT license](http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. + +[//]: # (badges) + +[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg +[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260052-utils +[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg +[deps-image]: https://deps.rs/repo/github/RustCrypto/utils/status.svg +[deps-link]: https://deps.rs/repo/github/RustCrypto/utils + +[msrv-1.39]: https://img.shields.io/badge/rustc-1.39.0+-blue.svg +[msrv-1.40]: https://img.shields.io/badge/rustc-1.40.0+-blue.svg +[msrv-1.41]: https://img.shields.io/badge/rustc-1.41.0+-blue.svg +[msrv-1.45]: https://img.shields.io/badge/rustc-1.45.0+-blue.svg +[msrv-1.51]: https://img.shields.io/badge/rustc-1.51.0+-blue.svg +[msrv-1.56]: https://img.shields.io/badge/rustc-1.56.0+-blue.svg +[msrv-1.57]: https://img.shields.io/badge/rustc-1.57.0+-blue.svg +[msrv-1.59]: https://img.shields.io/badge/rustc-1.59.0+-blue.svg +[msrv-1.60]: https://img.shields.io/badge/rustc-1.60.0+-blue.svg + +[//]: # (crates) + +[`blobby`]: ./blobby +[`block-buffer`]: ./block-buffer +[`blockā€‘padding`]: ./block-padding +[`cmov`]: ./cmov +[`collectable`]: ./collectable +[`cpufeatures`]: ./cpufeatures +[`dbl`]: ./dbl +[`hex-literal`]: ./hex-literal +[`inout`]: ./inout +[`opaque-debug`]: ./opaque-debug +[`wycheproof2blb`]: ./wycheproof2blb +[`zeroize`]: ./zeroize + +[//]: # (misc) + +[Wycheproof]: https://github.com/google/wycheproof +--------------------------------------------------------- + +--------------------------------------------------------- + +blocking 1.3.1 - Apache-2.0 OR MIT +https://github.com/smol-rs/blocking + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +bumpalo 3.12.0 - MIT/Apache-2.0 +https://github.com/fitzgen/bumpalo + +Copyright (c) 2019 Nick Fitzgerald + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +byteorder 1.4.3 - Unlicense OR MIT +https://github.com/BurntSushi/byteorder + +The MIT License (MIT) + +Copyright (c) 2015 Andrew Gallant + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +bytes 1.4.0 - MIT +https://github.com/tokio-rs/bytes + +The MIT License (MIT) + +Copyright (c) 2018 Carl Lerche + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +cache-padded 1.2.0 - Apache-2.0 OR MIT +https://github.com/smol-rs/cache-padded + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +cc 1.0.73 - MIT/Apache-2.0 +https://github.com/rust-lang/cc-rs + +Copyright (c) 2014 Alex Crichton + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +cfg-if 1.0.0 - MIT/Apache-2.0 +https://github.com/alexcrichton/cfg-if + +Copyright (c) 2014 Alex Crichton + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +chrono 0.4.26 - MIT/Apache-2.0 +https://github.com/chronotope/chrono + +Rust-chrono is dual-licensed under The MIT License [1] and +Apache 2.0 License [2]. Copyright (c) 2014--2017, Kang Seonghoon and +contributors. + +Nota Bene: This is same as the Rust Project's own license. + + +[1]: , which is reproduced below: + +~~~~ +The MIT License (MIT) + +Copyright (c) 2014, Kang Seonghoon. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +~~~~ + + +[2]: , which is reproduced below: + +~~~~ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +~~~~ +--------------------------------------------------------- + +--------------------------------------------------------- + +clap 4.3.0 - MIT OR Apache-2.0 +https://github.com/clap-rs/clap + +Copyright (c) Individual contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +clap_builder 4.3.0 - MIT OR Apache-2.0 +https://github.com/clap-rs/clap + +Copyright (c) Individual contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +clap_derive 4.3.0 - MIT OR Apache-2.0 +https://github.com/clap-rs/clap/tree/master/clap_derive + +Copyright (c) Individual contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +clap_lex 0.5.0 - MIT OR Apache-2.0 +https://github.com/clap-rs/clap/tree/master/clap_lex + +Copyright (c) Individual contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +codespan-reporting 0.11.1 - Apache-2.0 +https://github.com/brendanzab/codespan + +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--------------------------------------------------------- + +--------------------------------------------------------- + +colorchoice 1.0.0 - MIT OR Apache-2.0 +https://github.com/rust-cli/anstyle + +This software is released under the MIT license: + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +concurrent-queue 1.2.4 - Apache-2.0 OR MIT +concurrent-queue 2.2.0 - Apache-2.0 OR MIT +https://github.com/smol-rs/concurrent-queue + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +console 0.15.7 - MIT +https://github.com/console-rs/console + +The MIT License (MIT) + +Copyright (c) 2017 Armin Ronacher + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +const_format 0.2.31 - Zlib +https://github.com/rodrimati1992/const_format_crates/ + +Copyright (c) 2020 Matias Rodriguez. + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +--------------------------------------------------------- + +--------------------------------------------------------- + +const_format_proc_macros 0.2.31 - Zlib +https://github.com/rodrimati1992/const_format_crates/ + +Copyright (c) 2020 Matias Rodriguez. + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +--------------------------------------------------------- + +--------------------------------------------------------- + +core-foundation 0.9.3 - MIT / Apache-2.0 +https://github.com/servo/core-foundation-rs + +Copyright (c) 2012-2013 Mozilla Foundation + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +core-foundation-sys 0.8.3 - MIT / Apache-2.0 +https://github.com/servo/core-foundation-rs + +Copyright (c) 2012-2013 Mozilla Foundation + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +cpufeatures 0.2.8 - MIT OR Apache-2.0 +https://github.com/RustCrypto/utils + +All crates licensed under either of + + * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) + * [MIT license](http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. + +[//]: # (badges) + +[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg +[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260052-utils +[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg +[deps-image]: https://deps.rs/repo/github/RustCrypto/utils/status.svg +[deps-link]: https://deps.rs/repo/github/RustCrypto/utils + +[msrv-1.39]: https://img.shields.io/badge/rustc-1.39.0+-blue.svg +[msrv-1.40]: https://img.shields.io/badge/rustc-1.40.0+-blue.svg +[msrv-1.41]: https://img.shields.io/badge/rustc-1.41.0+-blue.svg +[msrv-1.45]: https://img.shields.io/badge/rustc-1.45.0+-blue.svg +[msrv-1.51]: https://img.shields.io/badge/rustc-1.51.0+-blue.svg +[msrv-1.56]: https://img.shields.io/badge/rustc-1.56.0+-blue.svg +[msrv-1.57]: https://img.shields.io/badge/rustc-1.57.0+-blue.svg +[msrv-1.59]: https://img.shields.io/badge/rustc-1.59.0+-blue.svg +[msrv-1.60]: https://img.shields.io/badge/rustc-1.60.0+-blue.svg + +[//]: # (crates) + +[`blobby`]: ./blobby +[`block-buffer`]: ./block-buffer +[`blockā€‘padding`]: ./block-padding +[`cmov`]: ./cmov +[`collectable`]: ./collectable +[`cpufeatures`]: ./cpufeatures +[`dbl`]: ./dbl +[`hex-literal`]: ./hex-literal +[`inout`]: ./inout +[`opaque-debug`]: ./opaque-debug +[`wycheproof2blb`]: ./wycheproof2blb +[`zeroize`]: ./zeroize + +[//]: # (misc) + +[Wycheproof]: https://github.com/google/wycheproof +--------------------------------------------------------- + +--------------------------------------------------------- + +crc32fast 1.3.2 - MIT OR Apache-2.0 +https://github.com/srijs/rust-crc32fast + +MIT License + +Copyright (c) 2018 Sam Rijs, Alex Crichton and contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +crossbeam-channel 0.5.6 - MIT OR Apache-2.0 +https://github.com/crossbeam-rs/crossbeam + +The MIT License (MIT) + +Copyright (c) 2019 The Crossbeam Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +crossbeam-utils 0.8.12 - MIT OR Apache-2.0 +https://github.com/crossbeam-rs/crossbeam + +The MIT License (MIT) + +Copyright (c) 2019 The Crossbeam Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +crypto-common 0.1.6 - MIT OR Apache-2.0 +https://github.com/RustCrypto/traits + +All crates licensed under either of + + * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) + * [MIT license](http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. + +[//]: # (badges) + +[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg +[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260050-traits +[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg +[deps-image]: https://deps.rs/repo/github/RustCrypto/traits/status.svg +[deps-link]: https://deps.rs/repo/github/RustCrypto/traits +[msrv-1.56]: https://img.shields.io/badge/rustc-1.56.0+-blue.svg +[msrv-1.57]: https://img.shields.io/badge/rustc-1.57.0+-blue.svg +[msrv-1.60]: https://img.shields.io/badge/rustc-1.60.0+-blue.svg +[msrv-1.65]: https://img.shields.io/badge/rustc-1.65.0+-blue.svg + +[//]: # (crates) + +[`aead`]: ./aead +[`asyncā€‘signature`]: ./signature/async +[`cipher`]: ./cipher +[`cryptoā€‘common`]: ./crypto-common +[`crypto`]: ./crypto +[`digest`]: ./digest +[`ellipticā€‘curve`]: ./elliptic-curve +[`kem`]: ./kem +[`password-hash`]: ./password-hash +[`signature`]: ./signature +[`universalā€‘hash`]: ./universal-hash + +[//]: # (algorithms) + +[Authenticated encryption]: https://en.wikipedia.org/wiki/Authenticated_encryption +[Block]: https://en.wikipedia.org/wiki/Block_cipher +[Message authentication code]: https://en.wikipedia.org/wiki/Message_authentication_code +[Cryptographic hash function]: https://en.wikipedia.org/wiki/Cryptographic_hash_function +[Digital signature]: https://en.wikipedia.org/wiki/Digital_signature +[Elliptic curve cryptography]: https://en.wikipedia.org/wiki/Elliptic-curve_cryptography +[Key encapsulation mechanism]: https://en.wikipedia.org/wiki/Key_encapsulation +[Password hashing]: https://en.wikipedia.org/wiki/Cryptographic_hash_function#Password_verification +[Stream cipher]: https://en.wikipedia.org/wiki/Stream_cipher +[Universal hash function]: https://en.wikipedia.org/wiki/Universal_hashing +--------------------------------------------------------- + +--------------------------------------------------------- + +cxx 1.0.78 - MIT OR Apache-2.0 +https://github.com/dtolnay/cxx + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +cxx-build 1.0.78 - MIT OR Apache-2.0 +https://github.com/dtolnay/cxx + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +cxxbridge-flags 1.0.78 - MIT OR Apache-2.0 +https://github.com/dtolnay/cxx + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +cxxbridge-macro 1.0.78 - MIT OR Apache-2.0 +https://github.com/dtolnay/cxx + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +data-encoding 2.3.2 - MIT +https://github.com/ia0/data-encoding + +The MIT License (MIT) + +Copyright (c) 2015-2020 Julien Cretin +Copyright (c) 2017-2020 Google Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +derivative 2.2.0 - MIT/Apache-2.0 +https://github.com/mcarton/rust-derivative + +Copyright (c) 2016 Martin Carton + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +dialoguer 0.10.4 - MIT +https://github.com/mitsuhiko/dialoguer + +The MIT License (MIT) + +Copyright (c) 2017 Armin Ronacher + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +digest 0.10.5 - MIT OR Apache-2.0 +https://github.com/RustCrypto/traits + +All crates licensed under either of + + * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) + * [MIT license](http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. + +[//]: # (badges) + +[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg +[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260050-traits +[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg +[deps-image]: https://deps.rs/repo/github/RustCrypto/traits/status.svg +[deps-link]: https://deps.rs/repo/github/RustCrypto/traits +[msrv-1.56]: https://img.shields.io/badge/rustc-1.56.0+-blue.svg +[msrv-1.57]: https://img.shields.io/badge/rustc-1.57.0+-blue.svg +[msrv-1.60]: https://img.shields.io/badge/rustc-1.60.0+-blue.svg +[msrv-1.65]: https://img.shields.io/badge/rustc-1.65.0+-blue.svg + +[//]: # (crates) + +[`aead`]: ./aead +[`asyncā€‘signature`]: ./signature/async +[`cipher`]: ./cipher +[`cryptoā€‘common`]: ./crypto-common +[`crypto`]: ./crypto +[`digest`]: ./digest +[`ellipticā€‘curve`]: ./elliptic-curve +[`kem`]: ./kem +[`password-hash`]: ./password-hash +[`signature`]: ./signature +[`universalā€‘hash`]: ./universal-hash + +[//]: # (algorithms) + +[Authenticated encryption]: https://en.wikipedia.org/wiki/Authenticated_encryption +[Block]: https://en.wikipedia.org/wiki/Block_cipher +[Message authentication code]: https://en.wikipedia.org/wiki/Message_authentication_code +[Cryptographic hash function]: https://en.wikipedia.org/wiki/Cryptographic_hash_function +[Digital signature]: https://en.wikipedia.org/wiki/Digital_signature +[Elliptic curve cryptography]: https://en.wikipedia.org/wiki/Elliptic-curve_cryptography +[Key encapsulation mechanism]: https://en.wikipedia.org/wiki/Key_encapsulation +[Password hashing]: https://en.wikipedia.org/wiki/Cryptographic_hash_function#Password_verification +[Stream cipher]: https://en.wikipedia.org/wiki/Stream_cipher +[Universal hash function]: https://en.wikipedia.org/wiki/Universal_hashing +--------------------------------------------------------- + +--------------------------------------------------------- + +dirs 4.0.0 - MIT OR Apache-2.0 +dirs 5.0.1 - MIT OR Apache-2.0 +https://github.com/dirs-dev/dirs-rs + +Copyright (c) 2018-2019 dirs-rs contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +dirs-sys 0.3.7 - MIT OR Apache-2.0 +dirs-sys 0.4.1 - MIT OR Apache-2.0 +https://github.com/dirs-dev/dirs-sys-rs + +Copyright (c) 2018-2019 dirs-rs contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +encode_unicode 0.3.6 - MIT/Apache-2.0 +https://github.com/tormol/encode_unicode + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE +--------------------------------------------------------- + +--------------------------------------------------------- + +encoding_rs 0.8.31 - (Apache-2.0 OR MIT) AND BSD-3-Clause +https://github.com/hsivonen/encoding_rs + +Copyright Mozilla Foundation + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +enumflags2 0.7.7 - MIT OR Apache-2.0 +https://github.com/meithecatte/enumflags2 + +Copyright (c) 2017-2023 Maik Klein, Maja Kądziołka + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +enumflags2_derive 0.7.7 - MIT OR Apache-2.0 +https://github.com/meithecatte/enumflags2 + +Copyright (c) 2017-2023 Maik Klein, Maja Kądziołka + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +errno 0.3.1 - MIT OR Apache-2.0 +https://github.com/lambda-fairy/rust-errno + +Copyright (c) 2014 Chris Wong + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +errno-dragonfly 0.1.2 - MIT +https://github.com/mneumann/errno-dragonfly-rs + +MIT License + +Copyright (c) 2017 Michael Neumann + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +event-listener 2.5.3 - Apache-2.0 OR MIT +https://github.com/smol-rs/event-listener + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +fastrand 1.8.0 - Apache-2.0 OR MIT +https://github.com/smol-rs/fastrand + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +filetime 0.2.17 - MIT/Apache-2.0 +https://github.com/alexcrichton/filetime + +Copyright (c) 2014 Alex Crichton + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +flate2 1.0.26 - MIT OR Apache-2.0 +https://github.com/rust-lang/flate2-rs + +Copyright (c) 2014 Alex Crichton + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +fnv 1.0.7 - Apache-2.0 / MIT +https://github.com/servo/rust-fnv + +Copyright (c) 2017 Contributors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +foreign-types 0.3.2 - MIT/Apache-2.0 +https://github.com/sfackler/foreign-types + +Copyright (c) 2017 The foreign-types Developers + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +foreign-types-shared 0.1.1 - MIT/Apache-2.0 +https://github.com/sfackler/foreign-types + +Copyright (c) 2017 The foreign-types Developers + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +form_urlencoded 1.1.0 - MIT OR Apache-2.0 +https://github.com/servo/rust-url + +Copyright (c) 2013-2022 The rust-url developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +futures 0.3.28 - MIT OR Apache-2.0 +https://github.com/rust-lang/futures-rs + +Copyright (c) 2016 Alex Crichton +Copyright (c) 2017 The Tokio Authors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +futures-channel 0.3.28 - MIT OR Apache-2.0 +https://github.com/rust-lang/futures-rs + +Copyright (c) 2016 Alex Crichton +Copyright (c) 2017 The Tokio Authors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +futures-core 0.3.28 - MIT OR Apache-2.0 +https://github.com/rust-lang/futures-rs + +Copyright (c) 2016 Alex Crichton +Copyright (c) 2017 The Tokio Authors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +futures-executor 0.3.28 - MIT OR Apache-2.0 +https://github.com/rust-lang/futures-rs + +Copyright (c) 2016 Alex Crichton +Copyright (c) 2017 The Tokio Authors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +futures-io 0.3.28 - MIT OR Apache-2.0 +https://github.com/rust-lang/futures-rs + +Copyright (c) 2016 Alex Crichton +Copyright (c) 2017 The Tokio Authors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +futures-lite 1.12.0 - Apache-2.0 OR MIT +https://github.com/smol-rs/futures-lite + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +futures-macro 0.3.28 - MIT OR Apache-2.0 +https://github.com/rust-lang/futures-rs + +Copyright (c) 2016 Alex Crichton +Copyright (c) 2017 The Tokio Authors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +futures-sink 0.3.28 - MIT OR Apache-2.0 +https://github.com/rust-lang/futures-rs + +Copyright (c) 2016 Alex Crichton +Copyright (c) 2017 The Tokio Authors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +futures-task 0.3.28 - MIT OR Apache-2.0 +https://github.com/rust-lang/futures-rs + +Copyright (c) 2016 Alex Crichton +Copyright (c) 2017 The Tokio Authors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +futures-util 0.3.28 - MIT OR Apache-2.0 +https://github.com/rust-lang/futures-rs + +Copyright (c) 2016 Alex Crichton +Copyright (c) 2017 The Tokio Authors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +generic-array 0.14.6 - MIT +https://github.com/fizyk20/generic-array + +The MIT License (MIT) + +Copyright (c) 2015 Bartłomiej Kamiński + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +gethostname 0.4.3 - Apache-2.0 +https://github.com/swsnr/gethostname.rs + +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +--------------------------------------------------------- + +--------------------------------------------------------- + +getrandom 0.1.16 - MIT OR Apache-2.0 +getrandom 0.2.7 - MIT OR Apache-2.0 +https://github.com/rust-random/getrandom + +Copyright 2018 Developers of the Rand project +Copyright (c) 2014 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +h2 0.3.17 - MIT +https://github.com/hyperium/h2 + +The MIT License (MIT) + +Copyright (c) 2017 h2 authors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +hashbrown 0.12.3 - MIT OR Apache-2.0 +https://github.com/rust-lang/hashbrown + +Copyright (c) 2016 Amanieu d'Antras + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +heck 0.4.0 - MIT OR Apache-2.0 +https://github.com/withoutboats/heck + +Copyright (c) 2015 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +hermit-abi 0.1.19 - MIT/Apache-2.0 +hermit-abi 0.3.1 - MIT OR Apache-2.0 +https://github.com/hermitcore/rusty-hermit + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +hex 0.4.3 - MIT OR Apache-2.0 +https://github.com/KokaKiwi/rust-hex + +Copyright (c) 2013-2014 The Rust Project Developers. +Copyright (c) 2015-2020 The rust-hex Developers + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +hex-literal 0.3.4 - MIT OR Apache-2.0 +https://github.com/RustCrypto/utils + +All crates licensed under either of + + * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) + * [MIT license](http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. + +[//]: # (badges) + +[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg +[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260052-utils +[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg +[deps-image]: https://deps.rs/repo/github/RustCrypto/utils/status.svg +[deps-link]: https://deps.rs/repo/github/RustCrypto/utils + +[msrv-1.39]: https://img.shields.io/badge/rustc-1.39.0+-blue.svg +[msrv-1.40]: https://img.shields.io/badge/rustc-1.40.0+-blue.svg +[msrv-1.41]: https://img.shields.io/badge/rustc-1.41.0+-blue.svg +[msrv-1.45]: https://img.shields.io/badge/rustc-1.45.0+-blue.svg +[msrv-1.51]: https://img.shields.io/badge/rustc-1.51.0+-blue.svg +[msrv-1.56]: https://img.shields.io/badge/rustc-1.56.0+-blue.svg +[msrv-1.57]: https://img.shields.io/badge/rustc-1.57.0+-blue.svg +[msrv-1.59]: https://img.shields.io/badge/rustc-1.59.0+-blue.svg +[msrv-1.60]: https://img.shields.io/badge/rustc-1.60.0+-blue.svg + +[//]: # (crates) + +[`blobby`]: ./blobby +[`block-buffer`]: ./block-buffer +[`blockā€‘padding`]: ./block-padding +[`cmov`]: ./cmov +[`collectable`]: ./collectable +[`cpufeatures`]: ./cpufeatures +[`dbl`]: ./dbl +[`hex-literal`]: ./hex-literal +[`inout`]: ./inout +[`opaque-debug`]: ./opaque-debug +[`wycheproof2blb`]: ./wycheproof2blb +[`zeroize`]: ./zeroize + +[//]: # (misc) + +[Wycheproof]: https://github.com/google/wycheproof +--------------------------------------------------------- + +--------------------------------------------------------- + +hmac 0.12.1 - MIT OR Apache-2.0 +https://github.com/RustCrypto/MACs + +All crates licensed under either of + +* [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) +* [MIT license](http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. + +[//]: # (badges) + +[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg +[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260044-MACs +[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg +[deps-image]: https://deps.rs/repo/github/RustCrypto/MACs/status.svg +[deps-link]: https://deps.rs/repo/github/RustCrypto/MACs +[msrv-1.41]: https://img.shields.io/badge/rustc-1.41.0+-blue.svg +[msrv-1.56]: https://img.shields.io/badge/rustc-1.56.0+-blue.svg +[msrv-1.57]: https://img.shields.io/badge/rustc-1.57.0+-blue.svg + +[//]: # (crates) + +[`belt-mac`]: ./belt-mac +[`cbc-mac`]: ./cbc-mac +[`cmac`]: ./cmac +[`hmac`]: ./hmac +[`pmac`]: ./pmac + +[//]: # (footnotes) + +[1]: https://en.wikipedia.org/wiki/Message_authentication_code + +[//]: # (algorithms) + +[BelT MAC]: https://apmi.bsu.by/assets/files/std/belt-spec371.pdf +[CBC-MAC]: https://en.wikipedia.org/wiki/CBC-MAC +[CMAC]: https://en.wikipedia.org/wiki/One-key_MAC +[HMAC]: https://en.wikipedia.org/wiki/HMAC +[PMAC]: https://en.wikipedia.org/wiki/PMAC_(cryptography) +--------------------------------------------------------- + +--------------------------------------------------------- + +http 0.2.8 - MIT OR Apache-2.0 +https://github.com/hyperium/http + +Copyright (c) 2017 http-rs authors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +http-body 0.4.5 - MIT +https://github.com/hyperium/http-body + +The MIT License (MIT) + +Copyright (c) 2019 Hyper Contributors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +httparse 1.8.0 - MIT/Apache-2.0 +https://github.com/seanmonstar/httparse + +Copyright (c) 2015-2021 Sean McArthur + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +httpdate 1.0.2 - MIT/Apache-2.0 +https://github.com/pyfisch/httpdate + +Copyright (c) 2016 Pyfisch + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +hyper 0.14.26 - MIT +https://github.com/hyperium/hyper + +The MIT License (MIT) + +Copyright (c) 2014-2021 Sean McArthur + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +hyper-tls 0.5.0 - MIT/Apache-2.0 +https://github.com/hyperium/hyper-tls + +Copyright (c) 2017 Sean McArthur + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +iana-time-zone 0.1.51 - MIT OR Apache-2.0 +https://github.com/strawlab/iana-time-zone + +Copyright (c) 2020 Andrew D. Straw + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +iana-time-zone-haiku 0.1.0 - MIT OR Apache-2.0 +https://github.com/strawlab/iana-time-zone + +Copyright (c) 2020 Andrew D. Straw + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +idna 0.3.0 - MIT OR Apache-2.0 +https://github.com/servo/rust-url/ + +Copyright (c) 2013-2022 The rust-url developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +indexmap 1.9.1 - Apache-2.0 OR MIT +https://github.com/bluss/indexmap + +Copyright (c) 2016--2017 + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +indicatif 0.17.4 - MIT +https://github.com/console-rs/indicatif + +The MIT License (MIT) + +Copyright (c) 2017 Armin Ronacher + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +inout 0.1.3 - MIT OR Apache-2.0 +https://github.com/RustCrypto/utils + +All crates licensed under either of + + * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) + * [MIT license](http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. + +[//]: # (badges) + +[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg +[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260052-utils +[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg +[deps-image]: https://deps.rs/repo/github/RustCrypto/utils/status.svg +[deps-link]: https://deps.rs/repo/github/RustCrypto/utils + +[msrv-1.39]: https://img.shields.io/badge/rustc-1.39.0+-blue.svg +[msrv-1.40]: https://img.shields.io/badge/rustc-1.40.0+-blue.svg +[msrv-1.41]: https://img.shields.io/badge/rustc-1.41.0+-blue.svg +[msrv-1.45]: https://img.shields.io/badge/rustc-1.45.0+-blue.svg +[msrv-1.51]: https://img.shields.io/badge/rustc-1.51.0+-blue.svg +[msrv-1.56]: https://img.shields.io/badge/rustc-1.56.0+-blue.svg +[msrv-1.57]: https://img.shields.io/badge/rustc-1.57.0+-blue.svg +[msrv-1.59]: https://img.shields.io/badge/rustc-1.59.0+-blue.svg +[msrv-1.60]: https://img.shields.io/badge/rustc-1.60.0+-blue.svg + +[//]: # (crates) + +[`blobby`]: ./blobby +[`block-buffer`]: ./block-buffer +[`blockā€‘padding`]: ./block-padding +[`cmov`]: ./cmov +[`collectable`]: ./collectable +[`cpufeatures`]: ./cpufeatures +[`dbl`]: ./dbl +[`hex-literal`]: ./hex-literal +[`inout`]: ./inout +[`opaque-debug`]: ./opaque-debug +[`wycheproof2blb`]: ./wycheproof2blb +[`zeroize`]: ./zeroize + +[//]: # (misc) + +[Wycheproof]: https://github.com/google/wycheproof +--------------------------------------------------------- + +--------------------------------------------------------- + +instant 0.1.12 - BSD-3-Clause +https://github.com/sebcrozet/instant + +Copyright (c) 2019, SĆ©bastien Crozet +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the author nor the names of its contributors may be used + to endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------- + +--------------------------------------------------------- + +io-lifetimes 1.0.11 - Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT +https://github.com/sunfishcode/io-lifetimes + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +ipnet 2.5.0 - MIT OR Apache-2.0 +https://github.com/krisprice/ipnet + +Copyright 2017 Juniper Networks, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +is-docker 0.2.0 - MIT +https://github.com/TheLarkInn/is-docker + +MIT License + +Copyright (c) 2023 Sean Larkin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +is-terminal 0.4.7 - MIT +https://github.com/sunfishcode/is-terminal + +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +is-wsl 0.4.0 - MIT +https://github.com/TheLarkInn/is-wsl + +MIT License + +Copyright (c) 2023 Sean Larkin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +itoa 1.0.4 - MIT OR Apache-2.0 +https://github.com/dtolnay/itoa + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +js-sys 0.3.60 - MIT/Apache-2.0 +https://github.com/rustwasm/wasm-bindgen/tree/master/crates/js-sys + +Copyright (c) 2014 Alex Crichton + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +keyring 2.0.3 - MIT OR Apache-2.0 +https://github.com/hwchen/keyring-rs + +Copyright (c) 2016 keyring Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +lazy_static 1.4.0 - MIT/Apache-2.0 +https://github.com/rust-lang-nursery/lazy-static.rs + +Copyright (c) 2010 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +libc 0.2.144 - MIT OR Apache-2.0 +https://github.com/rust-lang/libc + +Copyright (c) 2014-2020 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +link-cplusplus 1.0.7 - MIT OR Apache-2.0 +https://github.com/dtolnay/link-cplusplus + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +linux-keyutils 0.2.3 - Apache-2.0 OR MIT +https://github.com/landhb/linux-keyutils + +Licensed under either of the following at your discretion: + + * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) + * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you shall be dual licensed as above, without any +additional terms or conditions. + +[//]: # (badges) +[license-badge]: https://img.shields.io/badge/license-MIT/Apache--2.0-lightgray.svg?style=flat-square +[license]: #license +[rust-version-badge]: https://img.shields.io/badge/rust-latest%20stable-blue.svg?style=flat-square +[rust-version]: #rust-version-policy +[cargo-badge-lib]: https://img.shields.io/crates/v/linux-keyutils.svg?style=flat-square&label=linux-keyutils +[cargo-lib]: https://crates.io/crates/linux-keyutils +[docs-badge-lib]: https://img.shields.io/docsrs/linux-keyutils/latest?style=flat-square +[docs-lib]: https://docs.rs/linux-keyutils +[codecov]: https://img.shields.io/codecov/c/github/landhb/linux-keyutils?style=flat-square +[codecov-url]: https://codecov.io/gh/landhb/linux-keyutils +[build]: https://img.shields.io/github/actions/workflow/status/landhb/linux-keyutils/checks.yml?branch=main&style=flat-square +[build-url]: https://github.com/landhb/linux-keyutils/actions?query=workflow%3Achecks +--------------------------------------------------------- + +--------------------------------------------------------- + +linux-raw-sys 0.3.8 - Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT +https://github.com/sunfishcode/linux-raw-sys + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +lock_api 0.4.9 - MIT OR Apache-2.0 +https://github.com/Amanieu/parking_lot + +Copyright (c) 2016 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +log 0.4.18 - MIT OR Apache-2.0 +https://github.com/rust-lang/log + +Copyright (c) 2014 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +md5 0.7.0 - Apache-2.0/MIT +https://github.com/stainless-steel/md5 + +The project is dual licensed under the terms of the Apache License, Version 2.0, +and the MIT License. You may obtain copies of the two licenses at + +* https://www.apache.org/licenses/LICENSE-2.0 and +* https://opensource.org/licenses/MIT, respectively. + +The following two notices apply to every file of the project. + +## The Apache License + +``` +Copyright 2015ā€“2019 The md5 Developers + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed +under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. +``` + +## The MIT License + +``` +Copyright 2015ā€“2019 The md5 Developers + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +``` +--------------------------------------------------------- + +--------------------------------------------------------- + +memchr 2.5.0 - Unlicense/MIT +https://github.com/BurntSushi/memchr + +The MIT License (MIT) + +Copyright (c) 2015 Andrew Gallant + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +memoffset 0.7.1 - MIT +https://github.com/Gilnaa/memoffset + +The MIT License (MIT) + +Copyright (c) 2017 Gilad Naaman + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +mime 0.3.16 - MIT/Apache-2.0 +https://github.com/hyperium/mime + +Copyright (c) 2014-2019 Sean McArthur + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +miniz_oxide 0.7.1 - MIT OR Zlib OR Apache-2.0 +https://github.com/Frommi/miniz_oxide/tree/master/miniz_oxide + +This library (excluding the miniz C code used for tests) is licensed under the MIT license. The library is based on the miniz C library, of which the parts used are dual-licensed under the [MIT license](https://github.com/Frommi/miniz_oxide/blob/master/miniz/miniz.c#L1) and also the [unlicense](https://github.com/Frommi/miniz_oxide/blob/master/miniz/miniz.c#L577). +The parts of miniz that are not covered by the unlicense is [some Zip64 code](https://github.com/richgel999/miniz/commit/224d207ce8fffb908e156d27478be3afb5d83e6a#diff-edc0e9ccfae3b5324b85b3ec0a53dc74) which is only MIT licensed. This and other Zip functionality in miniz is not part of the miniz_oxidde and miniz_oxide_c_api rust libraries. +--------------------------------------------------------- + +--------------------------------------------------------- + +mio 0.8.4 - MIT +https://github.com/tokio-rs/mio + +The MIT License (MIT) + +Copyright (c) 2014 Carl Lerche and other MIO contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +native-tls 0.2.10 - MIT/Apache-2.0 +https://github.com/sfackler/rust-native-tls + +Copyright (c) 2016 The rust-native-tls Developers + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +nix 0.26.2 - MIT +https://github.com/nix-rust/nix + +The MIT License (MIT) + +Copyright (c) 2015 Carl Lerche + nix-rust Authors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +ntapi 0.4.0 - Apache-2.0 OR MIT +https://github.com/MSxDOS/ntapi + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"),to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +num 0.4.0 - MIT OR Apache-2.0 +https://github.com/rust-num/num + +Copyright (c) 2014 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +num-bigint 0.4.3 - MIT OR Apache-2.0 +https://github.com/rust-num/num-bigint + +Copyright (c) 2014 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +num-complex 0.4.2 - MIT OR Apache-2.0 +https://github.com/rust-num/num-complex + +Copyright (c) 2014 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +num-integer 0.1.45 - MIT OR Apache-2.0 +https://github.com/rust-num/num-integer + +Copyright (c) 2014 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +num-iter 0.1.43 - MIT OR Apache-2.0 +https://github.com/rust-num/num-iter + +Copyright (c) 2014 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +num-rational 0.4.1 - MIT OR Apache-2.0 +https://github.com/rust-num/num-rational + +Copyright (c) 2014 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +num-traits 0.2.15 - MIT OR Apache-2.0 +https://github.com/rust-num/num-traits + +Copyright (c) 2014 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +num_cpus 1.13.1 - MIT OR Apache-2.0 +https://github.com/seanmonstar/num_cpus + +Copyright (c) 2015 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +number_prefix 0.4.0 - MIT +https://github.com/ogham/rust-number-prefix + +MIT License + +Copyright (c) 2018 Benjamin Sago + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +once_cell 1.17.2 - MIT OR Apache-2.0 +https://github.com/matklad/once_cell + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +open 4.1.0 - MIT +https://github.com/Byron/open-rs + +The MIT License (MIT) + +Copyright Ā© `2015` `Sebastian Thiel` + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +openssl 0.10.55 - Apache-2.0 +https://github.com/sfackler/rust-openssl + +Copyright 2011-2017 Google Inc. + 2013 Jack Lloyd + 2013-2014 Steven Fackler + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +--------------------------------------------------------- + +--------------------------------------------------------- + +openssl-macros 0.1.0 - MIT/Apache-2.0 + + +This software is released under the MIT license: + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +openssl-probe 0.1.5 - MIT/Apache-2.0 +https://github.com/alexcrichton/openssl-probe + +Copyright (c) 2014 Alex Crichton + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +openssl-sys 0.9.90 - MIT +https://github.com/sfackler/rust-openssl + +The MIT License (MIT) + +Copyright (c) 2014 Alex Crichton + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +opentelemetry 0.19.0 - Apache-2.0 +https://github.com/open-telemetry/opentelemetry-rust + +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright The OpenTelemetry Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--------------------------------------------------------- + +--------------------------------------------------------- + +opentelemetry_api 0.19.0 - Apache-2.0 +https://github.com/open-telemetry/opentelemetry-rust + +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright The OpenTelemetry Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--------------------------------------------------------- + +--------------------------------------------------------- + +opentelemetry_sdk 0.19.0 - Apache-2.0 +https://github.com/open-telemetry/opentelemetry-rust + +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright The OpenTelemetry Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--------------------------------------------------------- + +--------------------------------------------------------- + +option-ext 0.2.0 - MPL-2.0 +https://github.com/soc/option-ext + +Mozilla Public License Version 2.0 +================================== + +1. Definitions +-------------- + +1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or + + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +1.6. "Executable Form" + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +1.8. "License" + means this document. + +1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + +1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +1.13. "Source Code Form" + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; + or + +(b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +* * +* 6. Disclaimer of Warranty * +* ------------------------- * +* * +* Covered Software is provided under this License on an "as is" * +* basis, without warranty of any kind, either expressed, implied, or * +* statutory, including, without limitation, warranties that the * +* Covered Software is free of defects, merchantable, fit for a * +* particular purpose or non-infringing. The entire risk as to the * +* quality and performance of the Covered Software is with You. * +* Should any Covered Software prove defective in any respect, You * +* (not any Contributor) assume the cost of any necessary servicing, * +* repair, or correction. This disclaimer of warranty constitutes an * +* essential part of this License. No use of any Covered Software is * +* authorized under this License except under this disclaimer. * +* * +************************************************************************ + +************************************************************************ +* * +* 7. Limitation of Liability * +* -------------------------- * +* * +* Under no circumstances and under no legal theory, whether tort * +* (including negligence), contract, or otherwise, shall any * +* Contributor, or anyone who distributes Covered Software as * +* permitted above, be liable to You for any direct, indirect, * +* special, incidental, or consequential damages of any character * +* including, without limitation, damages for lost profits, loss of * +* goodwill, work stoppage, computer failure or malfunction, or any * +* and all other commercial damages or losses, even if such party * +* shall have been informed of the possibility of such damages. This * +* limitation of liability shall not apply to liability for death or * +* personal injury resulting from such party's negligence to the * +* extent applicable law prohibits such limitation. Some * +* jurisdictions do not allow the exclusion or limitation of * +* incidental or consequential damages, so this exclusion and * +* limitation may not apply to You. * +* * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at https://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice +--------------------------------------------------------- + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. +--------------------------------------------------------- + +--------------------------------------------------------- + +ordered-stream 0.2.0 - MIT OR Apache-2.0 +https://github.com/danieldg/ordered-stream + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +parking 2.0.0 - Apache-2.0 OR MIT +https://github.com/smol-rs/parking + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +parking_lot 0.12.1 - MIT OR Apache-2.0 +https://github.com/Amanieu/parking_lot + +Copyright (c) 2016 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +parking_lot_core 0.9.3 - MIT OR Apache-2.0 +https://github.com/Amanieu/parking_lot + +Copyright (c) 2016 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +paste 1.0.9 - MIT OR Apache-2.0 +https://github.com/dtolnay/paste + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +pathdiff 0.2.1 - MIT/Apache-2.0 +https://github.com/Manishearth/pathdiff + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +percent-encoding 2.2.0 - MIT OR Apache-2.0 +https://github.com/servo/rust-url/ + +Copyright (c) 2013-2022 The rust-url developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +pin-project 1.1.0 - Apache-2.0 OR MIT +https://github.com/taiki-e/pin-project + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +pin-project-internal 1.1.0 - Apache-2.0 OR MIT +https://github.com/taiki-e/pin-project + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +pin-project-lite 0.2.9 - Apache-2.0 OR MIT +https://github.com/taiki-e/pin-project-lite + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +pin-utils 0.1.0 - MIT OR Apache-2.0 +https://github.com/rust-lang/pin-utils + +Copyright (c) 2018 The pin-utils authors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +pkg-config 0.3.25 - MIT OR Apache-2.0 +https://github.com/rust-lang/pkg-config-rs + +Copyright (c) 2014 Alex Crichton + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +polling 2.3.0 - Apache-2.0 OR MIT +https://github.com/smol-rs/polling + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +portable-atomic 1.3.3 - Apache-2.0 OR MIT +https://github.com/taiki-e/portable-atomic + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +ppv-lite86 0.2.16 - MIT/Apache-2.0 +https://github.com/cryptocorrosion/cryptocorrosion + +Copyright (c) 2019 The CryptoCorrosion Contributors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +proc-macro-crate 1.2.1 - Apache-2.0/MIT +https://github.com/bkchr/proc-macro-crate + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +proc-macro2 1.0.59 - MIT OR Apache-2.0 +https://github.com/dtolnay/proc-macro2 + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +quote 1.0.28 - MIT OR Apache-2.0 +https://github.com/dtolnay/quote + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +rand 0.7.3 - MIT OR Apache-2.0 +rand 0.8.5 - MIT OR Apache-2.0 +https://github.com/rust-random/rand + +Copyright 2018 Developers of the Rand project +Copyright (c) 2014 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +rand_chacha 0.2.2 - MIT OR Apache-2.0 +rand_chacha 0.3.1 - MIT OR Apache-2.0 +https://github.com/rust-random/rand + +Copyright 2018 Developers of the Rand project +Copyright (c) 2014 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +rand_core 0.5.1 - MIT OR Apache-2.0 +rand_core 0.6.4 - MIT OR Apache-2.0 +https://github.com/rust-random/rand + +Copyright 2018 Developers of the Rand project +Copyright (c) 2014 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +rand_hc 0.2.0 - MIT/Apache-2.0 +https://github.com/rust-random/rngs + +Copyright 2018 Developers of the Rand project +Copyright (c) 2014 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +redox_syscall 0.2.16 - MIT +redox_syscall 0.3.5 - MIT +https://github.com/redox-os/syscall + +Copyright (c) 2017 Redox OS Developers + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +redox_users 0.4.3 - MIT +https://gitlab.redox-os.org/redox-os/users + +The MIT License (MIT) + +Copyright (c) 2017 Jose Narvaez + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +regex 1.8.3 - MIT OR Apache-2.0 +https://github.com/rust-lang/regex + +Copyright (c) 2014 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +regex-syntax 0.7.2 - MIT OR Apache-2.0 +https://github.com/rust-lang/regex/tree/master/regex-syntax + +Copyright (c) 2014 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +reqwest 0.11.18 - MIT OR Apache-2.0 +https://github.com/seanmonstar/reqwest + +Copyright (c) 2016 Sean McArthur + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +rmp 0.8.11 - MIT +https://github.com/3Hren/msgpack-rust + +MIT License + +Copyright (c) 2017 Evgeny Safronov + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +rmp-serde 1.1.1 - MIT +https://github.com/3Hren/msgpack-rust + +MIT License + +Copyright (c) 2017 Evgeny Safronov + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +russh 6a15199c784c0b6d171a6fec09ed730a5cd1350d +https://github.com/microsoft/vscode-russh + +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--------------------------------------------------------- + +--------------------------------------------------------- + +russh-cryptovec 6a15199c784c0b6d171a6fec09ed730a5cd1350d +https://github.com/microsoft/vscode-russh + +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--------------------------------------------------------- + +--------------------------------------------------------- + +russh-keys 6a15199c784c0b6d171a6fec09ed730a5cd1350d +https://github.com/microsoft/vscode-russh + +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--------------------------------------------------------- + +--------------------------------------------------------- + +rustix 0.37.19 - Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT +https://github.com/bytecodealliance/rustix + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +ryu 1.0.11 - Apache-2.0 OR BSL-1.0 +https://github.com/dtolnay/ryu + + +Licensed under either of Apache License, Version +2.0 (LICENSE-APACHE) or Boost Software License 1.0 (LICENSE-BOOST) at your +option. + + +
+ + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in this crate by you, as defined in the Apache-2.0 license, shall +be dual licensed as above, without any additional terms or conditions. + +--------------------------------------------------------- + +--------------------------------------------------------- + +schannel 0.1.20 - MIT +https://github.com/steffengy/schannel-rs + +The MIT License (MIT) + +Copyright (c) 2015 steffengy + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +scopeguard 1.1.0 - MIT/Apache-2.0 +https://github.com/bluss/scopeguard + +Copyright (c) 2016-2019 Ulrik Sverdrup "bluss" and scopeguard developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +scratch 1.0.2 - MIT OR Apache-2.0 +https://github.com/dtolnay/scratch + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +secret-service 3.0.1 - MIT OR Apache-2.0 +https://github.com/hwchen/secret-service-rs + +Copyright (c) 2016 secret-service Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +security-framework 2.7.0 - MIT OR Apache-2.0 +https://github.com/kornelski/rust-security-framework + +The MIT License (MIT) + +Copyright (c) 2015 Steven Fackler + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +security-framework-sys 2.6.1 - MIT OR Apache-2.0 +https://github.com/kornelski/rust-security-framework + +The MIT License (MIT) + +Copyright (c) 2015 Steven Fackler + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +serde 1.0.163 - MIT OR Apache-2.0 +https://github.com/serde-rs/serde + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +serde_bytes 0.11.9 - MIT OR Apache-2.0 +https://github.com/serde-rs/bytes + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +serde_derive 1.0.163 - MIT OR Apache-2.0 +https://github.com/serde-rs/serde + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +serde_json 1.0.96 - MIT OR Apache-2.0 +https://github.com/serde-rs/json + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +serde_repr 0.1.9 - MIT OR Apache-2.0 +https://github.com/dtolnay/serde-repr + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +serde_urlencoded 0.7.1 - MIT/Apache-2.0 +https://github.com/nox/serde_urlencoded + +Copyright (c) 2016 Anthony Ramine + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +sha-1 0.10.0 - MIT OR Apache-2.0 +https://github.com/RustCrypto/hashes + +All crates licensed under either of + + * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) + * [MIT license](http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. + +[//]: # (badges) + +[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg +[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260041-hashes +[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg +[deps-image]: https://deps.rs/repo/github/RustCrypto/hashes/status.svg +[deps-link]: https://deps.rs/repo/github/RustCrypto/hashes +[msrv-1.41]: https://img.shields.io/badge/rustc-1.41.0+-blue.svg +[msrv-1.56]: https://img.shields.io/badge/rustc-1.56.0+-blue.svg +[msrv-1.57]: https://img.shields.io/badge/rustc-1.57.0+-blue.svg + +[//]: # (crates) + +[`asconā€‘hash`]: ./ascon-hash +[`beltā€‘hash`]: ./belt-hash +[`blake2`]: ./blake2 +[`fsb`]: ./fsb +[`gost94`]: ./gost94 +[`groestl`]: ./groestl +[`jh`]: ./jh +[`k12`]: ./k12 +[`md2`]: ./md2 +[`md4`]: ./md4 +[`md5`]: ./md5 +[`ripemd`]: ./ripemd +[`sha1`]: ./sha1 +[`sha2`]: ./sha2 +[`sha3`]: ./sha3 +[`shabal`]: ./shabal +[`skein`]: ./skein +[`sm3`]: ./sm3 +[`streebog`]: ./streebog +[`tiger`]: ./tiger +[`whirlpool`]: ./whirlpool + +[//]: # (footnotes) + +[1]: https://en.wikipedia.org/wiki/Cryptographic_hash_function +[`blake3`]: https://github.com/BLAKE3-team/BLAKE3 +[`base16ct`]: https://docs.rs/base16ct +[`base64ct`]: https://docs.rs/base64ct +[`digest`]: https://docs.rs/digest +[`Digest`]: https://docs.rs/digest/0.10.0/digest/trait.Digest.html +[`Digest::digest`]: https://docs.rs/digest/0.10.0/digest/trait.Digest.html#tymethod.digest +[`DynDigest`]: https://docs.rs/digest/0.10.0/digest/trait.DynDigest.html +[`generic-array`]: https://docs.rs/generic-array +[HMAC]: https://en.wikipedia.org/wiki/Hash-based_message_authentication_code +[`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html +[`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html +[`hmac`]: https://docs.rs/hmac +[RustCrypto/MACs]: https://github.com/RustCrypto/MACs + +[//]: # (algorithms) + +[Ascon]: https://ascon.iaik.tugraz.at +[BelT]: https://ru.wikipedia.org/wiki/BelT +[BLAKE2]: https://en.wikipedia.org/wiki/BLAKE_(hash_function)#BLAKE2 +[FSB]: https://en.wikipedia.org/wiki/Fast_syndrome-based_hash +[GOST94]: https://en.wikipedia.org/wiki/GOST_(hash_function) +[GrĆøstl]: https://en.wikipedia.org/wiki/GrĆøstl +[JH]: https://www3.ntu.edu.sg/home/wuhj/research/jh +[KangarooTwelve]: https://keccak.team/kangarootwelve.html +[MD2]: https://en.wikipedia.org/wiki/MD2_(cryptography) +[MD4]: https://en.wikipedia.org/wiki/MD4 +[MD5]: https://en.wikipedia.org/wiki/MD5 +[RIPEMD]: https://en.wikipedia.org/wiki/RIPEMD +[SHA-1]: https://en.wikipedia.org/wiki/SHA-1 +[SHA-2]: https://en.wikipedia.org/wiki/SHA-2 +[SHA-3]: https://en.wikipedia.org/wiki/SHA-3 +[SHABAL]: https://www.cs.rit.edu/~ark/20090927/Round2Candidates/Shabal.pdf +[Skein]: https://schneier.com/academic/skein +[SM3]: https://en.wikipedia.org/wiki/SM3_(hash_function) +[Streebog]: https://en.wikipedia.org/wiki/Streebog +[Whirlpool]: https://en.wikipedia.org/wiki/Whirlpool_(cryptography) +[Tiger]: http://www.cs.technion.ac.il/~biham/Reports/Tiger/tiger/tiger.html +--------------------------------------------------------- + +--------------------------------------------------------- + +sha1 0.10.5 - MIT OR Apache-2.0 +https://github.com/RustCrypto/hashes + +All crates licensed under either of + + * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) + * [MIT license](http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. + +[//]: # (badges) + +[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg +[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260041-hashes +[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg +[deps-image]: https://deps.rs/repo/github/RustCrypto/hashes/status.svg +[deps-link]: https://deps.rs/repo/github/RustCrypto/hashes +[msrv-1.41]: https://img.shields.io/badge/rustc-1.41.0+-blue.svg +[msrv-1.56]: https://img.shields.io/badge/rustc-1.56.0+-blue.svg +[msrv-1.57]: https://img.shields.io/badge/rustc-1.57.0+-blue.svg + +[//]: # (crates) + +[`asconā€‘hash`]: ./ascon-hash +[`beltā€‘hash`]: ./belt-hash +[`blake2`]: ./blake2 +[`fsb`]: ./fsb +[`gost94`]: ./gost94 +[`groestl`]: ./groestl +[`jh`]: ./jh +[`k12`]: ./k12 +[`md2`]: ./md2 +[`md4`]: ./md4 +[`md5`]: ./md5 +[`ripemd`]: ./ripemd +[`sha1`]: ./sha1 +[`sha2`]: ./sha2 +[`sha3`]: ./sha3 +[`shabal`]: ./shabal +[`skein`]: ./skein +[`sm3`]: ./sm3 +[`streebog`]: ./streebog +[`tiger`]: ./tiger +[`whirlpool`]: ./whirlpool + +[//]: # (footnotes) + +[1]: https://en.wikipedia.org/wiki/Cryptographic_hash_function +[`blake3`]: https://github.com/BLAKE3-team/BLAKE3 +[`base16ct`]: https://docs.rs/base16ct +[`base64ct`]: https://docs.rs/base64ct +[`digest`]: https://docs.rs/digest +[`Digest`]: https://docs.rs/digest/0.10.0/digest/trait.Digest.html +[`Digest::digest`]: https://docs.rs/digest/0.10.0/digest/trait.Digest.html#tymethod.digest +[`DynDigest`]: https://docs.rs/digest/0.10.0/digest/trait.DynDigest.html +[`generic-array`]: https://docs.rs/generic-array +[HMAC]: https://en.wikipedia.org/wiki/Hash-based_message_authentication_code +[`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html +[`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html +[`hmac`]: https://docs.rs/hmac +[RustCrypto/MACs]: https://github.com/RustCrypto/MACs + +[//]: # (algorithms) + +[Ascon]: https://ascon.iaik.tugraz.at +[BelT]: https://ru.wikipedia.org/wiki/BelT +[BLAKE2]: https://en.wikipedia.org/wiki/BLAKE_(hash_function)#BLAKE2 +[FSB]: https://en.wikipedia.org/wiki/Fast_syndrome-based_hash +[GOST94]: https://en.wikipedia.org/wiki/GOST_(hash_function) +[GrĆøstl]: https://en.wikipedia.org/wiki/GrĆøstl +[JH]: https://www3.ntu.edu.sg/home/wuhj/research/jh +[KangarooTwelve]: https://keccak.team/kangarootwelve.html +[MD2]: https://en.wikipedia.org/wiki/MD2_(cryptography) +[MD4]: https://en.wikipedia.org/wiki/MD4 +[MD5]: https://en.wikipedia.org/wiki/MD5 +[RIPEMD]: https://en.wikipedia.org/wiki/RIPEMD +[SHA-1]: https://en.wikipedia.org/wiki/SHA-1 +[SHA-2]: https://en.wikipedia.org/wiki/SHA-2 +[SHA-3]: https://en.wikipedia.org/wiki/SHA-3 +[SHABAL]: https://www.cs.rit.edu/~ark/20090927/Round2Candidates/Shabal.pdf +[Skein]: https://schneier.com/academic/skein +[SM3]: https://en.wikipedia.org/wiki/SM3_(hash_function) +[Streebog]: https://en.wikipedia.org/wiki/Streebog +[Whirlpool]: https://en.wikipedia.org/wiki/Whirlpool_(cryptography) +[Tiger]: http://www.cs.technion.ac.il/~biham/Reports/Tiger/tiger/tiger.html +--------------------------------------------------------- + +--------------------------------------------------------- + +sha2 0.10.6 - MIT OR Apache-2.0 +https://github.com/RustCrypto/hashes + +All crates licensed under either of + + * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) + * [MIT license](http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. + +[//]: # (badges) + +[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg +[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260041-hashes +[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg +[deps-image]: https://deps.rs/repo/github/RustCrypto/hashes/status.svg +[deps-link]: https://deps.rs/repo/github/RustCrypto/hashes +[msrv-1.41]: https://img.shields.io/badge/rustc-1.41.0+-blue.svg +[msrv-1.56]: https://img.shields.io/badge/rustc-1.56.0+-blue.svg +[msrv-1.57]: https://img.shields.io/badge/rustc-1.57.0+-blue.svg + +[//]: # (crates) + +[`asconā€‘hash`]: ./ascon-hash +[`beltā€‘hash`]: ./belt-hash +[`blake2`]: ./blake2 +[`fsb`]: ./fsb +[`gost94`]: ./gost94 +[`groestl`]: ./groestl +[`jh`]: ./jh +[`k12`]: ./k12 +[`md2`]: ./md2 +[`md4`]: ./md4 +[`md5`]: ./md5 +[`ripemd`]: ./ripemd +[`sha1`]: ./sha1 +[`sha2`]: ./sha2 +[`sha3`]: ./sha3 +[`shabal`]: ./shabal +[`skein`]: ./skein +[`sm3`]: ./sm3 +[`streebog`]: ./streebog +[`tiger`]: ./tiger +[`whirlpool`]: ./whirlpool + +[//]: # (footnotes) + +[1]: https://en.wikipedia.org/wiki/Cryptographic_hash_function +[`blake3`]: https://github.com/BLAKE3-team/BLAKE3 +[`base16ct`]: https://docs.rs/base16ct +[`base64ct`]: https://docs.rs/base64ct +[`digest`]: https://docs.rs/digest +[`Digest`]: https://docs.rs/digest/0.10.0/digest/trait.Digest.html +[`Digest::digest`]: https://docs.rs/digest/0.10.0/digest/trait.Digest.html#tymethod.digest +[`DynDigest`]: https://docs.rs/digest/0.10.0/digest/trait.DynDigest.html +[`generic-array`]: https://docs.rs/generic-array +[HMAC]: https://en.wikipedia.org/wiki/Hash-based_message_authentication_code +[`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html +[`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html +[`hmac`]: https://docs.rs/hmac +[RustCrypto/MACs]: https://github.com/RustCrypto/MACs + +[//]: # (algorithms) + +[Ascon]: https://ascon.iaik.tugraz.at +[BelT]: https://ru.wikipedia.org/wiki/BelT +[BLAKE2]: https://en.wikipedia.org/wiki/BLAKE_(hash_function)#BLAKE2 +[FSB]: https://en.wikipedia.org/wiki/Fast_syndrome-based_hash +[GOST94]: https://en.wikipedia.org/wiki/GOST_(hash_function) +[GrĆøstl]: https://en.wikipedia.org/wiki/GrĆøstl +[JH]: https://www3.ntu.edu.sg/home/wuhj/research/jh +[KangarooTwelve]: https://keccak.team/kangarootwelve.html +[MD2]: https://en.wikipedia.org/wiki/MD2_(cryptography) +[MD4]: https://en.wikipedia.org/wiki/MD4 +[MD5]: https://en.wikipedia.org/wiki/MD5 +[RIPEMD]: https://en.wikipedia.org/wiki/RIPEMD +[SHA-1]: https://en.wikipedia.org/wiki/SHA-1 +[SHA-2]: https://en.wikipedia.org/wiki/SHA-2 +[SHA-3]: https://en.wikipedia.org/wiki/SHA-3 +[SHABAL]: https://www.cs.rit.edu/~ark/20090927/Round2Candidates/Shabal.pdf +[Skein]: https://schneier.com/academic/skein +[SM3]: https://en.wikipedia.org/wiki/SM3_(hash_function) +[Streebog]: https://en.wikipedia.org/wiki/Streebog +[Whirlpool]: https://en.wikipedia.org/wiki/Whirlpool_(cryptography) +[Tiger]: http://www.cs.technion.ac.il/~biham/Reports/Tiger/tiger/tiger.html +--------------------------------------------------------- + +--------------------------------------------------------- + +shell-escape 0.1.5 - MIT/Apache-2.0 +https://github.com/sfackler/shell-escape + +Copyright (c) 2014 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +shell-words 1.1.0 - MIT/Apache-2.0 +https://github.com/tmiasko/shell-words + +Copyright (c) 2016 Tomasz Miąsko + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +signal-hook 0.3.15 - Apache-2.0/MIT +https://github.com/vorner/signal-hook + +Copyright (c) 2017 tokio-jsonrpc developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +signal-hook-registry 1.4.0 - Apache-2.0/MIT +https://github.com/vorner/signal-hook + +Copyright (c) 2017 tokio-jsonrpc developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +slab 0.4.7 - MIT +https://github.com/tokio-rs/slab + +The MIT License (MIT) + +Copyright (c) 2019 Carl Lerche + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +smallvec 1.10.0 - MIT OR Apache-2.0 +https://github.com/servo/rust-smallvec + +Copyright (c) 2018 The Servo Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +socket2 0.4.9 - MIT OR Apache-2.0 +https://github.com/rust-lang/socket2 + +Copyright (c) 2014 Alex Crichton + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +static_assertions 1.1.0 - MIT OR Apache-2.0 +https://github.com/nvzqz/static-assertions-rs + +MIT License + +Copyright (c) 2017 Nikolai Vazquez + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +strsim 0.10.0 - MIT +https://github.com/dguo/strsim-rs + +The MIT License (MIT) + +Copyright (c) 2015 Danny Guo +Copyright (c) 2016 Titus Wormer +Copyright (c) 2018 Akash Kurdekar + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +subtle 2.4.1 - BSD-3-Clause +https://github.com/dalek-cryptography/subtle + +Copyright (c) 2016-2017 Isis Agora Lovecruft, Henry de Valence. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------- + +--------------------------------------------------------- + +syn 1.0.103 - MIT OR Apache-2.0 +syn 2.0.18 - MIT OR Apache-2.0 +https://github.com/dtolnay/syn + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +sysinfo 0.29.0 - MIT +https://github.com/GuillaumeGomez/sysinfo + +The MIT License (MIT) + +Copyright (c) 2015 Guillaume Gomez + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +tar 0.4.38 - MIT/Apache-2.0 +https://github.com/alexcrichton/tar-rs + +Copyright (c) 2014 Alex Crichton + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +tempfile 3.5.0 - MIT OR Apache-2.0 +https://github.com/Stebalien/tempfile + +Copyright (c) 2015 Steven Allen + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +termcolor 1.1.3 - Unlicense OR MIT +https://github.com/BurntSushi/termcolor + +The MIT License (MIT) + +Copyright (c) 2015 Andrew Gallant + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +thiserror 1.0.40 - MIT OR Apache-2.0 +https://github.com/dtolnay/thiserror + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +thiserror-impl 1.0.40 - MIT OR Apache-2.0 +https://github.com/dtolnay/thiserror + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +time 0.1.44 - MIT/Apache-2.0 +time 0.3.21 - MIT OR Apache-2.0 +https://github.com/time-rs/time + +Copyright (c) 2022 Jacob Pratt et al. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +time-core 0.1.1 - MIT OR Apache-2.0 +https://github.com/time-rs/time + +Copyright (c) 2022 Jacob Pratt et al. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +tinyvec 1.6.0 - Zlib OR Apache-2.0 OR MIT +https://github.com/Lokathor/tinyvec + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +tinyvec_macros 0.1.0 - MIT OR Apache-2.0 OR Zlib +https://github.com/Soveu/tinyvec_macros + +MIT License + +Copyright (c) 2020 Soveu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +tokio 1.28.2 - MIT +https://github.com/tokio-rs/tokio + +The MIT License (MIT) + +Copyright (c) 2023 Tokio Contributors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +tokio-macros 2.1.0 - MIT +https://github.com/tokio-rs/tokio + +The MIT License (MIT) + +Copyright (c) 2023 Tokio Contributors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +tokio-native-tls 0.3.0 - MIT +https://github.com/tokio-rs/tls + +The MIT License (MIT) + +Copyright (c) 2019 Tokio Contributors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +tokio-stream 0.1.11 - MIT +https://github.com/tokio-rs/tokio + +The MIT License (MIT) + +Copyright (c) 2023 Tokio Contributors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +tokio-tungstenite 0.17.2 - MIT +https://github.com/snapview/tokio-tungstenite + +The MIT License (MIT) + +Copyright (c) 2017 Daniel Abramov +Copyright (c) 2017 Alexey Galakhov + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +tokio-util 0.7.8 - MIT +https://github.com/tokio-rs/tokio + +The MIT License (MIT) + +Copyright (c) 2023 Tokio Contributors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +toml 0.5.9 - MIT/Apache-2.0 +https://github.com/toml-rs/toml + +Copyright (c) 2014 Alex Crichton + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +tower-service 0.3.2 - MIT +https://github.com/tower-rs/tower + +The MIT License (MIT) + +Copyright (c) 2019 Tower Contributors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +tracing 0.1.37 - MIT +https://github.com/tokio-rs/tracing + +The MIT License (MIT) + +Copyright (c) 2019 Tokio Contributors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +tracing-attributes 0.1.23 - MIT +https://github.com/tokio-rs/tracing + +The MIT License (MIT) + +Copyright (c) 2019 Tokio Contributors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +tracing-core 0.1.30 - MIT +https://github.com/tokio-rs/tracing + +The MIT License (MIT) + +Copyright (c) 2019 Tokio Contributors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +try-lock 0.2.3 - MIT +https://github.com/seanmonstar/try-lock + +The MIT License (MIT) + +Copyright (c) 2018 Sean McArthur +Copyright (c) 2016 Alex Crichton + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +tungstenite 0.17.3 - MIT/Apache-2.0 +https://github.com/snapview/tungstenite-rs + +Copyright (c) 2017 Alexey Galakhov +Copyright (c) 2016 Jason Housley + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +tunnels 2621784a9ad72aa39500372391332a14bad581a3 +https://github.com/microsoft/dev-tunnels + +MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE +--------------------------------------------------------- + +--------------------------------------------------------- + +typenum 1.15.0 - MIT OR Apache-2.0 +https://github.com/paholg/typenum + +MIT OR Apache-2.0 +--------------------------------------------------------- + +--------------------------------------------------------- + +uds_windows 1.0.2 - MIT +https://github.com/haraldh/rust_uds_windows + +MIT License + + Copyright (c) Microsoft Corporation. All rights reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE +--------------------------------------------------------- + +--------------------------------------------------------- + +unicode-bidi 0.3.8 - MIT OR Apache-2.0 +https://github.com/servo/unicode-bidi + +Copyright (c) 2015 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +unicode-ident 1.0.5 - (MIT OR Apache-2.0) AND Unicode-DFS-2016 +https://github.com/dtolnay/unicode-ident + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +unicode-normalization 0.1.22 - MIT/Apache-2.0 +https://github.com/unicode-rs/unicode-normalization + +Copyright (c) 2015 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +unicode-width 0.1.10 - MIT/Apache-2.0 +https://github.com/unicode-rs/unicode-width + +Copyright (c) 2015 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +unicode-xid 0.2.4 - MIT OR Apache-2.0 +https://github.com/unicode-rs/unicode-xid + +Copyright (c) 2015 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +url 2.3.1 - MIT OR Apache-2.0 +https://github.com/servo/rust-url + +Copyright (c) 2013-2022 The rust-url developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +urlencoding 2.1.2 - MIT +https://github.com/kornelski/rust_urlencoding + +The MIT License (MIT) + +Ā© 2016 Bertram Truong +Ā© 2021 Kornel Lesiński + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +utf-8 0.7.6 - MIT OR Apache-2.0 +https://github.com/SimonSapin/rust-utf8 + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +utf8parse 0.2.1 - Apache-2.0 OR MIT +https://github.com/alacritty/vte + +Copyright (c) 2016 Joe Wilm + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +uuid 0.8.2 - Apache-2.0 OR MIT +uuid 1.3.3 - Apache-2.0 OR MIT +https://github.com/uuid-rs/uuid + +Copyright (c) 2014 The Rust Project Developers +Copyright (c) 2018 Ashley Mannix, Christopher Armstrong, Dylan DPC, Hunar Roop Kahlon + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +vcpkg 0.2.15 - MIT/Apache-2.0 +https://github.com/mcgoo/vcpkg-rs + +Copyright (c) 2017 Jim McGrath + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +version_check 0.9.4 - MIT/Apache-2.0 +https://github.com/SergioBenitez/version_check + +The MIT License (MIT) +Copyright (c) 2017-2018 Sergio Benitez + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +waker-fn 1.1.0 - Apache-2.0 OR MIT +https://github.com/smol-rs/waker-fn + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +want 0.3.0 - MIT +https://github.com/seanmonstar/want + +The MIT License (MIT) + +Copyright (c) 2018-2019 Sean McArthur + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +wasi 0.10.0+wasi-snapshot-preview1 - Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT +wasi 0.11.0+wasi-snapshot-preview1 - Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT +wasi 0.9.0+wasi-snapshot-preview1 - Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT +https://github.com/bytecodealliance/wasi + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +wasm-bindgen 0.2.83 - MIT/Apache-2.0 +https://github.com/rustwasm/wasm-bindgen + +Copyright (c) 2014 Alex Crichton + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +wasm-bindgen-backend 0.2.83 - MIT/Apache-2.0 +https://github.com/rustwasm/wasm-bindgen/tree/master/crates/backend + +Copyright (c) 2014 Alex Crichton + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +wasm-bindgen-futures 0.4.33 - MIT/Apache-2.0 +https://github.com/rustwasm/wasm-bindgen/tree/master/crates/futures + +Copyright (c) 2014 Alex Crichton + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +wasm-bindgen-macro 0.2.83 - MIT/Apache-2.0 +https://github.com/rustwasm/wasm-bindgen/tree/master/crates/macro + +Copyright (c) 2014 Alex Crichton + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +wasm-bindgen-macro-support 0.2.83 - MIT/Apache-2.0 +https://github.com/rustwasm/wasm-bindgen/tree/master/crates/macro-support + +Copyright (c) 2014 Alex Crichton + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +wasm-bindgen-shared 0.2.83 - MIT/Apache-2.0 +https://github.com/rustwasm/wasm-bindgen/tree/master/crates/shared + +Copyright (c) 2014 Alex Crichton + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +wasm-streams 0.2.3 - MIT OR Apache-2.0 +https://github.com/MattiasBuelens/wasm-streams/ + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +web-sys 0.3.60 - MIT/Apache-2.0 +https://github.com/rustwasm/wasm-bindgen/tree/master/crates/web-sys + +Copyright (c) 2014 Alex Crichton + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +wepoll-ffi 0.1.2 - MIT OR Apache-2.0 OR BSD-2-Clause +https://github.com/aclysma/wepoll-ffi + +MIT License + +Copyright (c) 2019-2020 Philip Degarmo and other wepoll-ffi contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +winapi 0.3.9 - MIT/Apache-2.0 +https://github.com/retep998/winapi-rs + +Copyright (c) 2015-2018 The winapi-rs Developers + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +winapi-i686-pc-windows-gnu 0.4.0 - MIT/Apache-2.0 +https://github.com/retep998/winapi-rs + +Copyright (c) 2015-2018 The winapi-rs Developers + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +winapi-util 0.1.5 - Unlicense/MIT +https://github.com/BurntSushi/winapi-util + +The MIT License (MIT) + +Copyright (c) 2017 Andrew Gallant + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +winapi-x86_64-pc-windows-gnu 0.4.0 - MIT/Apache-2.0 +https://github.com/retep998/winapi-rs + +Copyright (c) 2015-2018 The winapi-rs Developers + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +windows-sys 0.36.1 - MIT OR Apache-2.0 +windows-sys 0.45.0 - MIT OR Apache-2.0 +windows-sys 0.48.0 - MIT OR Apache-2.0 +https://github.com/microsoft/windows-rs + +MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE +--------------------------------------------------------- + +--------------------------------------------------------- + +windows-targets 0.42.2 - MIT OR Apache-2.0 +windows-targets 0.48.0 - MIT OR Apache-2.0 +https://github.com/microsoft/windows-rs + +MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE +--------------------------------------------------------- + +--------------------------------------------------------- + +windows_aarch64_gnullvm 0.42.2 - MIT OR Apache-2.0 +windows_aarch64_gnullvm 0.48.0 - MIT OR Apache-2.0 +https://github.com/microsoft/windows-rs + +MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE +--------------------------------------------------------- + +--------------------------------------------------------- + +windows_aarch64_msvc 0.36.1 - MIT OR Apache-2.0 +windows_aarch64_msvc 0.42.2 - MIT OR Apache-2.0 +windows_aarch64_msvc 0.48.0 - MIT OR Apache-2.0 +https://github.com/microsoft/windows-rs + +MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE +--------------------------------------------------------- + +--------------------------------------------------------- + +windows_i686_gnu 0.36.1 - MIT OR Apache-2.0 +windows_i686_gnu 0.42.2 - MIT OR Apache-2.0 +windows_i686_gnu 0.48.0 - MIT OR Apache-2.0 +https://github.com/microsoft/windows-rs + +MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE +--------------------------------------------------------- + +--------------------------------------------------------- + +windows_i686_msvc 0.36.1 - MIT OR Apache-2.0 +windows_i686_msvc 0.42.2 - MIT OR Apache-2.0 +windows_i686_msvc 0.48.0 - MIT OR Apache-2.0 +https://github.com/microsoft/windows-rs + +MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE +--------------------------------------------------------- + +--------------------------------------------------------- + +windows_x86_64_gnu 0.36.1 - MIT OR Apache-2.0 +windows_x86_64_gnu 0.42.2 - MIT OR Apache-2.0 +windows_x86_64_gnu 0.48.0 - MIT OR Apache-2.0 +https://github.com/microsoft/windows-rs + +MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE +--------------------------------------------------------- + +--------------------------------------------------------- + +windows_x86_64_gnullvm 0.42.2 - MIT OR Apache-2.0 +windows_x86_64_gnullvm 0.48.0 - MIT OR Apache-2.0 +https://github.com/microsoft/windows-rs + +MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE +--------------------------------------------------------- + +--------------------------------------------------------- + +windows_x86_64_msvc 0.36.1 - MIT OR Apache-2.0 +windows_x86_64_msvc 0.42.2 - MIT OR Apache-2.0 +windows_x86_64_msvc 0.48.0 - MIT OR Apache-2.0 +https://github.com/microsoft/windows-rs + +MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE +--------------------------------------------------------- + +--------------------------------------------------------- + +winnow 0.4.1 - MIT +https://github.com/winnow-rs/winnow + +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +winreg 0.10.1 - MIT +winreg 0.50.0 - MIT +https://github.com/gentoo90/winreg-rs + +The MIT License (MIT) + +Copyright (c) 2015 Igor Shaula + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +xattr 0.2.3 - MIT/Apache-2.0 +https://github.com/Stebalien/xattr + +Copyright (c) 2015 Steven Allen + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +xdg-home 1.0.0 - MIT +https://github.com/zeenix/xdg-home + +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +yasna 0.5.2 - MIT OR Apache-2.0 +https://github.com/qnighy/yasna.rs + +Copyright (c) 2016 Masaki Hara + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +zbus 3.13.1 - MIT +https://github.com/dbus2/zbus/ + +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +zbus_macros 3.13.1 - MIT +https://github.com/dbus2/zbus/ + +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +zbus_names 2.5.1 - MIT +https://github.com/dbus2/zbus/ + +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +zeroize 1.3.0 - Apache-2.0 OR MIT +https://github.com/RustCrypto/utils/tree/master/zeroize + +All crates licensed under either of + + * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) + * [MIT license](http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. + +[//]: # (badges) + +[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg +[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260052-utils +[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg +[deps-image]: https://deps.rs/repo/github/RustCrypto/utils/status.svg +[deps-link]: https://deps.rs/repo/github/RustCrypto/utils + +[msrv-1.39]: https://img.shields.io/badge/rustc-1.39.0+-blue.svg +[msrv-1.40]: https://img.shields.io/badge/rustc-1.40.0+-blue.svg +[msrv-1.41]: https://img.shields.io/badge/rustc-1.41.0+-blue.svg +[msrv-1.45]: https://img.shields.io/badge/rustc-1.45.0+-blue.svg +[msrv-1.51]: https://img.shields.io/badge/rustc-1.51.0+-blue.svg +[msrv-1.56]: https://img.shields.io/badge/rustc-1.56.0+-blue.svg +[msrv-1.57]: https://img.shields.io/badge/rustc-1.57.0+-blue.svg +[msrv-1.59]: https://img.shields.io/badge/rustc-1.59.0+-blue.svg +[msrv-1.60]: https://img.shields.io/badge/rustc-1.60.0+-blue.svg + +[//]: # (crates) + +[`blobby`]: ./blobby +[`block-buffer`]: ./block-buffer +[`blockā€‘padding`]: ./block-padding +[`cmov`]: ./cmov +[`collectable`]: ./collectable +[`cpufeatures`]: ./cpufeatures +[`dbl`]: ./dbl +[`hex-literal`]: ./hex-literal +[`inout`]: ./inout +[`opaque-debug`]: ./opaque-debug +[`wycheproof2blb`]: ./wycheproof2blb +[`zeroize`]: ./zeroize + +[//]: # (misc) + +[Wycheproof]: https://github.com/google/wycheproof +--------------------------------------------------------- + +--------------------------------------------------------- + +zip 0.6.6 - MIT +https://github.com/zip-rs/zip + +The MIT License (MIT) + +Copyright (c) 2014 Mathijs van de Nes + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +zvariant 3.14.0 - MIT +https://github.com/dbus2/zbus/ + +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +zvariant_derive 3.14.0 - MIT +https://github.com/dbus2/zbus/ + +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + +zvariant_utils 1.0.1 - MIT +https://github.com/dbus2/zbus/ + +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- \ No newline at end of file diff --git a/cli/build.rs b/cli/build.rs index bcf1bf27e0ac3..16078e34044bd 100644 --- a/cli/build.rs +++ b/cli/build.rs @@ -6,53 +6,146 @@ const FILE_HEADER: &str = "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/"; use std::{ + collections::HashMap, env, fs, io, - path::PathBuf, - process::{self, Command}, + path::{Path, PathBuf}, + process::{self}, str::FromStr, }; +use serde::{de::DeserializeOwned, Deserialize}; +use serde_json::Value; + fn main() { let files = enumerate_source_files().expect("expected to enumerate files"); ensure_file_headers(&files).expect("expected to ensure file headers"); apply_build_environment_variables(); } -fn apply_build_environment_variables() { - // only do this for local, debug builds - if env::var("PROFILE").unwrap() != "debug" || env::var("VSCODE_CLI_ALREADY_PREPARED").is_ok() { - return; +fn camel_case_to_constant_case(key: &str) -> String { + let mut output = String::new(); + let mut prev_upper = false; + for c in key.chars() { + if c.is_uppercase() { + if prev_upper { + output.push(c.to_ascii_lowercase()); + } else { + output.push('_'); + output.push(c.to_ascii_uppercase()); + } + prev_upper = true; + } else if c.is_lowercase() { + output.push(c.to_ascii_uppercase()); + prev_upper = false; + } else { + output.push(c); + prev_upper = false; + } } - let pkg_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); - let mut cmd = Command::new("node"); - cmd.arg("../build/azure-pipelines/cli/prepare.js"); - cmd.current_dir(&pkg_dir); - cmd.env("VSCODE_CLI_PREPARE_OUTPUT", "json"); - - let mut distro_location = PathBuf::from_str(&pkg_dir).unwrap(); - distro_location.pop(); // vscode dir - distro_location.pop(); // parent dir - distro_location.push("vscode-distro"); // distro dir, perhaps? - if distro_location.exists() { - cmd.env("VSCODE_CLI_PREPARE_ROOT", distro_location); - cmd.env("VSCODE_QUALITY", "insider"); + output +} + +fn set_env_vars_from_map_keys(prefix: &str, map: impl IntoIterator) { + let mut win32_app_ids = vec![]; + + for (key, value) in map { + //#region special handling + let value = match key.as_str() { + "tunnelServerQualities" | "serverLicense" => { + Value::String(serde_json::to_string(&value).unwrap()) + } + "nameLong" => { + if let Value::String(s) = &value { + let idx = s.find(" - "); + println!( + "cargo:rustc-env=VSCODE_CLI_QUALITYLESS_PRODUCT_NAME={}", + idx.map(|i| &s[..i]).unwrap_or(s) + ); + } + + value + } + "tunnelApplicationConfig" => { + if let Value::Object(v) = value { + set_env_vars_from_map_keys(&format!("{}_{}", prefix, "TUNNEL"), v); + } + continue; + } + _ => value, + }; + if key.contains("win32") && key.contains("AppId") { + if let Value::String(s) = value { + win32_app_ids.push(s); + continue; + } + } + //#endregion + + if let Value::String(s) = value { + println!( + "cargo:rustc-env={}_{}={}", + prefix, + camel_case_to_constant_case(&key), + s + ); + } } - let output = cmd.output().expect("expected to run prepare script"); - if !output.status.success() { - eprint!( - "error running prepare script: {}", - String::from_utf8_lossy(&output.stderr) + if !win32_app_ids.is_empty() { + println!( + "cargo:rustc-env=VSCODE_CLI_WIN32_APP_IDS={}", + win32_app_ids.join(",") ); - process::exit(output.status.code().unwrap_or(1)); } +} - let vars = serde_json::from_slice::>(&output.stdout) - .expect("expected to deserialize output"); - for (key, value) in vars { - println!("cargo:rustc-env={}={}", key, value); - } +fn read_json_from_path(path: &Path) -> T +where + T: DeserializeOwned, +{ + let mut file = fs::File::open(path).expect("failed to open file"); + serde_json::from_reader(&mut file).expect("failed to deserialize JSON") +} + +fn apply_build_from_product_json(path: &Path) { + let json: HashMap = read_json_from_path(path); + set_env_vars_from_map_keys("VSCODE_CLI", json); +} + +#[derive(Deserialize)] +struct PackageJson { + pub version: String, +} + +fn apply_build_environment_variables() { + let repo_dir = env::current_dir().unwrap().join(".."); + let package_json = read_json_from_path::(&repo_dir.join("package.json")); + println!( + "cargo:rustc-env=VSCODE_CLI_VERSION={}", + package_json.version + ); + + match env::var("VSCODE_CLI_PRODUCT_JSON") { + Ok(v) => { + let path = if cfg!(windows) { + PathBuf::from_str(&v.replace('/', "\\")).unwrap() + } else { + PathBuf::from_str(&v).unwrap() + }; + println!("cargo:warning=loading product.json from <{:?}>", path); + apply_build_from_product_json(&path); + } + + Err(_) => { + apply_build_from_product_json(&repo_dir.join("product.json")); + + let overrides = repo_dir.join("product.overrides.json"); + if overrides.exists() { + apply_build_from_product_json(&overrides); + } + } + }; } fn ensure_file_headers(files: &[PathBuf]) -> Result<(), io::Error> { diff --git a/cli/src/async_pipe.rs b/cli/src/async_pipe.rs index dcbe0d1601739..e9b710c1d6815 100644 --- a/cli/src/async_pipe.rs +++ b/cli/src/async_pipe.rs @@ -4,7 +4,12 @@ *--------------------------------------------------------------------------------------------*/ use crate::{constants::APPLICATION_NAME, util::errors::CodeError}; +use async_trait::async_trait; use std::path::{Path, PathBuf}; +use std::pin::Pin; +use std::task::{Context, Poll}; +use tokio::io::{AsyncRead, AsyncWrite}; +use tokio::net::TcpListener; use uuid::Uuid; // todo: we could probably abstract this into some crate, if one doesn't already exist @@ -39,9 +44,9 @@ cfg_if::cfg_if! { pipe.into_split() } } else { - use tokio::{time::sleep, io::{AsyncRead, AsyncWrite, ReadBuf}}; + use tokio::{time::sleep, io::ReadBuf}; use tokio::net::windows::named_pipe::{ClientOptions, ServerOptions, NamedPipeClient, NamedPipeServer}; - use std::{time::Duration, pin::Pin, task::{Context, Poll}, io}; + use std::{time::Duration, io}; use pin_project::pin_project; #[pin_project(project = AsyncPipeProj)] @@ -171,6 +176,57 @@ cfg_if::cfg_if! { } } +impl AsyncPipeListener { + pub fn into_pollable(self) -> PollableAsyncListener { + PollableAsyncListener { + listener: Some(self), + write_fut: tokio_util::sync::ReusableBoxFuture::new(make_accept_fut(None)), + } + } +} + +pub struct PollableAsyncListener { + listener: Option, + write_fut: tokio_util::sync::ReusableBoxFuture< + 'static, + (AsyncPipeListener, Result), + >, +} + +async fn make_accept_fut( + data: Option, +) -> (AsyncPipeListener, Result) { + match data { + Some(mut l) => { + let c = l.accept().await; + (l, c) + } + None => unreachable!("this future should not be pollable in this state"), + } +} + +impl hyper::server::accept::Accept for PollableAsyncListener { + type Conn = AsyncPipe; + type Error = CodeError; + + fn poll_accept( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll>> { + if let Some(l) = self.listener.take() { + self.write_fut.set(make_accept_fut(Some(l))) + } + + match self.write_fut.poll(cx) { + Poll::Ready((l, cnx)) => { + self.listener = Some(l); + Poll::Ready(Some(cnx)) + } + Poll::Pending => Poll::Pending, + } + } +} + /// Gets a random name for a pipe/socket on the paltform pub fn get_socket_name() -> PathBuf { cfg_if::cfg_if! { @@ -181,3 +237,34 @@ pub fn get_socket_name() -> PathBuf { } } } + +pub type AcceptedRW = ( + Box, + Box, +); + +#[async_trait] +pub trait AsyncRWAccepter { + async fn accept_rw(&mut self) -> Result; +} + +#[async_trait] +impl AsyncRWAccepter for AsyncPipeListener { + async fn accept_rw(&mut self) -> Result { + let pipe = self.accept().await?; + let (read, write) = socket_stream_split(pipe); + Ok((Box::new(read), Box::new(write))) + } +} + +#[async_trait] +impl AsyncRWAccepter for TcpListener { + async fn accept_rw(&mut self) -> Result { + let (stream, _) = self + .accept() + .await + .map_err(CodeError::AsyncPipeListenerFailed)?; + let (read, write) = tokio::io::split(stream); + Ok((Box::new(read), Box::new(write))) + } +} diff --git a/cli/src/auth.rs b/cli/src/auth.rs index bc2737afc0021..42bd3a894dcbf 100644 --- a/cli/src/auth.rs +++ b/cli/src/auth.rs @@ -161,6 +161,7 @@ impl StoredCredential { struct StorageWithLastRead { storage: Box, + fallback_storage: Option, last_read: Cell, WrappedError>>, } @@ -392,14 +393,18 @@ impl Auth { let mut keyring_storage = ThreadKeyringStorage::default(); let mut file_storage = FileStorage(PersistedState::new(self.file_storage_path.clone())); - let keyring_storage_result = match std::env::var("VSCODE_CLI_USE_FILE_KEYCHAIN") { - Ok(_) => Err(wrap("", "user prefers file storage").into()), - _ => keyring_storage.read(), + let native_storage_result = if std::env::var("VSCODE_CLI_USE_FILE_KEYCHAIN").is_ok() + || self.file_storage_path.exists() + { + Err(wrap("", "user prefers file storage").into()) + } else { + keyring_storage.read() }; - let mut storage = match keyring_storage_result { + let mut storage = match native_storage_result { Ok(v) => StorageWithLastRead { last_read: Cell::new(Ok(v)), + fallback_storage: Some(file_storage), storage: Box::new(keyring_storage), }, Err(e) => { @@ -410,6 +415,7 @@ impl Auth { .read() .map_err(|e| wrap(e, "could not read from file storage")), ), + fallback_storage: None, storage: Box::new(file_storage), } } @@ -531,7 +537,18 @@ impl Auth { "Failed to update keyring with new credentials: {}", e ); + + if let Some(fb) = storage.fallback_storage.take() { + storage.storage = Box::new(fb); + match storage.storage.store(creds.clone()) { + Err(e) => { + warning!(self.log, "Also failed to update fallback storage: {}", e) + } + Ok(_) => debug!(self.log, "Updated fallback storage successfully"), + } + } } + storage.last_read.set(Ok(Some(creds))); }) } diff --git a/cli/src/bin/code/main.rs b/cli/src/bin/code/main.rs index d000998c7dcf4..b104976b9ab39 100644 --- a/cli/src/bin/code/main.rs +++ b/cli/src/bin/code/main.rs @@ -8,7 +8,7 @@ use std::process::Command; use clap::Parser; use cli::{ - commands::{args, tunnels, update, version, CommandContext}, + commands::{args, serve_web, tunnels, update, version, CommandContext}, constants::get_default_user_agent, desktop, log, state::LauncherPaths, @@ -95,7 +95,13 @@ async fn main() -> Result<(), std::convert::Infallible> { args::VersionSubcommand::Show => version::show(context!()).await, }, - Some(args::Commands::CommandShell) => tunnels::command_shell(context!()).await, + Some(args::Commands::CommandShell(cs_args)) => { + tunnels::command_shell(context!(), cs_args).await + } + + Some(args::Commands::ServeWeb(sw_args)) => { + serve_web::serve_web(context!(), sw_args).await + } Some(args::Commands::Tunnel(tunnel_args)) => match tunnel_args.subcommand { Some(args::TunnelSubcommand::Prune) => tunnels::prune(context!()).await, @@ -112,6 +118,9 @@ async fn main() -> Result<(), std::convert::Infallible> { Some(args::TunnelSubcommand::Service(service_args)) => { tunnels::service(context_no_logger(), service_args).await } + Some(args::TunnelSubcommand::ForwardInternal(forward_args)) => { + tunnels::forward(context_no_logger(), forward_args).await + } None => tunnels::serve(context_no_logger(), tunnel_args.serve_args).await, }, }, diff --git a/cli/src/commands.rs b/cli/src/commands.rs index 754729f2c04c8..d10a52ad774cf 100644 --- a/cli/src/commands.rs +++ b/cli/src/commands.rs @@ -9,4 +9,5 @@ pub mod args; pub mod tunnels; pub mod update; pub mod version; +pub mod serve_web; pub use context::CommandContext; diff --git a/cli/src/commands/args.rs b/cli/src/commands/args.rs index ad961496bcce1..bfa1c6f2da4ed 100644 --- a/cli/src/commands/args.rs +++ b/cli/src/commands/args.rs @@ -172,9 +172,56 @@ pub enum Commands { /// Changes the version of the editor you're using. Version(VersionArgs), + /// Runs a local web version of VS Code. + ServeWeb(ServeWebArgs), + /// Runs the control server on process stdin/stdout #[clap(hide = true)] - CommandShell, + CommandShell(CommandShellArgs), +} + +#[derive(Args, Debug, Clone)] +pub struct ServeWebArgs { + /// Host to listen on, defaults to 'localhost' + #[clap(long)] + pub host: Option, + // The path to a socket file for the server to listen to. + #[clap(long)] + pub socket_path: Option, + /// Port to listen on. If 0 is passed a random free port is picked. + #[clap(long, default_value_t = 8000)] + pub port: u16, + /// A secret that must be included with all requests. + #[clap(long)] + pub connection_token: Option, + /// Run without a connection token. Only use this if the connection is secured by other means. + #[clap(long)] + pub without_connection_token: bool, + /// If set, the user accepts the server license terms and the server will be started without a user prompt. + #[clap(long)] + pub accept_server_license_terms: bool, + /// Specifies the directory that server data is kept in. + #[clap(long)] + pub server_data_dir: Option, + /// Specifies the directory that user data is kept in. Can be used to open multiple distinct instances of Code. + #[clap(long)] + pub user_data_dir: Option, + /// Set the root path for extensions. + #[clap(long)] + pub extensions_dir: Option, +} + +#[derive(Args, Debug, Clone)] +pub struct CommandShellArgs { + /// Listen on a socket instead of stdin/stdout. + #[clap(long)] + pub on_socket: bool, + /// Listen on a port instead of stdin/stdout. + #[clap(long)] + pub on_port: bool, + /// Require the given token string to be given in the handshake. + #[clap(long)] + pub require_token: Option, } #[derive(Args, Debug, Clone)] @@ -291,7 +338,7 @@ pub enum VersionSubcommand { #[derive(Args, Debug, Clone)] pub struct UseVersionArgs { /// The version of the editor you want to use. Can be "stable", "insiders", - /// a version number, or an absolute path to an existing install. + /// or an absolute path to an existing install. #[clap(value_name = "stable | insiders | x.y.z | path")] pub name: String, @@ -548,6 +595,7 @@ pub enum OutputFormat { #[derive(Args, Clone, Debug, Default)] pub struct ExistingTunnelArgs { /// Name you'd like to assign preexisting tunnel to use to connect the tunnel + /// Old option, new code sohuld just use `--name`. #[clap(long, hide = true)] pub tunnel_name: Option, @@ -626,6 +674,10 @@ pub enum TunnelSubcommand { /// (Preview) Manages the tunnel when installed as a system service, #[clap(subcommand)] Service(TunnelServiceSubCommands), + + /// (Preview) Forwards local port using the dev tunnel + #[clap(hide = true)] + ForwardInternal(TunnelForwardArgs), } #[derive(Subcommand, Debug, Clone)] @@ -649,6 +701,10 @@ pub struct TunnelServiceInstallArgs { /// If set, the user accepts the server license terms and the server will be started without a user prompt. #[clap(long)] pub accept_server_license_terms: bool, + + /// Sets the machine name for port forwarding service + #[clap(long)] + pub name: Option, } #[derive(Args, Debug, Clone)] @@ -657,6 +713,16 @@ pub struct TunnelRenameArgs { pub name: String, } +#[derive(Args, Debug, Clone)] +pub struct TunnelForwardArgs { + /// One or more ports to forward. + pub ports: Vec, + + /// Login args -- used for convenience so the forwarding call is a single action. + #[clap(flatten)] + pub login: LoginArgs, +} + #[derive(Subcommand, Debug, Clone)] pub enum TunnelUserSubCommands { /// Log in to port forwarding service diff --git a/cli/src/commands/serve_web.rs b/cli/src/commands/serve_web.rs new file mode 100644 index 0000000000000..4a3af432444b9 --- /dev/null +++ b/cli/src/commands/serve_web.rs @@ -0,0 +1,629 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +use std::collections::HashMap; +use std::convert::Infallible; +use std::net::{IpAddr, Ipv4Addr, SocketAddr}; +use std::path::PathBuf; +use std::sync::{Arc, Mutex}; +use std::time::{Duration, Instant}; + +use hyper::service::{make_service_fn, service_fn}; +use hyper::{Body, Request, Response, Server}; +use tokio::io::{AsyncBufReadExt, BufReader}; +use tokio::pin; +use tokio::process::Command; + +use crate::async_pipe::{ + get_socket_name, get_socket_rw_stream, listen_socket_rw_stream, AsyncPipe, +}; +use crate::constants::VSCODE_CLI_QUALITY; +use crate::download_cache::DownloadCache; +use crate::log; +use crate::options::Quality; +use crate::update_service::{ + unzip_downloaded_release, Platform, Release, TargetKind, UpdateService, +}; +use crate::util::errors::AnyError; +use crate::util::http::{self, ReqwestSimpleHttp}; +use crate::util::io::SilentCopyProgress; +use crate::util::sync::{new_barrier, Barrier, BarrierOpener}; +use crate::{ + tunnels::legal, + util::{errors::CodeError, prereqs::PreReqChecker}, +}; + +use super::{args::ServeWebArgs, CommandContext}; + +/// Length of a commit hash, for validation +const COMMIT_HASH_LEN: usize = 40; +/// Number of seconds where, if there's no connections to a VS Code server, +/// the server is shut down. +const SERVER_IDLE_TIMEOUT_SECS: u64 = 60 * 60; +/// Number of seconds in which the server times out when there is a connection +/// (should be large enough to basically never happen) +const SERVER_ACTIVE_TIMEOUT_SECS: u64 = SERVER_IDLE_TIMEOUT_SECS * 24 * 30 * 12; +/// How long to cache the "latest" version we get from the update service. +const RELEASE_CACHE_SECS: u64 = 60 * 60; + +/// Implements the vscode "server of servers". Clients who go to the URI get +/// served the latest version of the VS Code server whenever they load the +/// page. The VS Code server prefixes all assets and connections it loads with +/// its version string, so existing clients can continue to get served even +/// while new clients get new VS Code Server versions. +pub async fn serve_web(ctx: CommandContext, mut args: ServeWebArgs) -> Result { + legal::require_consent(&ctx.paths, args.accept_server_license_terms)?; + + let platform: crate::update_service::Platform = PreReqChecker::new().verify().await?; + + if !args.without_connection_token { + // Ensure there's a defined connection token, since if multiple server versions + // are excuted, they will need to have a single shared token. + args.connection_token = Some( + args.connection_token + .clone() + .unwrap_or_else(|| uuid::Uuid::new_v4().to_string()), + ); + } + + let cm = ConnectionManager::new(&ctx, platform, args.clone()); + let make_svc = move || { + let cm = cm.clone(); + let log = cm.log.clone(); + let service = service_fn(move |req| handle(cm.clone(), log.clone(), req)); + async move { Ok::<_, Infallible>(service) } + }; + + let r = if let Some(s) = args.socket_path { + let socket = listen_socket_rw_stream(&PathBuf::from(&s)).await?; + ctx.log.result(format!("Web UI available on {}", s)); + Server::builder(socket.into_pollable()) + .serve(make_service_fn(|_| make_svc())) + .await + } else { + let addr: SocketAddr = match &args.host { + Some(h) => { + SocketAddr::new(h.parse().map_err(CodeError::InvalidHostAddress)?, args.port) + } + None => SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), args.port), + }; + + let mut listening = format!("Web UI available at http://{}", addr); + if let Some(ct) = args.connection_token { + listening.push_str(&format!("?tkn={}", ct)); + } + ctx.log.result(listening); + + Server::bind(&addr) + .serve(make_service_fn(|_| make_svc())) + .await + }; + + r.map_err(CodeError::CouldNotListenOnInterface)?; + + Ok(0) +} + +/// Handler function for an inbound request +async fn handle( + cm: Arc, + log: log::Logger, + req: Request, +) -> Result, Infallible> { + let release = if let Some((r, _)) = get_release_from_path(req.uri().path(), cm.platform) { + r + } else { + match cm.get_latest_release().await { + Ok(r) => r, + Err(e) => { + error!(log, "error getting latest version: {}", e); + return Ok(response::code_err(e)); + } + } + }; + + Ok(match cm.get_connection(release).await { + Ok(rw) => { + if req.headers().contains_key(hyper::header::UPGRADE) { + forward_ws_req_to_server(cm.log.clone(), rw, req).await + } else { + forward_http_req_to_server(rw, req).await + } + } + Err(CodeError::ServerNotYetDownloaded) => response::wait_for_download(), + Err(e) => response::code_err(e), + }) +} + +/// Gets the release info from the VS Code path prefix, which is in the +/// format `/-/...` +fn get_release_from_path(path: &str, platform: Platform) -> Option<(Release, String)> { + if !path.starts_with('/') { + return None; // paths must start with '/' + } + + let path = &path[1..]; + let i = path.find('/').unwrap_or(path.len()); + let quality_commit_sep = path.get(..i).and_then(|p| p.find('-'))?; + + let (quality_commit, remaining) = path.split_at(i); + let (quality, commit) = quality_commit.split_at(quality_commit_sep); + + if !is_commit_hash(commit) { + return None; + } + + Some(( + Release { + // remember to trim off the leading '/' which is now part of th quality + quality: Quality::try_from(quality).ok()?, + commit: commit.to_string(), + platform, + target: TargetKind::Web, + name: "".to_string(), + }, + remaining.to_string(), + )) +} + +/// Proxies the standard HTTP request to the async pipe, returning the piped response +async fn forward_http_req_to_server( + (rw, handle): (AsyncPipe, ConnectionHandle), + req: Request, +) -> Response { + let (mut request_sender, connection) = + match hyper::client::conn::Builder::new().handshake(rw).await { + Ok(r) => r, + Err(e) => return response::connection_err(e), + }; + + tokio::spawn(connection); + + let res = request_sender + .send_request(req) + .await + .unwrap_or_else(response::connection_err); + + // technically, we should buffer the body into memory since it may not be + // read at this point, but because the keepalive time is very large + // there's not going to be responses that take hours to send and x + // cause us to kill the server before the response is sent + drop(handle); + + res +} + +/// Proxies the websocket request to the async pipe +async fn forward_ws_req_to_server( + log: log::Logger, + (rw, handle): (AsyncPipe, ConnectionHandle), + mut req: Request, +) -> Response { + // splicing of client and servers inspired by https://github.com/hyperium/hyper/blob/fece9f7f50431cf9533cfe7106b53a77b48db699/examples/upgrades.rs + let (mut request_sender, connection) = + match hyper::client::conn::Builder::new().handshake(rw).await { + Ok(r) => r, + Err(e) => return response::connection_err(e), + }; + + tokio::spawn(connection); + + let mut proxied_req = Request::builder().uri(req.uri()); + for (k, v) in req.headers() { + proxied_req = proxied_req.header(k, v); + } + + let mut res = request_sender + .send_request(proxied_req.body(Body::empty()).unwrap()) + .await + .unwrap_or_else(response::connection_err); + + let mut proxied_res = Response::new(Body::empty()); + *proxied_res.status_mut() = res.status(); + for (k, v) in res.headers() { + proxied_res.headers_mut().insert(k, v.clone()); + } + + // only start upgrade at this point in case the server decides to deny socket + if res.status() == hyper::StatusCode::SWITCHING_PROTOCOLS { + tokio::spawn(async move { + let (s_req, s_res) = + tokio::join!(hyper::upgrade::on(&mut req), hyper::upgrade::on(&mut res)); + + match (s_req, s_res) { + (Err(e1), Err(e2)) => debug!( + log, + "client ({}) and server ({}) websocket upgrade failed", e1, e2 + ), + (Err(e1), _) => debug!(log, "client ({}) websocket upgrade failed", e1), + (_, Err(e2)) => debug!(log, "server ({}) websocket upgrade failed", e2), + (Ok(mut s_req), Ok(mut s_res)) => { + trace!(log, "websocket upgrade succeeded"); + let r = tokio::io::copy_bidirectional(&mut s_req, &mut s_res).await; + trace!(log, "websocket closed (error: {:?})", r.err()); + } + } + + drop(handle); + }); + } + + proxied_res +} + +/// Returns whether the string looks like a commit hash. +fn is_commit_hash(s: &str) -> bool { + s.len() == COMMIT_HASH_LEN && s.chars().all(|c| c.is_ascii_hexdigit()) +} + +/// Module holding original responses the CLI's server makes. +mod response { + use const_format::concatcp; + + use crate::constants::QUALITYLESS_SERVER_NAME; + + use super::*; + + pub fn connection_err(err: hyper::Error) -> Response { + Response::builder() + .status(503) + .body(Body::from(format!("Error connecting to server: {:?}", err))) + .unwrap() + } + + pub fn code_err(err: CodeError) -> Response { + Response::builder() + .status(500) + .body(Body::from(format!("Error serving request: {}", err))) + .unwrap() + } + + pub fn wait_for_download() -> Response { + Response::builder() + .status(202) + .header("Content-Type", "text/html") // todo: get latest + .body(Body::from(concatcp!("The latest version of the ", QUALITYLESS_SERVER_NAME, " is downloading, please wait a moment...", ))) + .unwrap() + } +} + +/// Handle returned when getting a stream to the server, used to refcount +/// connections to a server so it can be disposed when there are no more clients. +struct ConnectionHandle { + client_counter: Arc>, +} + +impl ConnectionHandle { + pub fn new(client_counter: Arc>) -> Self { + client_counter.send_modify(|v| { + *v += 1; + }); + Self { client_counter } + } +} + +impl Drop for ConnectionHandle { + fn drop(&mut self) { + self.client_counter.send_modify(|v| { + *v -= 1; + }); + } +} + +type StartData = (PathBuf, Arc>); + +/// State stored in the ConnectionManager for each server version. +struct VersionState { + downloaded: bool, + socket_path: Barrier>, +} + +type ConnectionStateMap = Arc>>; + +/// Manages the connections to running web UI instances. Multiple web servers +/// can run concurrently, with routing based on the URL path. +struct ConnectionManager { + pub platform: Platform, + pub log: log::Logger, + args: ServeWebArgs, + /// Cache where servers are stored + cache: DownloadCache, + /// Mapping of (Quality, Commit) to the state each server is in + state: ConnectionStateMap, + /// Update service instance + update_service: UpdateService, + /// Cache of the latest released version, storing the time we checked as well + latest_version: tokio::sync::Mutex>, +} + +fn key_for_release(release: &Release) -> (Quality, String) { + (release.quality, release.commit.clone()) +} + +impl ConnectionManager { + pub fn new(ctx: &CommandContext, platform: Platform, args: ServeWebArgs) -> Arc { + Arc::new(Self { + platform, + args, + log: ctx.log.clone(), + cache: DownloadCache::new(ctx.paths.web_server_storage()), + update_service: UpdateService::new( + ctx.log.clone(), + Arc::new(ReqwestSimpleHttp::with_client(ctx.http.clone())), + ), + state: ConnectionStateMap::default(), + latest_version: tokio::sync::Mutex::default(), + }) + } + + /// Gets a connection to a server version + pub async fn get_connection( + &self, + release: Release, + ) -> Result<(AsyncPipe, ConnectionHandle), CodeError> { + // todo@connor4312: there is likely some performance benefit to + // implementing a 'keepalive' for these connections. + let (path, counter) = self.get_version_data(release).await?; + let handle = ConnectionHandle::new(counter); + let rw = get_socket_rw_stream(&path).await?; + Ok((rw, handle)) + } + + /// Gets the latest release for the CLI quality, caching its result for some + /// time to allow for fast loads. + pub async fn get_latest_release(&self) -> Result { + let mut latest = self.latest_version.lock().await; + let now = Instant::now(); + if let Some((checked_at, release)) = &*latest { + if checked_at.elapsed() < Duration::from_secs(RELEASE_CACHE_SECS) { + return Ok(release.clone()); + } + } + + let quality = VSCODE_CLI_QUALITY + .ok_or_else(|| CodeError::UpdatesNotConfigured("no configured quality")) + .and_then(|q| { + Quality::try_from(q).map_err(|_| CodeError::UpdatesNotConfigured("unknown quality")) + })?; + + let release = self + .update_service + .get_latest_commit(self.platform, TargetKind::Web, quality) + .await + .map_err(|e| CodeError::UpdateCheckFailed(e.to_string())); + + // If the update service is unavailable and we have stale data, use that + if let (Err(e), Some((_, previous))) = (&release, &*latest) { + warning!(self.log, "error getting latest release, using stale: {}", e); + return Ok(previous.clone()); + } + + let release = release?; + debug!(self.log, "refreshed latest release: {}", release); + *latest = Some((now, release.clone())); + + Ok(release) + } + + /// Gets the StartData for the a version of the VS Code server, triggering + /// download/start if necessary. It returns `CodeError::ServerNotYetDownloaded` + /// while the server is downloading, which is used to have a refresh loop on the page. + async fn get_version_data(&self, release: Release) -> Result { + self.get_version_data_inner(release)? + .wait() + .await + .unwrap() + .map_err(CodeError::ServerDownloadError) + } + + fn get_version_data_inner( + &self, + release: Release, + ) -> Result>, CodeError> { + let mut state = self.state.lock().unwrap(); + let key = key_for_release(&release); + if let Some(s) = state.get_mut(&key) { + if !s.downloaded { + if s.socket_path.is_open() { + s.downloaded = true; + } else { + return Err(CodeError::ServerNotYetDownloaded); + } + } + + return Ok(s.socket_path.clone()); + } + + let (socket_path, opener) = new_barrier(); + let state_map_dup = self.state.clone(); + let args = StartArgs { + args: self.args.clone(), + log: self.log.clone(), + opener, + release, + }; + + if let Some(p) = self.cache.exists(&args.release.commit) { + state.insert( + key.clone(), + VersionState { + socket_path: socket_path.clone(), + downloaded: true, + }, + ); + + tokio::spawn(async move { + Self::start_version(args, p).await; + state_map_dup.lock().unwrap().remove(&key); + }); + Ok(socket_path) + } else { + state.insert( + key.clone(), + VersionState { + socket_path, + downloaded: false, + }, + ); + let update_service = self.update_service.clone(); + let cache = self.cache.clone(); + tokio::spawn(async move { + Self::download_version(args, update_service.clone(), cache.clone()).await; + state_map_dup.lock().unwrap().remove(&key); + }); + Err(CodeError::ServerNotYetDownloaded) + } + } + + /// Downloads a server version into the cache and starts it. + async fn download_version( + args: StartArgs, + update_service: UpdateService, + cache: DownloadCache, + ) { + let release_for_fut = args.release.clone(); + let log_for_fut = args.log.clone(); + let dir_fut = cache.create(&args.release.commit, |target_dir| async move { + info!(log_for_fut, "Downloading server {}", release_for_fut.commit); + let tmpdir = tempfile::tempdir().unwrap(); + let response = update_service.get_download_stream(&release_for_fut).await?; + + let name = response.url_path_basename().unwrap(); + let archive_path = tmpdir.path().join(name); + http::download_into_file( + &archive_path, + log_for_fut.get_download_logger("Downloading server:"), + response, + ) + .await?; + unzip_downloaded_release(&archive_path, &target_dir, SilentCopyProgress())?; + Ok(()) + }); + + match dir_fut.await { + Err(e) => args.opener.open(Err(e.to_string())), + Ok(dir) => Self::start_version(args, dir).await, + } + } + + /// Starts a downloaded server that can be found in the given `path`. + async fn start_version(args: StartArgs, path: PathBuf) { + info!(args.log, "Starting server {}", args.release.commit); + + let executable = path + .join("bin") + .join(args.release.quality.server_entrypoint()); + let socket_path = get_socket_name(); + + #[cfg(not(windows))] + let mut cmd = Command::new(&executable); + #[cfg(windows)] + let mut cmd = { + let mut cmd = Command::new("cmd"); + cmd.arg("/Q"); + cmd.arg("/C"); + cmd.arg(&executable); + cmd + }; + + cmd.stdin(std::process::Stdio::null()); + cmd.stderr(std::process::Stdio::piped()); + cmd.stdout(std::process::Stdio::piped()); + cmd.arg("--socket-path"); + cmd.arg(&socket_path); + + // License agreement already checked by the `server_web` function. + cmd.args(["--accept-server-license-terms"]); + + if let Some(a) = &args.args.server_data_dir { + cmd.arg("--server-data-dir"); + cmd.arg(a); + } + if let Some(a) = &args.args.user_data_dir { + cmd.arg("--user-data-dir"); + cmd.arg(a); + } + if let Some(a) = &args.args.extensions_dir { + cmd.arg("--extensions-dir"); + cmd.arg(a); + } + if args.args.without_connection_token { + cmd.arg("--without-connection-token"); + } + if let Some(ct) = &args.args.connection_token { + cmd.arg("--connection-token"); + cmd.arg(ct); + } + + // removed, otherwise the workbench will not be usable when running the CLI from sources. + cmd.env_remove("VSCODE_DEV"); + + let mut child = match cmd.spawn() { + Ok(c) => c, + Err(e) => { + args.opener.open(Err(e.to_string())); + return; + } + }; + + let (mut stdout, mut stderr) = ( + BufReader::new(child.stdout.take().unwrap()).lines(), + BufReader::new(child.stderr.take().unwrap()).lines(), + ); + + // wrapped option to prove that we only use this once in the loop + let (counter_tx, mut counter_rx) = tokio::sync::watch::channel(0); + let mut opener = Some((args.opener, socket_path, Arc::new(counter_tx))); + let commit_prefix = &args.release.commit[..7]; + let kill_timer = tokio::time::sleep(Duration::from_secs(SERVER_IDLE_TIMEOUT_SECS)); + pin!(kill_timer); + + loop { + tokio::select! { + Ok(Some(l)) = stdout.next_line() => { + info!(args.log, "[{} stdout]: {}", commit_prefix, l); + + if l.contains("Server bound to") { + if let Some((opener, path, counter_tx)) = opener.take() { + opener.open(Ok((path, counter_tx))); + } + } + } + Ok(Some(l)) = stderr.next_line() => { + info!(args.log, "[{} stderr]: {}", commit_prefix, l); + }, + n = counter_rx.changed() => { + kill_timer.as_mut().reset(match n { + // err means that the record was dropped + Err(_) => tokio::time::Instant::now(), + Ok(_) => { + if *counter_rx.borrow() == 0 { + tokio::time::Instant::now() + Duration::from_secs(SERVER_IDLE_TIMEOUT_SECS) + } else { + tokio::time::Instant::now() + Duration::from_secs(SERVER_ACTIVE_TIMEOUT_SECS) + } + } + }); + } + _ = &mut kill_timer => { + info!(args.log, "[{} process]: idle timeout reached, ending", commit_prefix); + let _ = child.kill().await; + break; + } + e = child.wait() => { + info!(args.log, "[{} process]: exited: {:?}", commit_prefix, e); + break; + } + } + } + } +} + +struct StartArgs { + log: log::Logger, + args: ServeWebArgs, + release: Release, + opener: BarrierOpener>, +} diff --git a/cli/src/commands/tunnels.rs b/cli/src/commands/tunnels.rs index d11c15ef1e336..0cc0b8d264baf 100644 --- a/cli/src/commands/tunnels.rs +++ b/cli/src/commands/tunnels.rs @@ -5,27 +5,37 @@ use async_trait::async_trait; use base64::{engine::general_purpose as b64, Engine as _}; +use futures::{stream::FuturesUnordered, StreamExt}; use serde::Serialize; use sha2::{Digest, Sha256}; use std::{str::FromStr, time::Duration}; use sysinfo::Pid; +use tokio::{ + io::{AsyncBufReadExt, BufReader}, + sync::watch, +}; use super::{ args::{ - AuthProvider, CliCore, ExistingTunnelArgs, TunnelRenameArgs, TunnelServeArgs, - TunnelServiceSubCommands, TunnelUserSubCommands, + AuthProvider, CliCore, CommandShellArgs, ExistingTunnelArgs, TunnelForwardArgs, + TunnelRenameArgs, TunnelServeArgs, TunnelServiceSubCommands, TunnelUserSubCommands, }, CommandContext, }; use crate::{ + async_pipe::{get_socket_name, listen_socket_rw_stream, AsyncRWAccepter}, auth::Auth, - constants::{APPLICATION_NAME, TUNNEL_CLI_LOCK_NAME, TUNNEL_SERVICE_LOCK_NAME}, + constants::{ + APPLICATION_NAME, CONTROL_PORT, IS_A_TTY, TUNNEL_CLI_LOCK_NAME, TUNNEL_SERVICE_LOCK_NAME, + }, log, state::LauncherPaths, tunnels::{ code_server::CodeServerArgs, - create_service_manager, dev_tunnels, legal, + create_service_manager, + dev_tunnels::{self, DevTunnels}, + legal, local_forwarding, paths::get_all_servers, protocol, serve_stream, shutdown_signal::ShutdownRequest, @@ -33,7 +43,7 @@ use crate::{ singleton_server::{ make_singleton_server, start_singleton_server, BroadcastLogSink, SingletonServerArgs, }, - Next, ServeStreamParams, ServiceContainer, ServiceManager, + AuthRequired, Next, ServeStreamParams, ServiceContainer, ServiceManager, }, util::{ app_lock::AppMutex, @@ -59,20 +69,31 @@ impl From for crate::auth::AuthProvider { } } -impl From for Option { - fn from(d: ExistingTunnelArgs) -> Option { - if let (Some(tunnel_id), Some(tunnel_name), Some(cluster), Some(host_token)) = - (d.tunnel_id, d.tunnel_name, d.cluster, d.host_token) - { +fn fulfill_existing_tunnel_args( + d: ExistingTunnelArgs, + name_arg: &Option, +) -> Option { + let tunnel_name = d.tunnel_name.or_else(|| name_arg.clone()); + + match (d.tunnel_id, d.cluster, d.host_token) { + (Some(tunnel_id), None, Some(host_token)) => { + let i = tunnel_id.find('.')?; Some(dev_tunnels::ExistingTunnel { - tunnel_id, + tunnel_id: tunnel_id[..i].to_string(), + cluster: tunnel_id[i + 1..].to_string(), tunnel_name, host_token, - cluster, }) - } else { - None } + + (Some(tunnel_id), Some(cluster), Some(host_token)) => Some(dev_tunnels::ExistingTunnel { + tunnel_id, + tunnel_name, + host_token, + cluster, + }), + + _ => None, } } @@ -109,23 +130,71 @@ impl ServiceContainer for TunnelServiceContainer { } } -pub async fn command_shell(ctx: CommandContext) -> Result { +pub async fn command_shell(ctx: CommandContext, args: CommandShellArgs) -> Result { let platform = PreReqChecker::new().verify().await?; - serve_stream( - tokio::io::stdin(), - tokio::io::stderr(), - ServeStreamParams { - log: ctx.log, - launcher_paths: ctx.paths, - platform, - requires_auth: true, - exit_barrier: ShutdownRequest::create_rx([ShutdownRequest::CtrlC]), - code_server_args: (&ctx.args).into(), - }, - ) - .await; + let mut params = ServeStreamParams { + log: ctx.log, + launcher_paths: ctx.paths, + platform, + requires_auth: args + .require_token + .map(AuthRequired::VSDAWithToken) + .unwrap_or(AuthRequired::VSDA), + exit_barrier: ShutdownRequest::create_rx([ShutdownRequest::CtrlC]), + code_server_args: (&ctx.args).into(), + }; - Ok(0) + let mut listener: Box = match (args.on_port, args.on_socket) { + (_, true) => { + let socket = get_socket_name(); + let listener = listen_socket_rw_stream(&socket) + .await + .map_err(|e| wrap(e, "error listening on socket"))?; + + params + .log + .result(format!("Listening on {}", socket.display())); + + Box::new(listener) + } + (true, _) => { + let listener = tokio::net::TcpListener::bind("127.0.0.1:0") + .await + .map_err(|e| wrap(e, "error listening on port"))?; + + params + .log + .result(format!("Listening on {}", listener.local_addr().unwrap())); + + Box::new(listener) + } + _ => { + serve_stream(tokio::io::stdin(), tokio::io::stderr(), params).await; + return Ok(0); + } + }; + + let mut servers = FuturesUnordered::new(); + + loop { + tokio::select! { + Some(_) = servers.next() => {}, + socket = listener.accept_rw() => { + match socket { + Ok((read, write)) => servers.push(serve_stream(read, write, params.clone())), + Err(e) => { + error!(params.log, &format!("Error accepting connection: {}", e)); + return Ok(1); + } + } + }, + _ = params.exit_barrier.wait() => { + // wait for all servers to finish up: + while (servers.next().await).is_some() { } + return Ok(0); + } + } + } } pub async fn service( @@ -135,10 +204,17 @@ pub async fn service( let manager = create_service_manager(ctx.log.clone(), &ctx.paths); match service_args { TunnelServiceSubCommands::Install(args) => { - // ensure logged in, otherwise subsequent serving will fail - Auth::new(&ctx.paths, ctx.log.clone()) - .get_credential() - .await?; + let auth = Auth::new(&ctx.paths, ctx.log.clone()); + + if let Some(name) = &args.name { + // ensure the name matches, and tunnel exists + dev_tunnels::DevTunnels::new_remote_tunnel(&ctx.log, auth, &ctx.paths) + .rename_tunnel(name) + .await?; + } else { + // still ensure they're logged in, otherwise subsequent serving will fail + auth.get_credential().await?; + } // likewise for license consent legal::require_consent(&ctx.paths, args.accept_server_license_terms)?; @@ -203,23 +279,23 @@ pub async fn user(ctx: CommandContext, user_args: TunnelUserSubCommands) -> Resu Ok(0) } -/// Remove the tunnel used by this gateway, if any. +/// Remove the tunnel used by this tunnel, if any. pub async fn rename(ctx: CommandContext, rename_args: TunnelRenameArgs) -> Result { let auth = Auth::new(&ctx.paths, ctx.log.clone()); - let mut dt = dev_tunnels::DevTunnels::new(&ctx.log, auth, &ctx.paths); + let mut dt = dev_tunnels::DevTunnels::new_remote_tunnel(&ctx.log, auth, &ctx.paths); dt.rename_tunnel(&rename_args.name).await?; ctx.log.result(format!( - "Successfully renamed this gateway to {}", + "Successfully renamed this tunnel to {}", &rename_args.name )); Ok(0) } -/// Remove the tunnel used by this gateway, if any. +/// Remove the tunnel used by this tunnel, if any. pub async fn unregister(ctx: CommandContext) -> Result { let auth = Auth::new(&ctx.paths, ctx.log.clone()); - let mut dt = dev_tunnels::DevTunnels::new(&ctx.log, auth, &ctx.paths); + let mut dt = dev_tunnels::DevTunnels::new_remote_tunnel(&ctx.log, auth, &ctx.paths); dt.remove_tunnel().await?; Ok(0) } @@ -250,12 +326,12 @@ pub async fn kill(ctx: CommandContext) -> Result { #[derive(Serialize)] pub struct StatusOutput { - pub tunnel: Option, + pub tunnel: Option, pub service_installed: bool, } pub async fn status(ctx: CommandContext) -> Result { - let tunnel_status = do_single_rpc_call::<_, protocol::singleton::Status>( + let tunnel = do_single_rpc_call::<_, protocol::singleton::StatusWithTunnelName>( &ctx.paths.tunnel_lockfile(), ctx.log.clone(), protocol::singleton::METHOD_STATUS, @@ -271,8 +347,8 @@ pub async fn status(ctx: CommandContext) -> Result { ctx.log.result( serde_json::to_string(&StatusOutput { service_installed, - tunnel: match tunnel_status { - Ok(s) => Some(s.tunnel), + tunnel: match tunnel { + Ok(s) => Some(s), Err(CodeError::NoRunningTunnel) => None, Err(e) => return Err(e.into()), }, @@ -327,6 +403,85 @@ pub async fn serve(ctx: CommandContext, gateway_args: TunnelServeArgs) -> Result result } +/// Internal command used by port forwarding. It reads requests for forwarded ports +/// on lines from stdin, as JSON. It uses singleton logic as well (though on +/// a different tunnel than the main one used for the control server) so that +/// all forward requests on a single machine go through a single hosted tunnel +/// process. Without singleton logic, requests could get routed to processes +/// that aren't forwarding a given port and then fail. +pub async fn forward( + ctx: CommandContext, + mut forward_args: TunnelForwardArgs, +) -> Result { + // Spooky: check IS_A_TTY before starting the stdin reader, since IS_A_TTY will + // access stdin but a lock will later be held on stdin by the line-reader. + if *IS_A_TTY { + trace!(ctx.log, "port forwarding is an internal preview feature"); + } + + // #region stdin reading logic: + let (own_ports_tx, own_ports_rx) = watch::channel(vec![]); + let ports_process_log = ctx.log.clone(); + tokio::spawn(async move { + let mut lines = BufReader::new(tokio::io::stdin()).lines(); + while let Ok(Some(line)) = lines.next_line().await { + match serde_json::from_str(&line) { + Ok(p) => { + let _ = own_ports_tx.send(p); + } + Err(e) => warning!(ports_process_log, "error parsing ports: {}", e), + } + } + }); + + // #region singleton acquisition + let shutdown = ShutdownRequest::create_rx([ShutdownRequest::CtrlC]); + let server = loop { + if shutdown.is_open() { + return Ok(0); + } + + match acquire_singleton(&ctx.paths.forwarding_lockfile()).await { + Ok(SingletonConnection::Client(stream)) => { + debug!(ctx.log, "starting as client to singleton"); + let r = local_forwarding::client(local_forwarding::SingletonClientArgs { + log: ctx.log.clone(), + shutdown: shutdown.clone(), + stream, + port_requests: own_ports_rx.clone(), + }) + .await; + if let Err(e) = r { + warning!(ctx.log, "error contacting forwarding singleton: {}", e); + } + } + Ok(SingletonConnection::Singleton(server)) => break server, + Err(e) => { + warning!(ctx.log, "error access singleton, retrying: {}", e); + tokio::time::sleep(Duration::from_secs(2)).await + } + } + }; + + // #region singleton handler + let auth = Auth::new(&ctx.paths, ctx.log.clone()); + if let (Some(p), Some(at)) = ( + forward_args.login.provider.take(), + forward_args.login.access_token.take(), + ) { + auth.login(Some(p.into()), Some(at)).await?; + } + + let mut tunnels = DevTunnels::new_port_forwarding(&ctx.log, auth, &ctx.paths); + let tunnel = tunnels + .start_new_launcher_tunnel(None, true, &forward_args.ports) + .await?; + + local_forwarding::server(ctx.log, tunnel, server, own_ports_rx, shutdown).await?; + + Ok(0) +} + fn get_connection_token(tunnel: &ActiveTunnel) -> String { let mut hash = Sha256::new(); hash.update(tunnel.id.as_bytes()); @@ -374,7 +529,7 @@ async fn serve_with_csa( return Ok(0); } - match acquire_singleton(paths.tunnel_lockfile()).await { + match acquire_singleton(&paths.tunnel_lockfile()).await { Ok(SingletonConnection::Client(stream)) => { debug!(log, "starting as client to singleton"); let should_exit = start_singleton_client(SingletonClientArgs { @@ -403,13 +558,19 @@ async fn serve_with_csa( let _lock = app_mutex_name.map(AppMutex::new); let auth = Auth::new(&paths, log.clone()); - let mut dt = dev_tunnels::DevTunnels::new(&log, auth, &paths); + let mut dt = dev_tunnels::DevTunnels::new_remote_tunnel(&log, auth, &paths); loop { - let tunnel = if let Some(d) = gateway_args.tunnel.clone().into() { - dt.start_existing_tunnel(d).await + let tunnel = if let Some(t) = + fulfill_existing_tunnel_args(gateway_args.tunnel.clone(), &gateway_args.name) + { + dt.start_existing_tunnel(t).await } else { - dt.start_new_launcher_tunnel(gateway_args.name.as_deref(), gateway_args.random_name) - .await + dt.start_new_launcher_tunnel( + gateway_args.name.as_deref(), + gateway_args.random_name, + &[CONTROL_PORT], + ) + .await }?; csa.connection_token = Some(get_connection_token(&tunnel)); diff --git a/cli/src/constants.rs b/cli/src/constants.rs index 2dac5d435636d..6f604e8876ee6 100644 --- a/cli/src/constants.rs +++ b/cli/src/constants.rs @@ -3,7 +3,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -use std::collections::HashMap; +use serde::Deserialize; +use std::{collections::HashMap, io::IsTerminal}; use const_format::concatcp; use lazy_static::lazy_static; @@ -32,17 +33,16 @@ pub const VSCODE_CLI_AI_ENDPOINT: Option<&'static str> = option_env!("VSCODE_CLI pub const VSCODE_CLI_QUALITY: Option<&'static str> = option_env!("VSCODE_CLI_QUALITY"); pub const DOCUMENTATION_URL: Option<&'static str> = option_env!("VSCODE_CLI_DOCUMENTATION_URL"); pub const VSCODE_CLI_COMMIT: Option<&'static str> = option_env!("VSCODE_CLI_COMMIT"); -pub const VSCODE_CLI_UPDATE_ENDPOINT: Option<&'static str> = - option_env!("VSCODE_CLI_UPDATE_ENDPOINT"); +pub const VSCODE_CLI_UPDATE_ENDPOINT: Option<&'static str> = option_env!("VSCODE_CLI_UPDATE_URL"); /// Windows lock name for the running tunnel service. Used by the setup script /// to detect a tunnel process. See #179265. pub const TUNNEL_SERVICE_LOCK_NAME: Option<&'static str> = - option_env!("VSCODE_CLI_TUNNEL_SERVICE_MUTEX"); + option_env!("VSCODE_CLI_WIN32_TUNNEL_SERVICE_MUTEX"); /// Windows lock name for the running tunnel without a service. Used by the setup /// script to detect a tunnel process. See #179265. -pub const TUNNEL_CLI_LOCK_NAME: Option<&'static str> = option_env!("VSCODE_CLI_TUNNEL_CLI_MUTEX"); +pub const TUNNEL_CLI_LOCK_NAME: Option<&'static str> = option_env!("VSCODE_CLI_WIN32_TUNNEL_MUTEX"); pub const TUNNEL_SERVICE_USER_AGENT_ENV_VAR: &str = "TUNNEL_SERVICE_USER_AGENT"; @@ -68,16 +68,24 @@ pub const QUALITYLESS_PRODUCT_NAME: &str = match option_env!("VSCODE_CLI_QUALITY /// Name of the application without quality information. pub const QUALITYLESS_SERVER_NAME: &str = concatcp!(QUALITYLESS_PRODUCT_NAME, " Server"); +pub const QUALITY: &str = match VSCODE_CLI_QUALITY { + Some(q) => q, + _ => "oss", +}; + /// Web URL the editor is hosted at. For VS Code, this is vscode.dev. -pub const EDITOR_WEB_URL: Option<&'static str> = option_env!("VSCODE_CLI_EDITOR_WEB_URL"); +pub const EDITOR_WEB_URL: Option<&'static str> = option_env!("VSCODE_CLI_TUNNEL_EDITOR_WEB_URL"); /// Name shown in places where we need to tell a user what a process is, e.g. in sleep inhibition. pub const TUNNEL_ACTIVITY_NAME: &str = concatcp!(PRODUCT_NAME_LONG, " Tunnel"); +/// Download URL of the desktop product. +pub const PRODUCT_DOWNLOAD_URL: Option<&'static str> = option_env!("VSCODE_CLI_DOWNLOAD_URL"); + const NONINTERACTIVE_VAR: &str = "VSCODE_CLI_NONINTERACTIVE"; /// Default data CLI data directory. -pub const DEFAULT_DATA_PARENT_DIR: &str = match option_env!("VSCODE_CLI_DEFAULT_PARENT_DATA_DIR") { +pub const DEFAULT_DATA_PARENT_DIR: &str = match option_env!("VSCODE_CLI_DATA_FOLDER_NAME") { Some(n) => n, None => ".vscode-oss", }; @@ -91,6 +99,12 @@ pub fn get_default_user_agent() -> String { const NO_COLOR_ENV: &str = "NO_COLOR"; +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct ServerQualityInfo { + pub server_application_name: String, +} + lazy_static! { pub static ref TUNNEL_SERVICE_USER_AGENT: String = match std::env::var(TUNNEL_SERVICE_USER_AGENT_ENV_VAR) { @@ -98,32 +112,20 @@ lazy_static! { _ => get_default_user_agent(), }; - /// Map of quality names to arrays of app IDs used for them, for example, `{"stable":["ABC123"]}` - pub static ref WIN32_APP_IDS: Option>> = - option_env!("VSCODE_CLI_WIN32_APP_IDS").and_then(|s| serde_json::from_str(s).unwrap()); - - /// Map of quality names to desktop download URIs - pub static ref QUALITY_DOWNLOAD_URIS: Option> = - option_env!("VSCODE_CLI_QUALITY_DOWNLOAD_URIS").and_then(|s| serde_json::from_str(s).unwrap()); - - /// Map of qualities to the long name of the app in that quality - pub static ref PRODUCT_NAME_LONG_MAP: Option> = - option_env!("VSCODE_CLI_NAME_LONG_MAP").and_then(|s| serde_json::from_str(s).unwrap()); - - /// Map of qualities to the application name - pub static ref APPLICATION_NAME_MAP: Option> = - option_env!("VSCODE_CLI_APPLICATION_NAME_MAP").and_then(|s| serde_json::from_str(s).unwrap()); - /// Map of qualities to the server name - pub static ref SERVER_NAME_MAP: Option> = - option_env!("VSCODE_CLI_SERVER_NAME_MAP").and_then(|s| serde_json::from_str(s).unwrap()); + pub static ref SERVER_NAME_MAP: Option> = + option_env!("VSCODE_CLI_TUNNEL_SERVER_QUALITIES").and_then(|s| serde_json::from_str(s).unwrap()); /// Whether i/o interactions are allowed in the current CLI. - pub static ref IS_A_TTY: bool = atty::is(atty::Stream::Stdin); + pub static ref IS_A_TTY: bool = std::io::stdin().is_terminal(); /// Whether i/o interactions are allowed in the current CLI. pub static ref COLORS_ENABLED: bool = *IS_A_TTY && std::env::var(NO_COLOR_ENV).is_err(); /// Whether i/o interactions are allowed in the current CLI. pub static ref IS_INTERACTIVE_CLI: bool = *IS_A_TTY && std::env::var(NONINTERACTIVE_VAR).is_err(); + + /// Map of quality names to arrays of app IDs used for them, for example, `{"stable":["ABC123"]}` + pub static ref WIN32_APP_IDS: Option> = + option_env!("VSCODE_CLI_WIN32_APP_IDS").map(|s| s.split(',').map(|s| s.to_string()).collect()); } diff --git a/cli/src/desktop/version_manager.rs b/cli/src/desktop/version_manager.rs index e08b42aa98201..bb0f1011ab67c 100644 --- a/cli/src/desktop/version_manager.rs +++ b/cli/src/desktop/version_manager.rs @@ -14,9 +14,8 @@ use regex::Regex; use serde::{Deserialize, Serialize}; use crate::{ - constants::{QUALITYLESS_PRODUCT_NAME, QUALITY_DOWNLOAD_URIS}, + constants::{PRODUCT_DOWNLOAD_URL, QUALITY, QUALITYLESS_PRODUCT_NAME}, log, - options::{self, Quality}, state::{LauncherPaths, PersistedState}, update_service::Platform, util::errors::{AnyError, InvalidRequestedVersion}, @@ -26,34 +25,23 @@ use crate::{ #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] #[serde(tag = "t", content = "c")] pub enum RequestedVersion { - Quality(options::Quality), - Version { - version: String, - quality: options::Quality, - }, - Commit { - commit: String, - quality: options::Quality, - }, + Default, + Commit(String), Path(String), } lazy_static! { - static ref SEMVER_RE: Regex = Regex::new(r"^\d+\.\d+\.\d+(-insider)?$").unwrap(); - static ref COMMIT_RE: Regex = Regex::new(r"^[a-z]+/[a-e0-f]{40}$").unwrap(); + static ref COMMIT_RE: Regex = Regex::new(r"^[a-e0-f]{40}$").unwrap(); } impl RequestedVersion { pub fn get_command(&self) -> String { match self { - RequestedVersion::Quality(quality) => { - format!("code version use {}", quality.get_machine_name()) + RequestedVersion::Default => { + format!("code version use {}", QUALITY) } - RequestedVersion::Version { version, .. } => { - format!("code version use {}", version) - } - RequestedVersion::Commit { commit, quality } => { - format!("code version use {}/{}", quality.get_machine_name(), commit) + RequestedVersion::Commit(commit) => { + format!("code version use {}/{}", QUALITY, commit) } RequestedVersion::Path(path) => { format!("code version use {}", path) @@ -65,12 +53,11 @@ impl RequestedVersion { impl std::fmt::Display for RequestedVersion { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - RequestedVersion::Quality(quality) => write!(f, "{}", quality.get_capitalized_name()), - RequestedVersion::Version { version, .. } => { - write!(f, "{}", version) + RequestedVersion::Default => { + write!(f, "{}", QUALITY) } - RequestedVersion::Commit { commit, quality } => { - write!(f, "{}/{}", quality, commit) + RequestedVersion::Commit(commit) => { + write!(f, "{}/{}", QUALITY, commit) } RequestedVersion::Path(path) => write!(f, "{}", path), } @@ -81,19 +68,8 @@ impl TryFrom<&str> for RequestedVersion { type Error = InvalidRequestedVersion; fn try_from(s: &str) -> Result { - if let Ok(quality) = options::Quality::try_from(s) { - return Ok(RequestedVersion::Quality(quality)); - } - - if SEMVER_RE.is_match(s) { - return Ok(RequestedVersion::Version { - quality: if s.ends_with("-insider") { - options::Quality::Insiders - } else { - options::Quality::Stable - }, - version: s.to_string(), - }); + if s == QUALITY { + return Ok(RequestedVersion::Default); } if Path::is_absolute(&PathBuf::from(s)) { @@ -101,13 +77,7 @@ impl TryFrom<&str> for RequestedVersion { } if COMMIT_RE.is_match(s) { - let idx = s.find('/').expect("expected a /"); - if let Ok(quality) = options::Quality::try_from(&s[0..idx]) { - return Ok(RequestedVersion::Commit { - commit: s[idx + 1..].to_string(), - quality, - }); - } + return Ok(RequestedVersion::Commit(s.to_string())); } Err(InvalidRequestedVersion()) @@ -206,7 +176,7 @@ impl CodeVersionManager { .versions .get(stored.current) .map(|(v, _)| v.clone()) - .unwrap_or(RequestedVersion::Quality(options::Quality::Stable)) + .unwrap_or(RequestedVersion::Default) } /// Tries to get the entrypoint for the version, if one can be found. @@ -221,7 +191,7 @@ impl CodeVersionManager { // For simple quality requests, see if that's installed already on the system let candidates = match &version { - RequestedVersion::Quality(q) => match detect_installed_program(&self.log, *q) { + RequestedVersion::Default => match detect_installed_program(&self.log) { Ok(p) => p, Err(e) => { warning!(self.log, "error looking up installed applications: {}", e); @@ -254,8 +224,8 @@ pub fn prompt_to_install(version: &RequestedVersion) { QUALITYLESS_PRODUCT_NAME, version ); - if let RequestedVersion::Quality(quality) = version { - if let Some(uri) = QUALITY_DOWNLOAD_URIS.as_ref().and_then(|m| m.get(quality)) { + if let RequestedVersion::Default = version { + if let Some(uri) = PRODUCT_DOWNLOAD_URL { // todo: on some platforms, we may be able to help automate installation. For example, // we can unzip the app ourselves on macOS and on windows we can download and spawn the GUI installer #[cfg(target_os = "linux")] @@ -272,11 +242,12 @@ pub fn prompt_to_install(version: &RequestedVersion) { } #[cfg(target_os = "macos")] -fn detect_installed_program(log: &log::Logger, quality: Quality) -> io::Result> { +fn detect_installed_program(log: &log::Logger) -> io::Result> { + use crate::constants::PRODUCT_NAME_LONG; + // easy, fast detection for where apps are usually installed let mut probable = PathBuf::from("/Applications"); - let app_name = quality.get_long_name(); - probable.push(format!("{}.app", app_name)); + probable.push(format!("{}.app", PRODUCT_NAME_LONG)); if probable.exists() { probable.extend(["Contents/Resources", "app", "bin", "code"]); return Ok(vec![probable]); @@ -316,7 +287,7 @@ fn detect_installed_program(log: &log::Logger, quality: Quality) -> io::Result { - if line.starts_with(app_name) && line.ends_with(':') { + if line.starts_with(PRODUCT_NAME_LONG) && line.ends_with(':') { state = State::LookingForLocation; } } @@ -341,13 +312,13 @@ fn detect_installed_program(log: &log::Logger, quality: Quality) -> io::Result io::Result> { - use crate::constants::WIN32_APP_IDS; +fn detect_installed_program(_log: &log::Logger) -> io::Result> { + use crate::constants::{APPLICATION_NAME, WIN32_APP_IDS}; use winreg::enums::{HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE}; use winreg::RegKey; let mut output: Vec = vec![]; - let app_ids = match WIN32_APP_IDS.as_ref().and_then(|m| m.get(&quality)) { + let app_ids = match WIN32_APP_IDS.as_ref() { Some(ids) => ids, None => return Ok(output), }; @@ -381,7 +352,7 @@ fn detect_installed_program(_log: &log::Logger, quality: Quality) -> io::Result< [ location.as_str(), "bin", - &format!("{}.cmd", quality.get_application_name()), + &format!("{}.cmd", APPLICATION_NAME), ] .iter() .collect(), @@ -397,7 +368,9 @@ fn detect_installed_program(_log: &log::Logger, quality: Quality) -> io::Result< // Looks for the given binary name in the PATH, returning all candidate matches. // Based on https://github.dev/microsoft/vscode-js-debug/blob/7594d05518df6700df51771895fcad0ddc7f92f9/src/common/pathUtils.ts#L15 #[cfg(target_os = "linux")] -fn detect_installed_program(log: &log::Logger, quality: Quality) -> io::Result> { +fn detect_installed_program(log: &log::Logger) -> io::Result> { + use crate::constants::APPLICATION_NAME; + let path = match std::env::var("PATH") { Ok(p) => p, Err(e) => { @@ -406,11 +379,10 @@ fn detect_installed_program(log: &log::Logger, quality: Quality) -> io::Result continue, Ok(_) => {} @@ -471,97 +443,40 @@ mod tests { fn test_detect_installed_program() { // developers can run this test and debug output manually; VS Code will not // be installed in CI, so the test only makes sure it doesn't error out - let result = detect_installed_program(&log::Logger::test(), Quality::Insiders); + let result = detect_installed_program(&log::Logger::test()); println!("result: {:?}", result); assert!(result.is_ok()); } - #[test] - fn test_requested_version_parses() { - assert_eq!( - RequestedVersion::try_from("1.2.3").unwrap(), - RequestedVersion::Version { - quality: options::Quality::Stable, - version: "1.2.3".to_string(), - } - ); - - assert_eq!( - RequestedVersion::try_from("1.2.3-insider").unwrap(), - RequestedVersion::Version { - quality: options::Quality::Insiders, - version: "1.2.3-insider".to_string(), - } - ); - - assert_eq!( - RequestedVersion::try_from("stable").unwrap(), - RequestedVersion::Quality(options::Quality::Stable) - ); - - assert_eq!( - RequestedVersion::try_from("insiders").unwrap(), - RequestedVersion::Quality(options::Quality::Insiders) - ); - - assert_eq!( - RequestedVersion::try_from("insiders/92fd228156aafeb326b23f6604028d342152313b") - .unwrap(), - RequestedVersion::Commit { - commit: "92fd228156aafeb326b23f6604028d342152313b".to_string(), - quality: options::Quality::Insiders - } - ); - - assert_eq!( - RequestedVersion::try_from("stable/92fd228156aafeb326b23f6604028d342152313b").unwrap(), - RequestedVersion::Commit { - commit: "92fd228156aafeb326b23f6604028d342152313b".to_string(), - quality: options::Quality::Stable - } - ); - - let exe = std::env::current_exe() - .expect("expected to get exe") - .to_string_lossy() - .to_string(); - assert_eq!( - RequestedVersion::try_from(exe.as_str()).unwrap(), - RequestedVersion::Path(exe), - ); - } - #[tokio::test] async fn test_set_preferred_version() { let dir = make_multiple_vscode_install(); let lp = LauncherPaths::new_without_replacements(dir.path().to_owned()); let vm1 = CodeVersionManager::new(log::Logger::test(), &lp, Platform::LinuxARM64); - assert_eq!( - vm1.get_preferred_version(), - RequestedVersion::Quality(options::Quality::Stable) - ); + assert_eq!(vm1.get_preferred_version(), RequestedVersion::Default); vm1.set_preferred_version( - RequestedVersion::Quality(options::Quality::Exploration), + RequestedVersion::Commit("foobar".to_string()), dir.path().join("desktop/stable"), ) .await .expect("expected to store"); vm1.set_preferred_version( - RequestedVersion::Quality(options::Quality::Insiders), + RequestedVersion::Commit("foobar2".to_string()), dir.path().join("desktop/stable"), ) .await .expect("expected to store"); + assert_eq!( vm1.get_preferred_version(), - RequestedVersion::Quality(options::Quality::Insiders) + RequestedVersion::Commit("foobar2".to_string()), ); let vm2 = CodeVersionManager::new(log::Logger::test(), &lp, Platform::LinuxARM64); assert_eq!( vm2.get_preferred_version(), - RequestedVersion::Quality(options::Quality::Insiders) + RequestedVersion::Commit("foobar2".to_string()), ); } diff --git a/cli/src/msgpack_rpc.rs b/cli/src/msgpack_rpc.rs index 219c923cdf2ab..ef6b7782074c3 100644 --- a/cli/src/msgpack_rpc.rs +++ b/cli/src/msgpack_rpc.rs @@ -122,7 +122,7 @@ pub struct MsgPackCodec { impl MsgPackCodec { pub fn new() -> Self { Self { - _marker: std::marker::PhantomData::default(), + _marker: std::marker::PhantomData, } } } diff --git a/cli/src/options.rs b/cli/src/options.rs index 9423a6da92ecd..e37a718a49a44 100644 --- a/cli/src/options.rs +++ b/cli/src/options.rs @@ -7,7 +7,7 @@ use std::fmt; use serde::{Deserialize, Serialize}; -use crate::constants::{APPLICATION_NAME_MAP, PRODUCT_NAME_LONG_MAP, SERVER_NAME_MAP}; +use crate::constants::SERVER_NAME_MAP; #[derive(clap::ValueEnum, Copy, Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)] pub enum Quality { @@ -38,30 +38,12 @@ impl Quality { } } - /// Product long name - pub fn get_long_name(&self) -> &'static str { - PRODUCT_NAME_LONG_MAP - .as_ref() - .and_then(|m| m.get(self)) - .map(|s| s.as_str()) - .unwrap_or("Code - OSS") - } - - /// Product application name - pub fn get_application_name(&self) -> &'static str { - APPLICATION_NAME_MAP - .as_ref() - .and_then(|m| m.get(self)) - .map(|s| s.as_str()) - .unwrap_or("code") - } - /// Server application name pub fn server_entrypoint(&self) -> String { let mut server_name = SERVER_NAME_MAP .as_ref() .and_then(|m| m.get(self)) - .map(|s| s.as_str()) + .map(|s| s.server_application_name.as_str()) .unwrap_or("code-server-oss") .to_string(); diff --git a/cli/src/rpc.rs b/cli/src/rpc.rs index acd53dc38e077..a9a66153735dc 100644 --- a/cli/src/rpc.rs +++ b/cli/src/rpc.rs @@ -117,7 +117,7 @@ impl RpcMethodBuilder { Ok(p) => p, Err(err) => { return id.map(|id| { - serial.serialize(&ErrorResponse { + serial.serialize(ErrorResponse { id, error: ResponseError { code: 0, @@ -131,7 +131,7 @@ impl RpcMethodBuilder { match callback(param.params, &context) { Ok(result) => id.map(|id| serial.serialize(&SuccessResponse { id, result })), Err(err) => id.map(|id| { - serial.serialize(&ErrorResponse { + serial.serialize(ErrorResponse { id, error: ResponseError { code: -1, @@ -161,7 +161,7 @@ impl RpcMethodBuilder { Ok(p) => p, Err(err) => { return future::ready(id.map(|id| { - serial.serialize(&ErrorResponse { + serial.serialize(ErrorResponse { id, error: ResponseError { code: 0, @@ -182,7 +182,7 @@ impl RpcMethodBuilder { id.map(|id| serial.serialize(&SuccessResponse { id, result })) } Err(err) => id.map(|id| { - serial.serialize(&ErrorResponse { + serial.serialize(ErrorResponse { id, error: ResponseError { code: -1, @@ -222,7 +222,7 @@ impl RpcMethodBuilder { return ( None, future::ready(id.map(|id| { - serial.serialize(&ErrorResponse { + serial.serialize(ErrorResponse { id, error: ResponseError { code: 0, @@ -255,7 +255,7 @@ impl RpcMethodBuilder { match callback(servers, param.params, context).await { Ok(r) => id.map(|id| serial.serialize(&SuccessResponse { id, result: r })), Err(err) => id.map(|id| { - serial.serialize(&ErrorResponse { + serial.serialize(ErrorResponse { id, error: ResponseError { code: -1, @@ -427,7 +427,7 @@ impl RpcDispatcher { Some(Method::Async(callback)) => MaybeSync::Future(callback(id, body)), Some(Method::Duplex(callback)) => MaybeSync::Stream(callback(id, body)), None => MaybeSync::Sync(id.map(|id| { - self.serializer.serialize(&ErrorResponse { + self.serializer.serialize(ErrorResponse { id, error: ResponseError { code: -1, diff --git a/cli/src/self_update.rs b/cli/src/self_update.rs index 2e95719a3b9b3..4a878dc544716 100644 --- a/cli/src/self_update.rs +++ b/cli/src/self_update.rs @@ -11,7 +11,7 @@ use crate::{ options::Quality, update_service::{unzip_downloaded_release, Platform, Release, TargetKind, UpdateService}, util::{ - errors::{wrap, AnyError, CorruptDownload, UpdatesNotConfigured}, + errors::{wrap, AnyError, CodeError, CorruptDownload}, http, io::{ReportCopyProgress, SilentCopyProgress}, }, @@ -27,14 +27,16 @@ pub struct SelfUpdate<'a> { impl<'a> SelfUpdate<'a> { pub fn new(update_service: &'a UpdateService) -> Result { let commit = VSCODE_CLI_COMMIT - .ok_or_else(|| UpdatesNotConfigured("unknown build commit".to_string()))?; + .ok_or_else(|| CodeError::UpdatesNotConfigured("unknown build commit"))?; let quality = VSCODE_CLI_QUALITY - .ok_or_else(|| UpdatesNotConfigured("no configured quality".to_string())) - .and_then(|q| Quality::try_from(q).map_err(UpdatesNotConfigured))?; + .ok_or_else(|| CodeError::UpdatesNotConfigured("no configured quality")) + .and_then(|q| { + Quality::try_from(q).map_err(|_| CodeError::UpdatesNotConfigured("unknown quality")) + })?; let platform = Platform::env_default().ok_or_else(|| { - UpdatesNotConfigured("Unknown platform, please report this error".to_string()) + CodeError::UpdatesNotConfigured("Unknown platform, please report this error") })?; Ok(Self { diff --git a/cli/src/singleton.rs b/cli/src/singleton.rs index 0ea9cda2a8a43..635c400fb0f6d 100644 --- a/cli/src/singleton.rs +++ b/cli/src/singleton.rs @@ -53,12 +53,12 @@ struct LockFileMatter { /// Tries to acquire the singleton homed at the given lock file, either starting /// a new singleton if it doesn't exist, or connecting otherwise. -pub async fn acquire_singleton(lock_file: PathBuf) -> Result { +pub async fn acquire_singleton(lock_file: &Path) -> Result { let file = OpenOptions::new() .read(true) .write(true) .create(true) - .open(&lock_file) + .open(lock_file) .map_err(CodeError::SingletonLockfileOpenFailed)?; match FileLock::acquire(file) { @@ -158,7 +158,7 @@ mod tests { #[tokio::test] async fn test_acquires_singleton() { let dir = tempfile::tempdir().expect("expected to make temp dir"); - let s = acquire_singleton(dir.path().join("lock")) + let s = acquire_singleton(&dir.path().join("lock")) .await .expect("expected to acquire"); @@ -172,7 +172,7 @@ mod tests { async fn test_acquires_client() { let dir = tempfile::tempdir().expect("expected to make temp dir"); let lockfile = dir.path().join("lock"); - let s1 = acquire_singleton(lockfile.clone()) + let s1 = acquire_singleton(&lockfile) .await .expect("expected to acquire1"); match s1 { @@ -182,7 +182,7 @@ mod tests { _ => panic!("expected to be singleton"), }; - let s2 = acquire_singleton(lockfile) + let s2 = acquire_singleton(&lockfile) .await .expect("expected to acquire2"); match s2 { diff --git a/cli/src/state.rs b/cli/src/state.rs index af0d18e160b34..8815e2df40ce4 100644 --- a/cli/src/state.rs +++ b/cli/src/state.rs @@ -187,6 +187,14 @@ impl LauncherPaths { )) } + /// Lockfile for port forwarding + pub fn forwarding_lockfile(&self) -> PathBuf { + self.root.join(format!( + "forwarding-{}.lock", + VSCODE_CLI_QUALITY.unwrap_or("oss") + )) + } + /// Suggested path for tunnel service logs, when using file logs pub fn service_log_file(&self) -> PathBuf { self.root.join("tunnel-service.log") @@ -204,4 +212,10 @@ impl LauncherPaths { ) }) } + + /// Suggested path for web server storage + pub fn web_server_storage(&self) -> PathBuf { + self.root.join("serve-web") + } + } diff --git a/cli/src/tunnels.rs b/cli/src/tunnels.rs index 5d97b757afc1d..7378cf34afd6d 100644 --- a/cli/src/tunnels.rs +++ b/cli/src/tunnels.rs @@ -11,6 +11,7 @@ pub mod protocol; pub mod shutdown_signal; pub mod singleton_client; pub mod singleton_server; +pub mod local_forwarding; mod wsl_detect; mod challenge; @@ -34,7 +35,7 @@ mod service_macos; mod service_windows; mod socket_signal; -pub use control_server::{serve, serve_stream, Next, ServeStreamParams}; +pub use control_server::{serve, serve_stream, Next, ServeStreamParams, AuthRequired}; pub use nosleep::SleepInhibitor; pub use service::{ create_service_manager, ServiceContainer, ServiceManager, SERVICE_LOG_FILE_NAME, diff --git a/cli/src/tunnels/code_server.rs b/cli/src/tunnels/code_server.rs index 1246e1c944146..5bc5e39514a6a 100644 --- a/cli/src/tunnels/code_server.rs +++ b/cli/src/tunnels/code_server.rs @@ -541,6 +541,15 @@ impl<'a> ServerBuilder<'a> { debug!(self.logger, "Starting server with command... {:?}", cmd); + // On Windows spawning a code-server binary will run cmd.exe /c C:\path\to\code-server.cmd... + // This spawns a cmd.exe window for the user, which if they close will kill the code-server process + // and disconnect the tunnel. To prevent this, pass the CREATE_NO_WINDOW flag to the Command + // only on Windows. + // Original issue: https://github.com/microsoft/vscode/issues/184058 + // Partial fix: https://github.com/microsoft/vscode/pull/184621 + #[cfg(target_os = "windows")] + let cmd = cmd.creation_flags(winapi::um::winbase::CREATE_NO_WINDOW); + let child = cmd .stderr(std::process::Stdio::piped()) .stdout(std::process::Stdio::piped()) @@ -566,7 +575,17 @@ impl<'a> ServerBuilder<'a> { } fn get_base_command(&self) -> Command { + #[cfg(not(windows))] let mut cmd = Command::new(&self.server_paths.executable); + #[cfg(windows)] + let mut cmd = { + let mut cmd = Command::new("cmd"); + cmd.arg("/Q"); + cmd.arg("/C"); + cmd.arg(&self.server_paths.executable); + cmd + }; + cmd.stdin(std::process::Stdio::null()) .args(self.server_params.code_server_args.command_arguments()); cmd diff --git a/cli/src/tunnels/control_server.rs b/cli/src/tunnels/control_server.rs index e0c1ec19fc282..6f8c1060e1f44 100644 --- a/cli/src/tunnels/control_server.rs +++ b/cli/src/tunnels/control_server.rs @@ -48,11 +48,11 @@ use super::dev_tunnels::ActiveTunnel; use super::paths::prune_stopped_servers; use super::port_forwarder::{PortForwarding, PortForwardingProcessor}; use super::protocol::{ - AcquireCliParams, CallServerHttpParams, CallServerHttpResult, ChallengeIssueResponse, - ChallengeVerifyParams, ClientRequestMethod, EmptyObject, ForwardParams, ForwardResult, - FsStatRequest, FsStatResponse, GetEnvResponse, GetHostnameResponse, HttpBodyParams, - HttpHeadersParams, ServeParams, ServerLog, ServerMessageParams, SpawnParams, SpawnResult, - ToClientRequest, UnforwardParams, UpdateParams, UpdateResult, VersionResponse, + AcquireCliParams, CallServerHttpParams, CallServerHttpResult, ChallengeIssueParams, + ChallengeIssueResponse, ChallengeVerifyParams, ClientRequestMethod, EmptyObject, ForwardParams, + ForwardResult, FsStatRequest, FsStatResponse, GetEnvResponse, GetHostnameResponse, + HttpBodyParams, HttpHeadersParams, ServeParams, ServerLog, ServerMessageParams, SpawnParams, + SpawnResult, ToClientRequest, UnforwardParams, UpdateParams, UpdateResult, VersionResponse, METHOD_CHALLENGE_VERIFY, }; use super::server_bridge::ServerBridge; @@ -94,8 +94,8 @@ struct HandlerContext { /// Handler auth state. enum AuthState { - /// Auth is required, we're waiting for the client to send its challenge. - WaitingForChallenge, + /// Auth is required, we're waiting for the client to send its challenge optionally bearing a token. + WaitingForChallenge(Option), /// A challenge has been issued. Waiting for a verification. ChallengeIssued(String), /// Auth is no longer required. @@ -215,7 +215,7 @@ pub async fn serve( code_server_args: own_code_server_args, platform, exit_barrier: own_exit, - requires_auth: false, + requires_auth: AuthRequired::None, }).with_context(cx.clone()).await; cx.span().add_event( @@ -233,12 +233,20 @@ pub async fn serve( } } +#[derive(Clone)] +pub enum AuthRequired { + None, + VSDA, + VSDAWithToken(String), +} + +#[derive(Clone)] pub struct ServeStreamParams { pub log: log::Logger, pub launcher_paths: LauncherPaths, pub code_server_args: CodeServerArgs, pub platform: Platform, - pub requires_auth: bool, + pub requires_auth: AuthRequired, pub exit_barrier: Barrier, } @@ -268,7 +276,7 @@ fn make_socket_rpc( launcher_paths: LauncherPaths, code_server_args: CodeServerArgs, port_forwarding: Option, - requires_auth: bool, + requires_auth: AuthRequired, platform: Platform, ) -> RpcDispatcher { let http_requests = Arc::new(std::sync::Mutex::new(HashMap::new())); @@ -276,8 +284,9 @@ fn make_socket_rpc( let mut rpc = RpcBuilder::new(MsgPackSerializer {}).methods(HandlerContext { did_update: Arc::new(AtomicBool::new(false)), auth_state: Arc::new(std::sync::Mutex::new(match requires_auth { - true => AuthState::WaitingForChallenge, - false => AuthState::Authenticated, + AuthRequired::VSDAWithToken(t) => AuthState::WaitingForChallenge(Some(t)), + AuthRequired::VSDA => AuthState::WaitingForChallenge(None), + AuthRequired::None => AuthState::Authenticated, })), socket_tx, log: log.clone(), @@ -304,8 +313,8 @@ fn make_socket_rpc( ensure_auth(&c.auth_state)?; handle_get_env() }); - rpc.register_sync(METHOD_CHALLENGE_ISSUE, |_: EmptyObject, c| { - handle_challenge_issue(&c.auth_state) + rpc.register_sync(METHOD_CHALLENGE_ISSUE, |p: ChallengeIssueParams, c| { + handle_challenge_issue(p, &c.auth_state) }); rpc.register_sync(METHOD_CHALLENGE_VERIFY, |p: ChallengeVerifyParams, c| { handle_challenge_verify(p.response, &c.auth_state) @@ -422,6 +431,7 @@ async fn process_socket( let rx_counter = Arc::new(AtomicUsize::new(0)); let http_requests = Arc::new(std::sync::Mutex::new(HashMap::new())); + let already_authed = matches!(requires_auth, AuthRequired::None); let rpc = make_socket_rpc( log.clone(), socket_tx.clone(), @@ -439,7 +449,7 @@ async fn process_socket( let socket_tx = socket_tx.clone(); let exit_barrier = exit_barrier.clone(); tokio::spawn(async move { - if !requires_auth { + if already_authed { send_version(&socket_tx).await; } @@ -825,13 +835,22 @@ fn handle_get_env() -> Result { } fn handle_challenge_issue( + params: ChallengeIssueParams, auth_state: &Arc>, ) -> Result { let challenge = create_challenge(); let mut auth_state = auth_state.lock().unwrap(); - *auth_state = AuthState::ChallengeIssued(challenge.clone()); + if let AuthState::WaitingForChallenge(Some(s)) = &*auth_state { + println!("looking for token {}, got {:?}", s, params.token); + match ¶ms.token { + Some(t) if s != t => return Err(CodeError::AuthChallengeBadToken.into()), + None => return Err(CodeError::AuthChallengeBadToken.into()), + _ => {} + } + } + *auth_state = AuthState::ChallengeIssued(challenge.clone()); Ok(ChallengeIssueResponse { challenge }) } @@ -843,7 +862,7 @@ fn handle_challenge_verify( match &*auth_state { AuthState::Authenticated => Ok(EmptyObject {}), - AuthState::WaitingForChallenge => Err(CodeError::AuthChallengeNotIssued.into()), + AuthState::WaitingForChallenge(_) => Err(CodeError::AuthChallengeNotIssued.into()), AuthState::ChallengeIssued(c) => match verify_challenge(c, &response) { false => Err(CodeError::AuthChallengeNotIssued.into()), true => { diff --git a/cli/src/tunnels/dev_tunnels.rs b/cli/src/tunnels/dev_tunnels.rs index 8476028a2f5fc..b77f6da5f2e15 100644 --- a/cli/src/tunnels/dev_tunnels.rs +++ b/cli/src/tunnels/dev_tunnels.rs @@ -3,12 +3,11 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use crate::auth; -use crate::constants::{ - CONTROL_PORT, IS_INTERACTIVE_CLI, PROTOCOL_VERSION_TAG, TUNNEL_SERVICE_USER_AGENT, -}; +use crate::constants::{IS_INTERACTIVE_CLI, PROTOCOL_VERSION_TAG, TUNNEL_SERVICE_USER_AGENT}; use crate::state::{LauncherPaths, PersistedState}; use crate::util::errors::{ - wrap, AnyError, DevTunnelError, InvalidTunnelName, TunnelCreationFailed, WrappedError, + wrap, AnyError, CodeError, DevTunnelError, InvalidTunnelName, TunnelCreationFailed, + WrappedError, }; use crate::util::input::prompt_placeholder; use crate::{debug, info, log, spanf, trace, warning}; @@ -24,15 +23,19 @@ use std::time::Duration; use tokio::sync::{mpsc, watch}; use tunnels::connections::{ForwardedPortConnection, RelayTunnelHost}; use tunnels::contracts::{ - Tunnel, TunnelPort, TunnelRelayTunnelEndpoint, PORT_TOKEN, TUNNEL_PROTOCOL_AUTO, + Tunnel, TunnelAccessControl, TunnelPort, TunnelRelayTunnelEndpoint, PORT_TOKEN, + TUNNEL_ACCESS_SCOPES_CONNECT, TUNNEL_PROTOCOL_AUTO, }; use tunnels::management::{ new_tunnel_management, HttpError, TunnelLocator, TunnelManagementClient, TunnelRequestOptions, NO_REQUEST_OPTIONS, }; +use super::protocol::{self, PortPrivacy}; use super::wsl_detect::is_wsl_installed; +static TUNNEL_COUNT_LIMIT_NAME: &str = "TunnelsPerUserPerLocation"; + #[derive(Clone, Serialize, Deserialize)] pub struct PersistedTunnel { pub name: String, @@ -134,6 +137,7 @@ pub struct DevTunnels { log: log::Logger, launcher_tunnel: PersistedState>, client: TunnelManagementClient, + tag: &'static str, } /// Representation of a tunnel returned from the `start` methods. @@ -162,30 +166,52 @@ impl ActiveTunnel { } /// Forwards a port over TCP. - pub async fn add_port_tcp(&mut self, port_number: u16) -> Result<(), AnyError> { - self.manager.add_port_tcp(port_number).await?; + pub async fn add_port_tcp( + &self, + port_number: u16, + privacy: PortPrivacy, + ) -> Result<(), AnyError> { + self.manager.add_port_tcp(port_number, privacy).await?; Ok(()) } /// Removes a forwarded port TCP. - pub async fn remove_port(&mut self, port_number: u16) -> Result<(), AnyError> { + pub async fn remove_port(&self, port_number: u16) -> Result<(), AnyError> { self.manager.remove_port(port_number).await?; Ok(()) } + /// Gets the template string for forming forwarded port web URIs.. + pub fn get_port_format(&self) -> Result { + if let Some(details) = &*self.manager.endpoint_rx.borrow() { + return details + .as_ref() + .map(|r| { + r.base + .port_uri_format + .clone() + .expect("expected to have port format") + }) + .map_err(|e| e.clone().into()); + } + + Err(CodeError::NoTunnelEndpoint.into()) + } + /// Gets the public URI on which a forwarded port can be access in browser. - pub async fn get_port_uri(&mut self, port: u16) -> Result { - let endpoint = self.manager.get_endpoint().await?; - let format = endpoint - .base - .port_uri_format - .expect("expected to have port format"); - - Ok(format.replace(PORT_TOKEN, &port.to_string())) + pub fn get_port_uri(&self, port: u16) -> Result { + self.get_port_format() + .map(|f| f.replace(PORT_TOKEN, &port.to_string())) + } + + /// Gets an object to read the current tunnel status. + pub fn status(&self) -> StatusLock { + self.manager.get_status() } } const VSCODE_CLI_TUNNEL_TAG: &str = "vscode-server-launcher"; +const VSCODE_CLI_FORWARDING_TAG: &str = "vscode-port-forward"; const MAX_TUNNEL_NAME_LENGTH: usize = 20; fn get_host_token_from_tunnel(tunnel: &Tunnel) -> String { @@ -229,7 +255,7 @@ lazy_static! { #[derive(Clone, Debug)] pub struct ExistingTunnel { /// Name you'd like to assign preexisting tunnel to use to connect to the VS Code Server - pub tunnel_name: String, + pub tunnel_name: Option, /// Token to authenticate and use preexisting tunnel pub host_token: String, @@ -242,7 +268,29 @@ pub struct ExistingTunnel { } impl DevTunnels { - pub fn new(log: &log::Logger, auth: auth::Auth, paths: &LauncherPaths) -> DevTunnels { + /// Creates a new DevTunnels client used for port forwarding. + pub fn new_port_forwarding( + log: &log::Logger, + auth: auth::Auth, + paths: &LauncherPaths, + ) -> DevTunnels { + let mut client = new_tunnel_management(&TUNNEL_SERVICE_USER_AGENT); + client.authorization_provider(auth); + + DevTunnels { + log: log.clone(), + client: client.into(), + launcher_tunnel: PersistedState::new(paths.root().join("port_forwarding_tunnel.json")), + tag: VSCODE_CLI_FORWARDING_TAG, + } + } + + /// Creates a new DevTunnels client used for the Remote Tunnels extension to access the VS Code Server. + pub fn new_remote_tunnel( + log: &log::Logger, + auth: auth::Auth, + paths: &LauncherPaths, + ) -> DevTunnels { let mut client = new_tunnel_management(&TUNNEL_SERVICE_USER_AGENT); client.authorization_provider(auth); @@ -250,6 +298,7 @@ impl DevTunnels { log: log.clone(), client: client.into(), launcher_tunnel: PersistedState::new(paths.root().join("code_tunnel.json")), + tag: VSCODE_CLI_TUNNEL_TAG, } } @@ -275,7 +324,9 @@ impl DevTunnels { /// Renames the current tunnel to the new name. pub async fn rename_tunnel(&mut self, name: &str) -> Result<(), AnyError> { - self.update_tunnel_name(None, name).await.map(|_| ()) + self.update_tunnel_name(self.launcher_tunnel.load(), name) + .await + .map(|_| ()) } /// Updates the name of the existing persisted tunnel to the new name. @@ -286,28 +337,34 @@ impl DevTunnels { name: &str, ) -> Result<(Tunnel, PersistedTunnel), AnyError> { let name = name.to_ascii_lowercase(); - self.check_is_name_free(&name).await?; - - debug!(self.log, "Tunnel name changed, applying updates..."); let (mut full_tunnel, mut persisted, is_new) = match persisted { Some(persisted) => { + debug!( + self.log, + "Found a persisted tunnel, seeing if the name matches..." + ); self.get_or_create_tunnel(persisted, Some(&name), NO_REQUEST_OPTIONS) .await } - None => self - .create_tunnel(&name, NO_REQUEST_OPTIONS) - .await - .map(|(pt, t)| (t, pt, true)), + None => { + debug!(self.log, "Creating a new tunnel with the requested name"); + self.create_tunnel(&name, NO_REQUEST_OPTIONS) + .await + .map(|(pt, t)| (t, pt, true)) + } }?; - if is_new { + let desired_tags = self.get_tags(&name); + if is_new || vec_eq_as_set(&full_tunnel.tags, &desired_tags) { return Ok((full_tunnel, persisted)); } - full_tunnel.tags = self.get_tags(&name); + debug!(self.log, "Tunnel name changed, applying updates..."); + + full_tunnel.tags = desired_tags; - let new_tunnel = spanf!( + let updated_tunnel = spanf!( self.log, self.log.span("dev-tunnel.tag.update"), self.client.update_tunnel(&full_tunnel, NO_REQUEST_OPTIONS) @@ -317,7 +374,7 @@ impl DevTunnels { persisted.name = name; self.launcher_tunnel.save(Some(persisted.clone()))?; - Ok((new_tunnel, persisted)) + Ok((updated_tunnel, persisted)) } /// Gets the persisted tunnel from the service, or creates a new one. @@ -356,6 +413,7 @@ impl DevTunnels { &mut self, preferred_name: Option<&str>, use_random_name: bool, + preserve_ports: &[u16], ) -> Result { let (mut tunnel, persisted) = match self.launcher_tunnel.load() { Some(mut persisted) => { @@ -385,7 +443,12 @@ impl DevTunnels { }; tunnel = self - .sync_tunnel_tags(&persisted.name, tunnel, &HOST_TUNNEL_REQUEST_OPTIONS) + .sync_tunnel_tags( + &self.client, + &persisted.name, + tunnel, + &HOST_TUNNEL_REQUEST_OPTIONS, + ) .await?; let locator = TunnelLocator::try_from(&tunnel).unwrap(); @@ -394,7 +457,7 @@ impl DevTunnels { for port_to_delete in tunnel .ports .iter() - .filter(|p| p.port_number != CONTROL_PORT) + .filter(|p: &&TunnelPort| !preserve_ports.contains(&p.port_number)) { let output_fut = self.client.delete_tunnel_port( &locator, @@ -443,64 +506,73 @@ impl DevTunnels { ) -> Result<(PersistedTunnel, Tunnel), AnyError> { info!(self.log, "Creating tunnel with the name: {}", name); - let mut tried_recycle = false; - - let new_tunnel = Tunnel { - tags: vec![ - name.to_string(), - PROTOCOL_VERSION_TAG.to_string(), - VSCODE_CLI_TUNNEL_TAG.to_string(), - ], - ..Default::default() - }; - - loop { - let result = spanf!( - self.log, - self.log.span("dev-tunnel.create"), - self.client.create_tunnel(&new_tunnel, options) - ); - - match result { - Err(HttpError::ResponseError(e)) - if e.status_code == StatusCode::TOO_MANY_REQUESTS => - { - if !tried_recycle && self.try_recycle_tunnel().await? { - tried_recycle = true; - continue; - } - - if let Some(d) = e.get_details() { - let detail = d.detail.unwrap_or_else(|| "unknown".to_string()); - return Err(AnyError::from(TunnelCreationFailed( - name.to_string(), - detail, - ))); + let tunnel = match self.get_existing_tunnel_with_name(name).await? { + Some(e) => { + let loc = TunnelLocator::try_from(&e).unwrap(); + info!(self.log, "Adopting existing tunnel (ID={:?})", loc); + spanf!( + self.log, + self.log.span("dev-tunnel.tag.get"), + self.client.get_tunnel(&loc, &HOST_TUNNEL_REQUEST_OPTIONS) + ) + .map_err(|e| wrap(e, "failed to lookup tunnel"))? + } + None => { + let new_tunnel = Tunnel { + tags: self.get_tags(name), + ..Default::default() + }; + + loop { + let result = spanf!( + self.log, + self.log.span("dev-tunnel.create"), + self.client.create_tunnel(&new_tunnel, options) + ); + + match result { + Err(HttpError::ResponseError(e)) + if e.status_code == StatusCode::TOO_MANY_REQUESTS => + { + if let Some(d) = e.get_details() { + let detail = d.detail.unwrap_or_else(|| "unknown".to_string()); + if detail.contains(TUNNEL_COUNT_LIMIT_NAME) + && self.try_recycle_tunnel().await? + { + continue; + } + + return Err(AnyError::from(TunnelCreationFailed( + name.to_string(), + detail, + ))); + } + + return Err(AnyError::from(TunnelCreationFailed( + name.to_string(), + "You have exceeded a limit for the port fowarding service. Please remove other machines before trying to add this machine.".to_string(), + ))); + } + Err(e) => { + return Err(AnyError::from(TunnelCreationFailed( + name.to_string(), + format!("{:?}", e), + ))) + } + Ok(t) => break t, } - - return Err(AnyError::from(TunnelCreationFailed( - name.to_string(), - "You have exceeded a limit for the port fowarding service. Please remove other machines before trying to add this machine.".to_string(), - ))); - } - Err(e) => { - return Err(AnyError::from(TunnelCreationFailed( - name.to_string(), - format!("{:?}", e), - ))) - } - Ok(t) => { - let pt = PersistedTunnel { - cluster: t.cluster_id.clone().unwrap(), - id: t.tunnel_id.clone().unwrap(), - name: name.to_string(), - }; - - self.launcher_tunnel.save(Some(pt.clone()))?; - return Ok((pt, t)); } } - } + }; + + let pt = PersistedTunnel { + cluster: tunnel.cluster_id.clone().unwrap(), + id: tunnel.tunnel_id.clone().unwrap(), + name: name.to_string(), + }; + + self.launcher_tunnel.save(Some(pt.clone()))?; + Ok((pt, tunnel)) } /// Gets the expected tunnel tags @@ -508,7 +580,7 @@ impl DevTunnels { let mut tags = vec![ name.to_string(), PROTOCOL_VERSION_TAG.to_string(), - VSCODE_CLI_TUNNEL_TAG.to_string(), + self.tag.to_string(), ]; if is_wsl_installed(&self.log) { @@ -522,12 +594,13 @@ impl DevTunnels { /// other version tags. async fn sync_tunnel_tags( &self, + client: &TunnelManagementClient, name: &str, tunnel: Tunnel, options: &TunnelRequestOptions, ) -> Result { let new_tags = self.get_tags(name); - if vec_eq_unsorted(&tunnel.tags, &new_tags) { + if vec_eq_as_set(&tunnel.tags, &new_tags) { return Ok(tunnel); } @@ -548,7 +621,7 @@ impl DevTunnels { let result = spanf!( self.log, self.log.span("dev-tunnel.protocol-tag-update"), - self.client.update_tunnel(&tunnel_update, options) + client.update_tunnel(&tunnel_update, options) ); result.map_err(|e| wrap(e, "tunnel tag update failed").into()) @@ -599,7 +672,7 @@ impl DevTunnels { self.log, self.log.span("dev-tunnel.listall"), self.client.list_all_tunnels(&TunnelRequestOptions { - tags: vec![VSCODE_CLI_TUNNEL_TAG.to_string()], + tags: vec![self.tag.to_string()], require_all_tags: true, ..Default::default() }) @@ -609,24 +682,28 @@ impl DevTunnels { Ok(tunnels) } - async fn check_is_name_free(&mut self, name: &str) -> Result<(), AnyError> { - let existing = spanf!( + async fn get_existing_tunnel_with_name(&self, name: &str) -> Result, AnyError> { + let existing: Vec = spanf!( self.log, self.log.span("dev-tunnel.rename.search"), self.client.list_all_tunnels(&TunnelRequestOptions { - tags: vec![VSCODE_CLI_TUNNEL_TAG.to_string(), name.to_string()], + tags: vec![self.tag.to_string(), name.to_string()], require_all_tags: true, + limit: 1, + include_ports: true, + token_scopes: vec!["host".to_string()], ..Default::default() }) ) .map_err(|e| wrap(e, "failed to list existing tunnels"))?; - if !existing.is_empty() { - return Err(AnyError::from(TunnelCreationFailed( - name.to_string(), - "tunnel name already in use".to_string(), - ))); - }; - Ok(()) + + Ok(existing.into_iter().next()) + } + + fn get_placeholder_name() -> String { + let mut n = clean_hostname_for_tunnel(&gethostname::gethostname().to_string_lossy()); + n.make_ascii_lowercase(); + n } async fn get_name_for_tunnel( @@ -660,10 +737,7 @@ impl DevTunnels { use_random_name = true; } - let mut placeholder_name = - clean_hostname_for_tunnel(&gethostname::gethostname().to_string_lossy()); - placeholder_name.make_ascii_lowercase(); - + let mut placeholder_name = Self::get_placeholder_name(); if !is_name_free(&placeholder_name) { for i in 2.. { let fixed_name = format!("{}{}", placeholder_name, i); @@ -705,7 +779,10 @@ impl DevTunnels { tunnel: ExistingTunnel, ) -> Result { let tunnel_details = PersistedTunnel { - name: tunnel.tunnel_name, + name: match tunnel.tunnel_name { + Some(n) => n, + None => Self::get_placeholder_name(), + }, id: tunnel.tunnel_id, cluster: tunnel.cluster, }; @@ -715,10 +792,23 @@ impl DevTunnels { tunnel.host_token.clone(), )); + let client = mgmt.into(); + self.sync_tunnel_tags( + &client, + &tunnel_details.name, + Tunnel { + cluster_id: Some(tunnel_details.cluster.clone()), + tunnel_id: Some(tunnel_details.id.clone()), + ..Default::default() + }, + &HOST_TUNNEL_REQUEST_OPTIONS, + ) + .await?; + self.start_tunnel( tunnel_details.locator(), &tunnel_details, - mgmt.into(), + client, StaticAccessTokenProvider::new(tunnel.host_token), ) .await @@ -758,10 +848,36 @@ impl DevTunnels { } } +#[derive(Clone, Default)] +pub struct StatusLock(Arc>); + +impl StatusLock { + fn succeed(&self) { + let mut status = self.0.lock().unwrap(); + status.tunnel = protocol::singleton::TunnelState::Connected; + status.last_connected_at = Some(chrono::Utc::now()); + } + + fn fail(&self, reason: String) { + let mut status = self.0.lock().unwrap(); + if let protocol::singleton::TunnelState::Connected = status.tunnel { + status.last_disconnected_at = Some(chrono::Utc::now()); + status.tunnel = protocol::singleton::TunnelState::Disconnected; + } + status.last_fail_reason = Some(reason); + } + + pub fn read(&self) -> protocol::singleton::Status { + let status = self.0.lock().unwrap(); + status.clone() + } +} + struct ActiveTunnelManager { close_tx: Option>, endpoint_rx: watch::Receiver>>, relay: Arc>, + status: StatusLock, } impl ActiveTunnelManager { @@ -777,6 +893,9 @@ impl ActiveTunnelManager { let relay = Arc::new(tokio::sync::Mutex::new(RelayTunnelHost::new(locator, mgmt))); let relay_spawned = relay.clone(); + let status = StatusLock::default(); + + let status_spawned = status.clone(); tokio::spawn(async move { ActiveTunnelManager::spawn_tunnel( log, @@ -784,6 +903,7 @@ impl ActiveTunnelManager { close_rx, endpoint_tx, access_token, + status_spawned, ) .await; }); @@ -792,18 +912,29 @@ impl ActiveTunnelManager { endpoint_rx, relay, close_tx: Some(close_tx), + status, } } + /// Gets a copy of the current tunnel status information + pub fn get_status(&self) -> StatusLock { + self.status.clone() + } + /// Adds a port for TCP/IP forwarding. #[allow(dead_code)] // todo: port forwarding - pub async fn add_port_tcp(&self, port_number: u16) -> Result<(), WrappedError> { + pub async fn add_port_tcp( + &self, + port_number: u16, + privacy: PortPrivacy, + ) -> Result<(), WrappedError> { self.relay .lock() .await .add_port(&TunnelPort { port_number, protocol: Some(TUNNEL_PROTOCOL_AUTO.to_owned()), + access_control: Some(privacy_to_tunnel_acl(privacy)), ..Default::default() }) .await @@ -877,12 +1008,15 @@ impl ActiveTunnelManager { mut close_rx: mpsc::Receiver<()>, endpoint_tx: watch::Sender>>, access_token_provider: impl AccessTokenProvider + 'static, + status: StatusLock, ) { let mut backoff = Backoff::new(Duration::from_secs(5), Duration::from_secs(120)); macro_rules! fail { ($e: expr, $msg: expr) => { - warning!(log, "{}: {}", $msg, $e); + let fmt = format!("{}: {}", $msg, $e); + warning!(log, &fmt); + status.fail(fmt); endpoint_tx.send(Some(Err($e))).ok(); backoff.delay().await; }; @@ -918,6 +1052,7 @@ impl ActiveTunnelManager { }; backoff.reset(); + status.succeed(); endpoint_tx.send(Some(Ok(handle.endpoint().clone()))).ok(); tokio::select! { @@ -998,7 +1133,7 @@ fn clean_hostname_for_tunnel(hostname: &str) -> String { } } -fn vec_eq_unsorted(a: &[String], b: &[String]) -> bool { +fn vec_eq_as_set(a: &[String], b: &[String]) -> bool { if a.len() != b.len() { return false; } @@ -1012,6 +1147,26 @@ fn vec_eq_unsorted(a: &[String], b: &[String]) -> bool { true } +fn privacy_to_tunnel_acl(privacy: PortPrivacy) -> TunnelAccessControl { + let mut acl = TunnelAccessControl { entries: vec![] }; + + if privacy == PortPrivacy::Public { + acl.entries + .push(tunnels::contracts::TunnelAccessControlEntry { + kind: tunnels::contracts::TunnelAccessControlEntryType::Anonymous, + provider: None, + is_inherited: false, + is_deny: false, + is_inverse: false, + organization: None, + subjects: vec![], + scopes: vec![TUNNEL_ACCESS_SCOPES_CONNECT.to_string()], + }); + } + + acl +} + #[cfg(test)] mod test { use super::*; diff --git a/cli/src/tunnels/legal.rs b/cli/src/tunnels/legal.rs index 84b72bf8e695f..35316af4fde9a 100644 --- a/cli/src/tunnels/legal.rs +++ b/cli/src/tunnels/legal.rs @@ -2,13 +2,18 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -use crate::constants::{IS_INTERACTIVE_CLI, PRODUCT_NAME_LONG}; +use crate::constants::IS_INTERACTIVE_CLI; use crate::state::{LauncherPaths, PersistedState}; -use crate::util::errors::{AnyError, MissingLegalConsent}; +use crate::util::errors::{AnyError, CodeError}; use crate::util::input::prompt_yn; +use lazy_static::lazy_static; use serde::{Deserialize, Serialize}; -const LICENSE_TEXT: Option<&'static str> = option_env!("VSCODE_CLI_REMOTE_LICENSE_TEXT"); +lazy_static! { + static ref LICENSE_TEXT: Option> = + option_env!("VSCODE_CLI_SERVER_LICENSE").and_then(|s| serde_json::from_str(s).unwrap()); +} + const LICENSE_PROMPT: Option<&'static str> = option_env!("VSCODE_CLI_REMOTE_LICENSE_PROMPT"); #[derive(Clone, Default, Serialize, Deserialize)] @@ -20,8 +25,8 @@ pub fn require_consent( paths: &LauncherPaths, accept_server_license_terms: bool, ) -> Result<(), AnyError> { - match LICENSE_TEXT { - Some(t) => println!("{}", t.replace("\\n", "\r\n")), + match &*LICENSE_TEXT { + Some(t) => println!("{}", t.join("\r\n")), None => return Ok(()), } @@ -41,23 +46,14 @@ pub fn require_consent( if accept_server_license_terms { load.consented = Some(true); } else if !*IS_INTERACTIVE_CLI { - return Err(MissingLegalConsent( - "Run this command again with --accept-server-license-terms to indicate your agreement." - .to_string(), - ) - .into()); + return Err(CodeError::NeedsInteractiveLegalConsent.into()); } else { match prompt_yn(prompt) { Ok(true) => { load.consented = Some(true); } - Ok(false) => { - return Err(AnyError::from(MissingLegalConsent(format!( - "Sorry you cannot use {} CLI without accepting the terms.", - PRODUCT_NAME_LONG - )))) - } - Err(e) => return Err(AnyError::from(MissingLegalConsent(e.to_string()))), + Ok(false) => return Err(CodeError::DeniedLegalConset.into()), + Err(_) => return Err(CodeError::NeedsInteractiveLegalConsent.into()), } } diff --git a/cli/src/tunnels/local_forwarding.rs b/cli/src/tunnels/local_forwarding.rs new file mode 100644 index 0000000000000..e6410860cb0e7 --- /dev/null +++ b/cli/src/tunnels/local_forwarding.rs @@ -0,0 +1,331 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +use std::{ + collections::HashMap, + ops::{Index, IndexMut}, + sync::{Arc, Mutex}, +}; + +use tokio::{ + pin, + sync::{mpsc, watch}, +}; + +use crate::{ + async_pipe::{socket_stream_split, AsyncPipe}, + json_rpc::{new_json_rpc, start_json_rpc}, + log, + singleton::SingletonServer, + util::{errors::CodeError, sync::Barrier}, +}; + +use super::{ + dev_tunnels::ActiveTunnel, + protocol::{ + self, + forward_singleton::{PortList, SetPortsResponse}, + PortPrivacy, + }, + shutdown_signal::ShutdownSignal, +}; + +#[derive(Default, Clone)] +struct PortCount { + public: u32, + private: u32, +} + +impl Index for PortCount { + type Output = u32; + + fn index(&self, privacy: PortPrivacy) -> &Self::Output { + match privacy { + PortPrivacy::Public => &self.public, + PortPrivacy::Private => &self.private, + } + } +} + +impl IndexMut for PortCount { + fn index_mut(&mut self, privacy: PortPrivacy) -> &mut Self::Output { + match privacy { + PortPrivacy::Public => &mut self.public, + PortPrivacy::Private => &mut self.private, + } + } +} + +impl PortCount { + fn is_empty(&self) -> bool { + self.public == 0 && self.private == 0 + } + + fn primary_privacy(&self) -> PortPrivacy { + if self.public > 0 { + PortPrivacy::Public + } else { + PortPrivacy::Private + } + } +} + +type PortMap = HashMap; + +/// The PortForwardingHandle is given out to multiple consumers to allow +/// them to set_ports that they want to be forwarded. +struct PortForwardingSender { + /// Todo: when `SyncUnsafeCell` is no longer nightly, we can use it here with + /// the following comment: + /// + /// SyncUnsafeCell is used and safe here because PortForwardingSender is used + /// exclusively in synchronous dispatch *and* we create a new sender in the + /// context for each connection, in `serve_singleton_rpc`. + /// + /// If PortForwardingSender is ever used in a different context, this should + /// be refactored, e.g. to use locks or `&mut self` in set_ports` + /// + /// see https://doc.rust-lang.org/stable/std/cell/struct.SyncUnsafeCell.html + current: Mutex, + sender: Arc>>, +} + +impl PortForwardingSender { + pub fn set_ports(&self, ports: PortList) { + let mut current = self.current.lock().unwrap(); + self.sender.lock().unwrap().send_modify(|v| { + for p in current.iter() { + if !ports.contains(p) { + let n = v.get_mut(&p.number).expect("expected port in map"); + n[p.privacy] -= 1; + if n.is_empty() { + v.remove(&p.number); + } + } + } + + for p in ports.iter() { + if !current.contains(p) { + match v.get_mut(&p.number) { + Some(n) => { + n[p.privacy] += 1; + } + None => { + let mut pc = PortCount::default(); + pc[p.privacy] += 1; + v.insert(p.number, pc); + } + }; + } + } + + current.splice(.., ports); + }); + } +} + +impl Clone for PortForwardingSender { + fn clone(&self) -> Self { + Self { + current: Mutex::new(vec![]), + sender: self.sender.clone(), + } + } +} + +impl Drop for PortForwardingSender { + fn drop(&mut self) { + self.set_ports(vec![]); + } +} + +struct PortForwardingReceiver { + receiver: watch::Receiver, +} + +impl PortForwardingReceiver { + pub fn new() -> (PortForwardingSender, Self) { + let (sender, receiver) = watch::channel(HashMap::new()); + let handle = PortForwardingSender { + current: Mutex::new(vec![]), + sender: Arc::new(Mutex::new(sender)), + }; + + let tracker = Self { receiver }; + + (handle, tracker) + } + + /// Applies all changes from PortForwardingHandles to the tunnel. + pub async fn apply_to(&mut self, log: log::Logger, tunnel: Arc) { + let mut current: PortMap = HashMap::new(); + while self.receiver.changed().await.is_ok() { + let next = self.receiver.borrow().clone(); + + for (port, count) in current.iter() { + let privacy = count.primary_privacy(); + if !matches!(next.get(port), Some(n) if n.primary_privacy() == privacy) { + match tunnel.remove_port(*port).await { + Ok(_) => info!(log, "stopped forwarding port {} at {:?}", *port, privacy), + Err(e) => error!(log, "failed to stop forwarding port {}: {}", port, e), + } + } + } + + for (port, count) in next.iter() { + let privacy = count.primary_privacy(); + if !matches!(current.get(port), Some(n) if n.primary_privacy() == privacy) { + match tunnel.add_port_tcp(*port, privacy).await { + Ok(_) => info!(log, "forwarding port {} at {:?}", port, privacy), + Err(e) => error!(log, "failed to forward port {}: {}", port, e), + } + } + } + + current = next; + } + } +} + +pub struct SingletonClientArgs { + pub log: log::Logger, + pub stream: AsyncPipe, + pub shutdown: Barrier, + pub port_requests: watch::Receiver, +} + +#[derive(Clone)] +struct SingletonServerContext { + log: log::Logger, + handle: PortForwardingSender, + tunnel: Arc, +} + +/// Serves a client singleton for port forwarding. +pub async fn client(args: SingletonClientArgs) -> Result<(), std::io::Error> { + let mut rpc = new_json_rpc(); + let (msg_tx, msg_rx) = mpsc::unbounded_channel(); + let SingletonClientArgs { + log, + shutdown, + stream, + mut port_requests, + } = args; + + debug!( + log, + "An existing port forwarding process is running on this machine, connecting to it..." + ); + + let caller = rpc.get_caller(msg_tx); + let rpc = rpc.methods(()).build(log.clone()); + let (read, write) = socket_stream_split(stream); + + let serve = start_json_rpc(rpc, read, write, msg_rx, shutdown); + let forward = async move { + while port_requests.changed().await.is_ok() { + let ports = port_requests.borrow().clone(); + let r = caller + .call::<_, _, protocol::forward_singleton::SetPortsResponse>( + protocol::forward_singleton::METHOD_SET_PORTS, + protocol::forward_singleton::SetPortsParams { ports }, + ) + .await + .unwrap(); + + match r { + Err(e) => error!(log, "failed to set ports: {:?}", e), + Ok(r) => print_forwarding_addr(&r), + }; + } + }; + + tokio::select! { + r = serve => r.map(|_| ()), + _ = forward => Ok(()), + } +} + +/// Serves a port-forwarding singleton. +pub async fn server( + log: log::Logger, + tunnel: ActiveTunnel, + server: SingletonServer, + mut port_requests: watch::Receiver, + shutdown_rx: Barrier, +) -> Result<(), CodeError> { + let tunnel = Arc::new(tunnel); + let (forward_tx, mut forward_rx) = PortForwardingReceiver::new(); + + let forward_own_tunnel = tunnel.clone(); + let forward_own_tx = forward_tx.clone(); + let forward_own = async move { + while port_requests.changed().await.is_ok() { + forward_own_tx.set_ports(port_requests.borrow().clone()); + print_forwarding_addr(&SetPortsResponse { + port_format: forward_own_tunnel.get_port_format().ok(), + }); + } + }; + + tokio::select! { + _ = forward_own => Ok(()), + _ = forward_rx.apply_to(log.clone(), tunnel.clone()) => Ok(()), + r = serve_singleton_rpc(server, log, tunnel, forward_tx, shutdown_rx) => r, + } +} + +async fn serve_singleton_rpc( + mut server: SingletonServer, + log: log::Logger, + tunnel: Arc, + forward_tx: PortForwardingSender, + shutdown_rx: Barrier, +) -> Result<(), CodeError> { + let mut own_shutdown = shutdown_rx.clone(); + let shutdown_fut = own_shutdown.wait(); + pin!(shutdown_fut); + + loop { + let cnx = tokio::select! { + c = server.accept() => c?, + _ = &mut shutdown_fut => return Ok(()), + }; + + let (read, write) = socket_stream_split(cnx); + let shutdown_rx = shutdown_rx.clone(); + + let handle = forward_tx.clone(); + let log = log.clone(); + let tunnel = tunnel.clone(); + tokio::spawn(async move { + // we make an rpc for the connection instead of re-using a dispatcher + // so that we can have the "handle" drop when the connection drops. + let rpc = new_json_rpc(); + let mut rpc = rpc.methods(SingletonServerContext { + log: log.clone(), + handle, + tunnel, + }); + + rpc.register_sync( + protocol::forward_singleton::METHOD_SET_PORTS, + |p: protocol::forward_singleton::SetPortsParams, ctx| { + info!(ctx.log, "client setting ports to {:?}", p.ports); + ctx.handle.set_ports(p.ports); + Ok(SetPortsResponse { + port_format: ctx.tunnel.get_port_format().ok(), + }) + }, + ); + + let _ = start_json_rpc(rpc.build(log), read, write, (), shutdown_rx).await; + }); + } +} + +fn print_forwarding_addr(r: &SetPortsResponse) { + eprintln!("{}\n", serde_json::to_string(r).unwrap()); +} diff --git a/cli/src/tunnels/port_forwarder.rs b/cli/src/tunnels/port_forwarder.rs index bb60a670dea9f..093c1c8176f09 100644 --- a/cli/src/tunnels/port_forwarder.rs +++ b/cli/src/tunnels/port_forwarder.rs @@ -12,7 +12,7 @@ use crate::{ util::errors::{AnyError, CannotForwardControlPort, ServerHasClosed}, }; -use super::dev_tunnels::ActiveTunnel; +use super::{dev_tunnels::ActiveTunnel, protocol::PortPrivacy}; pub enum PortForwardingRec { Forward(u16, oneshot::Sender>), @@ -87,11 +87,11 @@ impl PortForwardingProcessor { } if !self.forwarded.contains(&port) { - tunnel.add_port_tcp(port).await?; + tunnel.add_port_tcp(port, PortPrivacy::Private).await?; self.forwarded.insert(port); } - tunnel.get_port_uri(port).await + tunnel.get_port_uri(port) } } diff --git a/cli/src/tunnels/protocol.rs b/cli/src/tunnels/protocol.rs index eb20afe0ce588..316e3672ba69b 100644 --- a/cli/src/tunnels/protocol.rs +++ b/cli/src/tunnels/protocol.rs @@ -199,6 +199,11 @@ pub struct SpawnResult { pub const METHOD_CHALLENGE_ISSUE: &str = "challenge_issue"; pub const METHOD_CHALLENGE_VERIFY: &str = "challenge_verify"; +#[derive(Serialize, Deserialize)] +pub struct ChallengeIssueParams { + pub token: Option, +} + #[derive(Serialize, Deserialize)] pub struct ChallengeIssueResponse { pub challenge: String, @@ -209,8 +214,42 @@ pub struct ChallengeVerifyParams { pub response: String, } +#[derive(Serialize, Deserialize, PartialEq, Eq, Copy, Clone, Debug)] +#[serde(rename_all = "lowercase")] +pub enum PortPrivacy { + Public, + Private, +} + +pub mod forward_singleton { + use serde::{Deserialize, Serialize}; + + use super::PortPrivacy; + + pub const METHOD_SET_PORTS: &str = "set_ports"; + + #[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug)] + pub struct PortRec { + pub number: u16, + pub privacy: PortPrivacy, + } + + pub type PortList = Vec; + + #[derive(Serialize, Deserialize)] + pub struct SetPortsParams { + pub ports: PortList, + } + + #[derive(Serialize, Deserialize)] + pub struct SetPortsResponse { + pub port_format: Option, + } +} + pub mod singleton { use crate::log; + use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; pub const METHOD_RESTART: &str = "restart"; @@ -233,17 +272,41 @@ pub mod singleton { pub message: String, } - #[derive(Serialize, Deserialize)] + #[derive(Serialize, Deserialize, Clone, Default)] + pub struct StatusWithTunnelName { + pub name: Option, + #[serde(flatten)] + pub status: Status, + } + + #[derive(Serialize, Deserialize, Clone)] pub struct Status { + pub started_at: DateTime, pub tunnel: TunnelState, + pub last_connected_at: Option>, + pub last_disconnected_at: Option>, + pub last_fail_reason: Option, + } + + impl Default for Status { + fn default() -> Self { + Self { + started_at: Utc::now(), + tunnel: TunnelState::Disconnected, + last_connected_at: None, + last_disconnected_at: None, + last_fail_reason: None, + } + } } #[derive(Deserialize, Serialize, Debug)] pub struct LogReplayFinished {} - #[derive(Deserialize, Serialize, Debug)] + #[derive(Deserialize, Serialize, Debug, Default, Clone)] pub enum TunnelState { + #[default] Disconnected, - Connected { name: String }, + Connected, } } diff --git a/cli/src/tunnels/service_windows.rs b/cli/src/tunnels/service_windows.rs index 427eddd620d9e..3d2dc9f0c55b3 100644 --- a/cli/src/tunnels/service_windows.rs +++ b/cli/src/tunnels/service_windows.rs @@ -78,6 +78,7 @@ impl CliServiceManager for WindowsService { cmd.stderr(Stdio::null()); cmd.stdout(Stdio::null()); cmd.stdin(Stdio::null()); + cmd.creation_flags(CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS); cmd.spawn() .map_err(|e| wrapdbg(e, "error starting service"))?; @@ -121,8 +122,12 @@ impl CliServiceManager for WindowsService { async fn unregister(&self) -> Result<(), AnyError> { let key = WindowsService::open_key()?; - key.delete_value(TUNNEL_ACTIVITY_NAME) - .map_err(|e| AnyError::from(wrap(e, "error deleting registry key")))?; + match key.delete_value(TUNNEL_ACTIVITY_NAME) { + Ok(_) => {} + Err(e) if e.kind() == std::io::ErrorKind::NotFound => {} + Err(e) => return Err(wrap(e, "error deleting registry key").into()), + } + info!(self.log, "Tunnel service uninstalled"); let r = do_single_rpc_call::<_, ()>( diff --git a/cli/src/tunnels/singleton_client.rs b/cli/src/tunnels/singleton_client.rs index ef9fdf85cc067..ca29b7349f193 100644 --- a/cli/src/tunnels/singleton_client.rs +++ b/cli/src/tunnels/singleton_client.rs @@ -114,16 +114,18 @@ pub async fn start_singleton_client(args: SingletonClientArgs) -> bool { CONTROL_INSTRUCTIONS_COMMON }); - let res = c.caller.call::<_, _, protocol::singleton::Status>( - protocol::singleton::METHOD_STATUS, - protocol::EmptyObject {}, - ); + let res = c + .caller + .call::<_, _, protocol::singleton::StatusWithTunnelName>( + protocol::singleton::METHOD_STATUS, + protocol::EmptyObject {}, + ); // we want to ensure the "listening" string always gets printed for // consumers (i.e. VS Code). Ask for it. If the tunnel is not currently // connected though, it will be soon, and that'll be in the log replays. if let Ok(Ok(s)) = res.await { - if let protocol::singleton::TunnelState::Connected { name } = s.tunnel { + if let Some(name) = s.name { print_listening(&c.log, &name); } } diff --git a/cli/src/tunnels/singleton_server.rs b/cli/src/tunnels/singleton_server.rs index 703c09f51201e..6189c06a493b9 100644 --- a/cli/src/tunnels/singleton_server.rs +++ b/cli/src/tunnels/singleton_server.rs @@ -11,7 +11,7 @@ use std::{ use super::{ code_server::CodeServerArgs, control_server::ServerTermination, - dev_tunnels::ActiveTunnel, + dev_tunnels::{ActiveTunnel, StatusLock}, protocol, shutdown_signal::{ShutdownRequest, ShutdownSignal}, }; @@ -48,18 +48,28 @@ pub struct SingletonServerArgs<'a> { pub log_broadcast: &'a BroadcastLogSink, } +struct StatusInfo { + name: String, + lock: StatusLock, +} + #[derive(Clone)] struct SingletonServerContext { log: log::Logger, shutdown_tx: broadcast::Sender, broadcast_tx: broadcast::Sender>, - current_name: Arc>>, + // ugly: a lock in a lock. current_status needs to be provided only + // after we set up the tunnel, however the tunnel is created after the + // singleton server starts to avoid a gap in singleton availability. + // However, this should be safe, as the lock is only used for immediate + // data reads (in the `status` method). + current_status: Arc>>, } pub struct RpcServer { fut: JoinHandle>, shutdown_broadcast: broadcast::Sender, - current_name: Arc>>, + current_status: Arc>>, } pub fn make_singleton_server( @@ -71,12 +81,12 @@ pub fn make_singleton_server( let (shutdown_broadcast, _) = broadcast::channel(4); let rpc = new_json_rpc(); - let current_name = Arc::new(Mutex::new(None)); + let current_status = Arc::new(Mutex::default()); let mut rpc = rpc.methods(SingletonServerContext { log: log.clone(), shutdown_tx: shutdown_broadcast.clone(), broadcast_tx: log_broadcast.get_brocaster(), - current_name: current_name.clone(), + current_status: current_status.clone(), }); rpc.register_sync( @@ -91,12 +101,15 @@ pub fn make_singleton_server( rpc.register_sync( protocol::singleton::METHOD_STATUS, |_: protocol::EmptyObject, c| { - Ok(protocol::singleton::Status { - tunnel: match c.current_name.lock().unwrap().clone() { - Some(name) => protocol::singleton::TunnelState::Connected { name }, - None => protocol::singleton::TunnelState::Disconnected, - }, - }) + Ok(c.current_status + .lock() + .unwrap() + .as_ref() + .map(|s| protocol::singleton::StatusWithTunnelName { + name: Some(s.name.clone()), + status: s.lock.read(), + }) + .unwrap_or_default()) }, ); @@ -124,7 +137,7 @@ pub fn make_singleton_server( }); RpcServer { shutdown_broadcast, - current_name, + current_status, fut, } } @@ -139,8 +152,11 @@ pub async fn start_singleton_server<'a>( { print_listening(&args.log, &args.tunnel.name); - let mut name = args.server.current_name.lock().unwrap(); - *name = Some(args.tunnel.name.clone()) + let mut status = args.server.current_status.lock().unwrap(); + *status = Some(StatusInfo { + name: args.tunnel.name.clone(), + lock: args.tunnel.status(), + }) } let serve_fut = super::serve( @@ -217,7 +233,7 @@ impl BroadcastLogSink { } } - fn get_brocaster(&self) -> broadcast::Sender> { + pub fn get_brocaster(&self) -> broadcast::Sender> { self.tx.clone() } diff --git a/cli/src/update_service.rs b/cli/src/update_service.rs index b03d8ea596319..d218e4a133394 100644 --- a/cli/src/update_service.rs +++ b/cli/src/update_service.rs @@ -11,7 +11,7 @@ use crate::{ constants::VSCODE_CLI_UPDATE_ENDPOINT, debug, log, options, spanf, util::{ - errors::{AnyError, CodeError, UpdatesNotConfigured, WrappedError}, + errors::{AnyError, CodeError, WrappedError}, http::{BoxedHttp, SimpleResponse}, io::ReportCopyProgress, tar, zipper, @@ -19,6 +19,7 @@ use crate::{ }; /// Implementation of the VS Code Update service for use in the CLI. +#[derive(Clone)] pub struct UpdateService { client: BoxedHttp, log: log::Logger, @@ -54,6 +55,10 @@ fn quality_download_segment(quality: options::Quality) -> &'static str { } } +fn get_update_endpoint() -> Result<&'static str, CodeError> { + VSCODE_CLI_UPDATE_ENDPOINT.ok_or_else(|| CodeError::UpdatesNotConfigured("no service url")) +} + impl UpdateService { pub fn new(log: log::Logger, http: BoxedHttp) -> Self { UpdateService { client: http, log } @@ -66,8 +71,7 @@ impl UpdateService { quality: options::Quality, version: &str, ) -> Result { - let update_endpoint = - VSCODE_CLI_UPDATE_ENDPOINT.ok_or_else(UpdatesNotConfigured::no_url)?; + let update_endpoint = get_update_endpoint()?; let download_segment = target .download_segment(platform) .ok_or_else(|| CodeError::UnsupportedPlatform(platform.to_string()))?; @@ -108,8 +112,7 @@ impl UpdateService { target: TargetKind, quality: options::Quality, ) -> Result { - let update_endpoint = - VSCODE_CLI_UPDATE_ENDPOINT.ok_or_else(UpdatesNotConfigured::no_url)?; + let update_endpoint = get_update_endpoint()?; let download_segment = target .download_segment(platform) .ok_or_else(|| CodeError::UnsupportedPlatform(platform.to_string()))?; @@ -144,8 +147,7 @@ impl UpdateService { /// Gets the download stream for the release. pub async fn get_download_stream(&self, release: &Release) -> Result { - let update_endpoint = - VSCODE_CLI_UPDATE_ENDPOINT.ok_or_else(UpdatesNotConfigured::no_url)?; + let update_endpoint = get_update_endpoint()?; let download_segment = release .target .download_segment(release.platform) diff --git a/cli/src/util/errors.rs b/cli/src/util/errors.rs index ca6d4bf3d8a57..38d9b36f54bf5 100644 --- a/cli/src/util/errors.rs +++ b/cli/src/util/errors.rs @@ -2,7 +2,7 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ - use crate::{ +use crate::{ constants::{APPLICATION_NAME, CONTROL_PORT, DOCUMENTATION_URL, QUALITYLESS_PRODUCT_NAME}, rpc::ResponseError, }; @@ -108,16 +108,6 @@ impl StatusError { } } -// When the user has not consented to the licensing terms in using the Launcher -#[derive(Debug)] -pub struct MissingLegalConsent(pub String); - -impl std::fmt::Display for MissingLegalConsent { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(f, "{}", self.0) - } -} - // When the provided connection token doesn't match the one used to set up the original VS Code Server // This is most likely due to a new user joining. #[derive(Debug)] @@ -313,20 +303,6 @@ impl std::fmt::Display for ServerHasClosed { } } -#[derive(Debug)] -pub struct UpdatesNotConfigured(pub String); - -impl UpdatesNotConfigured { - pub fn no_url() -> Self { - UpdatesNotConfigured("no service url".to_owned()) - } -} - -impl std::fmt::Display for UpdatesNotConfigured { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(f, "Update service is not configured: {}", self.0) - } -} #[derive(Debug)] pub struct ServiceAlreadyRegistered(); @@ -509,14 +485,36 @@ pub enum CodeError { ServerAuthRequired, #[error("challenge not yet issued")] AuthChallengeNotIssued, + #[error("challenge token is invalid")] + AuthChallengeBadToken, #[error("unauthorized client refused")] AuthMismatch, #[error("keyring communication timed out after 5s")] KeyringTimeout, + #[error("no host is connected to the tunnel relay")] + NoTunnelEndpoint, + #[error("could not parse `host`: {0}")] + InvalidHostAddress(std::net::AddrParseError), + #[error("could not start server on the given host/port: {0}")] + CouldNotListenOnInterface(hyper::Error), + #[error( + "Run this command again with --accept-server-license-terms to indicate your agreement." + )] + NeedsInteractiveLegalConsent, + #[error("Sorry, you cannot use this CLI without accepting the terms.")] + DeniedLegalConset, + #[error("The server is not yet downloaded, try again shortly.")] + ServerNotYetDownloaded, + #[error("An error was encountered downloading the server, please retry: {0}")] + ServerDownloadError(String), + #[error("Updates are are not available: {0}")] + UpdatesNotConfigured(&'static str), + // todo: can be specialized when update service is moved to CodeErrors + #[error("Could not check for update: {0}")] + UpdateCheckFailed(String), } makeAnyError!( - MissingLegalConsent, MismatchConnectionToken, DevTunnelError, StatusError, @@ -539,7 +537,6 @@ makeAnyError!( ServerHasClosed, ServiceAlreadyRegistered, WindowsNeedsElevation, - UpdatesNotConfigured, CorruptDownload, MissingHomeDirectory, OAuthError, diff --git a/cli/src/util/sync.rs b/cli/src/util/sync.rs index 8b653cd2d535c..67c777b75ed21 100644 --- a/cli/src/util/sync.rs +++ b/cli/src/util/sync.rs @@ -63,7 +63,7 @@ impl BarrierOpener { /// and is thereafter permanently closed. It can contain a value. pub fn new_barrier() -> (Barrier, BarrierOpener) where - T: Copy, + T: Clone, { let (closed_tx, closed_rx) = watch::channel(None); (Barrier(closed_rx), BarrierOpener(Arc::new(closed_tx))) diff --git a/extensions/configuration-editing/package.json b/extensions/configuration-editing/package.json index 676e0b2f0f8c7..520682059e189 100644 --- a/extensions/configuration-editing/package.json +++ b/extensions/configuration-editing/package.json @@ -41,8 +41,7 @@ ".code-workspace", "language-configuration.json", "icon-theme.json", - "color-theme.json", - ".code-snippets" + "color-theme.json" ], "filenames": [ "settings.json", @@ -54,10 +53,6 @@ "profiles.json", "devcontainer.json", ".devcontainer.json" - ], - "filenamePatterns": [ - "**/User/snippets/*.json", - "**/User/profiles/*/snippets/*.json" ] }, { "id": "json", @@ -166,7 +161,7 @@ ] }, "devDependencies": { - "@types/node": "16.x" + "@types/node": "18.x" }, "repository": { "type": "git", diff --git a/extensions/configuration-editing/schemas/attachContainer.schema.json b/extensions/configuration-editing/schemas/attachContainer.schema.json index 6d9d794265b8d..5e5bd571d69d1 100644 --- a/extensions/configuration-editing/schemas/attachContainer.schema.json +++ b/extensions/configuration-editing/schemas/attachContainer.schema.json @@ -24,7 +24,7 @@ }, { "type": "string", - "pattern": "^([a-z0-9-]+):(\\d{1,5})$" + "pattern": "^([a-z0-9_-]+):(\\d{1,5})$" } ] } diff --git a/extensions/configuration-editing/yarn.lock b/extensions/configuration-editing/yarn.lock index 39b630a1bccba..549c578a9ac1a 100644 --- a/extensions/configuration-editing/yarn.lock +++ b/extensions/configuration-editing/yarn.lock @@ -115,10 +115,10 @@ dependencies: "@octokit/openapi-types" "^14.0.0" -"@types/node@16.x": - version "16.11.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae" - integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w== +"@types/node@18.x": + version "18.15.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" + integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== before-after-hook@^2.2.0: version "2.2.3" diff --git a/extensions/cpp/build/update-grammars.js b/extensions/cpp/build/update-grammars.js index 983e61488ef78..50b31708c6e31 100644 --- a/extensions/cpp/build/update-grammars.js +++ b/extensions/cpp/build/update-grammars.js @@ -8,12 +8,14 @@ var updateGrammar = require('vscode-grammar-updater'); async function updateGrammars() { await updateGrammar.update('jeff-hykin/better-c-syntax', 'autogenerated/c.tmLanguage.json', './syntaxes/c.tmLanguage.json', undefined, 'master'); - await updateGrammar.update('jeff-hykin/better-cpp-syntax', 'autogenerated/cpp.tmLanguage.json', './syntaxes/cpp.tmLanguage.json', undefined, 'master'); - await updateGrammar.update('jeff-hykin/better-cpp-syntax', 'autogenerated/cpp.embedded.macro.tmLanguage.json', './syntaxes/cpp.embedded.macro.tmLanguage.json', undefined, 'master'); + + // The license has changed for these two grammar. We have to freeze them as the new license is not compatible with our license. + // await updateGrammar.update('jeff-hykin/better-cpp-syntax', 'autogenerated/cpp.tmLanguage.json', './syntaxes/cpp.tmLanguage.json', undefined, 'master'); + // await updateGrammar.update('jeff-hykin/better-cpp-syntax', 'autogenerated/cpp.embedded.macro.tmLanguage.json', './syntaxes/cpp.embedded.macro.tmLanguage.json', undefined, 'master'); await updateGrammar.update('NVIDIA/cuda-cpp-grammar', 'syntaxes/cuda-cpp.tmLanguage.json', './syntaxes/cuda-cpp.tmLanguage.json', undefined, 'master'); -// `source.c.platform` which is still included by other grammars + // `source.c.platform` which is still included by other grammars await updateGrammar.update('textmate/c.tmbundle', 'Syntaxes/Platform.tmLanguage', './syntaxes/platform.tmLanguage.json'); } diff --git a/extensions/csharp/cgmanifest.json b/extensions/csharp/cgmanifest.json index 733388a98a189..962188ea97198 100644 --- a/extensions/csharp/cgmanifest.json +++ b/extensions/csharp/cgmanifest.json @@ -6,7 +6,7 @@ "git": { "name": "dotnet/csharp-tmLanguage", "repositoryUrl": "https://github.com/dotnet/csharp-tmLanguage", - "commitHash": "878aefe73f942ac68dc4a46a0f154661bcb9eff4" + "commitHash": "772323937fedd65c6dc1c8ce6ea41d97415ed7d1" } }, "license": "MIT", diff --git a/extensions/csharp/syntaxes/csharp.tmLanguage.json b/extensions/csharp/syntaxes/csharp.tmLanguage.json index 27af054bc3b93..c08bea9ce0182 100644 --- a/extensions/csharp/syntaxes/csharp.tmLanguage.json +++ b/extensions/csharp/syntaxes/csharp.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/dotnet/csharp-tmLanguage/commit/878aefe73f942ac68dc4a46a0f154661bcb9eff4", + "version": "https://github.com/dotnet/csharp-tmLanguage/commit/772323937fedd65c6dc1c8ce6ea41d97415ed7d1", "name": "C#", "scopeName": "source.cs", "patterns": [ @@ -286,6 +286,9 @@ { "include": "#nameof-expression" }, + { + "include": "#default-literal-expression" + }, { "include": "#throw-expression" }, @@ -298,6 +301,9 @@ { "include": "#verbatim-interpolated-string" }, + { + "include": "#type-builtin" + }, { "include": "#this-or-base-expression" }, @@ -2733,6 +2739,14 @@ } ] }, + "default-literal-expression": { + "match": "(?\n (?:\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s* # array suffix?\n \\[\n (?:\\s*,\\s*)* # commata for multi-dimensional arrays\n \\]\n \\s*\n (?:\\?)? # arrays can be nullable reference types\n \\s*\n )*\n )\n)\\s*\n(?=\\()", + "begin": "(?x)\n(new)(?:\\s+\n(?\n (?:\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s* # array suffix?\n \\[\n (?:\\s*,\\s*)* # commata for multi-dimensional arrays\n \\]\n \\s*\n (?:\\?)? # arrays can be nullable reference types\n \\s*\n )*\n )\n))?\\s*\n(?=\\()", "beginCaptures": { "1": { "name": "keyword.other.new.cs" diff --git a/extensions/css-language-features/package.json b/extensions/css-language-features/package.json index 2cdaf061ea96d..b267163da39bf 100644 --- a/extensions/css-language-features/package.json +++ b/extensions/css-language-features/package.json @@ -998,7 +998,7 @@ "vscode-uri": "^3.0.7" }, "devDependencies": { - "@types/node": "16.x" + "@types/node": "18.x" }, "repository": { "type": "git", diff --git a/extensions/css-language-features/server/package.json b/extensions/css-language-features/server/package.json index bcf7e51ea888e..bdb66297271c9 100644 --- a/extensions/css-language-features/server/package.json +++ b/extensions/css-language-features/server/package.json @@ -17,7 +17,7 @@ }, "devDependencies": { "@types/mocha": "^9.1.1", - "@types/node": "16.x" + "@types/node": "18.x" }, "scripts": { "compile": "gulp compile-extension:css-language-features-server", diff --git a/extensions/css-language-features/server/yarn.lock b/extensions/css-language-features/server/yarn.lock index 75a7ede426f5c..649160819e36a 100644 --- a/extensions/css-language-features/server/yarn.lock +++ b/extensions/css-language-features/server/yarn.lock @@ -7,10 +7,10 @@ resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-9.1.1.tgz#e7c4f1001eefa4b8afbd1eee27a237fee3bf29c4" integrity sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw== -"@types/node@16.x": - version "16.11.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae" - integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w== +"@types/node@18.x": + version "18.15.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" + integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== "@vscode/l10n@^0.0.14": version "0.0.14" diff --git a/extensions/css-language-features/yarn.lock b/extensions/css-language-features/yarn.lock index d39fbd0e22f33..acd761d8f5b4c 100644 --- a/extensions/css-language-features/yarn.lock +++ b/extensions/css-language-features/yarn.lock @@ -2,10 +2,10 @@ # yarn lockfile v1 -"@types/node@16.x": - version "16.11.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae" - integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w== +"@types/node@18.x": + version "18.15.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" + integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== balanced-match@^1.0.0: version "1.0.0" diff --git a/extensions/debug-auto-launch/package.json b/extensions/debug-auto-launch/package.json index 33dfc9b0ce146..0bc095522a0ab 100644 --- a/extensions/debug-auto-launch/package.json +++ b/extensions/debug-auto-launch/package.json @@ -33,7 +33,7 @@ ] }, "devDependencies": { - "@types/node": "16.x" + "@types/node": "18.x" }, "prettier": { "printWidth": 100, diff --git a/extensions/debug-auto-launch/yarn.lock b/extensions/debug-auto-launch/yarn.lock index e724e7fffa317..8a3d10f2b65cf 100644 --- a/extensions/debug-auto-launch/yarn.lock +++ b/extensions/debug-auto-launch/yarn.lock @@ -2,7 +2,7 @@ # yarn lockfile v1 -"@types/node@16.x": - version "16.11.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae" - integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w== +"@types/node@18.x": + version "18.15.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" + integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== diff --git a/extensions/debug-server-ready/package.json b/extensions/debug-server-ready/package.json index 5bfccfb575e69..fdfe45b73b8ac 100644 --- a/extensions/debug-server-ready/package.json +++ b/extensions/debug-server-ready/package.json @@ -168,7 +168,7 @@ ] }, "devDependencies": { - "@types/node": "16.x" + "@types/node": "18.x" }, "repository": { "type": "git", diff --git a/extensions/debug-server-ready/yarn.lock b/extensions/debug-server-ready/yarn.lock index e724e7fffa317..8a3d10f2b65cf 100644 --- a/extensions/debug-server-ready/yarn.lock +++ b/extensions/debug-server-ready/yarn.lock @@ -2,7 +2,7 @@ # yarn lockfile v1 -"@types/node@16.x": - version "16.11.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae" - integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w== +"@types/node@18.x": + version "18.15.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" + integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== diff --git a/extensions/emmet/package.json b/extensions/emmet/package.json index 1b791b48365b8..b7291b9552fa3 100644 --- a/extensions/emmet/package.json +++ b/extensions/emmet/package.json @@ -479,7 +479,7 @@ "deps": "yarn add @vscode/emmet-helper" }, "devDependencies": { - "@types/node": "16.x" + "@types/node": "18.x" }, "dependencies": { "@emmetio/css-parser": "ramya-rao-a/css-parser#vscode", diff --git a/extensions/emmet/src/test/abbreviationAction.test.ts b/extensions/emmet/src/test/abbreviationAction.test.ts index beb3bfa1ef3e6..17ccacfc94a52 100644 --- a/extensions/emmet/src/test/abbreviationAction.test.ts +++ b/extensions/emmet/src/test/abbreviationAction.test.ts @@ -410,7 +410,7 @@ suite('Tests for Expand Abbreviations (HTML)', () => { // }); // }); - test.skip('No expanding when html is excluded in the settings in completion list', async () => { + test('No expanding when html is excluded in the settings in completion list', async () => { const oldConfig = workspace.getConfiguration('emmet').inspect('excludeLanguages')?.globalValue; await workspace.getConfiguration('emmet').update('excludeLanguages', ['html'], ConfigurationTarget.Global); await testHtmlCompletionProvider(new Selection(9, 6, 9, 6), '', '', true); @@ -469,7 +469,7 @@ suite('Tests for jsx, xml and xsl', () => { }); }); - test.skip('Expand abbreviation with no self closing tags for html', () => { + test('Expand abbreviation with no self closing tags for html', () => { return withRandomFileEditor('img', 'html', async (editor, _doc) => { editor.selection = new Selection(0, 6, 0, 6); await expandEmmetAbbreviation({ language: 'html' }); diff --git a/extensions/emmet/yarn.lock b/extensions/emmet/yarn.lock index f5321aede7076..f177cdb5ec86b 100644 --- a/extensions/emmet/yarn.lock +++ b/extensions/emmet/yarn.lock @@ -53,10 +53,10 @@ resolved "https://registry.yarnpkg.com/@emmetio/stream-reader/-/stream-reader-2.2.0.tgz#46cffea119a0a003312a21c2d9b5628cb5fcd442" integrity sha1-Rs/+oRmgoAMxKiHC2bVijLX81EI= -"@types/node@16.x": - version "16.11.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae" - integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w== +"@types/node@18.x": + version "18.15.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" + integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== "@vscode/emmet-helper@^2.8.8": version "2.9.2" diff --git a/extensions/extension-editing/package.json b/extensions/extension-editing/package.json index f7ed1ccc1649b..5d6d342783f0b 100644 --- a/extensions/extension-editing/package.json +++ b/extensions/extension-editing/package.json @@ -67,7 +67,7 @@ }, "devDependencies": { "@types/markdown-it": "0.0.2", - "@types/node": "16.x" + "@types/node": "18.x" }, "repository": { "type": "git", diff --git a/extensions/extension-editing/yarn.lock b/extensions/extension-editing/yarn.lock index 1902937e894de..ff42c95677754 100644 --- a/extensions/extension-editing/yarn.lock +++ b/extensions/extension-editing/yarn.lock @@ -7,10 +7,10 @@ resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-0.0.2.tgz#5d9ad19e6e6508cdd2f2596df86fd0aade598660" integrity sha1-XZrRnm5lCM3S8llt+G/Qqt5ZhmA= -"@types/node@16.x": - version "16.11.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae" - integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w== +"@types/node@18.x": + version "18.15.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" + integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== "@types/node@^6.0.46": version "6.0.78" diff --git a/extensions/fsharp/cgmanifest.json b/extensions/fsharp/cgmanifest.json index 30868b0b9696c..b81869f111a58 100644 --- a/extensions/fsharp/cgmanifest.json +++ b/extensions/fsharp/cgmanifest.json @@ -6,7 +6,7 @@ "git": { "name": "ionide/ionide-fsgrammar", "repositoryUrl": "https://github.com/ionide/ionide-fsgrammar", - "commitHash": "71b1ead8c99715f6c994115ebab7ee4a14cf0c59" + "commitHash": "8740e610a367c5e3f15be716acc7207655ced4cf" } }, "license": "MIT", diff --git a/extensions/fsharp/syntaxes/fsharp.tmLanguage.json b/extensions/fsharp/syntaxes/fsharp.tmLanguage.json index ceb5a4c1a272f..39c34a97b251e 100644 --- a/extensions/fsharp/syntaxes/fsharp.tmLanguage.json +++ b/extensions/fsharp/syntaxes/fsharp.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/ionide/ionide-fsgrammar/commit/71b1ead8c99715f6c994115ebab7ee4a14cf0c59", + "version": "https://github.com/ionide/ionide-fsgrammar/commit/8740e610a367c5e3f15be716acc7207655ced4cf", "name": "fsharp", "scopeName": "source.fsharp", "patterns": [ @@ -314,7 +314,7 @@ }, { "match": "(?!when|and|or\\b)\\b([\\w0-9'`^._]+)", - "comments": "Here we need the \\w modifier in order to check that the words isn't blacklisted", + "comments": "Here we need the \\w modifier in order to check that the words are allowed", "captures": { "1": { "name": "entity.name.type.fsharp" @@ -1832,4 +1832,4 @@ ] } } -} +} \ No newline at end of file diff --git a/extensions/git-base/README.md b/extensions/git-base/README.md index ff5bcc321c7e2..d6f0b7c128b21 100644 --- a/extensions/git-base/README.md +++ b/extensions/git-base/README.md @@ -14,7 +14,8 @@ The Git extension exposes an API, reachable by any other extension. 2. Include `git-base.d.ts` in your extension's compilation. 3. Get a hold of the API with the following snippet: - ```ts - const gitBaseExtension = vscode.extensions.getExtension('vscode.git-base').exports; - const git = gitBaseExtension.getAPI(1); - ``` + ```ts + const gitBaseExtension = vscode.extensions.getExtension('vscode.git-base').exports; + const git = gitBaseExtension.getAPI(1); + + ``` diff --git a/extensions/git-base/package.json b/extensions/git-base/package.json index d9402c8506581..dd013f246e872 100644 --- a/extensions/git-base/package.json +++ b/extensions/git-base/package.json @@ -103,7 +103,7 @@ ] }, "devDependencies": { - "@types/node": "16.x" + "@types/node": "18.x" }, "repository": { "type": "git", diff --git a/extensions/git-base/yarn.lock b/extensions/git-base/yarn.lock index cad6a8475b87c..8a3d10f2b65cf 100644 --- a/extensions/git-base/yarn.lock +++ b/extensions/git-base/yarn.lock @@ -2,7 +2,7 @@ # yarn lockfile v1 -"@types/node@16.x": - version "16.11.21" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.21.tgz#474d7589a30afcf5291f59bd49cca9ad171ffde4" - integrity sha512-Pf8M1XD9i1ksZEcCP8vuSNwooJ/bZapNmIzpmsMaL+jMI+8mEYU3PKvs+xDNuQcJWF/x24WzY4qxLtB0zNow9A== +"@types/node@18.x": + version "18.15.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" + integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== diff --git a/extensions/git/README.md b/extensions/git/README.md index a20f320753424..2a6678de93339 100644 --- a/extensions/git/README.md +++ b/extensions/git/README.md @@ -14,7 +14,7 @@ The Git extension exposes an API, reachable by any other extension. 2. Include `git.d.ts` in your extension's compilation. 3. Get a hold of the API with the following snippet: - ```ts - const gitExtension = vscode.extensions.getExtension('vscode.git').exports; - const git = gitExtension.getAPI(1); - ``` \ No newline at end of file + ```ts + const gitExtension = vscode.extensions.getExtension('vscode.git').exports; + const git = gitExtension.getAPI(1); + ``` diff --git a/extensions/git/package.json b/extensions/git/package.json index f45447de7f1a2..105491916ca65 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -3005,7 +3005,7 @@ }, "dependencies": { "@joaomoreno/unique-names-generator": "^5.1.0", - "@vscode/extension-telemetry": "0.7.5", + "@vscode/extension-telemetry": "^0.8.4", "@vscode/iconv-lite-umd": "0.7.0", "byline": "^5.0.0", "file-type": "16.5.4", @@ -3017,7 +3017,7 @@ "devDependencies": { "@types/byline": "4.2.31", "@types/mocha": "^9.1.1", - "@types/node": "16.x", + "@types/node": "18.x", "@types/picomatch": "2.3.0", "@types/which": "3.0.0" }, diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index 8eba9cbac03f2..af40853e27efe 100644 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -749,20 +749,26 @@ export class CommandCenter { const ref = selection.repository.HEAD?.upstream?.name; if (uri !== undefined) { - // Launch desktop client if currently in web let target = `${env.uriScheme}://vscode.git/clone?url=${encodeURIComponent(uri)}`; - if (env.uiKind === UIKind.Web) { + const isWeb = env.uiKind === UIKind.Web; + const isRemote = env.remoteName !== undefined; + + if (isWeb || isRemote) { if (ref !== undefined) { target += `&ref=${encodeURIComponent(ref)}`; } - return Uri.parse(target); - } - // If already in desktop client but in a remote window, we need to force a new window - // so that the git extension can access the local filesystem for cloning - if (env.remoteName !== undefined) { - target += `&windowId=_blank`; - return Uri.parse(target); + if (isWeb) { + // Launch desktop client if currently in web + return Uri.parse(target); + } + + if (isRemote) { + // If already in desktop client but in a remote window, we need to force a new window + // so that the git extension can access the local filesystem for cloning + target += `&windowId=_blank`; + return Uri.parse(target); + } } // Otherwise, directly clone diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index ab03a354d1161..62bdf24ebcbd2 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -481,7 +481,7 @@ export class Git { const result = await this.exec(pathInsidePossibleRepository, ['rev-parse', '--show-toplevel']); // Keep trailing spaces which are part of the directory name - const repositoryRootPath = path.normalize(result.stdout.trimLeft().replace(/[\r\n]+$/, '')); + const repositoryRootPath = path.normalize(result.stdout.trimStart().replace(/[\r\n]+$/, '')); if (isWindows) { // On Git 2.25+ if you call `rev-parse --show-toplevel` on a mapped drive, instead of getting the mapped @@ -528,7 +528,7 @@ export class Git { !isDescendant(pathInsidePossibleRepository, repositoryRootPath) && this.compareGitVersionTo('2.31.0') !== -1) { const relativePathResult = await this.exec(pathInsidePossibleRepository, ['rev-parse', '--path-format=relative', '--show-toplevel',]); - return path.resolve(pathInsidePossibleRepository, relativePathResult.stdout.trimLeft().replace(/[\r\n]+$/, '')); + return path.resolve(pathInsidePossibleRepository, relativePathResult.stdout.trimStart().replace(/[\r\n]+$/, '')); } return repositoryRootPath; diff --git a/extensions/git/yarn.lock b/extensions/git/yarn.lock index 1a928aec322b8..bb3a09d947c0b 100644 --- a/extensions/git/yarn.lock +++ b/extensions/git/yarn.lock @@ -17,7 +17,16 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" -"@azure/core-rest-pipeline@^1.10.0": +"@azure/core-auth@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.5.0.tgz#a41848c5c31cb3b7c84c409885267d55a2c92e44" + integrity sha512-udzoBuYG1VBoHVohDTrvKjyzel34zt77Bhp7dQntVGGD0ehVq48owENbBG8fIgkHRNUBQH5k1r0hpoMu5L8+kw== + dependencies: + "@azure/abort-controller" "^1.0.0" + "@azure/core-util" "^1.1.0" + tslib "^2.2.0" + +"@azure/core-rest-pipeline@1.10.1": version "1.10.1" resolved "https://registry.yarnpkg.com/@azure/core-rest-pipeline/-/core-rest-pipeline-1.10.1.tgz#348290847ca31b9eecf9cf5de7519aaccdd30968" integrity sha512-Kji9k6TOFRDB5ZMTw8qUf2IJ+CeJtsuMdAHox9eqpTf1cefiNMpzrfnF6sINEBZJsaVaWgQ0o48B6kcUH68niA== @@ -33,13 +42,21 @@ tslib "^2.2.0" uuid "^8.3.0" -"@azure/core-tracing@^1.0.1": +"@azure/core-tracing@^1.0.0", "@azure/core-tracing@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.0.1.tgz#352a38cbea438c4a83c86b314f48017d70ba9503" integrity sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw== dependencies: tslib "^2.2.0" +"@azure/core-util@1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.2.0.tgz#3499deba1fc36dda6f1912b791809b6f15d4a392" + integrity sha512-ffGIw+Qs8bNKNLxz5UPkz4/VBM/EZY07mPve1ZYFqYUdPwFqRj0RPk0U7LZMOfT7GCck9YjuT1Rfp1PApNl1ng== + dependencies: + "@azure/abort-controller" "^1.0.0" + tslib "^2.2.0" + "@azure/core-util@^1.0.0": version "1.1.1" resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.1.1.tgz#8f87b3dd468795df0f0849d9f096c3e7b29452c1" @@ -48,6 +65,14 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" +"@azure/core-util@^1.1.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.4.0.tgz#c120a56b3e48a9e4d20619a0b00268ae9de891c7" + integrity sha512-eGAyJpm3skVQoLiRqm/xPa+SXi/NPDdSHMxbRAz2lSprd+Zs+qrpQGQQ2VQ3Nttu+nSZR4XoYQC71LbEI7jsig== + dependencies: + "@azure/abort-controller" "^1.0.0" + tslib "^2.2.0" + "@azure/logger@^1.0.0": version "1.0.3" resolved "https://registry.yarnpkg.com/@azure/logger/-/logger-1.0.3.tgz#6e36704aa51be7d4a1bae24731ea580836293c96" @@ -55,71 +80,105 @@ dependencies: tslib "^2.2.0" +"@azure/opentelemetry-instrumentation-azure-sdk@^1.0.0-beta.5": + version "1.0.0-beta.5" + resolved "https://registry.yarnpkg.com/@azure/opentelemetry-instrumentation-azure-sdk/-/opentelemetry-instrumentation-azure-sdk-1.0.0-beta.5.tgz#78809e6c005d08450701e5d37f087f6fce2f86eb" + integrity sha512-fsUarKQDvjhmBO4nIfaZkfNSApm1hZBzcvpNbSrXdcUBxu7lRvKsV5DnwszX7cnhLyVOW9yl1uigtRQ1yDANjA== + dependencies: + "@azure/core-tracing" "^1.0.0" + "@azure/logger" "^1.0.0" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/instrumentation" "^0.41.2" + tslib "^2.2.0" + "@joaomoreno/unique-names-generator@^5.1.0": version "5.1.0" resolved "https://registry.yarnpkg.com/@joaomoreno/unique-names-generator/-/unique-names-generator-5.1.0.tgz#d577d425aed794c44c0e8863cddd5dea349f74f3" integrity sha512-KEVThTpUIKPb7dBKJ9mJ3WYnD1mJZZsEinCSp9CVEPlWbDagurFv1RKRjvvujrLfJzsGc0HkBHS9W8Bughao4A== -"@microsoft/1ds-core-js@3.2.8", "@microsoft/1ds-core-js@^3.2.8": - version "3.2.8" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.8.tgz#1b6b7d9bb858238c818ccf4e4b58ece7aeae5760" - integrity sha512-9o9SUAamJiTXIYwpkQDuueYt83uZfXp8zp8YFix1IwVPwC9RmE36T2CX9gXOeq1nDckOuOduYpA8qHvdh5BGfQ== +"@microsoft/1ds-core-js@3.2.13", "@microsoft/1ds-core-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.13.tgz#0c105ed75091bae3f1555c0334704fa9911c58fb" + integrity sha512-CluYTRWcEk0ObG5EWFNWhs87e2qchJUn0p2D21ZUa3PWojPZfPSBs4//WIE0MYV8Qg1Hdif2ZTwlM7TbYUjfAg== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.9" + "@microsoft/applicationinsights-core-js" "2.8.15" "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@microsoft/1ds-post-js@^3.2.8": - version "3.2.8" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.8.tgz#46793842cca161bf7a2a5b6053c349f429e55110" - integrity sha512-SjlRoNcXcXBH6WQD/5SkkaCHIVqldH3gDu+bI7YagrOVJ5APxwT1Duw9gm3L1FjFa9S2i81fvJ3EVSKpp9wULA== +"@microsoft/1ds-post-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.13.tgz#560aacac8a92fdbb79e8c2ebcb293d56e19f51aa" + integrity sha512-HgS574fdD19Bo2vPguyznL4eDw7Pcm1cVNpvbvBLWiW3x4e1FCQ3VMXChWnAxCae8Hb0XqlA2sz332ZobBavTA== dependencies: - "@microsoft/1ds-core-js" "3.2.8" + "@microsoft/1ds-core-js" "3.2.13" "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@microsoft/applicationinsights-channel-js@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.8.9.tgz#840656f3c716de8b3eb0a98c122aa1b92bb8ebfb" - integrity sha512-fMBsAEB7pWtPn43y72q9Xy5E5y55r6gMuDQqRRccccVoQDPXyS57VCj5IdATblctru0C6A8XpL2vRyNmEsu0Vg== +"@microsoft/applicationinsights-channel-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-3.0.2.tgz#be49fbf74831c7b8c97950027c5052ea99d2a8a5" + integrity sha512-jDBNKbCHsJgmpv0CKNhJ/uN9ZphvfGdb93Svk+R4LjO8L3apNNMbDDPxBvXXi0uigRmA1TBcmyBG4IRKjabGhw== dependencies: - "@microsoft/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" -"@microsoft/applicationinsights-common@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-2.8.9.tgz#a75e4a3143a7fd797687830c0ddd2069fd900827" - integrity sha512-mObn1moElyxZaGIRF/IU3cOaeKMgxghXnYEoHNUCA2e+rNwBIgxjyKkblFIpmGuHf4X7Oz3o3yBWpaC6AoMpig== +"@microsoft/applicationinsights-common@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-3.0.2.tgz#37670bb07f4858ed41ff9759119e0759007d6e05" + integrity sha512-y+WXWop+OVim954Cu1uyYMnNx6PWO8okHpZIQi/1YSqtqaYdtJVPv4P0AVzwJdohxzVfgzKvqj9nec/VWqE2Zg== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" -"@microsoft/applicationinsights-core-js@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.9.tgz#0e5d207acfae6986a6fc97249eeb6117e523bf1b" - integrity sha512-HRuIuZ6aOWezcg/G5VyFDDWGL8hDNe/ljPP01J7ImH2kRPEgbtcfPSUMjkamGMefgdq81GZsSoC/NNGTP4pp2w== +"@microsoft/applicationinsights-core-js@2.8.15": + version "2.8.15" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.15.tgz#8fa466474260e01967fe649f14dd9e5ff91dcdc8" + integrity sha512-yYAs9MyjGr2YijQdUSN9mVgT1ijI1FPMgcffpaPmYbHAVbQmF7bXudrBWHxmLzJlwl5rfep+Zgjli2e67lwUqQ== dependencies: "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/dynamicproto-js" "^1.1.9" + +"@microsoft/applicationinsights-core-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-3.0.2.tgz#108e20df8c162bec92b1f66f9de2530a25d9f51a" + integrity sha512-WQhVhzlRlLDrQzn3OShCW/pL3BW5WC57t0oywSknX3q7lMzI3jDg7Ihh0iuIcNTzGCTbDkuqr4d6IjEDWIMtJQ== + dependencies: + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-shims@2.0.2", "@microsoft/applicationinsights-shims@^2.0.2": version "2.0.2" resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.2.tgz#92b36a09375e2d9cb2b4203383b05772be837085" integrity sha512-PoHEgsnmcqruLNHZ/amACqdJ6YYQpED0KSRe6J7gIJTtpZC1FfFU9b1fmDKDKtFoUSrPzEh1qzO3kmRZP0betg== -"@microsoft/applicationinsights-web-basic@^2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-2.8.9.tgz#eed2f3d1e19069962ed2155915c1656e6936e1d5" - integrity sha512-CH0J8JFOy7MjK8JO4pXXU+EML+Ilix+94PMZTX5EJlBU1in+mrik74/8qSg3UC4ekPi12KwrXaHCQSVC3WseXQ== +"@microsoft/applicationinsights-shims@3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-3.0.1.tgz#3865b73ace8405b9c4618cc5c571f2fe3876f06f" + integrity sha512-DKwboF47H1nb33rSUfjqI6ryX29v+2QWcTrRvcQDA32AZr5Ilkr7whOOSsD1aBzwqX0RJEIP1Z81jfE3NBm/Lg== dependencies: - "@microsoft/applicationinsights-channel-js" "2.8.9" - "@microsoft/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" + +"@microsoft/applicationinsights-web-basic@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-3.0.2.tgz#f777a4d24b79dde3ae396d3b819e1fce06b7240a" + integrity sha512-6Lq0DE/pZp9RvSV+weGbcxN1NDmfczj6gNPhvZKV2YSQ3RK0LZE3+wjTWLXfuStq8a+nCBdsRpWk8tOKgsoxcg== + dependencies: + "@microsoft/applicationinsights-channel-js" "3.0.2" + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-web-snippet@^1.0.1": version "1.0.1" @@ -131,39 +190,74 @@ resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.7.tgz#ede48dd3f85af14ee369c805e5ed5b84222b9fe2" integrity sha512-SK3D3aVt+5vOOccKPnGaJWB5gQ8FuKfjboUJHedMP7gu54HqSCXX5iFXhktGD8nfJb0Go30eDvs/UDoTnR2kOA== -"@opentelemetry/api@^1.0.4": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.2.0.tgz#89ef99401cde6208cff98760b67663726ef26686" - integrity sha512-0nBr+VZNKm9tvNDZFstI3Pq1fCTEDK5OZTnVKNvBNAKgd0yIvmwsP4m61rEv7ZP+tOUjWJhROpxK5MsnlF911g== +"@microsoft/dynamicproto-js@^1.1.9": + version "1.1.9" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.9.tgz#7437db7aa061162ee94e4131b69a62b8dad5dea6" + integrity sha512-n1VPsljTSkthsAFYdiWfC+DKzK2WwcRp83Y1YAqdX552BstvsDjft9YXppjUzp11BPsapDoO1LDgrDB0XVsfNQ== -"@opentelemetry/core@1.7.0", "@opentelemetry/core@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.7.0.tgz#83bdd1b7a4ceafcdffd6590420657caec5f7b34c" - integrity sha512-AVqAi5uc8DrKJBimCTFUT4iFI+5eXpo4sYmGbQ0CypG0piOTHE2g9c5aSoTGYXu3CzOmJZf7pT6Xh+nwm5d6yQ== +"@microsoft/dynamicproto-js@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-2.0.2.tgz#e57fbec2e7067d48b7e8e1e1c1d354028ef718a6" + integrity sha512-MB8trWaFREpmb037k/d0bB7T2BP7Ai24w1e1tbz3ASLB0/lwphsq3Nq8S9I5AsI5vs4zAQT+SB5nC5/dLYTiOg== dependencies: - "@opentelemetry/semantic-conventions" "1.7.0" + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" -"@opentelemetry/resources@1.7.0": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.7.0.tgz#90ccd3a6a86b4dfba4e833e73944bd64958d78c5" - integrity sha512-u1M0yZotkjyKx8dj+46Sg5thwtOTBmtRieNXqdCRiWUp6SfFiIP0bI+1XK3LhuXqXkBXA1awJZaTqKduNMStRg== +"@nevware21/ts-async@>= 0.2.4 < 2.x": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@nevware21/ts-async/-/ts-async-0.3.0.tgz#a8b97ba01065fc930de9a3f4dd4a05e862becc6c" + integrity sha512-ZUcgUH12LN/F6nzN0cYd0F/rJaMLmXr0EHVTyYfaYmK55bdwE4338uue4UiVoRqHVqNW4KDUrJc49iGogHKeWA== dependencies: - "@opentelemetry/core" "1.7.0" - "@opentelemetry/semantic-conventions" "1.7.0" + "@nevware21/ts-utils" ">= 0.10.0 < 2.x" + +"@nevware21/ts-utils@>= 0.10.0 < 2.x", "@nevware21/ts-utils@>= 0.9.4 < 2.x", "@nevware21/ts-utils@>= 0.9.5 < 2.x": + version "0.10.1" + resolved "https://registry.yarnpkg.com/@nevware21/ts-utils/-/ts-utils-0.10.1.tgz#aa65abc71eba06749a396598f22263d26f796ac7" + integrity sha512-pMny25NnF2/MJwdqC3Iyjm2pGIXNxni4AROpcqDeWa+td9JMUY4bUS9uU9XW+BoBRqTLUL+WURF9SOd/6OQzRg== -"@opentelemetry/sdk-trace-base@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.7.0.tgz#b498424e0c6340a9d80de63fd408c5c2130a60a5" - integrity sha512-Iz84C+FVOskmauh9FNnj4+VrA+hG5o+tkMzXuoesvSfunVSioXib0syVFeNXwOm4+M5GdWCuW632LVjqEXStIg== +"@opentelemetry/api@^1.4.1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.4.1.tgz#ff22eb2e5d476fbc2450a196e40dd243cc20c28f" + integrity sha512-O2yRJce1GOc6PAy3QxFM4NzFiWzvScDC1/5ihYBL6BUEVdq0XMWN01sppE+H6bBXbaFYipjwFLEWLg5PaSOThA== + +"@opentelemetry/core@1.15.2", "@opentelemetry/core@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.15.2.tgz#5b170bf223a2333884bbc2d29d95812cdbda7c9f" + integrity sha512-+gBv15ta96WqkHZaPpcDHiaz0utiiHZVfm2YOYSqFGrUaJpPkMoSuLBB58YFQGi6Rsb9EHos84X6X5+9JspmLw== dependencies: - "@opentelemetry/core" "1.7.0" - "@opentelemetry/resources" "1.7.0" - "@opentelemetry/semantic-conventions" "1.7.0" + "@opentelemetry/semantic-conventions" "1.15.2" -"@opentelemetry/semantic-conventions@1.7.0", "@opentelemetry/semantic-conventions@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.7.0.tgz#af80a1ef7cf110ea3a68242acd95648991bcd763" - integrity sha512-FGBx/Qd09lMaqQcogCHyYrFEpTx4cAjeS+48lMIR12z7LdH+zofGDVQSubN59nL6IpubfKqTeIDu9rNO28iHVA== +"@opentelemetry/instrumentation@^0.41.2": + version "0.41.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.41.2.tgz#cae11fa64485dcf03dae331f35b315b64bc6189f" + integrity sha512-rxU72E0pKNH6ae2w5+xgVYZLzc5mlxAbGzF4shxMVK8YC2QQsfN38B2GPbj0jvrKWWNUElfclQ+YTykkNg/grw== + dependencies: + "@types/shimmer" "^1.0.2" + import-in-the-middle "1.4.2" + require-in-the-middle "^7.1.1" + semver "^7.5.1" + shimmer "^1.2.1" + +"@opentelemetry/resources@1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.15.2.tgz#0c9e26cb65652a1402834a3c030cce6028d6dd9d" + integrity sha512-xmMRLenT9CXmm5HMbzpZ1hWhaUowQf8UB4jMjFlAxx1QzQcsD3KFNAVX/CAWzFPtllTyTplrA4JrQ7sCH3qmYw== + dependencies: + "@opentelemetry/core" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" + +"@opentelemetry/sdk-trace-base@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.15.2.tgz#4821f94033c55a6c8bbd35ae387b715b6108517a" + integrity sha512-BEaxGZbWtvnSPchV98qqqqa96AOcb41pjgvhfzDij10tkBhIu9m0Jd6tZ1tJB5ZHfHbTffqYVYE0AOGobec/EQ== + dependencies: + "@opentelemetry/core" "1.15.2" + "@opentelemetry/resources" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" + +"@opentelemetry/semantic-conventions@1.15.2", "@opentelemetry/semantic-conventions@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.15.2.tgz#3bafb5de3e20e841dff6cb3c66f4d6e9694c4241" + integrity sha512-CjbOKwk2s+3xPIMcd5UNYQzsf+v94RczbdNix9/kQh38WiQkM90sUOi3if8eyHFgiBjBjhwXrA7W3ydiSQP9mw== "@tokenizer/token@^0.3.0": version "0.3.0" @@ -192,36 +286,51 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.51.tgz#b31d716fb8d58eeb95c068a039b9b6292817d5fb" integrity sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ== -"@types/node@16.x": - version "16.11.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae" - integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w== +"@types/node@18.x": + version "18.15.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" + integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== "@types/picomatch@2.3.0": version "2.3.0" resolved "https://registry.yarnpkg.com/@types/picomatch/-/picomatch-2.3.0.tgz#75db5e75a713c5a83d5b76780c3da84a82806003" integrity sha512-O397rnSS9iQI4OirieAtsDqvCj4+3eY1J+EPdNTKuHuRWIfUoGyzX294o8C4KJYaLqgSrd2o60c5EqCU8Zv02g== +"@types/shimmer@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/shimmer/-/shimmer-1.0.2.tgz#93eb2c243c351f3f17d5c580c7467ae5d686b65f" + integrity sha512-dKkr1bTxbEsFlh2ARpKzcaAmsYixqt9UyCdoEZk8rHyE4iQYcDCyvSjDSf7JUWJHlJiTtbIoQjxKh6ViywqDAg== + "@types/which@3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@types/which/-/which-3.0.0.tgz#849afdd9fdcb0b67339b9cfc80fa6ea4e0253fc5" integrity sha512-ASCxdbsrwNfSMXALlC3Decif9rwDMu+80KGp5zI2RLRotfMsTv7fHL8W8VDp24wymzDyIFudhUeSCugrgRFfHQ== -"@vscode/extension-telemetry@0.7.5": - version "0.7.5" - resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.7.5.tgz#bf965731816e08c3f146f96d901ec67954fc913b" - integrity sha512-fJ5y3TcpqqkFYHneabYaoB4XAhDdVflVm+TDKshw9VOs77jkgNS4UA7LNXrWeO0eDne3Sh3JgURf+xzc1rk69w== +"@vscode/extension-telemetry@^0.8.4": + version "0.8.4" + resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.8.4.tgz#c078c6f55df1c9e0592de3b4ce0f685dd345bfe7" + integrity sha512-UqM9+KZDDK3MyoHTsg6XNM+XO6pweQxzCpqJz33BoBEYAGsbBviRYcVpJglgay2oReuDD2pOI1Nio3BKNDLhWA== 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" + "@microsoft/1ds-core-js" "^3.2.13" + "@microsoft/1ds-post-js" "^3.2.13" + "@microsoft/applicationinsights-web-basic" "^3.0.2" + applicationinsights "^2.7.1" "@vscode/iconv-lite-umd@0.7.0": version "0.7.0" resolved "https://registry.yarnpkg.com/@vscode/iconv-lite-umd/-/iconv-lite-umd-0.7.0.tgz#d2f1e0664ee6036408f9743fee264ea0699b0e48" integrity sha512-bRRFxLfg5dtAyl5XyiVWz/ZBPahpOpPrNYnnHpOpUZvam4tKH35wdhP4Kj6PbM0+KdliOsPzbGWpkxcdpNB/sg== +acorn-import-assertions@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" + integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== + +acorn@^8.8.2: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== + agent-base@6: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" @@ -229,22 +338,24 @@ agent-base@6: dependencies: debug "4" -applicationinsights@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.4.1.tgz#4de4c4dd3c7c4a44445cfbf3d15808fc0dcc423d" - integrity sha512-0n0Ikd0gzSm460xm+M0UTWIwXrhrH/0bqfZatcJjYObWyefxfAxapGEyNnSGd1Tg90neHz+Yhf+Ff/zgvPiQYA== +applicationinsights@^2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.7.3.tgz#8781454d29c0b14c9773f2e892b4cf5e7468ffa5" + integrity sha512-JY8+kTEkjbA+kAVNWDtpfW2lqsrDALfDXuxOs74KLPu2y13fy/9WB52V4LfYVTVcW1/jYOXjTxNS2gPZIDh1iw== dependencies: - "@azure/core-auth" "^1.4.0" - "@azure/core-rest-pipeline" "^1.10.0" + "@azure/core-auth" "^1.5.0" + "@azure/core-rest-pipeline" "1.10.1" + "@azure/core-util" "1.2.0" + "@azure/opentelemetry-instrumentation-azure-sdk" "^1.0.0-beta.5" "@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" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/sdk-trace-base" "^1.15.2" + "@opentelemetry/semantic-conventions" "^1.15.2" cls-hooked "^4.2.2" continuation-local-storage "^3.2.1" - diagnostic-channel "1.1.0" - diagnostic-channel-publishers "1.0.5" + diagnostic-channel "1.1.1" + diagnostic-channel-publishers "1.0.7" async-hook-jl@^1.7.6: version "1.7.6" @@ -271,6 +382,11 @@ byline@^5.0.0: resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1" integrity sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE= +cjs-module-lexer@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" + integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== + cls-hooked@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/cls-hooked/-/cls-hooked-4.2.2.tgz#ad2e9a4092680cdaffeb2d3551da0e225eae1908" @@ -295,7 +411,7 @@ continuation-local-storage@^3.2.1: async-listener "^0.6.0" emitter-listener "^1.1.1" -debug@4: +debug@4, debug@^4.1.1: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -307,17 +423,17 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -diagnostic-channel-publishers@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.5.tgz#df8c317086c50f5727fdfb5d2fce214d2e4130ae" - integrity sha512-dJwUS0915pkjjimPJVDnS/QQHsH0aOYhnZsLJdnZIMOrB+csj8RnZhWTuwnm8R5v3Z7OZs+ksv5luC14DGB7eg== +diagnostic-channel-publishers@1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.7.tgz#9b7f8d5ee1295481aee19c827d917e96fedf2c4a" + integrity sha512-SEECbY5AiVt6DfLkhkaHNeshg1CogdLLANA8xlG/TKvS+XUgvIKl7VspJGYiEdL5OUyzMVnr7o0AwB7f+/Mjtg== -diagnostic-channel@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.0.tgz#6985e9dfedfbc072d91dc4388477e4087147756e" - integrity sha512-fwujyMe1gj6rk6dYi9hMZm0c8Mz8NDMVl2LB4iaYh3+LIAThZC8RKFGXWG0IML2OxAit/ZFRgZhMkhQ3d/bobQ== +diagnostic-channel@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.1.tgz#44b60972de9ee055c16216535b0e9db3f6a0efd0" + integrity sha512-r2HV5qFkUICyoaKlBEpLKHjxMXATUf/l+h8UZPGBHGLy4DDiY2sOLcIctax4eRnTw5wH2jTMExLntGPJ8eOJxw== dependencies: - semver "^5.3.0" + semver "^7.5.3" emitter-listener@^1.0.1, emitter-listener@^1.1.1: version "1.1.2" @@ -344,6 +460,18 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + http-proxy-agent@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" @@ -366,11 +494,28 @@ ieee754@^1.2.1: resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== +import-in-the-middle@1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/import-in-the-middle/-/import-in-the-middle-1.4.2.tgz#2a266676e3495e72c04bbaa5ec14756ba168391b" + integrity sha512-9WOz1Yh/cvO/p69sxRmhyQwrIGGSp7EIdcb+fFNVi7CzQGQB8U1/1XrKVSbEd/GNOAeM0peJtmi7+qphe7NvAw== + dependencies: + acorn "^8.8.2" + acorn-import-assertions "^1.9.0" + cjs-module-lexer "^1.2.2" + module-details-from-path "^1.0.3" + inherits@^2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +is-core-module@^2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" + integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== + dependencies: + has "^1.0.3" + isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -381,6 +526,13 @@ jschardet@3.0.0: resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-3.0.0.tgz#898d2332e45ebabbdb6bf2feece9feea9a99e882" integrity sha512-lJH6tJ77V8Nzd5QWRkFYCLc13a3vADkh3r/Fi8HupZGWk2OVVDfnZP8V/VgQgZ+lzW0kG2UGb5hFgt3V3ndotQ== +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + mime-db@1.52.0: version "1.52.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" @@ -393,11 +545,21 @@ mime-types@^2.1.12: dependencies: mime-db "1.52.0" +module-details-from-path@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/module-details-from-path/-/module-details-from-path-1.0.3.tgz#114c949673e2a8a35e9d35788527aa37b679da2b" + integrity sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A== + ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + peek-readable@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-4.1.0.tgz#4ece1111bf5c2ad8867c314c81356847e8a62e72" @@ -424,6 +586,24 @@ readable-web-to-node-stream@^3.0.0: dependencies: readable-stream "^3.6.0" +require-in-the-middle@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/require-in-the-middle/-/require-in-the-middle-7.2.0.tgz#b539de8f00955444dc8aed95e17c69b0a4f10fcf" + integrity sha512-3TLx5TGyAY6AOqLBoXmHkNql0HIf2RGbuMgCDT2WO/uGVAPJs6h7Kl+bN6TIZGd9bWhWPwnDnTHGtW8Iu77sdw== + dependencies: + debug "^4.1.1" + module-details-from-path "^1.0.3" + resolve "^1.22.1" + +resolve@^1.22.1: + version "1.22.4" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.4.tgz#1dc40df46554cdaf8948a486a10f6ba1e2026c34" + integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" @@ -434,7 +614,14 @@ semver@^5.3.0, semver@^5.4.1: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -shimmer@^1.1.0, shimmer@^1.2.0: +semver@^7.5.1, semver@^7.5.3: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +shimmer@^1.1.0, shimmer@^1.2.0, shimmer@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337" integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw== @@ -459,6 +646,11 @@ strtok3@^6.2.4: "@tokenizer/token" "^0.3.0" peek-readable "^4.1.0" +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + token-types@^4.1.1: version "4.2.0" resolved "https://registry.yarnpkg.com/token-types/-/token-types-4.2.0.tgz#b66bc3d67420c6873222a424eee64a744f4c2f13" @@ -493,3 +685,8 @@ which@3.0.1: integrity sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg== dependencies: isexe "^2.0.0" + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== diff --git a/extensions/github-authentication/extension-browser.webpack.config.js b/extensions/github-authentication/extension-browser.webpack.config.js index 37b207eb056d1..f109e203569be 100644 --- a/extensions/github-authentication/extension-browser.webpack.config.js +++ b/extensions/github-authentication/extension-browser.webpack.config.js @@ -21,7 +21,8 @@ module.exports = withBrowserDefaults({ 'uuid': path.resolve(__dirname, 'node_modules/uuid/dist/esm-browser/index.js'), './node/authServer': path.resolve(__dirname, 'src/browser/authServer'), './node/crypto': path.resolve(__dirname, 'src/browser/crypto'), - './node/fetch': path.resolve(__dirname, 'src/browser/fetch') + './node/fetch': path.resolve(__dirname, 'src/browser/fetch'), + './node/buffer': path.resolve(__dirname, 'src/browser/buffer'), } } }); diff --git a/extensions/github-authentication/package.json b/extensions/github-authentication/package.json index 97b728c3a1dee..4855716e08e06 100644 --- a/extensions/github-authentication/package.json +++ b/extensions/github-authentication/package.json @@ -60,11 +60,11 @@ }, "dependencies": { "node-fetch": "2.6.7", - "@vscode/extension-telemetry": "0.7.5", + "@vscode/extension-telemetry": "^0.8.4", "vscode-tas-client": "^0.1.47" }, "devDependencies": { - "@types/node": "16.x", + "@types/node": "18.x", "@types/node-fetch": "^2.5.7" }, "repository": { diff --git a/extensions/github-authentication/src/browser/buffer.ts b/extensions/github-authentication/src/browser/buffer.ts new file mode 100644 index 0000000000000..7192f5f104adc --- /dev/null +++ b/extensions/github-authentication/src/browser/buffer.ts @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +export function base64Encode(text: string): string { + return btoa(text); +} diff --git a/extensions/github-authentication/src/common/logger.ts b/extensions/github-authentication/src/common/logger.ts index 84225bd707f9d..cf90c4176a9ba 100644 --- a/extensions/github-authentication/src/common/logger.ts +++ b/extensions/github-authentication/src/common/logger.ts @@ -26,4 +26,7 @@ export class Log { this.output.error(message); } + public warn(message: string): void { + this.output.warn(message); + } } diff --git a/extensions/github-authentication/src/flows.ts b/extensions/github-authentication/src/flows.ts index f3f9277bdc1d4..5bc9d09538519 100644 --- a/extensions/github-authentication/src/flows.ts +++ b/extensions/github-authentication/src/flows.ts @@ -201,7 +201,8 @@ const allFlows: IFlow[] = [ supportsGitHubEnterpriseServer: false, supportsHostedGitHubEnterprise: true, supportsRemoteExtensionHost: true, - supportsWebWorkerExtensionHost: true, + // Web worker can't open a port to listen for the redirect + supportsWebWorkerExtensionHost: false, // exchanging a code for a token requires a client secret supportsNoClientSecret: false, supportsSupportedClients: true, diff --git a/extensions/github-authentication/src/github.ts b/extensions/github-authentication/src/github.ts index c710cbe4f2f6f..71aa17bd5ccdf 100644 --- a/extensions/github-authentication/src/github.ts +++ b/extensions/github-authentication/src/github.ts @@ -363,6 +363,7 @@ export class GitHubAuthenticationProvider implements vscode.AuthenticationProvid sessions.splice(sessionIndex, 1); await this.storeSessions(sessions); + await this._githubServer.logout(session); this._sessionChangeEmitter.fire({ added: [], removed: [session], changed: [] }); } else { diff --git a/extensions/github-authentication/src/githubServer.ts b/extensions/github-authentication/src/githubServer.ts index 7ac5cd8c5778f..0729c4c50776a 100644 --- a/extensions/github-authentication/src/githubServer.ts +++ b/extensions/github-authentication/src/githubServer.ts @@ -12,6 +12,8 @@ import { crypto } from './node/crypto'; import { fetching } from './node/fetch'; import { ExtensionHost, GitHubTarget, getFlows } from './flows'; import { NETWORK_ERROR, USER_CANCELLATION_ERROR } from './common/errors'; +import { Config } from './config'; +import { base64Encode } from './node/buffer'; // This is the error message that we throw if the login was cancelled for any reason. Extensions // calling `getSession` can handle this error to know that the user cancelled the login. @@ -22,6 +24,7 @@ const REDIRECT_URL_INSIDERS = 'https://insiders.vscode.dev/redirect'; export interface IGitHubServer { login(scopes: string): Promise; + logout(session: vscode.AuthenticationSession): Promise; getUserInfo(token: string): Promise<{ id: string; accountName: string }>; sendAdditionalTelemetryInfo(session: vscode.AuthenticationSession): Promise; friendlyName: string; @@ -78,9 +81,14 @@ export class GitHubServer implements IGitHubServer { } // TODO@joaomoreno TODO@TylerLeonhardt + private _isNoCorsEnvironment: boolean | undefined; private async isNoCorsEnvironment(): Promise { + if (this._isNoCorsEnvironment !== undefined) { + return this._isNoCorsEnvironment; + } const uri = await vscode.env.asExternalUri(vscode.Uri.parse(`${vscode.env.uriScheme}://vscode.github-authentication/dummy`)); - return (uri.scheme === 'https' && /^((insiders\.)?vscode|github)\./.test(uri.authority)) || (uri.scheme === 'http' && /^localhost/.test(uri.authority)); + this._isNoCorsEnvironment = (uri.scheme === 'https' && /^((insiders\.)?vscode|github)\./.test(uri.authority)) || (uri.scheme === 'http' && /^localhost/.test(uri.authority)); + return this._isNoCorsEnvironment; } public async login(scopes: string): Promise { @@ -144,6 +152,58 @@ export class GitHubServer implements IGitHubServer { throw new Error(userCancelled ? CANCELLATION_ERROR : 'No auth flow succeeded.'); } + public async logout(session: vscode.AuthenticationSession): Promise { + this._logger.trace(`Deleting session (${session.id}) from server...`); + + if (!Config.gitHubClientSecret) { + this._logger.warn('No client secret configured for GitHub authentication. The token has been deleted with best effort on this system, but we are unable to delete the token on server without the client secret.'); + return; + } + + // Only attempt to delete OAuth tokens. They are always prefixed with `gho_`. + // https://docs.github.com/en/rest/apps/oauth-applications#about-oauth-apps-and-oauth-authorizations-of-github-apps + if (!session.accessToken.startsWith('gho_')) { + this._logger.warn('The token being deleted is not an OAuth token. It has been deleted locally, but we cannot delete it on server.'); + return; + } + + if (!isSupportedTarget(this._type, this._ghesUri)) { + this._logger.trace('GitHub.com and GitHub hosted GitHub Enterprise are the only options that support deleting tokens on the server. Skipping.'); + return; + } + + const authHeader = 'Basic ' + base64Encode(`${Config.gitHubClientId}:${Config.gitHubClientSecret}`); + const uri = this.getServerUri(`/applications/${Config.gitHubClientId}/token`); + + try { + // Defined here: https://docs.github.com/en/rest/apps/oauth-applications?apiVersion=2022-11-28#delete-an-app-token + const result = await fetching(uri.toString(true), { + method: 'DELETE', + headers: { + Accept: 'application/vnd.github+json', + Authorization: authHeader, + 'X-GitHub-Api-Version': '2022-11-28', + 'User-Agent': `${vscode.env.appName} (${vscode.env.appHost})` + }, + body: JSON.stringify({ access_token: session.accessToken }), + }); + + if (result.status === 204) { + this._logger.trace(`Successfully deleted token from session (${session.id}) from server.`); + return; + } + + try { + const body = await result.text(); + throw new Error(body); + } catch (e) { + throw new Error(`${result.status} ${result.statusText}`); + } + } catch (e) { + this._logger.warn('Failed to delete token from server.' + e.message ?? e); + } + } + private getServerUri(path: string = '') { const apiUri = this.baseUri; // github.com and Hosted GitHub Enterprise instances diff --git a/extensions/github-authentication/src/node/buffer.ts b/extensions/github-authentication/src/node/buffer.ts new file mode 100644 index 0000000000000..8e6208aa22a7b --- /dev/null +++ b/extensions/github-authentication/src/node/buffer.ts @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +export function base64Encode(text: string): string { + return Buffer.from(text, 'binary').toString('base64'); +} diff --git a/extensions/github-authentication/yarn.lock b/extensions/github-authentication/yarn.lock index 752933d621f16..da5f5631576c3 100644 --- a/extensions/github-authentication/yarn.lock +++ b/extensions/github-authentication/yarn.lock @@ -17,7 +17,16 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" -"@azure/core-rest-pipeline@^1.10.0": +"@azure/core-auth@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.5.0.tgz#a41848c5c31cb3b7c84c409885267d55a2c92e44" + integrity sha512-udzoBuYG1VBoHVohDTrvKjyzel34zt77Bhp7dQntVGGD0ehVq48owENbBG8fIgkHRNUBQH5k1r0hpoMu5L8+kw== + dependencies: + "@azure/abort-controller" "^1.0.0" + "@azure/core-util" "^1.1.0" + tslib "^2.2.0" + +"@azure/core-rest-pipeline@1.10.1": version "1.10.1" resolved "https://registry.yarnpkg.com/@azure/core-rest-pipeline/-/core-rest-pipeline-1.10.1.tgz#348290847ca31b9eecf9cf5de7519aaccdd30968" integrity sha512-Kji9k6TOFRDB5ZMTw8qUf2IJ+CeJtsuMdAHox9eqpTf1cefiNMpzrfnF6sINEBZJsaVaWgQ0o48B6kcUH68niA== @@ -33,13 +42,21 @@ tslib "^2.2.0" uuid "^8.3.0" -"@azure/core-tracing@^1.0.1": +"@azure/core-tracing@^1.0.0", "@azure/core-tracing@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.0.1.tgz#352a38cbea438c4a83c86b314f48017d70ba9503" integrity sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw== dependencies: tslib "^2.2.0" +"@azure/core-util@1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.2.0.tgz#3499deba1fc36dda6f1912b791809b6f15d4a392" + integrity sha512-ffGIw+Qs8bNKNLxz5UPkz4/VBM/EZY07mPve1ZYFqYUdPwFqRj0RPk0U7LZMOfT7GCck9YjuT1Rfp1PApNl1ng== + dependencies: + "@azure/abort-controller" "^1.0.0" + tslib "^2.2.0" + "@azure/core-util@^1.0.0": version "1.1.1" resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.1.1.tgz#8f87b3dd468795df0f0849d9f096c3e7b29452c1" @@ -48,6 +65,14 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" +"@azure/core-util@^1.1.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.4.0.tgz#c120a56b3e48a9e4d20619a0b00268ae9de891c7" + integrity sha512-eGAyJpm3skVQoLiRqm/xPa+SXi/NPDdSHMxbRAz2lSprd+Zs+qrpQGQQ2VQ3Nttu+nSZR4XoYQC71LbEI7jsig== + dependencies: + "@azure/abort-controller" "^1.0.0" + tslib "^2.2.0" + "@azure/logger@^1.0.0": version "1.0.3" resolved "https://registry.yarnpkg.com/@azure/logger/-/logger-1.0.3.tgz#6e36704aa51be7d4a1bae24731ea580836293c96" @@ -55,66 +80,100 @@ dependencies: tslib "^2.2.0" -"@microsoft/1ds-core-js@3.2.8", "@microsoft/1ds-core-js@^3.2.8": - version "3.2.8" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.8.tgz#1b6b7d9bb858238c818ccf4e4b58ece7aeae5760" - integrity sha512-9o9SUAamJiTXIYwpkQDuueYt83uZfXp8zp8YFix1IwVPwC9RmE36T2CX9gXOeq1nDckOuOduYpA8qHvdh5BGfQ== +"@azure/opentelemetry-instrumentation-azure-sdk@^1.0.0-beta.5": + version "1.0.0-beta.5" + resolved "https://registry.yarnpkg.com/@azure/opentelemetry-instrumentation-azure-sdk/-/opentelemetry-instrumentation-azure-sdk-1.0.0-beta.5.tgz#78809e6c005d08450701e5d37f087f6fce2f86eb" + integrity sha512-fsUarKQDvjhmBO4nIfaZkfNSApm1hZBzcvpNbSrXdcUBxu7lRvKsV5DnwszX7cnhLyVOW9yl1uigtRQ1yDANjA== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "^2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@azure/core-tracing" "^1.0.0" + "@azure/logger" "^1.0.0" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/instrumentation" "^0.41.2" + tslib "^2.2.0" -"@microsoft/1ds-post-js@^3.2.8": - version "3.2.8" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.8.tgz#46793842cca161bf7a2a5b6053c349f429e55110" - integrity sha512-SjlRoNcXcXBH6WQD/5SkkaCHIVqldH3gDu+bI7YagrOVJ5APxwT1Duw9gm3L1FjFa9S2i81fvJ3EVSKpp9wULA== +"@microsoft/1ds-core-js@3.2.13", "@microsoft/1ds-core-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.13.tgz#0c105ed75091bae3f1555c0334704fa9911c58fb" + integrity sha512-CluYTRWcEk0ObG5EWFNWhs87e2qchJUn0p2D21ZUa3PWojPZfPSBs4//WIE0MYV8Qg1Hdif2ZTwlM7TbYUjfAg== dependencies: - "@microsoft/1ds-core-js" "3.2.8" + "@microsoft/applicationinsights-core-js" "2.8.15" "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@microsoft/applicationinsights-channel-js@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.8.9.tgz#840656f3c716de8b3eb0a98c122aa1b92bb8ebfb" - integrity sha512-fMBsAEB7pWtPn43y72q9Xy5E5y55r6gMuDQqRRccccVoQDPXyS57VCj5IdATblctru0C6A8XpL2vRyNmEsu0Vg== +"@microsoft/1ds-post-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.13.tgz#560aacac8a92fdbb79e8c2ebcb293d56e19f51aa" + integrity sha512-HgS574fdD19Bo2vPguyznL4eDw7Pcm1cVNpvbvBLWiW3x4e1FCQ3VMXChWnAxCae8Hb0XqlA2sz332ZobBavTA== dependencies: - "@microsoft/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" + "@microsoft/1ds-core-js" "3.2.13" + "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@microsoft/applicationinsights-common@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-2.8.9.tgz#a75e4a3143a7fd797687830c0ddd2069fd900827" - integrity sha512-mObn1moElyxZaGIRF/IU3cOaeKMgxghXnYEoHNUCA2e+rNwBIgxjyKkblFIpmGuHf4X7Oz3o3yBWpaC6AoMpig== +"@microsoft/applicationinsights-channel-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-3.0.2.tgz#be49fbf74831c7b8c97950027c5052ea99d2a8a5" + integrity sha512-jDBNKbCHsJgmpv0CKNhJ/uN9ZphvfGdb93Svk+R4LjO8L3apNNMbDDPxBvXXi0uigRmA1TBcmyBG4IRKjabGhw== + dependencies: + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" + +"@microsoft/applicationinsights-common@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-3.0.2.tgz#37670bb07f4858ed41ff9759119e0759007d6e05" + integrity sha512-y+WXWop+OVim954Cu1uyYMnNx6PWO8okHpZIQi/1YSqtqaYdtJVPv4P0AVzwJdohxzVfgzKvqj9nec/VWqE2Zg== + dependencies: + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" + +"@microsoft/applicationinsights-core-js@2.8.15": + version "2.8.15" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.15.tgz#8fa466474260e01967fe649f14dd9e5ff91dcdc8" + integrity sha512-yYAs9MyjGr2YijQdUSN9mVgT1ijI1FPMgcffpaPmYbHAVbQmF7bXudrBWHxmLzJlwl5rfep+Zgjli2e67lwUqQ== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.9" "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/dynamicproto-js" "^1.1.9" -"@microsoft/applicationinsights-core-js@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.9.tgz#0e5d207acfae6986a6fc97249eeb6117e523bf1b" - integrity sha512-HRuIuZ6aOWezcg/G5VyFDDWGL8hDNe/ljPP01J7ImH2kRPEgbtcfPSUMjkamGMefgdq81GZsSoC/NNGTP4pp2w== +"@microsoft/applicationinsights-core-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-3.0.2.tgz#108e20df8c162bec92b1f66f9de2530a25d9f51a" + integrity sha512-WQhVhzlRlLDrQzn3OShCW/pL3BW5WC57t0oywSknX3q7lMzI3jDg7Ihh0iuIcNTzGCTbDkuqr4d6IjEDWIMtJQ== dependencies: - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-shims@2.0.2", "@microsoft/applicationinsights-shims@^2.0.2": version "2.0.2" resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.2.tgz#92b36a09375e2d9cb2b4203383b05772be837085" integrity sha512-PoHEgsnmcqruLNHZ/amACqdJ6YYQpED0KSRe6J7gIJTtpZC1FfFU9b1fmDKDKtFoUSrPzEh1qzO3kmRZP0betg== -"@microsoft/applicationinsights-web-basic@^2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-2.8.9.tgz#eed2f3d1e19069962ed2155915c1656e6936e1d5" - integrity sha512-CH0J8JFOy7MjK8JO4pXXU+EML+Ilix+94PMZTX5EJlBU1in+mrik74/8qSg3UC4ekPi12KwrXaHCQSVC3WseXQ== +"@microsoft/applicationinsights-shims@3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-3.0.1.tgz#3865b73ace8405b9c4618cc5c571f2fe3876f06f" + integrity sha512-DKwboF47H1nb33rSUfjqI6ryX29v+2QWcTrRvcQDA32AZr5Ilkr7whOOSsD1aBzwqX0RJEIP1Z81jfE3NBm/Lg== dependencies: - "@microsoft/applicationinsights-channel-js" "2.8.9" - "@microsoft/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" + +"@microsoft/applicationinsights-web-basic@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-3.0.2.tgz#f777a4d24b79dde3ae396d3b819e1fce06b7240a" + integrity sha512-6Lq0DE/pZp9RvSV+weGbcxN1NDmfczj6gNPhvZKV2YSQ3RK0LZE3+wjTWLXfuStq8a+nCBdsRpWk8tOKgsoxcg== + dependencies: + "@microsoft/applicationinsights-channel-js" "3.0.2" + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-web-snippet@^1.0.1": version "1.0.1" @@ -126,39 +185,74 @@ resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.7.tgz#ede48dd3f85af14ee369c805e5ed5b84222b9fe2" integrity sha512-SK3D3aVt+5vOOccKPnGaJWB5gQ8FuKfjboUJHedMP7gu54HqSCXX5iFXhktGD8nfJb0Go30eDvs/UDoTnR2kOA== -"@opentelemetry/api@^1.0.4": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.2.0.tgz#89ef99401cde6208cff98760b67663726ef26686" - integrity sha512-0nBr+VZNKm9tvNDZFstI3Pq1fCTEDK5OZTnVKNvBNAKgd0yIvmwsP4m61rEv7ZP+tOUjWJhROpxK5MsnlF911g== +"@microsoft/dynamicproto-js@^1.1.9": + version "1.1.9" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.9.tgz#7437db7aa061162ee94e4131b69a62b8dad5dea6" + integrity sha512-n1VPsljTSkthsAFYdiWfC+DKzK2WwcRp83Y1YAqdX552BstvsDjft9YXppjUzp11BPsapDoO1LDgrDB0XVsfNQ== -"@opentelemetry/core@1.7.0", "@opentelemetry/core@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.7.0.tgz#83bdd1b7a4ceafcdffd6590420657caec5f7b34c" - integrity sha512-AVqAi5uc8DrKJBimCTFUT4iFI+5eXpo4sYmGbQ0CypG0piOTHE2g9c5aSoTGYXu3CzOmJZf7pT6Xh+nwm5d6yQ== +"@microsoft/dynamicproto-js@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-2.0.2.tgz#e57fbec2e7067d48b7e8e1e1c1d354028ef718a6" + integrity sha512-MB8trWaFREpmb037k/d0bB7T2BP7Ai24w1e1tbz3ASLB0/lwphsq3Nq8S9I5AsI5vs4zAQT+SB5nC5/dLYTiOg== dependencies: - "@opentelemetry/semantic-conventions" "1.7.0" + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" -"@opentelemetry/resources@1.7.0": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.7.0.tgz#90ccd3a6a86b4dfba4e833e73944bd64958d78c5" - integrity sha512-u1M0yZotkjyKx8dj+46Sg5thwtOTBmtRieNXqdCRiWUp6SfFiIP0bI+1XK3LhuXqXkBXA1awJZaTqKduNMStRg== +"@nevware21/ts-async@>= 0.2.4 < 2.x": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@nevware21/ts-async/-/ts-async-0.3.0.tgz#a8b97ba01065fc930de9a3f4dd4a05e862becc6c" + integrity sha512-ZUcgUH12LN/F6nzN0cYd0F/rJaMLmXr0EHVTyYfaYmK55bdwE4338uue4UiVoRqHVqNW4KDUrJc49iGogHKeWA== dependencies: - "@opentelemetry/core" "1.7.0" - "@opentelemetry/semantic-conventions" "1.7.0" + "@nevware21/ts-utils" ">= 0.10.0 < 2.x" + +"@nevware21/ts-utils@>= 0.10.0 < 2.x", "@nevware21/ts-utils@>= 0.9.4 < 2.x", "@nevware21/ts-utils@>= 0.9.5 < 2.x": + version "0.10.1" + resolved "https://registry.yarnpkg.com/@nevware21/ts-utils/-/ts-utils-0.10.1.tgz#aa65abc71eba06749a396598f22263d26f796ac7" + integrity sha512-pMny25NnF2/MJwdqC3Iyjm2pGIXNxni4AROpcqDeWa+td9JMUY4bUS9uU9XW+BoBRqTLUL+WURF9SOd/6OQzRg== + +"@opentelemetry/api@^1.4.1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.4.1.tgz#ff22eb2e5d476fbc2450a196e40dd243cc20c28f" + integrity sha512-O2yRJce1GOc6PAy3QxFM4NzFiWzvScDC1/5ihYBL6BUEVdq0XMWN01sppE+H6bBXbaFYipjwFLEWLg5PaSOThA== -"@opentelemetry/sdk-trace-base@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.7.0.tgz#b498424e0c6340a9d80de63fd408c5c2130a60a5" - integrity sha512-Iz84C+FVOskmauh9FNnj4+VrA+hG5o+tkMzXuoesvSfunVSioXib0syVFeNXwOm4+M5GdWCuW632LVjqEXStIg== +"@opentelemetry/core@1.15.2", "@opentelemetry/core@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.15.2.tgz#5b170bf223a2333884bbc2d29d95812cdbda7c9f" + integrity sha512-+gBv15ta96WqkHZaPpcDHiaz0utiiHZVfm2YOYSqFGrUaJpPkMoSuLBB58YFQGi6Rsb9EHos84X6X5+9JspmLw== dependencies: - "@opentelemetry/core" "1.7.0" - "@opentelemetry/resources" "1.7.0" - "@opentelemetry/semantic-conventions" "1.7.0" + "@opentelemetry/semantic-conventions" "1.15.2" -"@opentelemetry/semantic-conventions@1.7.0", "@opentelemetry/semantic-conventions@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.7.0.tgz#af80a1ef7cf110ea3a68242acd95648991bcd763" - integrity sha512-FGBx/Qd09lMaqQcogCHyYrFEpTx4cAjeS+48lMIR12z7LdH+zofGDVQSubN59nL6IpubfKqTeIDu9rNO28iHVA== +"@opentelemetry/instrumentation@^0.41.2": + version "0.41.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.41.2.tgz#cae11fa64485dcf03dae331f35b315b64bc6189f" + integrity sha512-rxU72E0pKNH6ae2w5+xgVYZLzc5mlxAbGzF4shxMVK8YC2QQsfN38B2GPbj0jvrKWWNUElfclQ+YTykkNg/grw== + dependencies: + "@types/shimmer" "^1.0.2" + import-in-the-middle "1.4.2" + require-in-the-middle "^7.1.1" + semver "^7.5.1" + shimmer "^1.2.1" + +"@opentelemetry/resources@1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.15.2.tgz#0c9e26cb65652a1402834a3c030cce6028d6dd9d" + integrity sha512-xmMRLenT9CXmm5HMbzpZ1hWhaUowQf8UB4jMjFlAxx1QzQcsD3KFNAVX/CAWzFPtllTyTplrA4JrQ7sCH3qmYw== + dependencies: + "@opentelemetry/core" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" + +"@opentelemetry/sdk-trace-base@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.15.2.tgz#4821f94033c55a6c8bbd35ae387b715b6108517a" + integrity sha512-BEaxGZbWtvnSPchV98qqqqa96AOcb41pjgvhfzDij10tkBhIu9m0Jd6tZ1tJB5ZHfHbTffqYVYE0AOGobec/EQ== + dependencies: + "@opentelemetry/core" "1.15.2" + "@opentelemetry/resources" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" + +"@opentelemetry/semantic-conventions@1.15.2", "@opentelemetry/semantic-conventions@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.15.2.tgz#3bafb5de3e20e841dff6cb3c66f4d6e9694c4241" + integrity sha512-CjbOKwk2s+3xPIMcd5UNYQzsf+v94RczbdNix9/kQh38WiQkM90sUOi3if8eyHFgiBjBjhwXrA7W3ydiSQP9mw== "@tootallnate/once@2": version "2.0.0" @@ -178,20 +272,35 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.5.tgz#3d03acd3b3414cf67faf999aed11682ed121f22b" integrity sha512-90hiq6/VqtQgX8Sp0EzeIsv3r+ellbGj4URKj5j30tLlZvRUpnAe9YbYnjl3pJM93GyXU0tghHhvXHq+5rnCKA== -"@types/node@16.x": - version "16.11.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae" - integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w== +"@types/node@18.x": + version "18.15.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" + integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== + +"@types/shimmer@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/shimmer/-/shimmer-1.0.2.tgz#93eb2c243c351f3f17d5c580c7467ae5d686b65f" + integrity sha512-dKkr1bTxbEsFlh2ARpKzcaAmsYixqt9UyCdoEZk8rHyE4iQYcDCyvSjDSf7JUWJHlJiTtbIoQjxKh6ViywqDAg== -"@vscode/extension-telemetry@0.7.5": - version "0.7.5" - resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.7.5.tgz#bf965731816e08c3f146f96d901ec67954fc913b" - integrity sha512-fJ5y3TcpqqkFYHneabYaoB4XAhDdVflVm+TDKshw9VOs77jkgNS4UA7LNXrWeO0eDne3Sh3JgURf+xzc1rk69w== +"@vscode/extension-telemetry@^0.8.4": + version "0.8.4" + resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.8.4.tgz#c078c6f55df1c9e0592de3b4ce0f685dd345bfe7" + integrity sha512-UqM9+KZDDK3MyoHTsg6XNM+XO6pweQxzCpqJz33BoBEYAGsbBviRYcVpJglgay2oReuDD2pOI1Nio3BKNDLhWA== 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" + "@microsoft/1ds-core-js" "^3.2.13" + "@microsoft/1ds-post-js" "^3.2.13" + "@microsoft/applicationinsights-web-basic" "^3.0.2" + applicationinsights "^2.7.1" + +acorn-import-assertions@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" + integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== + +acorn@^8.8.2: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== agent-base@6: version "6.0.2" @@ -200,22 +309,24 @@ agent-base@6: dependencies: debug "4" -applicationinsights@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.4.1.tgz#4de4c4dd3c7c4a44445cfbf3d15808fc0dcc423d" - integrity sha512-0n0Ikd0gzSm460xm+M0UTWIwXrhrH/0bqfZatcJjYObWyefxfAxapGEyNnSGd1Tg90neHz+Yhf+Ff/zgvPiQYA== +applicationinsights@^2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.7.3.tgz#8781454d29c0b14c9773f2e892b4cf5e7468ffa5" + integrity sha512-JY8+kTEkjbA+kAVNWDtpfW2lqsrDALfDXuxOs74KLPu2y13fy/9WB52V4LfYVTVcW1/jYOXjTxNS2gPZIDh1iw== dependencies: - "@azure/core-auth" "^1.4.0" - "@azure/core-rest-pipeline" "^1.10.0" + "@azure/core-auth" "^1.5.0" + "@azure/core-rest-pipeline" "1.10.1" + "@azure/core-util" "1.2.0" + "@azure/opentelemetry-instrumentation-azure-sdk" "^1.0.0-beta.5" "@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" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/sdk-trace-base" "^1.15.2" + "@opentelemetry/semantic-conventions" "^1.15.2" cls-hooked "^4.2.2" continuation-local-storage "^3.2.1" - diagnostic-channel "1.1.0" - diagnostic-channel-publishers "1.0.5" + diagnostic-channel "1.1.1" + diagnostic-channel-publishers "1.0.7" async-hook-jl@^1.7.6: version "1.7.6" @@ -244,6 +355,11 @@ axios@^0.26.1: dependencies: follow-redirects "^1.14.8" +cjs-module-lexer@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" + integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== + cls-hooked@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/cls-hooked/-/cls-hooked-4.2.2.tgz#ad2e9a4092680cdaffeb2d3551da0e225eae1908" @@ -268,7 +384,7 @@ continuation-local-storage@^3.2.1: async-listener "^0.6.0" emitter-listener "^1.1.1" -debug@4: +debug@4, debug@^4.1.1: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -280,17 +396,17 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= -diagnostic-channel-publishers@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.5.tgz#df8c317086c50f5727fdfb5d2fce214d2e4130ae" - integrity sha512-dJwUS0915pkjjimPJVDnS/QQHsH0aOYhnZsLJdnZIMOrB+csj8RnZhWTuwnm8R5v3Z7OZs+ksv5luC14DGB7eg== +diagnostic-channel-publishers@1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.7.tgz#9b7f8d5ee1295481aee19c827d917e96fedf2c4a" + integrity sha512-SEECbY5AiVt6DfLkhkaHNeshg1CogdLLANA8xlG/TKvS+XUgvIKl7VspJGYiEdL5OUyzMVnr7o0AwB7f+/Mjtg== -diagnostic-channel@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.0.tgz#6985e9dfedfbc072d91dc4388477e4087147756e" - integrity sha512-fwujyMe1gj6rk6dYi9hMZm0c8Mz8NDMVl2LB4iaYh3+LIAThZC8RKFGXWG0IML2OxAit/ZFRgZhMkhQ3d/bobQ== +diagnostic-channel@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.1.tgz#44b60972de9ee055c16216535b0e9db3f6a0efd0" + integrity sha512-r2HV5qFkUICyoaKlBEpLKHjxMXATUf/l+h8UZPGBHGLy4DDiY2sOLcIctax4eRnTw5wH2jTMExLntGPJ8eOJxw== dependencies: - semver "^5.3.0" + semver "^7.5.3" emitter-listener@^1.0.1, emitter-listener@^1.1.1: version "1.1.2" @@ -322,6 +438,18 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + http-proxy-agent@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" @@ -339,6 +467,30 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" +import-in-the-middle@1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/import-in-the-middle/-/import-in-the-middle-1.4.2.tgz#2a266676e3495e72c04bbaa5ec14756ba168391b" + integrity sha512-9WOz1Yh/cvO/p69sxRmhyQwrIGGSp7EIdcb+fFNVi7CzQGQB8U1/1XrKVSbEd/GNOAeM0peJtmi7+qphe7NvAw== + dependencies: + acorn "^8.8.2" + acorn-import-assertions "^1.9.0" + cjs-module-lexer "^1.2.2" + module-details-from-path "^1.0.3" + +is-core-module@^2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" + integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== + dependencies: + has "^1.0.3" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + mime-db@1.44.0: version "1.44.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" @@ -351,6 +503,11 @@ mime-types@^2.1.12: dependencies: mime-db "1.44.0" +module-details-from-path@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/module-details-from-path/-/module-details-from-path-1.0.3.tgz#114c949673e2a8a35e9d35788527aa37b679da2b" + integrity sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A== + ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" @@ -363,12 +520,42 @@ node-fetch@2.6.7: dependencies: whatwg-url "^5.0.0" +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +require-in-the-middle@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/require-in-the-middle/-/require-in-the-middle-7.2.0.tgz#b539de8f00955444dc8aed95e17c69b0a4f10fcf" + integrity sha512-3TLx5TGyAY6AOqLBoXmHkNql0HIf2RGbuMgCDT2WO/uGVAPJs6h7Kl+bN6TIZGd9bWhWPwnDnTHGtW8Iu77sdw== + dependencies: + debug "^4.1.1" + module-details-from-path "^1.0.3" + resolve "^1.22.1" + +resolve@^1.22.1: + version "1.22.4" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.4.tgz#1dc40df46554cdaf8948a486a10f6ba1e2026c34" + integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + semver@^5.3.0, semver@^5.4.1: version "5.7.2" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -shimmer@^1.1.0, shimmer@^1.2.0: +semver@^7.5.1, semver@^7.5.3: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +shimmer@^1.1.0, shimmer@^1.2.0, shimmer@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337" integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw== @@ -378,6 +565,11 @@ stack-chain@^1.3.7: resolved "https://registry.yarnpkg.com/stack-chain/-/stack-chain-1.3.7.tgz#d192c9ff4ea6a22c94c4dd459171e3f00cea1285" integrity sha512-D8cWtWVdIe/jBA7v5p5Hwl5yOSOrmZPWDPe2KxQ5UAGD+nxbxU0lKXA4h85Ta6+qgdKVL3vUxsbIZjc1kBG7ug== +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + tas-client@0.1.45: version "0.1.45" resolved "https://registry.yarnpkg.com/tas-client/-/tas-client-0.1.45.tgz#83bbf73f8458a0f527f9a389f7e1c37f63a64a76" @@ -419,3 +611,8 @@ whatwg-url@^5.0.0: dependencies: tr46 "~0.0.3" webidl-conversions "^3.0.0" + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== diff --git a/extensions/github/package.json b/extensions/github/package.json index 6e655fca9834a..afbb7253f7f9e 100644 --- a/extensions/github/package.json +++ b/extensions/github/package.json @@ -183,10 +183,10 @@ "@octokit/graphql-schema": "14.4.0", "@octokit/rest": "19.0.4", "tunnel": "^0.0.6", - "@vscode/extension-telemetry": "0.7.5" + "@vscode/extension-telemetry": "^0.8.4" }, "devDependencies": { - "@types/node": "16.x" + "@types/node": "18.x" }, "repository": { "type": "git", diff --git a/extensions/github/src/links.ts b/extensions/github/src/links.ts index b270792404f7b..911f0e5376bf3 100644 --- a/extensions/github/src/links.ts +++ b/extensions/github/src/links.ts @@ -191,6 +191,8 @@ export function getVscodeDevHost(): string { } export async function ensurePublished(repository: Repository, file: vscode.Uri) { + await repository.status(); + if ((repository.state.HEAD?.type === RefType.Head || repository.state.HEAD?.type === RefType.Tag) // If HEAD is not published, make sure it is && !repository?.state.HEAD?.upstream diff --git a/extensions/github/yarn.lock b/extensions/github/yarn.lock index 323df7dadbe65..ab4275a38b9c0 100644 --- a/extensions/github/yarn.lock +++ b/extensions/github/yarn.lock @@ -17,32 +17,50 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" -"@azure/core-rest-pipeline@^1.10.0": - version "1.11.0" - resolved "https://registry.yarnpkg.com/@azure/core-rest-pipeline/-/core-rest-pipeline-1.11.0.tgz#fc0e8f56caac08a9d4ac91c07a6c5a360ea31c82" - integrity sha512-nB4KXl6qAyJmBVLWA7SakT4tzpYZTCk4pvRBeI+Ye0WYSOrlTqlMhc4MSS/8atD3ufeYWdkN380LLoXlUUzThw== +"@azure/core-auth@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.5.0.tgz#a41848c5c31cb3b7c84c409885267d55a2c92e44" + integrity sha512-udzoBuYG1VBoHVohDTrvKjyzel34zt77Bhp7dQntVGGD0ehVq48owENbBG8fIgkHRNUBQH5k1r0hpoMu5L8+kw== + dependencies: + "@azure/abort-controller" "^1.0.0" + "@azure/core-util" "^1.1.0" + tslib "^2.2.0" + +"@azure/core-rest-pipeline@1.10.1": + version "1.10.1" + resolved "https://registry.yarnpkg.com/@azure/core-rest-pipeline/-/core-rest-pipeline-1.10.1.tgz#348290847ca31b9eecf9cf5de7519aaccdd30968" + integrity sha512-Kji9k6TOFRDB5ZMTw8qUf2IJ+CeJtsuMdAHox9eqpTf1cefiNMpzrfnF6sINEBZJsaVaWgQ0o48B6kcUH68niA== dependencies: "@azure/abort-controller" "^1.0.0" "@azure/core-auth" "^1.4.0" "@azure/core-tracing" "^1.0.1" - "@azure/core-util" "^1.3.0" + "@azure/core-util" "^1.0.0" "@azure/logger" "^1.0.0" form-data "^4.0.0" http-proxy-agent "^5.0.0" https-proxy-agent "^5.0.0" tslib "^2.2.0" + uuid "^8.3.0" -"@azure/core-tracing@^1.0.1": +"@azure/core-tracing@^1.0.0", "@azure/core-tracing@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.0.1.tgz#352a38cbea438c4a83c86b314f48017d70ba9503" integrity sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw== dependencies: tslib "^2.2.0" -"@azure/core-util@^1.3.0": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.3.2.tgz#3f8cfda1e87fac0ce84f8c1a42fcd6d2a986632d" - integrity sha512-2bECOUh88RvL1pMZTcc6OzfobBeWDBf5oBbhjIhT1MV9otMVWCzpOJkkiKtrnO88y5GGBelgY8At73KGAdbkeQ== +"@azure/core-util@1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.2.0.tgz#3499deba1fc36dda6f1912b791809b6f15d4a392" + integrity sha512-ffGIw+Qs8bNKNLxz5UPkz4/VBM/EZY07mPve1ZYFqYUdPwFqRj0RPk0U7LZMOfT7GCck9YjuT1Rfp1PApNl1ng== + dependencies: + "@azure/abort-controller" "^1.0.0" + tslib "^2.2.0" + +"@azure/core-util@^1.0.0", "@azure/core-util@^1.1.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.4.0.tgz#c120a56b3e48a9e4d20619a0b00268ae9de891c7" + integrity sha512-eGAyJpm3skVQoLiRqm/xPa+SXi/NPDdSHMxbRAz2lSprd+Zs+qrpQGQQ2VQ3Nttu+nSZR4XoYQC71LbEI7jsig== dependencies: "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" @@ -54,66 +72,100 @@ dependencies: tslib "^2.2.0" -"@microsoft/1ds-core-js@3.2.12", "@microsoft/1ds-core-js@^3.2.8": - version "3.2.12" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.12.tgz#f5f56626bd0385a357fae6f730eea347be02ce64" - integrity sha512-cHpxZZ+pbtOyqFMFB/c1COpaOE3VPFU6phYVHVvOA9DvoeMZfI/Xrxaj7B/vfq4MmkiE7nOAPhv5ZRn+i6OogA== +"@azure/opentelemetry-instrumentation-azure-sdk@^1.0.0-beta.5": + version "1.0.0-beta.5" + resolved "https://registry.yarnpkg.com/@azure/opentelemetry-instrumentation-azure-sdk/-/opentelemetry-instrumentation-azure-sdk-1.0.0-beta.5.tgz#78809e6c005d08450701e5d37f087f6fce2f86eb" + integrity sha512-fsUarKQDvjhmBO4nIfaZkfNSApm1hZBzcvpNbSrXdcUBxu7lRvKsV5DnwszX7cnhLyVOW9yl1uigtRQ1yDANjA== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.14" - "@microsoft/applicationinsights-shims" "^2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@azure/core-tracing" "^1.0.0" + "@azure/logger" "^1.0.0" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/instrumentation" "^0.41.2" + tslib "^2.2.0" -"@microsoft/1ds-post-js@^3.2.8": - version "3.2.12" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.12.tgz#60f6ff48ba48c88880c1bceb376711cdd34f87ea" - integrity sha512-vhIVYg4FzBfwtM8tBqDUq3xU+cFu6SQ7biuJHtQpd5PVjDgvAovVOMRF1khsZE/k2rttRRBpmBgNEqG3Ptoysw== +"@microsoft/1ds-core-js@3.2.13", "@microsoft/1ds-core-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.13.tgz#0c105ed75091bae3f1555c0334704fa9911c58fb" + integrity sha512-CluYTRWcEk0ObG5EWFNWhs87e2qchJUn0p2D21ZUa3PWojPZfPSBs4//WIE0MYV8Qg1Hdif2ZTwlM7TbYUjfAg== dependencies: - "@microsoft/1ds-core-js" "3.2.12" + "@microsoft/applicationinsights-core-js" "2.8.15" "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@microsoft/applicationinsights-channel-js@2.8.14": - version "2.8.14" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.8.14.tgz#daabd8a418d9b70a318c0126518e000dd6f67fa0" - integrity sha512-z1AG6lqV3ACtdUXnT0Ubj48BAZ8K01sFsYdWgroSXpw2lYUlXAzdx3tK8zpaqEXSEhok8CWTZki7aunHzkZHSw== +"@microsoft/1ds-post-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.13.tgz#560aacac8a92fdbb79e8c2ebcb293d56e19f51aa" + integrity sha512-HgS574fdD19Bo2vPguyznL4eDw7Pcm1cVNpvbvBLWiW3x4e1FCQ3VMXChWnAxCae8Hb0XqlA2sz332ZobBavTA== dependencies: - "@microsoft/applicationinsights-common" "2.8.14" - "@microsoft/applicationinsights-core-js" "2.8.14" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.9" + "@microsoft/1ds-core-js" "3.2.13" + "@microsoft/applicationinsights-shims" "^2.0.2" + "@microsoft/dynamicproto-js" "^1.1.7" -"@microsoft/applicationinsights-common@2.8.14": - version "2.8.14" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-2.8.14.tgz#7d082295f862a189c80aa98b3f4aaec926546051" - integrity sha512-1xjJvyyRN7tb5ahOTkEGGsvw8zvqmS714y3+1m7ooKHFfxO0wX+eYOU/kke74BCY0nJ/pocB/6hjWZOgwvbHig== +"@microsoft/applicationinsights-channel-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-3.0.2.tgz#be49fbf74831c7b8c97950027c5052ea99d2a8a5" + integrity sha512-jDBNKbCHsJgmpv0CKNhJ/uN9ZphvfGdb93Svk+R4LjO8L3apNNMbDDPxBvXXi0uigRmA1TBcmyBG4IRKjabGhw== + dependencies: + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" + +"@microsoft/applicationinsights-common@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-3.0.2.tgz#37670bb07f4858ed41ff9759119e0759007d6e05" + integrity sha512-y+WXWop+OVim954Cu1uyYMnNx6PWO8okHpZIQi/1YSqtqaYdtJVPv4P0AVzwJdohxzVfgzKvqj9nec/VWqE2Zg== + dependencies: + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" + +"@microsoft/applicationinsights-core-js@2.8.15": + version "2.8.15" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.15.tgz#8fa466474260e01967fe649f14dd9e5ff91dcdc8" + integrity sha512-yYAs9MyjGr2YijQdUSN9mVgT1ijI1FPMgcffpaPmYbHAVbQmF7bXudrBWHxmLzJlwl5rfep+Zgjli2e67lwUqQ== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.14" "@microsoft/applicationinsights-shims" "2.0.2" "@microsoft/dynamicproto-js" "^1.1.9" -"@microsoft/applicationinsights-core-js@2.8.14": - version "2.8.14" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.14.tgz#80e3d9d42102e741494726d78ac923098bad7132" - integrity sha512-XacWUHdjSHMUwdngMZBp0oiCBifD56CQK2Egu2PiBiF4xu2AO2yNCtWSXsQX2g5OkEhVwaEjfa/aH3WbpYxB1g== +"@microsoft/applicationinsights-core-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-3.0.2.tgz#108e20df8c162bec92b1f66f9de2530a25d9f51a" + integrity sha512-WQhVhzlRlLDrQzn3OShCW/pL3BW5WC57t0oywSknX3q7lMzI3jDg7Ihh0iuIcNTzGCTbDkuqr4d6IjEDWIMtJQ== dependencies: - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.9" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-shims@2.0.2", "@microsoft/applicationinsights-shims@^2.0.2": version "2.0.2" resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.2.tgz#92b36a09375e2d9cb2b4203383b05772be837085" integrity sha512-PoHEgsnmcqruLNHZ/amACqdJ6YYQpED0KSRe6J7gIJTtpZC1FfFU9b1fmDKDKtFoUSrPzEh1qzO3kmRZP0betg== -"@microsoft/applicationinsights-web-basic@^2.8.9": - version "2.8.14" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-2.8.14.tgz#8c43bcad2e12f25eb00a9aaad0182371507b21b9" - integrity sha512-R2mzg5NmCtLloq3lPQFmnlvjrPIqm3mWNYVy5ELJuOPZ7S6j9y7s4yHOzfXynmOziiQd+0q1j9pTth9aP9vo0g== +"@microsoft/applicationinsights-shims@3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-3.0.1.tgz#3865b73ace8405b9c4618cc5c571f2fe3876f06f" + integrity sha512-DKwboF47H1nb33rSUfjqI6ryX29v+2QWcTrRvcQDA32AZr5Ilkr7whOOSsD1aBzwqX0RJEIP1Z81jfE3NBm/Lg== + dependencies: + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" + +"@microsoft/applicationinsights-web-basic@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-3.0.2.tgz#f777a4d24b79dde3ae396d3b819e1fce06b7240a" + integrity sha512-6Lq0DE/pZp9RvSV+weGbcxN1NDmfczj6gNPhvZKV2YSQ3RK0LZE3+wjTWLXfuStq8a+nCBdsRpWk8tOKgsoxcg== dependencies: - "@microsoft/applicationinsights-channel-js" "2.8.14" - "@microsoft/applicationinsights-common" "2.8.14" - "@microsoft/applicationinsights-core-js" "2.8.14" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.9" + "@microsoft/applicationinsights-channel-js" "3.0.2" + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-web-snippet@^1.0.1": version "1.0.1" @@ -125,6 +177,25 @@ resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.9.tgz#7437db7aa061162ee94e4131b69a62b8dad5dea6" integrity sha512-n1VPsljTSkthsAFYdiWfC+DKzK2WwcRp83Y1YAqdX552BstvsDjft9YXppjUzp11BPsapDoO1LDgrDB0XVsfNQ== +"@microsoft/dynamicproto-js@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-2.0.2.tgz#e57fbec2e7067d48b7e8e1e1c1d354028ef718a6" + integrity sha512-MB8trWaFREpmb037k/d0bB7T2BP7Ai24w1e1tbz3ASLB0/lwphsq3Nq8S9I5AsI5vs4zAQT+SB5nC5/dLYTiOg== + dependencies: + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" + +"@nevware21/ts-async@>= 0.2.4 < 2.x": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@nevware21/ts-async/-/ts-async-0.3.0.tgz#a8b97ba01065fc930de9a3f4dd4a05e862becc6c" + integrity sha512-ZUcgUH12LN/F6nzN0cYd0F/rJaMLmXr0EHVTyYfaYmK55bdwE4338uue4UiVoRqHVqNW4KDUrJc49iGogHKeWA== + dependencies: + "@nevware21/ts-utils" ">= 0.10.0 < 2.x" + +"@nevware21/ts-utils@>= 0.10.0 < 2.x", "@nevware21/ts-utils@>= 0.9.4 < 2.x", "@nevware21/ts-utils@>= 0.9.5 < 2.x": + version "0.10.1" + resolved "https://registry.yarnpkg.com/@nevware21/ts-utils/-/ts-utils-0.10.1.tgz#aa65abc71eba06749a396598f22263d26f796ac7" + integrity sha512-pMny25NnF2/MJwdqC3Iyjm2pGIXNxni4AROpcqDeWa+td9JMUY4bUS9uU9XW+BoBRqTLUL+WURF9SOd/6OQzRg== + "@octokit/auth-token@^3.0.0": version "3.0.1" resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-3.0.1.tgz#88bc2baf5d706cb258474e722a720a8365dff2ec" @@ -255,59 +326,85 @@ dependencies: "@octokit/openapi-types" "^17.1.0" -"@opentelemetry/api@^1.0.4": +"@opentelemetry/api@^1.4.1": version "1.4.1" resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.4.1.tgz#ff22eb2e5d476fbc2450a196e40dd243cc20c28f" integrity sha512-O2yRJce1GOc6PAy3QxFM4NzFiWzvScDC1/5ihYBL6BUEVdq0XMWN01sppE+H6bBXbaFYipjwFLEWLg5PaSOThA== -"@opentelemetry/core@1.14.0", "@opentelemetry/core@^1.0.1": - version "1.14.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.14.0.tgz#64e876b29cb736c984d54164cd47433f513eafd3" - integrity sha512-MnMZ+sxsnlzloeuXL2nm5QcNczt/iO82UOeQQDHhV83F2fP3sgntW2evvtoxJki0MBLxEsh5ADD7PR/Hn5uzjw== +"@opentelemetry/core@1.15.2", "@opentelemetry/core@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.15.2.tgz#5b170bf223a2333884bbc2d29d95812cdbda7c9f" + integrity sha512-+gBv15ta96WqkHZaPpcDHiaz0utiiHZVfm2YOYSqFGrUaJpPkMoSuLBB58YFQGi6Rsb9EHos84X6X5+9JspmLw== + dependencies: + "@opentelemetry/semantic-conventions" "1.15.2" + +"@opentelemetry/instrumentation@^0.41.2": + version "0.41.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.41.2.tgz#cae11fa64485dcf03dae331f35b315b64bc6189f" + integrity sha512-rxU72E0pKNH6ae2w5+xgVYZLzc5mlxAbGzF4shxMVK8YC2QQsfN38B2GPbj0jvrKWWNUElfclQ+YTykkNg/grw== dependencies: - "@opentelemetry/semantic-conventions" "1.14.0" + "@types/shimmer" "^1.0.2" + import-in-the-middle "1.4.2" + require-in-the-middle "^7.1.1" + semver "^7.5.1" + shimmer "^1.2.1" -"@opentelemetry/resources@1.14.0": - version "1.14.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.14.0.tgz#d6b0a4e71c2706d33c8c6ec7a7b8fea6ad27ddea" - integrity sha512-qRfWIgBxxl3z47E036Aey0Lj2ZjlFb27Q7Xnj1y1z/P293RXJZGLtcfn/w8JF7v1Q2hs3SDGxz7Wb9Dko1YUQA== +"@opentelemetry/resources@1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.15.2.tgz#0c9e26cb65652a1402834a3c030cce6028d6dd9d" + integrity sha512-xmMRLenT9CXmm5HMbzpZ1hWhaUowQf8UB4jMjFlAxx1QzQcsD3KFNAVX/CAWzFPtllTyTplrA4JrQ7sCH3qmYw== dependencies: - "@opentelemetry/core" "1.14.0" - "@opentelemetry/semantic-conventions" "1.14.0" + "@opentelemetry/core" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" -"@opentelemetry/sdk-trace-base@^1.0.1": - version "1.14.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.14.0.tgz#831af08f002228a11e577ff860eb6059c8b80fb7" - integrity sha512-NzRGt3PS+HPKfQYMb6Iy8YYc5OKA73qDwci/6ujOIvyW9vcqBJSWbjZ8FeLEAmuatUB5WrRhEKu9b0sIiIYTrQ== +"@opentelemetry/sdk-trace-base@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.15.2.tgz#4821f94033c55a6c8bbd35ae387b715b6108517a" + integrity sha512-BEaxGZbWtvnSPchV98qqqqa96AOcb41pjgvhfzDij10tkBhIu9m0Jd6tZ1tJB5ZHfHbTffqYVYE0AOGobec/EQ== dependencies: - "@opentelemetry/core" "1.14.0" - "@opentelemetry/resources" "1.14.0" - "@opentelemetry/semantic-conventions" "1.14.0" + "@opentelemetry/core" "1.15.2" + "@opentelemetry/resources" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" -"@opentelemetry/semantic-conventions@1.14.0", "@opentelemetry/semantic-conventions@^1.0.1": - version "1.14.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.14.0.tgz#6a729b7f372ce30f77a3f217c09bc216f863fccb" - integrity sha512-rJfCY8rCWz3cb4KI6pEofnytvMPuj3YLQwoscCCYZ5DkdiPjo15IQ0US7+mjcWy9H3fcZIzf2pbJZ7ck/h4tug== +"@opentelemetry/semantic-conventions@1.15.2", "@opentelemetry/semantic-conventions@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.15.2.tgz#3bafb5de3e20e841dff6cb3c66f4d6e9694c4241" + integrity sha512-CjbOKwk2s+3xPIMcd5UNYQzsf+v94RczbdNix9/kQh38WiQkM90sUOi3if8eyHFgiBjBjhwXrA7W3ydiSQP9mw== "@tootallnate/once@2": version "2.0.0" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== -"@types/node@16.x": - version "16.11.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae" - integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w== +"@types/node@18.x": + version "18.15.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" + integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== -"@vscode/extension-telemetry@0.7.5": - version "0.7.5" - resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.7.5.tgz#bf965731816e08c3f146f96d901ec67954fc913b" - integrity sha512-fJ5y3TcpqqkFYHneabYaoB4XAhDdVflVm+TDKshw9VOs77jkgNS4UA7LNXrWeO0eDne3Sh3JgURf+xzc1rk69w== +"@types/shimmer@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/shimmer/-/shimmer-1.0.2.tgz#93eb2c243c351f3f17d5c580c7467ae5d686b65f" + integrity sha512-dKkr1bTxbEsFlh2ARpKzcaAmsYixqt9UyCdoEZk8rHyE4iQYcDCyvSjDSf7JUWJHlJiTtbIoQjxKh6ViywqDAg== + +"@vscode/extension-telemetry@^0.8.4": + version "0.8.4" + resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.8.4.tgz#c078c6f55df1c9e0592de3b4ce0f685dd345bfe7" + integrity sha512-UqM9+KZDDK3MyoHTsg6XNM+XO6pweQxzCpqJz33BoBEYAGsbBviRYcVpJglgay2oReuDD2pOI1Nio3BKNDLhWA== 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" + "@microsoft/1ds-core-js" "^3.2.13" + "@microsoft/1ds-post-js" "^3.2.13" + "@microsoft/applicationinsights-web-basic" "^3.0.2" + applicationinsights "^2.7.1" + +acorn-import-assertions@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" + integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== + +acorn@^8.8.2: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== agent-base@6: version "6.0.2" @@ -316,22 +413,24 @@ agent-base@6: dependencies: debug "4" -applicationinsights@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.4.1.tgz#4de4c4dd3c7c4a44445cfbf3d15808fc0dcc423d" - integrity sha512-0n0Ikd0gzSm460xm+M0UTWIwXrhrH/0bqfZatcJjYObWyefxfAxapGEyNnSGd1Tg90neHz+Yhf+Ff/zgvPiQYA== +applicationinsights@^2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.7.3.tgz#8781454d29c0b14c9773f2e892b4cf5e7468ffa5" + integrity sha512-JY8+kTEkjbA+kAVNWDtpfW2lqsrDALfDXuxOs74KLPu2y13fy/9WB52V4LfYVTVcW1/jYOXjTxNS2gPZIDh1iw== dependencies: - "@azure/core-auth" "^1.4.0" - "@azure/core-rest-pipeline" "^1.10.0" + "@azure/core-auth" "^1.5.0" + "@azure/core-rest-pipeline" "1.10.1" + "@azure/core-util" "1.2.0" + "@azure/opentelemetry-instrumentation-azure-sdk" "^1.0.0-beta.5" "@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" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/sdk-trace-base" "^1.15.2" + "@opentelemetry/semantic-conventions" "^1.15.2" cls-hooked "^4.2.2" continuation-local-storage "^3.2.1" - diagnostic-channel "1.1.0" - diagnostic-channel-publishers "1.0.5" + diagnostic-channel "1.1.1" + diagnostic-channel-publishers "1.0.7" async-hook-jl@^1.7.6: version "1.7.6" @@ -358,6 +457,11 @@ before-after-hook@^2.2.0: resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.2.tgz#a6e8ca41028d90ee2c24222f201c90956091613e" integrity sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ== +cjs-module-lexer@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" + integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== + cls-hooked@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/cls-hooked/-/cls-hooked-4.2.2.tgz#ad2e9a4092680cdaffeb2d3551da0e225eae1908" @@ -382,7 +486,7 @@ continuation-local-storage@^3.2.1: async-listener "^0.6.0" emitter-listener "^1.1.1" -debug@4: +debug@4, debug@^4.1.1: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -399,17 +503,17 @@ deprecation@^2.0.0, deprecation@^2.3.1: resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919" integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ== -diagnostic-channel-publishers@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.5.tgz#df8c317086c50f5727fdfb5d2fce214d2e4130ae" - integrity sha512-dJwUS0915pkjjimPJVDnS/QQHsH0aOYhnZsLJdnZIMOrB+csj8RnZhWTuwnm8R5v3Z7OZs+ksv5luC14DGB7eg== +diagnostic-channel-publishers@1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.7.tgz#9b7f8d5ee1295481aee19c827d917e96fedf2c4a" + integrity sha512-SEECbY5AiVt6DfLkhkaHNeshg1CogdLLANA8xlG/TKvS+XUgvIKl7VspJGYiEdL5OUyzMVnr7o0AwB7f+/Mjtg== -diagnostic-channel@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.0.tgz#6985e9dfedfbc072d91dc4388477e4087147756e" - integrity sha512-fwujyMe1gj6rk6dYi9hMZm0c8Mz8NDMVl2LB4iaYh3+LIAThZC8RKFGXWG0IML2OxAit/ZFRgZhMkhQ3d/bobQ== +diagnostic-channel@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.1.tgz#44b60972de9ee055c16216535b0e9db3f6a0efd0" + integrity sha512-r2HV5qFkUICyoaKlBEpLKHjxMXATUf/l+h8UZPGBHGLy4DDiY2sOLcIctax4eRnTw5wH2jTMExLntGPJ8eOJxw== dependencies: - semver "^5.3.0" + semver "^7.5.3" emitter-listener@^1.0.1, emitter-listener@^1.1.1: version "1.1.2" @@ -427,6 +531,11 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + graphql-tag@^2.10.3: version "2.12.6" resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.12.6.tgz#d441a569c1d2537ef10ca3d1633b48725329b5f1" @@ -439,6 +548,13 @@ graphql@^16.0.0: resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.6.0.tgz#c2dcffa4649db149f6282af726c8c83f1c7c5fdb" integrity sha512-KPIBPDlW7NxrbT/eh4qPXz5FiFdL5UbaA0XUNz2Rp3Z3hqBSkbj0GVjwFDztsWVauZUWsbKHgMg++sk8UX0bkw== +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + http-proxy-agent@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" @@ -456,11 +572,35 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" +import-in-the-middle@1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/import-in-the-middle/-/import-in-the-middle-1.4.2.tgz#2a266676e3495e72c04bbaa5ec14756ba168391b" + integrity sha512-9WOz1Yh/cvO/p69sxRmhyQwrIGGSp7EIdcb+fFNVi7CzQGQB8U1/1XrKVSbEd/GNOAeM0peJtmi7+qphe7NvAw== + dependencies: + acorn "^8.8.2" + acorn-import-assertions "^1.9.0" + cjs-module-lexer "^1.2.2" + module-details-from-path "^1.0.3" + +is-core-module@^2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" + integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== + dependencies: + has "^1.0.3" + is-plain-object@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + mime-db@1.52.0: version "1.52.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" @@ -473,6 +613,11 @@ mime-types@^2.1.12: dependencies: mime-db "1.52.0" +module-details-from-path@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/module-details-from-path/-/module-details-from-path-1.0.3.tgz#114c949673e2a8a35e9d35788527aa37b679da2b" + integrity sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A== + ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" @@ -492,12 +637,42 @@ once@^1.4.0: dependencies: wrappy "1" +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +require-in-the-middle@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/require-in-the-middle/-/require-in-the-middle-7.2.0.tgz#b539de8f00955444dc8aed95e17c69b0a4f10fcf" + integrity sha512-3TLx5TGyAY6AOqLBoXmHkNql0HIf2RGbuMgCDT2WO/uGVAPJs6h7Kl+bN6TIZGd9bWhWPwnDnTHGtW8Iu77sdw== + dependencies: + debug "^4.1.1" + module-details-from-path "^1.0.3" + resolve "^1.22.1" + +resolve@^1.22.1: + version "1.22.4" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.4.tgz#1dc40df46554cdaf8948a486a10f6ba1e2026c34" + integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + semver@^5.3.0, semver@^5.4.1: version "5.7.2" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -shimmer@^1.1.0, shimmer@^1.2.0: +semver@^7.5.1, semver@^7.5.3: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +shimmer@^1.1.0, shimmer@^1.2.0, shimmer@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337" integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw== @@ -507,6 +682,11 @@ stack-chain@^1.3.7: resolved "https://registry.yarnpkg.com/stack-chain/-/stack-chain-1.3.7.tgz#d192c9ff4ea6a22c94c4dd459171e3f00cea1285" integrity sha512-D8cWtWVdIe/jBA7v5p5Hwl5yOSOrmZPWDPe2KxQ5UAGD+nxbxU0lKXA4h85Ta6+qgdKVL3vUxsbIZjc1kBG7ug== +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + tr46@~0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" @@ -532,6 +712,11 @@ universal-user-agent@^6.0.0: resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee" integrity sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w== +uuid@^8.3.0: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" @@ -549,3 +734,8 @@ wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== diff --git a/extensions/grunt/package.json b/extensions/grunt/package.json index 35fc30eaba1e8..0c00aec71c63e 100644 --- a/extensions/grunt/package.json +++ b/extensions/grunt/package.json @@ -18,7 +18,7 @@ }, "dependencies": {}, "devDependencies": { - "@types/node": "16.x" + "@types/node": "18.x" }, "main": "./out/main", "activationEvents": [ diff --git a/extensions/grunt/yarn.lock b/extensions/grunt/yarn.lock index e724e7fffa317..8a3d10f2b65cf 100644 --- a/extensions/grunt/yarn.lock +++ b/extensions/grunt/yarn.lock @@ -2,7 +2,7 @@ # yarn lockfile v1 -"@types/node@16.x": - version "16.11.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae" - integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w== +"@types/node@18.x": + version "18.15.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" + integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== diff --git a/extensions/gulp/package.json b/extensions/gulp/package.json index 10e412222190e..3e29c75fe4d50 100644 --- a/extensions/gulp/package.json +++ b/extensions/gulp/package.json @@ -18,7 +18,7 @@ }, "dependencies": {}, "devDependencies": { - "@types/node": "16.x" + "@types/node": "18.x" }, "main": "./out/main", "activationEvents": [ diff --git a/extensions/gulp/yarn.lock b/extensions/gulp/yarn.lock index e724e7fffa317..8a3d10f2b65cf 100644 --- a/extensions/gulp/yarn.lock +++ b/extensions/gulp/yarn.lock @@ -2,7 +2,7 @@ # yarn lockfile v1 -"@types/node@16.x": - version "16.11.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae" - integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w== +"@types/node@18.x": + version "18.15.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" + integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== diff --git a/extensions/html-language-features/.vscode/settings.json b/extensions/html-language-features/.vscode/settings.json index 569ac10cf8f05..17b02728e8c55 100644 --- a/extensions/html-language-features/.vscode/settings.json +++ b/extensions/html-language-features/.vscode/settings.json @@ -1,6 +1,6 @@ { "editor.insertSpaces": false, "prettier.semi": true, - "prettier.singleQuote": true, - "prettier.printWidth": 120, -} \ No newline at end of file + "prettier.singleQuote": true, + "prettier.printWidth": 120 +} diff --git a/extensions/html-language-features/package.json b/extensions/html-language-features/package.json index 972caba7fb39d..58bd75f70e988 100644 --- a/extensions/html-language-features/package.json +++ b/extensions/html-language-features/package.json @@ -263,7 +263,7 @@ "vscode-uri": "^3.0.7" }, "devDependencies": { - "@types/node": "16.x" + "@types/node": "18.x" }, "repository": { "type": "git", diff --git a/extensions/html-language-features/server/package.json b/extensions/html-language-features/server/package.json index 5c3e9e116235e..3304c243b35d8 100644 --- a/extensions/html-language-features/server/package.json +++ b/extensions/html-language-features/server/package.json @@ -18,7 +18,7 @@ }, "devDependencies": { "@types/mocha": "^9.1.1", - "@types/node": "16.x" + "@types/node": "18.x" }, "scripts": { "compile": "npx gulp compile-extension:html-language-features-server", diff --git a/extensions/html-language-features/server/src/test/folding.test.ts b/extensions/html-language-features/server/src/test/folding.test.ts index 44aaea9026cf5..ec33f7a5198f0 100644 --- a/extensions/html-language-features/server/src/test/folding.test.ts +++ b/extensions/html-language-features/server/src/test/folding.test.ts @@ -37,7 +37,7 @@ function r(startLine: number, endLine: number, kind?: string): ExpectedIndentRan return { startLine, endLine, kind }; } -suite('HTML Folding', async () => { +suite('HTML Folding', () => { test('Embedded JavaScript', async () => { const input = [ diff --git a/extensions/html-language-features/server/yarn.lock b/extensions/html-language-features/server/yarn.lock index 8bed471b29cd7..fe6c91e3cf818 100644 --- a/extensions/html-language-features/server/yarn.lock +++ b/extensions/html-language-features/server/yarn.lock @@ -7,10 +7,10 @@ resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-9.1.1.tgz#e7c4f1001eefa4b8afbd1eee27a237fee3bf29c4" integrity sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw== -"@types/node@16.x": - version "16.11.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae" - integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w== +"@types/node@18.x": + version "18.15.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" + integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== "@vscode/l10n@^0.0.14": version "0.0.14" diff --git a/extensions/html-language-features/yarn.lock b/extensions/html-language-features/yarn.lock index c6dda3cbc533d..8bf14ed8f8208 100644 --- a/extensions/html-language-features/yarn.lock +++ b/extensions/html-language-features/yarn.lock @@ -165,10 +165,10 @@ resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== -"@types/node@16.x": - version "16.11.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae" - integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w== +"@types/node@18.x": + version "18.15.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" + integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== "@vscode/extension-telemetry@^0.7.5": version "0.7.5" diff --git a/extensions/ipynb/package.json b/extensions/ipynb/package.json index ce667a5d27779..f5e25ac369551 100644 --- a/extensions/ipynb/package.json +++ b/extensions/ipynb/package.json @@ -56,7 +56,11 @@ { "command": "ipynb.cleanInvalidImageAttachment", "title": "%cleanInvalidImageAttachment.title%" - } + }, + { + "command": "notebook.cellOutput.copyToClipboard", + "title": "%copyOutputToClipboard.title%" + } ], "notebooks": [ { @@ -99,7 +103,13 @@ "command": "ipynb.cleanInvalidImageAttachment", "when": "false" } - ] + ], + "webview/context": [ + { + "command": "notebook.cellOutput.copyToClipboard", + "when": "webviewId == 'notebook.output' && webviewSection == 'image'" + } + ] } }, "scripts": { diff --git a/extensions/ipynb/package.nls.json b/extensions/ipynb/package.nls.json index bd8e0ab1da0c3..45aa2aa03e83f 100644 --- a/extensions/ipynb/package.nls.json +++ b/extensions/ipynb/package.nls.json @@ -6,6 +6,7 @@ "newUntitledIpynb.shortTitle": "Jupyter Notebook", "openIpynbInNotebookEditor.title": "Open IPYNB File In Notebook Editor", "cleanInvalidImageAttachment.title": "Clean Invalid Image Attachment Reference", + "copyOutputToClipboard.title": "Copy Output to Clipboard", "markdownAttachmentRenderer.displayName": { "message": "Markdown-It ipynb Cell Attachment renderer", "comment": [ diff --git a/extensions/ipynb/src/notebookImagePaste.ts b/extensions/ipynb/src/notebookImagePaste.ts index 5a164643a1526..94292c26a7498 100644 --- a/extensions/ipynb/src/notebookImagePaste.ts +++ b/extensions/ipynb/src/notebookImagePaste.ts @@ -15,6 +15,7 @@ enum MimeType { png = 'image/png', tiff = 'image/tiff', webp = 'image/webp', + plain = 'text/plain', uriList = 'text/uri-list', } @@ -47,9 +48,7 @@ function getImageMimeType(uri: vscode.Uri): string | undefined { class DropOrPasteEditProvider implements vscode.DocumentPasteEditProvider, vscode.DocumentDropEditProvider { - private readonly id = 'insertAttachment'; - - private readonly defaultPriority = 5; + public readonly id = 'insertAttachment'; async provideDocumentPasteEdits( document: vscode.TextDocument, @@ -67,8 +66,8 @@ class DropOrPasteEditProvider implements vscode.DocumentPasteEditProvider, vscod return; } - const pasteEdit = new vscode.DocumentPasteEdit(insert.insertText, this.id, vscode.l10n.t('Insert Image as Attachment')); - pasteEdit.priority = this.getPastePriority(dataTransfer); + const pasteEdit = new vscode.DocumentPasteEdit(insert.insertText, vscode.l10n.t('Insert Image as Attachment')); + pasteEdit.yieldTo = [{ mimeType: MimeType.plain }]; pasteEdit.additionalEdit = insert.additionalEdit; return pasteEdit; } @@ -85,23 +84,12 @@ class DropOrPasteEditProvider implements vscode.DocumentPasteEditProvider, vscod } const dropEdit = new vscode.DocumentDropEdit(insert.insertText); - dropEdit.id = this.id; - dropEdit.priority = this.defaultPriority; + dropEdit.yieldTo = [{ mimeType: MimeType.plain }]; dropEdit.additionalEdit = insert.additionalEdit; dropEdit.label = vscode.l10n.t('Insert Image as Attachment'); return dropEdit; } - private getPastePriority(dataTransfer: vscode.DataTransfer): number { - if (dataTransfer.get('text/plain')) { - // Deprioritize in favor of normal text content - return -5; - } - - // Otherwise boost priority so attachments are preferred - return this.defaultPriority; - } - private async createInsertImageAttachmentEdit( document: vscode.TextDocument, dataTransfer: vscode.DataTransfer, @@ -311,12 +299,14 @@ export function notebookImagePasteSetup(): vscode.Disposable { const provider = new DropOrPasteEditProvider(); return vscode.Disposable.from( vscode.languages.registerDocumentPasteEditProvider(JUPYTER_NOTEBOOK_MARKDOWN_SELECTOR, provider, { + id: provider.id, pasteMimeTypes: [ MimeType.png, MimeType.uriList, ], }), vscode.languages.registerDocumentDropEditProvider(JUPYTER_NOTEBOOK_MARKDOWN_SELECTOR, provider, { + id: provider.id, dropMimeTypes: [ ...Object.values(imageExtToMime), MimeType.uriList, diff --git a/extensions/jake/package.json b/extensions/jake/package.json index e34118ca7a378..637d417e503df 100644 --- a/extensions/jake/package.json +++ b/extensions/jake/package.json @@ -18,7 +18,7 @@ }, "dependencies": {}, "devDependencies": { - "@types/node": "16.x" + "@types/node": "18.x" }, "main": "./out/main", "activationEvents": [ diff --git a/extensions/jake/yarn.lock b/extensions/jake/yarn.lock index e724e7fffa317..8a3d10f2b65cf 100644 --- a/extensions/jake/yarn.lock +++ b/extensions/jake/yarn.lock @@ -2,7 +2,7 @@ # yarn lockfile v1 -"@types/node@16.x": - version "16.11.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae" - integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w== +"@types/node@18.x": + version "18.15.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" + integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== diff --git a/extensions/java/cgmanifest.json b/extensions/java/cgmanifest.json index a4db862ab7d50..be9e7439fe763 100644 --- a/extensions/java/cgmanifest.json +++ b/extensions/java/cgmanifest.json @@ -4,13 +4,47 @@ "component": { "type": "git", "git": { - "name": "atom/language-java", - "repositoryUrl": "https://github.com/atom/language-java", - "commitHash": "29f977dc42a7e2568b39bb6fb34c4ef108eb59b3" + "name": "redhat-developer/vscode-java", + "repositoryUrl": "https://github.com/redhat-developer/vscode-java", + "commitHash": "5fb57e8e1c5d776b21be13cd7227b25b87edf4a6" } }, "license": "MIT", - "version": "0.32.1" + "licenseDetail": [ + "Copyright (c) 2014 GitHub Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining", + "a copy of this software and associated documentation files (the", + "\"Software\"), to deal in the Software without restriction, including", + "without limitation the rights to use, copy, modify, merge, publish,", + "distribute, sublicense, and/or sell copies of the Software, and to", + "permit persons to whom the Software is furnished to do so, subject to", + "the following conditions:", + "", + "The above copyright notice and this permission notice shall be", + "included in all copies or substantial portions of the Software.", + "", + "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,", + "EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF", + "MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND", + "NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE", + "LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION", + "OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION", + "WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.", + "", + "--------------------------------------------------------------------", + "", + "This package was derived from a TextMate bundle located at", + "https://github.com/textmate/java.tmbundle and distributed under the following", + "license, located in `README.mdown`:", + "", + "Permission to copy, use, modify, sell and distribute this", + "software is granted. This software is provided \"as is\" without", + "express or implied warranty, and with no claim as to its", + "suitability for any purpose." + ], + "description": "This grammar was derived from https://github.com/atom/language-java/blob/master/grammars/java.cson.", + "version": "1.21.0" } ], "version": 1 diff --git a/extensions/java/package.json b/extensions/java/package.json index d71aa1c146ccd..6788ddd213335 100644 --- a/extensions/java/package.json +++ b/extensions/java/package.json @@ -9,7 +9,7 @@ "vscode": "*" }, "scripts": { - "update-grammar": "node ../node_modules/vscode-grammar-updater/bin atom/language-java grammars/java.cson ./syntaxes/java.tmLanguage.json" + "update-grammar": "node ../node_modules/vscode-grammar-updater/bin redhat-developer/vscode-java language-support/java/java.tmLanguage.json ./syntaxes/java.tmLanguage.json" }, "contributes": { "languages": [ diff --git a/extensions/java/syntaxes/java.tmLanguage.json b/extensions/java/syntaxes/java.tmLanguage.json index be70cbb27c372..337545b0233ec 100644 --- a/extensions/java/syntaxes/java.tmLanguage.json +++ b/extensions/java/syntaxes/java.tmLanguage.json @@ -1,10 +1,10 @@ { "information_for_contributors": [ - "This file has been converted from https://github.com/atom/language-java/blob/master/grammars/java.cson", + "This file has been converted from https://github.com/redhat-developer/vscode-java/blob/master/language-support/java/java.tmLanguage.json", "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/atom/language-java/commit/29f977dc42a7e2568b39bb6fb34c4ef108eb59b3", + "version": "https://github.com/redhat-developer/vscode-java/commit/5fb57e8e1c5d776b21be13cd7227b25b87edf4a6", "name": "Java", "scopeName": "source.java", "patterns": [ @@ -1378,6 +1378,17 @@ }, "properties": { "patterns": [ + { + "match": "(\\.)\\s*(new)", + "captures": { + "1": { + "name": "punctuation.separator.period.java" + }, + "2": { + "name": "keyword.control.new.java" + } + } + }, { "match": "(\\.)\\s*([a-zA-Z_$][\\w$]*)(?=\\s*\\.\\s*[a-zA-Z_$][\\w$]*)", "captures": { @@ -1571,6 +1582,31 @@ }, "strings": { "patterns": [ + { + "begin": "\"\"\"", + "beginCaptures": { + "0": { + "name": "punctuation.definition.string.begin.java" + } + }, + "end": "\"\"\"", + "endCaptures": { + "0": { + "name": "punctuation.definition.string.end.java" + } + }, + "name": "string.quoted.triple.java", + "patterns": [ + { + "match": "\\\\\"\"\"", + "name": "constant.character.escape.java" + }, + { + "match": "\\\\.", + "name": "constant.character.escape.java" + } + ] + }, { "begin": "\"", "beginCaptures": { @@ -1632,6 +1668,9 @@ { "match": "[a-zA-Z$_][\\.a-zA-Z0-9$_]*", "name": "storage.type.java" + }, + { + "include": "#comments" } ] }, diff --git a/extensions/javascript/syntaxes/Readme.md b/extensions/javascript/syntaxes/Readme.md index bc29199fd73e7..b7db3a6a4c9bf 100644 --- a/extensions/javascript/syntaxes/Readme.md +++ b/extensions/javascript/syntaxes/Readme.md @@ -1,10 +1,12 @@ The file `JavaScript.tmLanguage.json` is derived from [TypeScriptReact.tmLanguage](https://github.com/microsoft/TypeScript-TmLanguage/blob/master/TypeScriptReact.tmLanguage). To update to the latest version: + - `cd extensions/typescript` and run `npm run update-grammars` - don't forget to run the integration tests at `./scripts/test-integration.sh` The script does the following changes: + - fileTypes .tsx -> .js & .jsx - scopeName scope.tsx -> scope.js - update all rule names .tsx -> .js diff --git a/extensions/json-language-features/README.md b/extensions/json-language-features/README.md index 2ff5e6e57d312..3de3d11081a6e 100644 --- a/extensions/json-language-features/README.md +++ b/extensions/json-language-features/README.md @@ -4,4 +4,4 @@ ## Features -See [JSON in Visual Studio Code](https://code.visualstudio.com/docs/languages/json) to learn about the features of this extension. \ No newline at end of file +See [JSON in Visual Studio Code](https://code.visualstudio.com/docs/languages/json) to learn about the features of this extension. diff --git a/extensions/json-language-features/client/src/jsonClient.ts b/extensions/json-language-features/client/src/jsonClient.ts index d6e1404a7ac16..23410ebb81442 100644 --- a/extensions/json-language-features/client/src/jsonClient.ts +++ b/extensions/json-language-features/client/src/jsonClient.ts @@ -8,7 +8,7 @@ export type JSONLanguageStatus = { schemas: string[] }; import { workspace, window, languages, commands, ExtensionContext, extensions, Uri, ColorInformation, Diagnostic, StatusBarAlignment, TextEditor, TextDocument, FormattingOptions, CancellationToken, FoldingRange, - ProviderResult, TextEdit, Range, Position, Disposable, CompletionItem, CompletionList, CompletionContext, Hover, MarkdownString, FoldingContext, DocumentSymbol, SymbolInformation, l10n + ProviderResult, TextEdit, Range, Position, Disposable, CompletionItem, CompletionList, CompletionContext, Hover, MarkdownString, FoldingContext, DocumentSymbol, SymbolInformation, l10n, TextEditorOptions } from 'vscode'; import { LanguageClientOptions, RequestType, NotificationType, FormattingOptions as LSPFormattingOptions, @@ -51,7 +51,14 @@ interface DocumentSortingParams { } namespace DocumentSortingRequest { - export const type: RequestType = new RequestType('json/sort'); + export interface ITextEdit { + range: { + start: { line: number; character: number }; + end: { line: number; character: number }; + }; + newText: string; + } + export const type: RequestType = new RequestType('json/sort'); } export interface ISchemaAssociations { @@ -95,6 +102,7 @@ export type JSONSchemaSettings = { export namespace SettingIds { export const enableFormatter = 'json.format.enable'; export const enableKeepLines = 'json.format.keepLines'; + export const enableSortOnSave = 'json.sortOnSave.enable'; export const enableValidation = 'json.validate.enable'; export const enableSchemaDownload = 'json.schemaDownload.enable'; export const maxItemsComputed = 'json.maxItemsComputed'; @@ -163,25 +171,23 @@ export async function startClient(context: ExtensionContext, newLanguageClient: window.showInformationMessage(l10n.t('JSON schema cache cleared.')); })); + toDispose.push(workspace.onWillSaveTextDocument(event => { + const sortOnSave = workspace.getConfiguration().get(SettingIds.enableSortOnSave); + const document = event.document; + if (sortOnSave && (document.languageId === 'json' || document.languageId === 'jsonc')) { + const documentOptions = getOptionsForDocument(document); + const textEditsPromise = getSortTextEdits(document, documentOptions?.tabSize, documentOptions?.insertSpaces); + event.waitUntil(textEditsPromise); + } + })); + toDispose.push(commands.registerCommand('json.sort', async () => { if (isClientReady) { const textEditor = window.activeTextEditor; if (textEditor) { - const document = textEditor.document; - const filesConfig = workspace.getConfiguration('files', document); - const options: SortOptions = { - tabSize: textEditor.options.tabSize ? Number(textEditor.options.tabSize) : 4, - insertSpaces: textEditor.options.insertSpaces ? Boolean(textEditor.options.insertSpaces) : true, - trimTrailingWhitespace: filesConfig.get('trimTrailingWhitespace'), - trimFinalNewlines: filesConfig.get('trimFinalNewlines'), - insertFinalNewline: filesConfig.get('insertFinalNewline'), - }; - const params: DocumentSortingParams = { - uri: document.uri.toString(), - options - }; - const textEdits = await client.sendRequest(DocumentSortingRequest.type, params); + const documentOptions = textEditor.options; + const textEdits = await getSortTextEdits(textEditor.document, documentOptions.tabSize, documentOptions.insertSpaces); const success = await textEditor.edit(mutator => { for (const edit of textEdits) { mutator.replace(client.protocol2CodeConverter.asRange(edit.range), edit.newText); @@ -471,6 +477,29 @@ export async function startClient(context: ExtensionContext, newLanguageClient: } } + async function getSortTextEdits(document: TextDocument, tabSize: string | number = 4, insertSpaces: string | boolean = true): Promise { + const filesConfig = workspace.getConfiguration('files', document); + const options: SortOptions = { + tabSize: Number(tabSize), + insertSpaces: Boolean(insertSpaces), + trimTrailingWhitespace: filesConfig.get('trimTrailingWhitespace'), + trimFinalNewlines: filesConfig.get('trimFinalNewlines'), + insertFinalNewline: filesConfig.get('insertFinalNewline'), + }; + const params: DocumentSortingParams = { + uri: document.uri.toString(), + options + }; + const edits = await client.sendRequest(DocumentSortingRequest.type, params); + // Here we convert the JSON objects to real TextEdit objects + return edits.map((edit) => { + return new TextEdit( + new Range(edit.range.start.line, edit.range.start.character, edit.range.end.line, edit.range.end.character), + edit.newText + ); + }); + } + return client; } @@ -614,3 +643,12 @@ function updateMarkdownString(h: MarkdownString): MarkdownString { function isSchemaResolveError(d: Diagnostic) { return d.code === /* SchemaResolveError */ 0x300; } + +function getOptionsForDocument(document: TextDocument): TextEditorOptions | undefined { + for (const editor of window.visibleTextEditors) { + if (editor.document.uri.toString() === document.uri.toString()) { + return editor.options; + } + } + return; +} diff --git a/extensions/json-language-features/client/src/node/jsonClientMain.ts b/extensions/json-language-features/client/src/node/jsonClientMain.ts index 10895276e1ff6..457a40f6a740d 100644 --- a/extensions/json-language-features/client/src/node/jsonClientMain.ts +++ b/extensions/json-language-features/client/src/node/jsonClientMain.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { ExtensionContext, OutputChannel, window, workspace, l10n } from 'vscode'; +import { ExtensionContext, OutputChannel, window, workspace, l10n, env } from 'vscode'; import { startClient, LanguageClientConstructor, SchemaRequestService, languageServerDescription } from '../jsonClient'; import { ServerOptions, TransportKind, LanguageClientOptions, LanguageClient, BaseLanguageClient } from 'vscode-languageclient/node'; @@ -129,7 +129,10 @@ async function getSchemaRequestService(context: ExtensionContext, log: Log): Pro const isXHRResponse = (error: any): error is XHRResponse => typeof error?.status === 'number'; const request = async (uri: string, etag?: string): Promise => { - const headers: Headers = { 'Accept-Encoding': 'gzip, deflate' }; + const headers: Headers = { + 'Accept-Encoding': 'gzip, deflate', + 'User-Agent': `${env.appName} (${env.appHost})` + }; if (etag) { headers['If-None-Match'] = etag; } diff --git a/extensions/json-language-features/package.json b/extensions/json-language-features/package.json index 2b43041ff0575..05075ec13899f 100644 --- a/extensions/json-language-features/package.json +++ b/extensions/json-language-features/package.json @@ -91,6 +91,12 @@ "default": false, "description": "%json.format.keepLines.desc%" }, + "json.sortOnSave.enable": { + "type": "boolean", + "scope": "window", + "default": false, + "description": "%json.sortOnSave.enable.desc%" + }, "json.trace.server": { "type": "string", "scope": "window", @@ -163,7 +169,7 @@ "vscode-languageclient": "^8.2.0-next.1" }, "devDependencies": { - "@types/node": "16.x" + "@types/node": "18.x" }, "repository": { "type": "git", diff --git a/extensions/json-language-features/package.nls.json b/extensions/json-language-features/package.nls.json index 571d047802d4a..df68b3f8eacfb 100644 --- a/extensions/json-language-features/package.nls.json +++ b/extensions/json-language-features/package.nls.json @@ -2,12 +2,13 @@ "displayName": "JSON Language Features", "description": "Provides rich language support for JSON files.", "json.schemas.desc": "Associate schemas to JSON files in the current project.", - "json.schemas.url.desc": "A URL to a schema or a relative path to a schema in the current directory", - "json.schemas.fileMatch.desc": "An array of file patterns to match against when resolving JSON files to schemas. `*` can be used as a wildcard. Exclusion patterns can also be defined and start with '!'. A file matches when there is at least one matching pattern and the last matching pattern is not an exclusion pattern.", - "json.schemas.fileMatch.item.desc": "A file pattern that can contain '*' to match against when resolving JSON files to schemas.", + "json.schemas.url.desc": "A URL or absolute file path to a schema. Can be a relative path in workspace and workspace folder settings.", + "json.schemas.fileMatch.desc": "An array of file patterns to match against when resolving JSON files to schemas. `*` and '**' can be used as a wildcard. Exclusion patterns can also be defined and start with '!'. A file matches when there is at least one matching pattern and the last matching pattern is not an exclusion pattern.", + "json.schemas.fileMatch.item.desc": "A file pattern that can contain '*' and '**' to match against when resolving JSON files to schemas. When beginning with '!', it defines an exclusion pattern.", "json.schemas.schema.desc": "The schema definition for the given URL. The schema only needs to be provided to avoid accesses to the schema URL.", "json.format.enable.desc": "Enable/disable default JSON formatter", "json.format.keepLines.desc" : "Keep all existing new lines when formatting.", + "json.sortOnSave.enable.desc": "Enable/disable default sorting on save", "json.validate.enable.desc": "Enable/disable JSON validation.", "json.tracing.desc": "Traces the communication between VS Code and the JSON language server.", "json.colorDecorators.enable.desc": "Enables or disables color decorators", diff --git a/extensions/json-language-features/server/README.md b/extensions/json-language-features/server/README.md index e9875ba59779a..10956439e320a 100644 --- a/extensions/json-language-features/server/README.md +++ b/extensions/json-language-features/server/README.md @@ -11,6 +11,7 @@ The JSON Language server provides language-specific smarts for editing, validati ### Server capabilities The JSON language server supports requests on documents of language id `json` and `jsonc`. + - `json` documents are parsed and validated following the [JSON specification](https://tools.ietf.org/html/rfc7159). - `jsonc` documents additionally accept single line (`//`) and multi-line comments (`/* ... */`). JSONC is a VSCode specific file format, intended for VSCode configuration files, without any aspirations to define a new common file format. @@ -25,12 +26,12 @@ The server implements the following capabilities of the language server protocol - Semantic Selection for semantic selection for one or multiple cursor positions. - [Goto Definition](https://microsoft.github.io/language-server-protocol/specification#textDocument_definition) for $ref references in JSON schemas - [Diagnostics (Validation)](https://microsoft.github.io/language-server-protocol/specification#textDocument_publishDiagnostics) are pushed for all open documents - - syntax errors - - structural validation based on the document's [JSON schema](http://json-schema.org/). + - syntax errors + - structural validation based on the document's [JSON schema](http://json-schema.org/). In order to load JSON schemas, the JSON server uses NodeJS `http` and `fs` modules. For all other features, the JSON server only relies on the documents and settings provided by the client through the LSP. -### Client requirements: +### Client requirements The JSON language server expects the client to only send requests and notifications for documents of language id `json` and `jsonc`. @@ -56,8 +57,8 @@ Clients may send a `workspace/didChangeConfiguration` notification to notify the The server supports the following settings: - http - - `proxy`: The URL of the proxy server to use when fetching schema. When undefined or empty, no proxy is used. - - `proxyStrictSSL`: Whether the proxy server certificate should be verified against the list of supplied CAs. + - `proxy`: The URL of the proxy server to use when fetching schema. When undefined or empty, no proxy is used. + - `proxyStrictSSL`: Whether the proxy server certificate should be verified against the list of supplied CAs. - json - `format` @@ -72,6 +73,7 @@ The server supports the following settings: - `resultLimit`: The max number of color decorators and outline symbols to be computed (for performance reasons) - `jsonFoldingLimit`: The max number of folding ranges to be computed for json documents (for performance reasons) - `jsoncFoldingLimit`: The max number of folding ranges to be computed for jsonc documents (for performance reasons) + ```json { "http": { @@ -103,6 +105,7 @@ The server supports the following settings: [JSON schemas](http://json-schema.org/) are essential for code assist, hovers, color decorators to work and are required for structural validation. To find the schema for a given JSON document, the server uses the following mechanisms: + - JSON documents can define the schema URL using a `$schema` property - The settings define a schema association based on the documents URL. Settings can either associate a schema URL to a file or path pattern, and they can directly provide a schema. - Additionally, schema associations can also be provided by a custom 'schemaAssociations' configuration call. @@ -115,9 +118,9 @@ The `initializationOptions.handledSchemaProtocols` initialization option defines ```ts let clientOptions: LanguageClientOptions = { - initializationOptions: { - handledSchemaProtocols: ['file'] // language server should only try to load file URLs - } + initializationOptions: { + handledSchemaProtocols: ['file'] // language server should only try to load file URLs + } ... } ``` @@ -132,6 +135,7 @@ If `handledSchemaProtocols` is not set, the JSON language server will load the f Requests for schemas with URLs not handled by the server are forwarded to the client through an LSP request. This request is a JSON language server-specific, non-standardized, extension to the LSP. Request: + - method: 'vscode/content' - params: `string` - The schema URL to request. - response: `string` - The content of the schema with the given URL @@ -146,6 +150,7 @@ The server will, as a response, clear the schema content from the cache and relo In addition to the settings, schemas associations can also be provided through a notification from the client to the server. This notification is a JSON language server-specific, non-standardized, extension to the LSP. Notification: + - method: 'json/schemaAssociations' - params: `ISchemaAssociations` or `ISchemaAssociation[]` defined as follows @@ -183,11 +188,14 @@ interface ISchemaAssociation { } ``` + `ISchemaAssociations` - - keys: a file names or file path (separated by `/`). `*` can be used as a wildcard. - - values: An array of schema URLs + +- keys: a file names or file path (separated by `/`). `*` can be used as a wildcard. +- values: An array of schema URLs Notification: + - method: 'json/schemaContent' - params: `string` the URL of the schema that has changed. @@ -226,6 +234,7 @@ The source code of the JSON language server can be found in the [VSCode reposito File issues and pull requests in the [VSCode GitHub Issues](https://github.com/microsoft/vscode/issues). See the document [How to Contribute](https://github.com/microsoft/vscode/wiki/How-to-Contribute) on how to build and run from source. Most of the functionality of the server is located in libraries: + - [jsonc-parser](https://github.com/microsoft/node-jsonc-parser) contains the JSON parser and scanner. - [vscode-json-languageservice](https://github.com/microsoft/vscode-json-languageservice) contains the implementation of all features as a re-usable library. - [vscode-languageserver-node](https://github.com/microsoft/vscode-languageserver-node) contains the implementation of language server for NodeJS. diff --git a/extensions/json-language-features/server/package.json b/extensions/json-language-features/server/package.json index 72e707a58e60c..b0012a7281682 100644 --- a/extensions/json-language-features/server/package.json +++ b/extensions/json-language-features/server/package.json @@ -21,7 +21,7 @@ }, "devDependencies": { "@types/mocha": "^9.1.1", - "@types/node": "16.x" + "@types/node": "18.x" }, "scripts": { "prepublishOnly": "npm run clean && npm run compile", diff --git a/extensions/json-language-features/server/yarn.lock b/extensions/json-language-features/server/yarn.lock index c8fabcbc15c8f..48f16a0f42f23 100644 --- a/extensions/json-language-features/server/yarn.lock +++ b/extensions/json-language-features/server/yarn.lock @@ -7,10 +7,10 @@ resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-9.1.1.tgz#e7c4f1001eefa4b8afbd1eee27a237fee3bf29c4" integrity sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw== -"@types/node@16.x": - version "16.11.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae" - integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w== +"@types/node@18.x": + version "18.15.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" + integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== "@vscode/l10n@^0.0.13": version "0.0.13" diff --git a/extensions/json-language-features/yarn.lock b/extensions/json-language-features/yarn.lock index 6113220bc303a..98083a9489fa9 100644 --- a/extensions/json-language-features/yarn.lock +++ b/extensions/json-language-features/yarn.lock @@ -165,10 +165,10 @@ resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== -"@types/node@16.x": - version "16.11.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae" - integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w== +"@types/node@18.x": + version "18.15.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" + integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== "@vscode/extension-telemetry@^0.7.5": version "0.7.5" diff --git a/extensions/json/build/update-grammars.js b/extensions/json/build/update-grammars.js index ff00951e126bd..2b7f76f8f909b 100644 --- a/extensions/json/build/update-grammars.js +++ b/extensions/json/build/update-grammars.js @@ -6,16 +6,16 @@ var updateGrammar = require('vscode-grammar-updater'); -function adaptJSON(grammar, name, replacementScope) { +function adaptJSON(grammar, name, replacementScope, replaceeScope = 'json') { grammar.name = name; grammar.scopeName = `source${replacementScope}`; - + const regex = new RegExp(`\.${replaceeScope}`, 'g'); var fixScopeNames = function (rule) { if (typeof rule.name === 'string') { - rule.name = rule.name.replace(/\.json/g, replacementScope); + rule.name = rule.name.replace(regex, replacementScope); } if (typeof rule.contentName === 'string') { - rule.contentName = rule.contentName.replace(/\.json/g, replacementScope); + rule.contentName = rule.contentName.replace(regex, replacementScope); } for (var property in rule) { var value = rule[property]; @@ -35,3 +35,5 @@ var tsGrammarRepo = 'microsoft/vscode-JSON.tmLanguage'; updateGrammar.update(tsGrammarRepo, 'JSON.tmLanguage', './syntaxes/JSON.tmLanguage.json'); updateGrammar.update(tsGrammarRepo, 'JSON.tmLanguage', './syntaxes/JSONC.tmLanguage.json', grammar => adaptJSON(grammar, 'JSON with Comments', '.json.comments')); updateGrammar.update(tsGrammarRepo, 'JSON.tmLanguage', './syntaxes/JSONL.tmLanguage.json', grammar => adaptJSON(grammar, 'JSON Lines', '.json.lines')); + +updateGrammar.update('jeff-hykin/better-snippet-syntax', 'autogenerated/jsonc.tmLanguage.json', './syntaxes/snippets.tmLanguage.json', grammar => adaptJSON(grammar, 'Snippets', '.json.comments.snippets', 'json.comments')); diff --git a/extensions/json/cgmanifest.json b/extensions/json/cgmanifest.json index 1af8426e53535..fe6b0ae6e6df2 100644 --- a/extensions/json/cgmanifest.json +++ b/extensions/json/cgmanifest.json @@ -11,6 +11,18 @@ }, "license": "MIT", "version": "0.0.0" + }, + { + "component": { + "type": "git", + "git": { + "name": "jeff-hykin/better-snippet-syntax", + "repositoryUrl": "https://github.com/jeff-hykin/better-snippet-syntax", + "commitHash": "2b1bb124cb2b9c75c3c80eae1b8f3a043841d654" + } + }, + "license": "MIT", + "version": "1.0.2" } ], "version": 1 diff --git a/extensions/json/package.json b/extensions/json/package.json index 57290e9d1dd87..7834eb38d751e 100644 --- a/extensions/json/package.json +++ b/extensions/json/package.json @@ -31,7 +31,7 @@ ".jslintrc", ".jsonld", ".geojson", - ".ipynb", + ".ipynb", ".vuerc" ], "filenames": [ @@ -77,6 +77,20 @@ ], "filenames": [], "configuration": "./language-configuration.json" + }, + { + "id": "snippets", + "aliases": [ + "Code Snippets" + ], + "extensions": [ + ".code-snippets" + ], + "filenamePatterns": [ + "**/User/snippets/*.json", + "**/User/profiles/*/snippets/*.json" + ], + "configuration": "./language-configuration.json" } ], "grammars": [ @@ -94,6 +108,11 @@ "language": "jsonl", "scopeName": "source.json.lines", "path": "./syntaxes/JSONL.tmLanguage.json" + }, + { + "language": "snippets", + "scopeName": "source.json.comments.snippets", + "path": "./syntaxes/snippets.tmLanguage.json" } ] }, diff --git a/extensions/json/syntaxes/snippets.tmLanguage.json b/extensions/json/syntaxes/snippets.tmLanguage.json new file mode 100644 index 0000000000000..289bc18f8c6eb --- /dev/null +++ b/extensions/json/syntaxes/snippets.tmLanguage.json @@ -0,0 +1,7463 @@ +{ + "information_for_contributors": [ + "This file has been converted from https://github.com/jeff-hykin/better-snippet-syntax/blob/master/autogenerated/jsonc.tmLanguage.json", + "If you want to provide a fix or improvement, please create a pull request against the original repository.", + "Once accepted there, we are happy to receive an update request." + ], + "version": "https://github.com/jeff-hykin/better-snippet-syntax/commit/2b1bb124cb2b9c75c3c80eae1b8f3a043841d654", + "name": "Snippets", + "scopeName": "source.json.comments.snippets", + "patterns": [ + { + "include": "#value" + } + ], + "repository": { + "array": { + "begin": "\\[", + "beginCaptures": { + "0": { + "name": "punctuation.definition.array.begin.json.comments.snippets" + } + }, + "end": "\\]", + "endCaptures": { + "0": { + "name": "punctuation.definition.array.end.json.comments.snippets" + } + }, + "name": "meta.structure.array.json.comments.snippets", + "patterns": [ + { + "include": "#value" + }, + { + "match": ",", + "name": "punctuation.separator.array.json.comments.snippets" + }, + { + "match": "[^\\s\\]]", + "name": "invalid.illegal.expected-array-separator.json.comments.snippets" + } + ] + }, + "basic_escape": { + "match": "\\\\(?:[\"\\\\\\/bfnrt]|(?:u[0-9a-fA-F]{4}))", + "name": "constant.character.escape.json.comments.snippets" + }, + "bnf_any": { + "match": "(?:\\}|((?:(?:(?:(?:(?:(?:((?:(\\$)([0-9]+)))|((?:(?:(\\$)(\\{))([0-9]+)(\\}))))|((?:(?:(\\$)(\\{))([0-9]+)((?:(\\/)((?:(?:(?:(?:(\\\\)(\\\\\\/))|(?:(\\\\\\\\\\\\)(\\\\\\/)))|[^\\/\\n])+))(\\/)(((?:(?:(?:(?:(?:(?:(?:(?:\\$(?:(?)*?))(\\|)(\\}))))|((?:(?:(\\$)(\\{))([0-9]+)(:)(?:(?:(?:(?:(?:\\$(?:[0-9]+))|(?:(?:\\$\\{)(?:[0-9]+)\\}))|(?:(?:\\$\\{)(?:[0-9]+)(?:\\/((?:(?:(?:(?:\\\\(?:\\\\\\/))|(?:(?:\\\\\\\\\\\\)(?:\\\\\\/)))|[^\\/\\n])+))\\/((?:(?:(?:(?:(?:(?:(?:(?:(?:\\$(?:(?)+)(\\}))))|(?:(?:(?:((?:(\\$)((?+))(\\}))))|((?:(?:(\\$)(\\{))((?)*?))(\\|)(\\}))", + "captures": { + "1": { + "name": "punctuation.section.insertion.dollar.brackets.json.comments.snippets keyword.operator.insertion.json.comments.snippets custom.punctuation.section.insertion.dollar.brackets.json.comments.snippets" + }, + "2": { + "name": "punctuation.section.insertion.bracket.json.comments.snippets keyword.operator.insertion.json.comments.snippets custom.punctuation.section.insertion.bracket.json.comments.snippets" + }, + "3": { + "name": "variable.other.normal.json.comments.snippets custom.variable.other.normal.numeric.json.comments.snippets" + }, + "4": { + "name": "punctuation.separator.choice.json.comments.snippets keyword.operator.insertion.json.comments.snippets custom.punctuation.separator.choice.json.comments.snippets" + }, + "5": { + "patterns": [ + { + "match": ",", + "name": "meta.insertion.choice.json.comments.snippets punctuation.separator.comma.json.comments.snippets" + }, + { + "include": "#choice_option" + } + ] + }, + "6": { + "name": "meta.insertion.choice.json.comments.snippets constant.other.option.json.comments.snippets" + }, + "7": { + "name": "punctuation.section.insertion.escape.escaper.json.comments.snippets comment.block.json.comments.snippets punctuation.definition.comment.insertion.escape.json.comments.snippets" + }, + "8": { + "name": "constant.character.escape.json.comments.snippets" + }, + "9": { + "name": "punctuation.section.insertion.escape.escaper.json.comments.snippets comment.block.json.comments.snippets punctuation.definition.comment.insertion.escape.json.comments.snippets" + }, + "10": { + "patterns": [ + { + "include": "#quad_backslash_match" + }, + { + "include": "#dollar_sign_escape" + }, + { + "include": "#bracket_escape" + }, + { + "include": "#basic_escape" + }, + { + "include": "#invalid_escape" + }, + { + "include": "#normal_characters" + } + ] + }, + "11": { + "patterns": [ + { + "include": "#quad_backslash_match" + }, + { + "match": "(\\\\\\\\)\\$", + "captures": { + "1": { + "name": "punctuation.section.insertion.escape.escaper.json.comments.snippets comment.block.json.comments.snippets punctuation.definition.comment.insertion.escape.json.comments.snippets" + } + }, + "name": "punctuation.section.insertion.escape.escapee.json.comments.snippets string.regexp.insertion.escape.json.comments.snippets string.quoted.double.json.comments.snippets" + }, + { + "include": "#invalid_escape" + } + ] + }, + "12": { + "patterns": [ + { + "include": "#quad_backslash_match" + }, + { + "match": "(\\\\\\\\)\\}", + "captures": { + "1": { + "name": "punctuation.section.insertion.escape.escaper.json.comments.snippets comment.block.json.comments.snippets punctuation.definition.comment.insertion.escape.json.comments.snippets" + } + }, + "name": "punctuation.section.insertion.escape.escapee.json.comments.snippets string.regexp.insertion.escape.json.comments.snippets string.quoted.double.json.comments.snippets" + } + ] + }, + "13": { + "name": "constant.character.escape.json.comments.snippets" + }, + "14": { + "name": "punctuation.separator.choice.json.comments.snippets keyword.operator.insertion.json.comments.snippets custom.punctuation.separator.choice.json.comments.snippets" + }, + "15": { + "name": "punctuation.section.insertion.bracket.json.comments.snippets keyword.operator.insertion.json.comments.snippets custom.punctuation.section.insertion.bracket.json.comments.snippets" + } + }, + "name": "meta.insertion.brackets.json.comments.snippets meta.insertion.choice.json.comments.snippets" + }, + "bnf_format": { + "match": "(?:(?:(?:(?:(?:(?:(?:(\\$)((? tbody > tr + tr > td { } blockquote { - margin: 0 7px 0 5px; - padding: 0 16px 0 10px; + margin: 0; + padding: 2px 16px 0 10px; border-left-width: 5px; border-left-style: solid; + border-radius: 2px; } code { @@ -232,6 +237,7 @@ pre code { pre { background-color: var(--vscode-textCodeBlock-background); + border: 1px solid var(--vscode-widget-border); } .vscode-high-contrast h1 { diff --git a/extensions/markdown-language-features/package.json b/extensions/markdown-language-features/package.json index 0c5e79b6373dc..9743845b8d971 100644 --- a/extensions/markdown-language-features/package.json +++ b/extensions/markdown-language-features/package.json @@ -123,7 +123,8 @@ "commands": [ { "command": "_markdown.copyImage", - "title": "%markdown.copyImage.title%" + "title": "%markdown.copyImage.title%", + "category": "Markdown" }, { "command": "markdown.showPreview", @@ -244,6 +245,10 @@ } ], "commandPalette": [ + { + "command": "_markdown.copyImage", + "when": "false" + }, { "command": "markdown.showPreview", "when": "editorLangId == markdown && !notebookEditorFocused", @@ -502,7 +507,7 @@ "type": "string", "scope": "resource", "markdownDescription": "%configuration.markdown.editor.pasteUrlAsFormattedLink.enabled%", - "default":"smart", + "default":"never", "enum": [ "always", "smart", @@ -721,8 +726,8 @@ "watch-web": "npx webpack-cli --config extension-browser.webpack.config --mode none --watch --info-verbosity verbose" }, "dependencies": { - "@vscode/extension-telemetry": "0.7.5", - "dompurify": "^2.4.1", + "@vscode/extension-telemetry": "^0.8.4", + "dompurify": "^3.0.5", "highlight.js": "^11.8.0", "markdown-it": "^12.3.2", "markdown-it-front-matter": "^0.2.1", @@ -732,7 +737,7 @@ "vscode-uri": "^3.0.3" }, "devDependencies": { - "@types/dompurify": "^2.3.1", + "@types/dompurify": "^3.0.2", "@types/lodash.throttle": "^4.1.3", "@types/markdown-it": "12.2.3", "@types/picomatch": "^2.3.0", diff --git a/extensions/markdown-language-features/package.nls.json b/extensions/markdown-language-features/package.nls.json index 0468fbf1d7946..7336657621ee8 100644 --- a/extensions/markdown-language-features/package.nls.json +++ b/extensions/markdown-language-features/package.nls.json @@ -44,9 +44,9 @@ "configuration.copyIntoWorkspace.mediaFiles": "Try to copy external image and video files into the workspace.", "configuration.copyIntoWorkspace.never": "Do not copy external files into the workspace.", "configuration.markdown.editor.pasteUrlAsFormattedLink.enabled": "Controls how a Markdown link is created when a URL is pasted into the Markdown editor. Requires enabling `#editor.pasteAs.enabled#`.", - "configuration.pasteUrlAsFormattedLink.always": "Always create a Markdown link when a URL is pasted into the Markdown editor.", - "configuration.pasteUrlAsFormattedLink.smart": "Does not create a Markdown link within a link snippet or code bracket.", - "configuration.pasteUrlAsFormattedLink.never": "Never create a Markdown link when a URL is pasted into the Markdown editor.", + "configuration.pasteUrlAsFormattedLink.always": "Always creates a Markdown link when a URL is pasted into the Markdown editor.", + "configuration.pasteUrlAsFormattedLink.smart": "Smartly avoids creating a Markdown link in specific cases, such as within code brackets or inside an existing Markdown link.", + "configuration.pasteUrlAsFormattedLink.never": "Never creates a Markdown link when a URL is pasted into the Markdown editor.", "configuration.markdown.validate.enabled.description": "Enable all error reporting in Markdown files.", "configuration.markdown.validate.referenceLinks.enabled.description": "Validate reference links in Markdown files, for example: `[link][ref]`. Requires enabling `#markdown.validate.enabled#`.", "configuration.markdown.validate.fragmentLinks.enabled.description": "Validate fragment links to headers in the current Markdown file, for example: `[link](#header)`. Requires enabling `#markdown.validate.enabled#`.", diff --git a/extensions/markdown-language-features/server/README.md b/extensions/markdown-language-features/server/README.md index 1fd38302195ff..4114d2698bf6a 100644 --- a/extensions/markdown-language-features/server/README.md +++ b/extensions/markdown-language-features/server/README.md @@ -6,7 +6,6 @@ The Markdown language server powers VS Code's built-in markdown support, providi This server uses the [Markdown Language Service](https://github.com/microsoft/vscode-markdown-languageservice) to implement almost all of the language features. You can use that library if you need a library for working with Markdown instead of a full language server. - ## Server capabilities - [Completions](https://microsoft.github.io/language-server-protocol/specification#textDocument_completion) for Markdown links. @@ -31,14 +30,13 @@ This server uses the [Markdown Language Service](https://github.com/microsoft/vs - [Code Actions](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_codeAction) - - Organize link definitions source action. - - Extract link to definition refactoring. + - Organize link definitions source action. + - Extract link to definition refactoring. - Updating links when a file is moved / renamed. Uses a custom `markdown/getEditForFileRenames` message. - [Pull diagnostics (validation)](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_pullDiagnostics) for links. - ## Client requirements ### Initialization options @@ -53,27 +51,27 @@ Clients may send a `workspace/didChangeConfiguration` notification to notify the The server supports the following settings: - `markdown` - - `suggest` - - `paths` - - `enabled` ā€” Enable/disable path suggestions. - - - `occurrencesHighlight` - - `enabled` ā€” Enable/disable highlighting of link occurrences. - - - `validate` - - `enabled` ā€”Ā Enable/disable all validation. - - `referenceLinks` - - `enabled` ā€”Ā Enable/disable validation of reference links: `[text][ref]` - - `fragmentLinks` - - `enabled` ā€”Ā Enable/disable validation of links to fragments in the current files: `[text](#head)` - - `fileLinks` - - `enabled` ā€”Ā Enable/disable validation of links to file in the workspace. - - `markdownFragmentLinks` ā€”Ā Enable/disable validation of links to headers in other Markdown files. Use `inherit` to inherit the `fragmentLinks` setting. - - `ignoredLinks` ā€”Ā Array of glob patterns for files that should not be validated. - - `unusedLinkDefinitions` - - `enabled` ā€”Ā Enable/disable validation of unused link definitions. - - `duplicateLinkDefinitions` - - `enabled` ā€”Ā Enable/disable validation of duplicated link definitions. + - `suggest` + - `paths` + - `enabled` ā€” Enable/disable path suggestions. + + - `occurrencesHighlight` + - `enabled` ā€” Enable/disable highlighting of link occurrences. + + - `validate` + - `enabled` ā€”Ā Enable/disable all validation. + - `referenceLinks` + - `enabled` ā€”Ā Enable/disable validation of reference links: `[text][ref]` + - `fragmentLinks` + - `enabled` ā€”Ā Enable/disable validation of links to fragments in the current files: `[text](#head)` + - `fileLinks` + - `enabled` ā€”Ā Enable/disable validation of links to file in the workspace. + - `markdownFragmentLinks` ā€”Ā Enable/disable validation of links to headers in other Markdown files. Use `inherit` to inherit the `fragmentLinks` setting. + - `ignoredLinks` ā€”Ā Array of glob patterns for files that should not be validated. + - `unusedLinkDefinitions` + - `enabled` ā€”Ā Enable/disable validation of unused link definitions. + - `duplicateLinkDefinitions` + - `enabled` ā€”Ā Enable/disable validation of duplicated link definitions. ### Custom requests @@ -109,7 +107,6 @@ Delete a previously created file watcher. Get a list of all markdown files in the workspace. - ## Contribute The source code of the Markdown language server can be found in the [VSCode repository](https://github.com/microsoft/vscode) at [extensions/markdown-language-features/server](https://github.com/microsoft/vscode/tree/master/extensions/markdown-language-features/server). @@ -132,4 +129,3 @@ This project has adopted the [Microsoft Open Source Code of Conduct](https://ope Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the [MIT](https://github.com/microsoft/vscode/blob/master/LICENSE.txt) License. - diff --git a/extensions/markdown-language-features/server/package.json b/extensions/markdown-language-features/server/package.json index 87ddad6aef17e..1b3e549b74876 100644 --- a/extensions/markdown-language-features/server/package.json +++ b/extensions/markdown-language-features/server/package.json @@ -22,7 +22,7 @@ "vscode-uri": "^3.0.7" }, "devDependencies": { - "@types/node": "16.x" + "@types/node": "18.x" }, "scripts": { "compile": "gulp compile-extension:markdown-language-features-server", diff --git a/extensions/markdown-language-features/server/yarn.lock b/extensions/markdown-language-features/server/yarn.lock index 6c6560ec7ea2e..c2a76d7f3915c 100644 --- a/extensions/markdown-language-features/server/yarn.lock +++ b/extensions/markdown-language-features/server/yarn.lock @@ -2,10 +2,10 @@ # yarn lockfile v1 -"@types/node@16.x": - version "16.18.3" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.3.tgz#d7f7ba828ad9e540270f01ce00d391c54e6e0abc" - integrity sha512-jh6m0QUhIRcZpNv7Z/rpN+ZWXOicUUQbSoWks7Htkbb9IjFQj4kzcX/xFCkjstCj5flMsN8FiSvt+q+Tcs4Llg== +"@types/node@18.x": + version "18.15.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" + integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== "@vscode/l10n@^0.0.10": version "0.0.10" diff --git a/extensions/markdown-language-features/src/commands/insertResource.ts b/extensions/markdown-language-features/src/commands/insertResource.ts index da50c83c991c5..87de74270caa1 100644 --- a/extensions/markdown-language-features/src/commands/insertResource.ts +++ b/extensions/markdown-language-features/src/commands/insertResource.ts @@ -60,7 +60,7 @@ export class InsertImageFromWorkspace implements Command { } function getDefaultUri(document: vscode.TextDocument) { - const docUri = getParentDocumentUri(document); + const docUri = getParentDocumentUri(document.uri); if (docUri.scheme === Schemes.untitled) { return vscode.workspace.workspaceFolders?.[0]?.uri; } @@ -76,10 +76,10 @@ async function insertLink(activeEditor: vscode.TextEditor, selectedFiles: vscode await vscode.workspace.applyEdit(edit); } -function createInsertLinkEdit(activeEditor: vscode.TextEditor, selectedFiles: vscode.Uri[], insertAsMedia: boolean, title = '', placeholderValue = 0, smartPaste = false) { +function createInsertLinkEdit(activeEditor: vscode.TextEditor, selectedFiles: vscode.Uri[], insertAsMedia: boolean, title = '', placeholderValue = 0, pasteAsMarkdownLink = true, isExternalLink = false) { const snippetEdits = coalesce(activeEditor.selections.map((selection, i): vscode.SnippetTextEdit | undefined => { const selectionText = activeEditor.document.getText(selection); - const snippet = createUriListSnippet(activeEditor.document, selectedFiles, title, placeholderValue, smartPaste, { + const snippet = createUriListSnippet(activeEditor.document, selectedFiles, [], title, placeholderValue, pasteAsMarkdownLink, isExternalLink, { insertAsMedia, placeholderText: selectionText, placeholderStartIndex: (i + 1) * selectedFiles.length, diff --git a/extensions/markdown-language-features/src/extension.shared.ts b/extensions/markdown-language-features/src/extension.shared.ts index 79242573136a5..0d6c160bffe30 100644 --- a/extensions/markdown-language-features/src/extension.shared.ts +++ b/extensions/markdown-language-features/src/extension.shared.ts @@ -7,10 +7,10 @@ import * as vscode from 'vscode'; import { MdLanguageClient } from './client/client'; import { CommandManager } from './commandManager'; import { registerMarkdownCommands } from './commands/index'; -import { registerPasteSupport } from './languageFeatures/copyFiles/copyPaste'; -import { registerLinkPasteSupport } from './languageFeatures/copyFiles/copyPasteLinks'; +import { registerPasteSupport } from './languageFeatures/copyFiles/pasteResourceProvider'; +import { registerLinkPasteSupport } from './languageFeatures/copyFiles/pasteUrlProvider'; import { registerDiagnosticSupport } from './languageFeatures/diagnostics'; -import { registerDropIntoEditorSupport } from './languageFeatures/copyFiles/dropIntoEditor'; +import { registerDropIntoEditorSupport } from './languageFeatures/copyFiles/dropResourceProvider'; import { registerFindFileReferenceSupport } from './languageFeatures/fileReferences'; import { registerUpdateLinksOnRename } from './languageFeatures/linkUpdater'; import { ILogger } from './logging'; diff --git a/extensions/markdown-language-features/src/languageFeatures/copyFiles/copyFiles.ts b/extensions/markdown-language-features/src/languageFeatures/copyFiles/copyFiles.ts index cb6a77e8c8d1e..c8f44fad2bccb 100644 --- a/extensions/markdown-language-features/src/languageFeatures/copyFiles/copyFiles.ts +++ b/extensions/markdown-language-features/src/languageFeatures/copyFiles/copyFiles.ts @@ -81,7 +81,7 @@ export class NewFilePathGenerator { } function getDesiredNewFilePath(config: CopyFileConfiguration, document: vscode.TextDocument, file: vscode.DataTransferFile): vscode.Uri { - const docUri = getParentDocumentUri(document); + const docUri = getParentDocumentUri(document.uri); for (const [rawGlob, rawDest] of Object.entries(config.destination)) { for (const glob of parseGlob(rawGlob)) { if (picomatch.isMatch(docUri.path, glob, { dot: true })) { diff --git a/extensions/markdown-language-features/src/languageFeatures/copyFiles/copyPasteLinks.ts b/extensions/markdown-language-features/src/languageFeatures/copyFiles/copyPasteLinks.ts deleted file mode 100644 index 90755d990fcac..0000000000000 --- a/extensions/markdown-language-features/src/languageFeatures/copyFiles/copyPasteLinks.ts +++ /dev/null @@ -1,52 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { getMarkdownLink } from './shared'; -class PasteLinkEditProvider implements vscode.DocumentPasteEditProvider { - - readonly id = 'insertMarkdownLink'; - async provideDocumentPasteEdits( - document: vscode.TextDocument, - ranges: readonly vscode.Range[], - dataTransfer: vscode.DataTransfer, - token: vscode.CancellationToken, - ): Promise { - const enabled = vscode.workspace.getConfiguration('markdown', document).get<'always' | 'smart' | 'never'>('editor.pasteUrlAsFormattedLink.enabled', 'smart'); - if (enabled === 'never') { - return; - } - - // Check if dataTransfer contains a URL - const item = dataTransfer.get('text/plain'); - try { - new URL(await item?.value); - } catch (error) { - return; - } - - const uriEdit = new vscode.DocumentPasteEdit('', this.id, ''); - const urlList = await item?.asString(); - if (!urlList) { - return undefined; - } - const pasteEdit = await getMarkdownLink(document, ranges, urlList, token); - if (!pasteEdit) { - return; - } - - uriEdit.label = pasteEdit.label; - uriEdit.additionalEdit = pasteEdit.additionalEdits; - return uriEdit; - } -} - -export function registerLinkPasteSupport(selector: vscode.DocumentSelector,) { - return vscode.languages.registerDocumentPasteEditProvider(selector, new PasteLinkEditProvider(), { - pasteMimeTypes: [ - 'text/plain', - ] - }); -} diff --git a/extensions/markdown-language-features/src/languageFeatures/copyFiles/dropIntoEditor.ts b/extensions/markdown-language-features/src/languageFeatures/copyFiles/dropResourceProvider.ts similarity index 68% rename from extensions/markdown-language-features/src/languageFeatures/copyFiles/dropIntoEditor.ts rename to extensions/markdown-language-features/src/languageFeatures/copyFiles/dropResourceProvider.ts index 95c8455e307ad..1c5a19461cf2f 100644 --- a/extensions/markdown-language-features/src/languageFeatures/copyFiles/dropIntoEditor.ts +++ b/extensions/markdown-language-features/src/languageFeatures/copyFiles/dropResourceProvider.ts @@ -4,12 +4,23 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import { createEditForMediaFiles as createEditForMediaFiles, mediaMimes, tryGetUriListSnippet } from './shared'; +import { Mime, mediaMimes } from '../../util/mimes'; import { Schemes } from '../../util/schemes'; +import { createEditForMediaFiles, tryGetUriListSnippet } from './shared'; +class ResourceDropProvider implements vscode.DocumentDropEditProvider { -class MarkdownImageDropProvider implements vscode.DocumentDropEditProvider { - private readonly _id = 'insertLink'; + public static readonly id = 'insertLink'; + + public static readonly dropMimeTypes = [ + Mime.textUriList, + ...mediaMimes, + ]; + + private readonly _yieldTo = [ + { mimeType: 'text/plain' }, + { extensionId: 'vscode.ipynb', providerId: 'insertAttachment' }, + ]; async provideDocumentDropEdits(document: vscode.TextDocument, _position: vscode.Position, dataTransfer: vscode.DataTransfer, token: vscode.CancellationToken): Promise { const enabled = vscode.workspace.getConfiguration('markdown', document).get('editor.drop.enabled', true); @@ -30,18 +41,19 @@ class MarkdownImageDropProvider implements vscode.DocumentDropEditProvider { } private async _getUriListEdit(document: vscode.TextDocument, dataTransfer: vscode.DataTransfer, token: vscode.CancellationToken): Promise { - const urlList = await dataTransfer.get('text/uri-list')?.asString(); - if (!urlList) { + const urlList = await dataTransfer.get(Mime.textUriList)?.asString(); + if (!urlList || token.isCancellationRequested) { return undefined; } + const snippet = await tryGetUriListSnippet(document, urlList, token); if (!snippet) { return undefined; } const edit = new vscode.DocumentDropEdit(snippet.snippet); - edit.id = this._id; edit.label = snippet.label; + edit.yieldTo = this._yieldTo; return edit; } @@ -55,24 +67,19 @@ class MarkdownImageDropProvider implements vscode.DocumentDropEditProvider { return; } - const filesEdit = await createEditForMediaFiles(document, dataTransfer, token); - if (!filesEdit) { + const edit = await createEditForMediaFiles(document, dataTransfer, token); + if (!edit) { return; } - const edit = new vscode.DocumentDropEdit(filesEdit.snippet); - edit.id = this._id; - edit.label = filesEdit.label; - edit.additionalEdit = filesEdit.additionalEdits; - return edit; + const dropEdit = new vscode.DocumentDropEdit(edit.snippet); + dropEdit.label = edit.label; + dropEdit.additionalEdit = edit.additionalEdits; + dropEdit.yieldTo = this._yieldTo; + return dropEdit; } } export function registerDropIntoEditorSupport(selector: vscode.DocumentSelector) { - return vscode.languages.registerDocumentDropEditProvider(selector, new MarkdownImageDropProvider(), { - dropMimeTypes: [ - 'text/uri-list', - ...mediaMimes, - ] - }); + return vscode.languages.registerDocumentDropEditProvider(selector, new ResourceDropProvider(), ResourceDropProvider); } diff --git a/extensions/markdown-language-features/src/languageFeatures/copyFiles/copyPaste.ts b/extensions/markdown-language-features/src/languageFeatures/copyFiles/pasteResourceProvider.ts similarity index 56% rename from extensions/markdown-language-features/src/languageFeatures/copyFiles/copyPaste.ts rename to extensions/markdown-language-features/src/languageFeatures/copyFiles/pasteResourceProvider.ts index 24e23758d2576..cd051210d2dcc 100644 --- a/extensions/markdown-language-features/src/languageFeatures/copyFiles/copyPaste.ts +++ b/extensions/markdown-language-features/src/languageFeatures/copyFiles/pasteResourceProvider.ts @@ -4,12 +4,23 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; +import { Mime, mediaMimes } from '../../util/mimes'; import { Schemes } from '../../util/schemes'; -import { createEditForMediaFiles, getMarkdownLink, mediaMimes } from './shared'; +import { PasteUrlAsFormattedLink, createEditAddingLinksForUriList, createEditForMediaFiles, getPasteUrlAsFormattedLinkSetting } from './shared'; -class PasteEditProvider implements vscode.DocumentPasteEditProvider { +class PasteResourceEditProvider implements vscode.DocumentPasteEditProvider { - private readonly _id = 'insertLink'; + public static readonly id = 'insertLink'; + + public static readonly pasteMimeTypes = [ + Mime.textUriList, + ...mediaMimes, + ]; + + private readonly _yieldTo = [ + { mimeType: 'text/plain' }, + { extensionId: 'vscode.ipynb', providerId: 'insertAttachment' }, + ]; async provideDocumentPasteEdits( document: vscode.TextDocument, @@ -27,19 +38,28 @@ class PasteEditProvider implements vscode.DocumentPasteEditProvider { return createEdit; } - const uriEdit = new vscode.DocumentPasteEdit('', this._id, ''); - const urlList = await dataTransfer.get('text/uri-list')?.asString(); - if (!urlList) { + if (token.isCancellationRequested) { return; } - const pasteEdit = await getMarkdownLink(document, ranges, urlList, token); + + return this._getUriListEdit(document, ranges, dataTransfer, token); + } + + private async _getUriListEdit(document: vscode.TextDocument, ranges: readonly vscode.Range[], dataTransfer: vscode.DataTransfer, token: vscode.CancellationToken): Promise { + const uriList = await dataTransfer.get(Mime.textUriList)?.asString(); + if (!uriList || token.isCancellationRequested) { + return; + } + + const pasteUrlSetting = getPasteUrlAsFormattedLinkSetting(document); + const pasteEdit = await createEditAddingLinksForUriList(document, ranges, uriList, false, pasteUrlSetting === PasteUrlAsFormattedLink.Smart, token); if (!pasteEdit) { return; } - uriEdit.label = pasteEdit.label; + const uriEdit = new vscode.DocumentPasteEdit('', pasteEdit.label); uriEdit.additionalEdit = pasteEdit.additionalEdits; - uriEdit.priority = this._getPriority(dataTransfer); + uriEdit.yieldTo = this._yieldTo; return uriEdit; } @@ -58,26 +78,13 @@ class PasteEditProvider implements vscode.DocumentPasteEditProvider { return; } - const pasteEdit = new vscode.DocumentPasteEdit(edit.snippet, this._id, edit.label); + const pasteEdit = new vscode.DocumentPasteEdit(edit.snippet, edit.label); pasteEdit.additionalEdit = edit.additionalEdits; - pasteEdit.priority = this._getPriority(dataTransfer); + pasteEdit.yieldTo = this._yieldTo; return pasteEdit; } - - private _getPriority(dataTransfer: vscode.DataTransfer): number { - if (dataTransfer.get('text/plain')) { - // Deprioritize in favor of normal text content - return -10; - } - return 0; - } } export function registerPasteSupport(selector: vscode.DocumentSelector,) { - return vscode.languages.registerDocumentPasteEditProvider(selector, new PasteEditProvider(), { - pasteMimeTypes: [ - 'text/uri-list', - ...mediaMimes, - ] - }); + return vscode.languages.registerDocumentPasteEditProvider(selector, new PasteResourceEditProvider(), PasteResourceEditProvider); } diff --git a/extensions/markdown-language-features/src/languageFeatures/copyFiles/pasteUrlProvider.ts b/extensions/markdown-language-features/src/languageFeatures/copyFiles/pasteUrlProvider.ts new file mode 100644 index 0000000000000..b68b9cdaa2b66 --- /dev/null +++ b/extensions/markdown-language-features/src/languageFeatures/copyFiles/pasteUrlProvider.ts @@ -0,0 +1,49 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as vscode from 'vscode'; +import { Mime } from '../../util/mimes'; +import { createEditAddingLinksForUriList, getPasteUrlAsFormattedLinkSetting, PasteUrlAsFormattedLink, validateLink } from './shared'; + +class PasteUrlEditProvider implements vscode.DocumentPasteEditProvider { + + public static readonly id = 'insertMarkdownLink'; + + public static readonly pasteMimeTypes = [ + Mime.textPlain, + ]; + + async provideDocumentPasteEdits( + document: vscode.TextDocument, + ranges: readonly vscode.Range[], + dataTransfer: vscode.DataTransfer, + token: vscode.CancellationToken, + ): Promise { + const pasteUrlSetting = getPasteUrlAsFormattedLinkSetting(document); + if (pasteUrlSetting === PasteUrlAsFormattedLink.Never) { + return; + } + + const item = dataTransfer.get(Mime.textPlain); + const urlList = await item?.asString(); + if (token.isCancellationRequested || !urlList || !validateLink(urlList).isValid) { + return; + } + + const pasteEdit = await createEditAddingLinksForUriList(document, ranges, validateLink(urlList).cleanedUrlList, true, pasteUrlSetting === PasteUrlAsFormattedLink.Smart, token); + if (!pasteEdit) { + return; + } + + const edit = new vscode.DocumentPasteEdit('', pasteEdit.label); + edit.additionalEdit = pasteEdit.additionalEdits; + edit.yieldTo = pasteEdit.markdownLink ? undefined : [{ mimeType: Mime.textPlain }]; + return edit; + } +} + +export function registerLinkPasteSupport(selector: vscode.DocumentSelector,) { + return vscode.languages.registerDocumentPasteEditProvider(selector, new PasteUrlEditProvider(), PasteUrlEditProvider); +} diff --git a/extensions/markdown-language-features/src/languageFeatures/copyFiles/shared.ts b/extensions/markdown-language-features/src/languageFeatures/copyFiles/shared.ts index f40fea3556fea..dc8c15075f4cc 100644 --- a/extensions/markdown-language-features/src/languageFeatures/copyFiles/shared.ts +++ b/extensions/markdown-language-features/src/languageFeatures/copyFiles/shared.ts @@ -6,10 +6,11 @@ import * as path from 'path'; import * as vscode from 'vscode'; import * as URI from 'vscode-uri'; -import { Schemes } from '../../util/schemes'; -import { NewFilePathGenerator } from './copyFiles'; import { coalesce } from '../../util/arrays'; import { getDocumentDir } from '../../util/document'; +import { mediaMimes } from '../../util/mimes'; +import { Schemes } from '../../util/schemes'; +import { NewFilePathGenerator } from './copyFiles'; enum MediaKind { Image, @@ -17,9 +18,10 @@ enum MediaKind { Audio, } -const externalUriSchemes = [ +export const externalUriSchemes = [ 'http', 'https', + 'mailto', ]; export const mediaFileExtensions = new Map([ @@ -48,82 +50,129 @@ export const mediaFileExtensions = new Map([ ['wav', MediaKind.Audio], ]); -export const mediaMimes = new Set([ - 'image/bmp', - 'image/gif', - 'image/jpeg', - 'image/png', - 'image/webp', - 'video/mp4', - 'video/ogg', - 'audio/mpeg', - 'audio/aac', - 'audio/x-wav', -]); +const smartPasteRegexes = [ + { regex: /(\[[^\[\]]*](?:\([^\(\)]*\)|\[[^\[\]]*]))/g }, // In a Markdown link + { regex: /^```[\s\S]*?```$/gm }, // In a backtick fenced code block + { regex: /^~~~[\s\S]*?~~~$/gm }, // In a tildefenced code block + { regex: /^\$\$[\s\S]*?\$\$$/gm }, // In a fenced math block + { regex: /`[^`]*`/g }, // In inline code + { regex: /\$[^$]*\$/g }, // In inline math +]; + +export interface SkinnyTextDocument { + offsetAt(position: vscode.Position): number; + getText(range?: vscode.Range): string; + readonly uri: vscode.Uri; +} + +export enum PasteUrlAsFormattedLink { + Always = 'always', + Smart = 'smart', + Never = 'never' +} + +export function getPasteUrlAsFormattedLinkSetting(document: vscode.TextDocument): PasteUrlAsFormattedLink { + return vscode.workspace.getConfiguration('markdown', document).get('editor.pasteUrlAsFormattedLink.enabled', PasteUrlAsFormattedLink.Smart); +} + +export async function createEditAddingLinksForUriList( + document: SkinnyTextDocument, + ranges: readonly vscode.Range[], + urlList: string, + isExternalLink: boolean, + useSmartPaste: boolean, + token: vscode.CancellationToken, +): Promise<{ additionalEdits: vscode.WorkspaceEdit; label: string; markdownLink: boolean } | undefined> { -export async function getMarkdownLink(document: vscode.TextDocument, ranges: readonly vscode.Range[], urlList: string, token: vscode.CancellationToken): Promise<{ additionalEdits: vscode.WorkspaceEdit; label: string } | undefined> { if (ranges.length === 0) { return; } - const enabled = vscode.workspace.getConfiguration('markdown', document).get<'always' | 'smart' | 'never'>('editor.pasteUrlAsFormattedLink.enabled', 'always'); - const edits: vscode.SnippetTextEdit[] = []; let placeHolderValue: number = ranges.length; let label: string = ''; - let smartPaste: boolean = false; - for (let i = 0; i < ranges.length; i++) { - if (enabled === 'smart') { - const inMarkdownLink = checkPaste(document, ranges, /\[([^\]]*)\]\(([^)]*)\)/g, i); - const inFencedCode = checkPaste(document, ranges, /^```[\s\S]*?```$/gm, i); - const inFencedMath = checkPaste(document, ranges, /^\$\$[\s\S]*?\$\$$/gm, i); - smartPaste = (inMarkdownLink || inFencedCode || inFencedMath); + let pasteAsMarkdownLink: boolean = true; + let markdownLink: boolean = true; + + for (const range of ranges) { + const selectedRange: vscode.Range = new vscode.Range( + new vscode.Position(range.start.line, document.offsetAt(range.start)), + new vscode.Position(range.end.line, document.offsetAt(range.end)) + ); + + if (useSmartPaste) { + pasteAsMarkdownLink = checkSmartPaste(document, selectedRange, range); + markdownLink = pasteAsMarkdownLink; // FIX: this will only match the last range } - const snippet = await tryGetUriListSnippet(document, urlList, token, document.getText(ranges[i]), placeHolderValue, smartPaste); + const snippet = await tryGetUriListSnippet(document, urlList, token, document.getText(range), placeHolderValue, pasteAsMarkdownLink, isExternalLink); if (!snippet) { return; } - smartPaste = false; + pasteAsMarkdownLink = true; placeHolderValue--; - edits.push(new vscode.SnippetTextEdit(ranges[i], snippet.snippet)); + edits.push(new vscode.SnippetTextEdit(range, snippet.snippet)); label = snippet.label; } const additionalEdits = new vscode.WorkspaceEdit(); additionalEdits.set(document.uri, edits); - return { additionalEdits, label }; + return { additionalEdits, label, markdownLink }; } -function checkPaste(document: vscode.TextDocument, ranges: readonly vscode.Range[], regex: RegExp, index: number): boolean { - const rangeStartOffset = document.offsetAt(ranges[index].start); - const rangeEndOffset = document.offsetAt(ranges[index].end); - const matches = [...document.getText().matchAll(regex)]; - for (const match of matches) { - if (match.index !== undefined && rangeStartOffset > match.index && rangeEndOffset < match.index + match[0].length) { - return true; +export function checkSmartPaste(document: SkinnyTextDocument, selectedRange: vscode.Range, range: vscode.Range): boolean { + if (selectedRange.isEmpty || /^[\s\n]*$/.test(document.getText(range)) || validateLink(document.getText(range)).isValid) { + return false; + } + if (/\[.*\]\(.*\)/.test(document.getText(range)) || /!\[.*\]\(.*\)/.test(document.getText(range))) { + return false; + } + for (const regex of smartPasteRegexes) { + const matches = [...document.getText().matchAll(regex.regex)]; + for (const match of matches) { + if (match.index !== undefined) { + const useDefaultPaste = selectedRange.start.character > match.index && selectedRange.end.character < match.index + match[0].length; + if (useDefaultPaste) { + return false; + } + } } } + return true; +} - return false; +export function validateLink(urlList: string): { isValid: boolean; cleanedUrlList: string } { + let isValid = false; + let uri = undefined; + const trimmedUrlList = urlList?.trim(); //remove leading and trailing whitespace and new lines + try { + uri = vscode.Uri.parse(trimmedUrlList); + } catch (error) { + return { isValid: false, cleanedUrlList: urlList }; + } + const splitUrlList = trimmedUrlList.split(' ').filter(item => item !== ''); //split on spaces and remove empty strings + if (uri) { + isValid = splitUrlList.length === 1 && !splitUrlList[0].includes('\n') && externalUriSchemes.includes(vscode.Uri.parse(splitUrlList[0]).scheme) && !!vscode.Uri.parse(splitUrlList[0]).authority; + } + return { isValid, cleanedUrlList: splitUrlList[0] }; } -export async function tryGetUriListSnippet(document: vscode.TextDocument, urlList: String, token: vscode.CancellationToken, title = '', placeHolderValue = 0, smartPaste = false): Promise<{ snippet: vscode.SnippetString; label: string } | undefined> { +export async function tryGetUriListSnippet(document: SkinnyTextDocument, urlList: String, token: vscode.CancellationToken, title = '', placeHolderValue = 0, pasteAsMarkdownLink = true, isExternalLink = false): Promise<{ snippet: vscode.SnippetString; label: string } | undefined> { if (token.isCancellationRequested) { return undefined; } - + const uriStrings: string[] = []; const uris: vscode.Uri[] = []; for (const resource of urlList.split(/\r?\n/g)) { try { uris.push(vscode.Uri.parse(resource)); + uriStrings.push(resource); } catch { // noop } } - - return createUriListSnippet(document, uris, title, placeHolderValue, smartPaste); + return createUriListSnippet(document, uris, uriStrings, title, placeHolderValue, pasteAsMarkdownLink, isExternalLink); } interface UriListSnippetOptions { @@ -141,28 +190,42 @@ interface UriListSnippetOptions { readonly separator?: string; } +export function appendToLinkSnippet( + snippet: vscode.SnippetString, + title: string, + uriString: string, + placeholderValue: number, + isExternalLink: boolean, +): vscode.SnippetString { + snippet.appendText('['); + snippet.appendPlaceholder(escapeBrackets(title) || 'Title', placeholderValue); + snippet.appendText(`](${escapeMarkdownLinkPath(uriString, isExternalLink)})`); + return snippet; +} + export function createUriListSnippet( - document: vscode.TextDocument, + document: SkinnyTextDocument, uris: readonly vscode.Uri[], + uriStrings?: readonly string[], title = '', placeholderValue = 0, - smartPaste = false, + pasteAsMarkdownLink = true, + isExternalLink = false, options?: UriListSnippetOptions, ): { snippet: vscode.SnippetString; label: string } | undefined { if (!uris.length) { return; } - const dir = getDocumentDir(document); - - const snippet = new vscode.SnippetString(); + const documentDir = getDocumentDir(document.uri); + let snippet = new vscode.SnippetString(); let insertedLinkCount = 0; let insertedImageCount = 0; let insertedAudioVideoCount = 0; uris.forEach((uri, i) => { - const mdPath = getMdPath(dir, uri); + const mdPath = getMdPath(documentDir, uri); const ext = URI.Utils.extname(uri).toLowerCase().replace('.', ''); const insertAsMedia = typeof options?.insertAsMedia === 'undefined' ? mediaFileExtensions.has(ext) : !!options.insertAsMedia; @@ -179,33 +242,26 @@ export function createUriListSnippet( snippet.appendText(`'); - } else { + } else if (insertAsMedia) { if (insertAsMedia) { insertedImageCount++; - snippet.appendText('!['); - const placeholderText = escapeBrackets(title) || options?.placeholderText || 'Alt text'; - const placeholderIndex = typeof options?.placeholderStartIndex !== 'undefined' ? options?.placeholderStartIndex + i : (placeholderValue === 0 ? undefined : placeholderValue); - snippet.appendPlaceholder(placeholderText, placeholderIndex); - snippet.appendText(`](${escapeMarkdownLinkPath(mdPath)})`); - } else { - insertedLinkCount++; - if (smartPaste) { - if (externalUriSchemes.includes(uri.scheme)) { - snippet.appendText(uri.toString(true)); - } else { - snippet.appendText(escapeMarkdownLinkPath(mdPath)); - } + if (pasteAsMarkdownLink) { + snippet.appendText('!['); + const placeholderText = escapeBrackets(title) || options?.placeholderText || 'Alt text'; + const placeholderIndex = typeof options?.placeholderStartIndex !== 'undefined' ? options?.placeholderStartIndex + i : (placeholderValue === 0 ? undefined : placeholderValue); + snippet.appendPlaceholder(placeholderText, placeholderIndex); + snippet.appendText(`](${escapeMarkdownLinkPath(mdPath, isExternalLink)})`); } else { - snippet.appendText('['); - snippet.appendPlaceholder(escapeBrackets(title) || 'Title', placeholderValue); - if (externalUriSchemes.includes(uri.scheme)) { - const uriString = uri.toString(true); - snippet.appendText(`](${uriString})`); - } else { - snippet.appendText(`](${escapeMarkdownLinkPath(mdPath)})`); - } + snippet.appendText(escapeMarkdownLinkPath(mdPath, isExternalLink)); } } + } else { + insertedLinkCount++; + if (uriStrings && isExternalLink) { + snippet = appendToLinkSnippet(snippet, title, uriStrings[i], placeholderValue, isExternalLink); + } else { + snippet.appendText(escapeMarkdownLinkPath(mdPath, isExternalLink)); + } } if (i < uris.length - 1 && uris.length > 1) { @@ -325,16 +381,16 @@ function escapeHtmlAttribute(attr: string): string { return encodeURI(attr).replaceAll('"', '"'); } -function escapeMarkdownLinkPath(mdPath: string): string { +function escapeMarkdownLinkPath(mdPath: string, isExternalLink: boolean): string { if (needsBracketLink(mdPath)) { return '<' + mdPath.replaceAll('<', '\\<').replaceAll('>', '\\>') + '>'; } - return encodeURI(mdPath); + return isExternalLink ? mdPath : encodeURI(mdPath); } function escapeBrackets(value: string): string { - value = value.replace(/[\[\]]/g, '\\$&'); + value = value.replace(/[\[\]]/g, '\\$&'); // CodeQL [SM02383] The Markdown is fully sanitized after being rendered. return value; } diff --git a/extensions/markdown-language-features/src/markdownEngine.ts b/extensions/markdown-language-features/src/markdownEngine.ts index 282cef1548dfc..cd999c4411639 100644 --- a/extensions/markdown-language-features/src/markdownEngine.ts +++ b/extensions/markdown-language-features/src/markdownEngine.ts @@ -114,6 +114,7 @@ export class MarkdownItEngine implements IMdParser { _contributionProvider.onContributionsChanged(() => { // Markdown plugin contributions may have changed this._md = undefined; + this._tokenCache.clean(); }); } diff --git a/extensions/markdown-language-features/src/preview/preview.ts b/extensions/markdown-language-features/src/preview/preview.ts index de58e54784aad..7ccbc625b4734 100644 --- a/extensions/markdown-language-features/src/preview/preview.ts +++ b/extensions/markdown-language-features/src/preview/preview.ts @@ -95,7 +95,7 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider { } this._register(_contributionProvider.onContributionsChanged(() => { - setTimeout(() => this.refresh(), 0); + setTimeout(() => this.refresh(true), 0); })); this._register(vscode.workspace.onDidChangeTextDocument(event => { diff --git a/extensions/markdown-language-features/src/test/markdownLink.test.ts b/extensions/markdown-language-features/src/test/markdownLink.test.ts new file mode 100644 index 0000000000000..f0133ad85ccd7 --- /dev/null +++ b/extensions/markdown-language-features/src/test/markdownLink.test.ts @@ -0,0 +1,233 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import * as vscode from 'vscode'; +import * as assert from 'assert'; +import 'mocha'; +import { SkinnyTextDocument, checkSmartPaste, createEditAddingLinksForUriList, appendToLinkSnippet, validateLink } from '../languageFeatures/copyFiles/shared'; + +suite('createEditAddingLinksForUriList', () => { + + test('Markdown Link Pasting should occur for a valid link (end to end)', async () => { + // createEditAddingLinksForUriList -> checkSmartPaste -> tryGetUriListSnippet -> createUriListSnippet -> createLinkSnippet + + const skinnyDocument: SkinnyTextDocument = { + uri: vscode.Uri.parse('file:///path/to/your/file'), + offsetAt: function () { return 0; }, + getText: function () { return 'hello world!'; }, + }; + + const result = await createEditAddingLinksForUriList(skinnyDocument, [new vscode.Range(0, 0, 0, 12)], 'https://www.microsoft.com/', true, true, new vscode.CancellationTokenSource().token); + // need to check the actual result -> snippet value + assert.strictEqual(result?.label, 'Insert Markdown Link'); + }); + + suite('validateLink', () => { + + test('Markdown pasting should occur for a valid link.', () => { + const isLink = validateLink('https://www.microsoft.com/').isValid; + assert.strictEqual(isLink, true); + }); + + test('Markdown pasting should occur for a valid link preceded by a new line.', () => { + const isLink = validateLink('\r\nhttps://www.microsoft.com/').isValid; + assert.strictEqual(isLink, true); + }); + + test('Markdown pasting should occur for a valid link followed by a new line.', () => { + const isLink = validateLink('https://www.microsoft.com/\r\n').isValid; + assert.strictEqual(isLink, true); + }); + + test('Markdown pasting should not occur for a valid hostname and invalid protool.', () => { + const isLink = validateLink('invalid:www.microsoft.com').isValid; + assert.strictEqual(isLink, false); + }); + + test('Markdown pasting should not occur for plain text.', () => { + const isLink = validateLink('hello world!').isValid; + assert.strictEqual(isLink, false); + }); + + test('Markdown pasting should not occur for plain text including a colon.', () => { + const isLink = validateLink('hello: world!').isValid; + assert.strictEqual(isLink, false); + }); + + test('Markdown pasting should not occur for plain text including a slashes.', () => { + const isLink = validateLink('helloworld!').isValid; + assert.strictEqual(isLink, false); + }); + + test('Markdown pasting should not occur for a link followed by text.', () => { + const isLink = validateLink('https://www.microsoft.com/ hello world!').isValid; + assert.strictEqual(isLink, false); + }); + + test('Markdown pasting should occur for a link preceded or followed by spaces.', () => { + const isLink = validateLink(' https://www.microsoft.com/ ').isValid; + assert.strictEqual(isLink, true); + }); + + test('Markdown pasting should not occur for a link with an invalid scheme.', () => { + const isLink = validateLink('hello:www.microsoft.com').isValid; + assert.strictEqual(isLink, false); + }); + + test('Markdown pasting should not occur for multiple links being pasted.', () => { + const isLink = validateLink('https://www.microsoft.com/\r\nhttps://www.microsoft.com/\r\nhttps://www.microsoft.com/\r\nhttps://www.microsoft.com/').isValid; + assert.strictEqual(isLink, false); + }); + + test('Markdown pasting should not occur for multiple links with spaces being pasted.', () => { + const isLink = validateLink('https://www.microsoft.com/ \r\nhttps://www.microsoft.com/\r\nhttps://www.microsoft.com/\r\n hello \r\nhttps://www.microsoft.com/').isValid; + assert.strictEqual(isLink, false); + }); + + test('Markdown pasting should not occur for just a valid uri scheme', () => { + const isLink = validateLink('https://').isValid; + assert.strictEqual(isLink, false); + }); + }); + + suite('appendToLinkSnippet', () => { + + test('Should create snippet with < > when pasted link has an mismatched parentheses', () => { + const uriString = 'https://www.mic(rosoft.com'; + const snippet = appendToLinkSnippet(new vscode.SnippetString(''), 'abc', uriString, 0, true); + assert.strictEqual(snippet?.value, '[${0:abc}]()'); + }); + + test('Should create Markdown link snippet when pasteAsMarkdownLink is true', () => { + const uriString = 'https://www.microsoft.com'; + const snippet = appendToLinkSnippet(new vscode.SnippetString(''), '', uriString, 0, true); + assert.strictEqual(snippet?.value, '[${0:Title}](https://www.microsoft.com)'); + }); + + test('Should use an unencoded URI string in Markdown link when passing in an external browser link', () => { + const uriString = 'https://www.microsoft.com'; + const snippet = appendToLinkSnippet(new vscode.SnippetString(''), '', uriString, 0, true); + assert.strictEqual(snippet?.value, '[${0:Title}](https://www.microsoft.com)'); + }); + + test('Should not decode an encoded URI string when passing in an external browser link', () => { + const uriString = 'https://www.microsoft.com/%20'; + const snippet = appendToLinkSnippet(new vscode.SnippetString(''), '', uriString, 0, true); + assert.strictEqual(snippet?.value, '[${0:Title}](https://www.microsoft.com/%20)'); + }); + + test('Should not encode an unencoded URI string when passing in an external browser link', () => { + const uriString = 'https://www.example.com/path?query=value&another=value#fragment'; + const snippet = appendToLinkSnippet(new vscode.SnippetString(''), '', uriString, 0, true); + assert.strictEqual(snippet?.value, '[${0:Title}](https://www.example.com/path?query=value&another=value#fragment)'); + }); + }); + + + suite('checkSmartPaste', () => { + + const skinnyDocument: SkinnyTextDocument = { + uri: vscode.Uri.file('/path/to/your/file'), + offsetAt: function () { return 0; }, + getText: function () { return 'hello world!'; }, + }; + + test('Should evaluate pasteAsMarkdownLink as true for selected plain text', () => { + const pasteAsMarkdownLink = checkSmartPaste(skinnyDocument, new vscode.Range(0, 0, 0, 12), new vscode.Range(0, 0, 0, 12)); + assert.strictEqual(pasteAsMarkdownLink, true); + }); + + test('Should evaluate pasteAsMarkdownLink as false for a valid selected link', () => { + skinnyDocument.getText = function () { return 'https://www.microsoft.com'; }; + const pasteAsMarkdownLink = checkSmartPaste(skinnyDocument, new vscode.Range(0, 0, 0, 25), new vscode.Range(0, 0, 0, 25)); + assert.strictEqual(pasteAsMarkdownLink, false); + }); + + test('Should evaluate pasteAsMarkdownLink as false for a valid selected link with trailing whitespace', () => { + skinnyDocument.getText = function () { return ' https://www.microsoft.com '; }; + const pasteAsMarkdownLink = checkSmartPaste(skinnyDocument, new vscode.Range(0, 0, 0, 30), new vscode.Range(0, 0, 0, 30)); + assert.strictEqual(pasteAsMarkdownLink, false); + }); + + test('Should evaluate pasteAsMarkdownLink as true for a link pasted in square brackets', () => { + skinnyDocument.getText = function () { return '[abc]'; }; + const pasteAsMarkdownLink = checkSmartPaste(skinnyDocument, new vscode.Range(0, 1, 0, 4), new vscode.Range(0, 1, 0, 4)); + assert.strictEqual(pasteAsMarkdownLink, true); + }); + + test('Should evaluate pasteAsMarkdownLink as false for no selection', () => { + const pasteAsMarkdownLink = checkSmartPaste(skinnyDocument, new vscode.Range(0, 0, 0, 0), new vscode.Range(0, 0, 0, 0)); + assert.strictEqual(pasteAsMarkdownLink, false); + }); + + test('Should evaluate pasteAsMarkdownLink as false for selected whitespace and new lines', () => { + skinnyDocument.getText = function () { return ' \r\n\r\n'; }; + const pasteAsMarkdownLink = checkSmartPaste(skinnyDocument, new vscode.Range(0, 0, 0, 7), new vscode.Range(0, 0, 0, 7)); + assert.strictEqual(pasteAsMarkdownLink, false); + }); + + test('Should evaluate pasteAsMarkdownLink as false for pasting within a backtick code block', () => { + skinnyDocument.getText = function () { return '```\r\n\r\n```'; }; + const pasteAsMarkdownLink = checkSmartPaste(skinnyDocument, new vscode.Range(0, 5, 0, 5), new vscode.Range(0, 5, 0, 5)); + assert.strictEqual(pasteAsMarkdownLink, false); + }); + + test('Should evaluate pasteAsMarkdownLink as false for pasting within a tilde code block', () => { + skinnyDocument.getText = function () { return '~~~\r\n\r\n~~~'; }; + const pasteAsMarkdownLink = checkSmartPaste(skinnyDocument, new vscode.Range(0, 5, 0, 5), new vscode.Range(0, 5, 0, 5)); + assert.strictEqual(pasteAsMarkdownLink, false); + }); + + test('Should evaluate pasteAsMarkdownLink as false for pasting within a math block', () => { + skinnyDocument.getText = function () { return '$$$\r\n\r\n$$$'; }; + const pasteAsMarkdownLink = checkSmartPaste(skinnyDocument, new vscode.Range(0, 5, 0, 5), new vscode.Range(0, 5, 0, 5)); + assert.strictEqual(pasteAsMarkdownLink, false); + }); + + const linkSkinnyDoc: SkinnyTextDocument = { + uri: vscode.Uri.file('/path/to/your/file'), + offsetAt: function () { return 0; }, + getText: function () { return '[a](bcdef)'; }, + }; + + test('Should evaluate pasteAsMarkdownLink as false for pasting within a Markdown link', () => { + const pasteAsMarkdownLink = checkSmartPaste(linkSkinnyDoc, new vscode.Range(0, 4, 0, 6), new vscode.Range(0, 4, 0, 6)); + assert.strictEqual(pasteAsMarkdownLink, false); + }); + + + const imageLinkSkinnyDoc: SkinnyTextDocument = { + uri: vscode.Uri.file('/path/to/your/file'), + offsetAt: function () { return 0; }, + getText: function () { return '![a](bcdef)'; }, + }; + + test('Should evaluate pasteAsMarkdownLink as false for pasting within a Markdown image link', () => { + const pasteAsMarkdownLink = checkSmartPaste(imageLinkSkinnyDoc, new vscode.Range(0, 5, 0, 10), new vscode.Range(0, 5, 0, 10)); + assert.strictEqual(pasteAsMarkdownLink, false); + }); + + const inlineCodeSkinnyCode: SkinnyTextDocument = { + uri: vscode.Uri.file('/path/to/your/file'), + offsetAt: function () { return 0; }, + getText: function () { return '``'; }, + }; + + test('Should evaluate pasteAsMarkdownLink as false for pasting within inline code', () => { + const pasteAsMarkdownLink = checkSmartPaste(inlineCodeSkinnyCode, new vscode.Range(0, 1, 0, 1), new vscode.Range(0, 1, 0, 1)); + assert.strictEqual(pasteAsMarkdownLink, false); + }); + + const inlineMathSkinnyDoc: SkinnyTextDocument = { + uri: vscode.Uri.file('/path/to/your/file'), + offsetAt: function () { return 0; }, + getText: function () { return '$$'; }, + }; + + test('Should evaluate pasteAsMarkdownLink as false for pasting within inline math', () => { + const pasteAsMarkdownLink = checkSmartPaste(inlineMathSkinnyDoc, new vscode.Range(0, 1, 0, 1), new vscode.Range(0, 1, 0, 1)); + assert.strictEqual(pasteAsMarkdownLink, false); + }); + }); +}); diff --git a/extensions/markdown-language-features/src/util/document.ts b/extensions/markdown-language-features/src/util/document.ts index 9c192227ee3b3..856226a737692 100644 --- a/extensions/markdown-language-features/src/util/document.ts +++ b/extensions/markdown-language-features/src/util/document.ts @@ -7,24 +7,24 @@ import * as vscode from 'vscode'; import { Schemes } from './schemes'; import { Utils } from 'vscode-uri'; -export function getDocumentDir(document: vscode.TextDocument): vscode.Uri | undefined { - const docUri = getParentDocumentUri(document); +export function getDocumentDir(uri: vscode.Uri): vscode.Uri | undefined { + const docUri = getParentDocumentUri(uri); if (docUri.scheme === Schemes.untitled) { return vscode.workspace.workspaceFolders?.[0]?.uri; } return Utils.dirname(docUri); } -export function getParentDocumentUri(document: vscode.TextDocument): vscode.Uri { - if (document.uri.scheme === Schemes.notebookCell) { +export function getParentDocumentUri(uri: vscode.Uri): vscode.Uri { + if (uri.scheme === Schemes.notebookCell) { for (const notebook of vscode.workspace.notebookDocuments) { for (const cell of notebook.getCells()) { - if (cell.document === document) { + if (cell.document.uri.toString() === uri.toString()) { return notebook.uri; } } } } - return document.uri; + return uri; } diff --git a/extensions/markdown-language-features/src/util/mimes.ts b/extensions/markdown-language-features/src/util/mimes.ts new file mode 100644 index 0000000000000..8028294b3f475 --- /dev/null +++ b/extensions/markdown-language-features/src/util/mimes.ts @@ -0,0 +1,22 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +export const Mime = { + textUriList: 'text/uri-list', + textPlain: 'text/plain', +} as const; + +export const mediaMimes = new Set([ + 'image/bmp', + 'image/gif', + 'image/jpeg', + 'image/png', + 'image/webp', + 'video/mp4', + 'video/ogg', + 'audio/mpeg', + 'audio/aac', + 'audio/x-wav', +]); diff --git a/extensions/markdown-language-features/yarn.lock b/extensions/markdown-language-features/yarn.lock index b6a3e689d99df..36b5aebfed8ff 100644 --- a/extensions/markdown-language-features/yarn.lock +++ b/extensions/markdown-language-features/yarn.lock @@ -17,7 +17,16 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" -"@azure/core-rest-pipeline@^1.10.0": +"@azure/core-auth@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.5.0.tgz#a41848c5c31cb3b7c84c409885267d55a2c92e44" + integrity sha512-udzoBuYG1VBoHVohDTrvKjyzel34zt77Bhp7dQntVGGD0ehVq48owENbBG8fIgkHRNUBQH5k1r0hpoMu5L8+kw== + dependencies: + "@azure/abort-controller" "^1.0.0" + "@azure/core-util" "^1.1.0" + tslib "^2.2.0" + +"@azure/core-rest-pipeline@1.10.1": version "1.10.1" resolved "https://registry.yarnpkg.com/@azure/core-rest-pipeline/-/core-rest-pipeline-1.10.1.tgz#348290847ca31b9eecf9cf5de7519aaccdd30968" integrity sha512-Kji9k6TOFRDB5ZMTw8qUf2IJ+CeJtsuMdAHox9eqpTf1cefiNMpzrfnF6sINEBZJsaVaWgQ0o48B6kcUH68niA== @@ -33,13 +42,21 @@ tslib "^2.2.0" uuid "^8.3.0" -"@azure/core-tracing@^1.0.1": +"@azure/core-tracing@^1.0.0", "@azure/core-tracing@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.0.1.tgz#352a38cbea438c4a83c86b314f48017d70ba9503" integrity sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw== dependencies: tslib "^2.2.0" +"@azure/core-util@1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.2.0.tgz#3499deba1fc36dda6f1912b791809b6f15d4a392" + integrity sha512-ffGIw+Qs8bNKNLxz5UPkz4/VBM/EZY07mPve1ZYFqYUdPwFqRj0RPk0U7LZMOfT7GCck9YjuT1Rfp1PApNl1ng== + dependencies: + "@azure/abort-controller" "^1.0.0" + tslib "^2.2.0" + "@azure/core-util@^1.0.0": version "1.1.1" resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.1.1.tgz#8f87b3dd468795df0f0849d9f096c3e7b29452c1" @@ -48,6 +65,14 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" +"@azure/core-util@^1.1.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.4.0.tgz#c120a56b3e48a9e4d20619a0b00268ae9de891c7" + integrity sha512-eGAyJpm3skVQoLiRqm/xPa+SXi/NPDdSHMxbRAz2lSprd+Zs+qrpQGQQ2VQ3Nttu+nSZR4XoYQC71LbEI7jsig== + dependencies: + "@azure/abort-controller" "^1.0.0" + tslib "^2.2.0" + "@azure/logger@^1.0.0": version "1.0.3" resolved "https://registry.yarnpkg.com/@azure/logger/-/logger-1.0.3.tgz#6e36704aa51be7d4a1bae24731ea580836293c96" @@ -55,66 +80,100 @@ dependencies: tslib "^2.2.0" -"@microsoft/1ds-core-js@3.2.8", "@microsoft/1ds-core-js@^3.2.8": - version "3.2.8" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.8.tgz#1b6b7d9bb858238c818ccf4e4b58ece7aeae5760" - integrity sha512-9o9SUAamJiTXIYwpkQDuueYt83uZfXp8zp8YFix1IwVPwC9RmE36T2CX9gXOeq1nDckOuOduYpA8qHvdh5BGfQ== +"@azure/opentelemetry-instrumentation-azure-sdk@^1.0.0-beta.5": + version "1.0.0-beta.5" + resolved "https://registry.yarnpkg.com/@azure/opentelemetry-instrumentation-azure-sdk/-/opentelemetry-instrumentation-azure-sdk-1.0.0-beta.5.tgz#78809e6c005d08450701e5d37f087f6fce2f86eb" + integrity sha512-fsUarKQDvjhmBO4nIfaZkfNSApm1hZBzcvpNbSrXdcUBxu7lRvKsV5DnwszX7cnhLyVOW9yl1uigtRQ1yDANjA== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.9" + "@azure/core-tracing" "^1.0.0" + "@azure/logger" "^1.0.0" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/instrumentation" "^0.41.2" + tslib "^2.2.0" + +"@microsoft/1ds-core-js@3.2.13", "@microsoft/1ds-core-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.13.tgz#0c105ed75091bae3f1555c0334704fa9911c58fb" + integrity sha512-CluYTRWcEk0ObG5EWFNWhs87e2qchJUn0p2D21ZUa3PWojPZfPSBs4//WIE0MYV8Qg1Hdif2ZTwlM7TbYUjfAg== + dependencies: + "@microsoft/applicationinsights-core-js" "2.8.15" "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@microsoft/1ds-post-js@^3.2.8": - version "3.2.8" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.8.tgz#46793842cca161bf7a2a5b6053c349f429e55110" - integrity sha512-SjlRoNcXcXBH6WQD/5SkkaCHIVqldH3gDu+bI7YagrOVJ5APxwT1Duw9gm3L1FjFa9S2i81fvJ3EVSKpp9wULA== +"@microsoft/1ds-post-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.13.tgz#560aacac8a92fdbb79e8c2ebcb293d56e19f51aa" + integrity sha512-HgS574fdD19Bo2vPguyznL4eDw7Pcm1cVNpvbvBLWiW3x4e1FCQ3VMXChWnAxCae8Hb0XqlA2sz332ZobBavTA== dependencies: - "@microsoft/1ds-core-js" "3.2.8" + "@microsoft/1ds-core-js" "3.2.13" "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@microsoft/applicationinsights-channel-js@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.8.9.tgz#840656f3c716de8b3eb0a98c122aa1b92bb8ebfb" - integrity sha512-fMBsAEB7pWtPn43y72q9Xy5E5y55r6gMuDQqRRccccVoQDPXyS57VCj5IdATblctru0C6A8XpL2vRyNmEsu0Vg== +"@microsoft/applicationinsights-channel-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-3.0.2.tgz#be49fbf74831c7b8c97950027c5052ea99d2a8a5" + integrity sha512-jDBNKbCHsJgmpv0CKNhJ/uN9ZphvfGdb93Svk+R4LjO8L3apNNMbDDPxBvXXi0uigRmA1TBcmyBG4IRKjabGhw== + dependencies: + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" + +"@microsoft/applicationinsights-common@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-3.0.2.tgz#37670bb07f4858ed41ff9759119e0759007d6e05" + integrity sha512-y+WXWop+OVim954Cu1uyYMnNx6PWO8okHpZIQi/1YSqtqaYdtJVPv4P0AVzwJdohxzVfgzKvqj9nec/VWqE2Zg== dependencies: - "@microsoft/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" -"@microsoft/applicationinsights-common@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-2.8.9.tgz#a75e4a3143a7fd797687830c0ddd2069fd900827" - integrity sha512-mObn1moElyxZaGIRF/IU3cOaeKMgxghXnYEoHNUCA2e+rNwBIgxjyKkblFIpmGuHf4X7Oz3o3yBWpaC6AoMpig== +"@microsoft/applicationinsights-core-js@2.8.15": + version "2.8.15" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.15.tgz#8fa466474260e01967fe649f14dd9e5ff91dcdc8" + integrity sha512-yYAs9MyjGr2YijQdUSN9mVgT1ijI1FPMgcffpaPmYbHAVbQmF7bXudrBWHxmLzJlwl5rfep+Zgjli2e67lwUqQ== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.9" "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/dynamicproto-js" "^1.1.9" -"@microsoft/applicationinsights-core-js@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.9.tgz#0e5d207acfae6986a6fc97249eeb6117e523bf1b" - integrity sha512-HRuIuZ6aOWezcg/G5VyFDDWGL8hDNe/ljPP01J7ImH2kRPEgbtcfPSUMjkamGMefgdq81GZsSoC/NNGTP4pp2w== +"@microsoft/applicationinsights-core-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-3.0.2.tgz#108e20df8c162bec92b1f66f9de2530a25d9f51a" + integrity sha512-WQhVhzlRlLDrQzn3OShCW/pL3BW5WC57t0oywSknX3q7lMzI3jDg7Ihh0iuIcNTzGCTbDkuqr4d6IjEDWIMtJQ== dependencies: - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-shims@2.0.2", "@microsoft/applicationinsights-shims@^2.0.2": version "2.0.2" resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.2.tgz#92b36a09375e2d9cb2b4203383b05772be837085" integrity sha512-PoHEgsnmcqruLNHZ/amACqdJ6YYQpED0KSRe6J7gIJTtpZC1FfFU9b1fmDKDKtFoUSrPzEh1qzO3kmRZP0betg== -"@microsoft/applicationinsights-web-basic@^2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-2.8.9.tgz#eed2f3d1e19069962ed2155915c1656e6936e1d5" - integrity sha512-CH0J8JFOy7MjK8JO4pXXU+EML+Ilix+94PMZTX5EJlBU1in+mrik74/8qSg3UC4ekPi12KwrXaHCQSVC3WseXQ== +"@microsoft/applicationinsights-shims@3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-3.0.1.tgz#3865b73ace8405b9c4618cc5c571f2fe3876f06f" + integrity sha512-DKwboF47H1nb33rSUfjqI6ryX29v+2QWcTrRvcQDA32AZr5Ilkr7whOOSsD1aBzwqX0RJEIP1Z81jfE3NBm/Lg== dependencies: - "@microsoft/applicationinsights-channel-js" "2.8.9" - "@microsoft/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" + +"@microsoft/applicationinsights-web-basic@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-3.0.2.tgz#f777a4d24b79dde3ae396d3b819e1fce06b7240a" + integrity sha512-6Lq0DE/pZp9RvSV+weGbcxN1NDmfczj6gNPhvZKV2YSQ3RK0LZE3+wjTWLXfuStq8a+nCBdsRpWk8tOKgsoxcg== + dependencies: + "@microsoft/applicationinsights-channel-js" "3.0.2" + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-web-snippet@^1.0.1": version "1.0.1" @@ -126,49 +185,84 @@ resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.7.tgz#ede48dd3f85af14ee369c805e5ed5b84222b9fe2" integrity sha512-SK3D3aVt+5vOOccKPnGaJWB5gQ8FuKfjboUJHedMP7gu54HqSCXX5iFXhktGD8nfJb0Go30eDvs/UDoTnR2kOA== -"@opentelemetry/api@^1.0.4": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.2.0.tgz#89ef99401cde6208cff98760b67663726ef26686" - integrity sha512-0nBr+VZNKm9tvNDZFstI3Pq1fCTEDK5OZTnVKNvBNAKgd0yIvmwsP4m61rEv7ZP+tOUjWJhROpxK5MsnlF911g== +"@microsoft/dynamicproto-js@^1.1.9": + version "1.1.9" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.9.tgz#7437db7aa061162ee94e4131b69a62b8dad5dea6" + integrity sha512-n1VPsljTSkthsAFYdiWfC+DKzK2WwcRp83Y1YAqdX552BstvsDjft9YXppjUzp11BPsapDoO1LDgrDB0XVsfNQ== -"@opentelemetry/core@1.7.0", "@opentelemetry/core@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.7.0.tgz#83bdd1b7a4ceafcdffd6590420657caec5f7b34c" - integrity sha512-AVqAi5uc8DrKJBimCTFUT4iFI+5eXpo4sYmGbQ0CypG0piOTHE2g9c5aSoTGYXu3CzOmJZf7pT6Xh+nwm5d6yQ== +"@microsoft/dynamicproto-js@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-2.0.2.tgz#e57fbec2e7067d48b7e8e1e1c1d354028ef718a6" + integrity sha512-MB8trWaFREpmb037k/d0bB7T2BP7Ai24w1e1tbz3ASLB0/lwphsq3Nq8S9I5AsI5vs4zAQT+SB5nC5/dLYTiOg== dependencies: - "@opentelemetry/semantic-conventions" "1.7.0" + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" -"@opentelemetry/resources@1.7.0": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.7.0.tgz#90ccd3a6a86b4dfba4e833e73944bd64958d78c5" - integrity sha512-u1M0yZotkjyKx8dj+46Sg5thwtOTBmtRieNXqdCRiWUp6SfFiIP0bI+1XK3LhuXqXkBXA1awJZaTqKduNMStRg== +"@nevware21/ts-async@>= 0.2.4 < 2.x": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@nevware21/ts-async/-/ts-async-0.3.0.tgz#a8b97ba01065fc930de9a3f4dd4a05e862becc6c" + integrity sha512-ZUcgUH12LN/F6nzN0cYd0F/rJaMLmXr0EHVTyYfaYmK55bdwE4338uue4UiVoRqHVqNW4KDUrJc49iGogHKeWA== dependencies: - "@opentelemetry/core" "1.7.0" - "@opentelemetry/semantic-conventions" "1.7.0" + "@nevware21/ts-utils" ">= 0.10.0 < 2.x" + +"@nevware21/ts-utils@>= 0.10.0 < 2.x", "@nevware21/ts-utils@>= 0.9.4 < 2.x", "@nevware21/ts-utils@>= 0.9.5 < 2.x": + version "0.10.1" + resolved "https://registry.yarnpkg.com/@nevware21/ts-utils/-/ts-utils-0.10.1.tgz#aa65abc71eba06749a396598f22263d26f796ac7" + integrity sha512-pMny25NnF2/MJwdqC3Iyjm2pGIXNxni4AROpcqDeWa+td9JMUY4bUS9uU9XW+BoBRqTLUL+WURF9SOd/6OQzRg== -"@opentelemetry/sdk-trace-base@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.7.0.tgz#b498424e0c6340a9d80de63fd408c5c2130a60a5" - integrity sha512-Iz84C+FVOskmauh9FNnj4+VrA+hG5o+tkMzXuoesvSfunVSioXib0syVFeNXwOm4+M5GdWCuW632LVjqEXStIg== +"@opentelemetry/api@^1.4.1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.4.1.tgz#ff22eb2e5d476fbc2450a196e40dd243cc20c28f" + integrity sha512-O2yRJce1GOc6PAy3QxFM4NzFiWzvScDC1/5ihYBL6BUEVdq0XMWN01sppE+H6bBXbaFYipjwFLEWLg5PaSOThA== + +"@opentelemetry/core@1.15.2", "@opentelemetry/core@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.15.2.tgz#5b170bf223a2333884bbc2d29d95812cdbda7c9f" + integrity sha512-+gBv15ta96WqkHZaPpcDHiaz0utiiHZVfm2YOYSqFGrUaJpPkMoSuLBB58YFQGi6Rsb9EHos84X6X5+9JspmLw== dependencies: - "@opentelemetry/core" "1.7.0" - "@opentelemetry/resources" "1.7.0" - "@opentelemetry/semantic-conventions" "1.7.0" + "@opentelemetry/semantic-conventions" "1.15.2" -"@opentelemetry/semantic-conventions@1.7.0", "@opentelemetry/semantic-conventions@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.7.0.tgz#af80a1ef7cf110ea3a68242acd95648991bcd763" - integrity sha512-FGBx/Qd09lMaqQcogCHyYrFEpTx4cAjeS+48lMIR12z7LdH+zofGDVQSubN59nL6IpubfKqTeIDu9rNO28iHVA== +"@opentelemetry/instrumentation@^0.41.2": + version "0.41.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.41.2.tgz#cae11fa64485dcf03dae331f35b315b64bc6189f" + integrity sha512-rxU72E0pKNH6ae2w5+xgVYZLzc5mlxAbGzF4shxMVK8YC2QQsfN38B2GPbj0jvrKWWNUElfclQ+YTykkNg/grw== + dependencies: + "@types/shimmer" "^1.0.2" + import-in-the-middle "1.4.2" + require-in-the-middle "^7.1.1" + semver "^7.5.1" + shimmer "^1.2.1" + +"@opentelemetry/resources@1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.15.2.tgz#0c9e26cb65652a1402834a3c030cce6028d6dd9d" + integrity sha512-xmMRLenT9CXmm5HMbzpZ1hWhaUowQf8UB4jMjFlAxx1QzQcsD3KFNAVX/CAWzFPtllTyTplrA4JrQ7sCH3qmYw== + dependencies: + "@opentelemetry/core" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" + +"@opentelemetry/sdk-trace-base@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.15.2.tgz#4821f94033c55a6c8bbd35ae387b715b6108517a" + integrity sha512-BEaxGZbWtvnSPchV98qqqqa96AOcb41pjgvhfzDij10tkBhIu9m0Jd6tZ1tJB5ZHfHbTffqYVYE0AOGobec/EQ== + dependencies: + "@opentelemetry/core" "1.15.2" + "@opentelemetry/resources" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" + +"@opentelemetry/semantic-conventions@1.15.2", "@opentelemetry/semantic-conventions@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.15.2.tgz#3bafb5de3e20e841dff6cb3c66f4d6e9694c4241" + integrity sha512-CjbOKwk2s+3xPIMcd5UNYQzsf+v94RczbdNix9/kQh38WiQkM90sUOi3if8eyHFgiBjBjhwXrA7W3ydiSQP9mw== "@tootallnate/once@2": version "2.0.0" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== -"@types/dompurify@^2.3.1": - version "2.3.1" - resolved "https://registry.yarnpkg.com/@types/dompurify/-/dompurify-2.3.1.tgz#2934adcd31c4e6b02676f9c22f9756e5091c04dd" - integrity sha512-YJth9qa0V/E6/XPH1Jq4BC8uCMmO8V1fKWn8PCvuZcAhMn7q0ez9LW6naQT04UZzjFfAPhyRMZmI2a2rbMlEFA== +"@types/dompurify@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/dompurify/-/dompurify-3.0.2.tgz#c1cd33a475bc49c43c2a7900e41028e2136a4553" + integrity sha512-YBL4ziFebbbfQfH5mlC+QTJsvh0oJUrWbmxKMyEdL7emlHJqGR2Qb34TEFKj+VCayBvjKy3xczMFNhugThUsfQ== dependencies: "@types/trusted-types" "*" @@ -207,6 +301,11 @@ resolved "https://registry.yarnpkg.com/@types/picomatch/-/picomatch-2.3.0.tgz#75db5e75a713c5a83d5b76780c3da84a82806003" integrity sha512-O397rnSS9iQI4OirieAtsDqvCj4+3eY1J+EPdNTKuHuRWIfUoGyzX294o8C4KJYaLqgSrd2o60c5EqCU8Zv02g== +"@types/shimmer@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/shimmer/-/shimmer-1.0.2.tgz#93eb2c243c351f3f17d5c580c7467ae5d686b65f" + integrity sha512-dKkr1bTxbEsFlh2ARpKzcaAmsYixqt9UyCdoEZk8rHyE4iQYcDCyvSjDSf7JUWJHlJiTtbIoQjxKh6ViywqDAg== + "@types/trusted-types@*": version "2.0.2" resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.2.tgz#fc25ad9943bcac11cceb8168db4f275e0e72e756" @@ -222,21 +321,31 @@ resolved "https://registry.yarnpkg.com/@types/vscode-webview/-/vscode-webview-1.57.0.tgz#bad5194d45ae8d03afc1c0f67f71ff5e7a243bbf" integrity sha512-x3Cb/SMa1IwRHfSvKaZDZOTh4cNoG505c3NjTqGlMC082m++x/ETUmtYniDsw6SSmYzZXO8KBNhYxR0+VqymqA== -"@vscode/extension-telemetry@0.7.5": - version "0.7.5" - resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.7.5.tgz#bf965731816e08c3f146f96d901ec67954fc913b" - integrity sha512-fJ5y3TcpqqkFYHneabYaoB4XAhDdVflVm+TDKshw9VOs77jkgNS4UA7LNXrWeO0eDne3Sh3JgURf+xzc1rk69w== +"@vscode/extension-telemetry@^0.8.4": + version "0.8.4" + resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.8.4.tgz#c078c6f55df1c9e0592de3b4ce0f685dd345bfe7" + integrity sha512-UqM9+KZDDK3MyoHTsg6XNM+XO6pweQxzCpqJz33BoBEYAGsbBviRYcVpJglgay2oReuDD2pOI1Nio3BKNDLhWA== 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" + "@microsoft/1ds-core-js" "^3.2.13" + "@microsoft/1ds-post-js" "^3.2.13" + "@microsoft/applicationinsights-web-basic" "^3.0.2" + applicationinsights "^2.7.1" "@vscode/l10n@^0.0.10": version "0.0.10" resolved "https://registry.yarnpkg.com/@vscode/l10n/-/l10n-0.0.10.tgz#9c513107c690c0dd16e3ec61e453743de15ebdb0" integrity sha512-E1OCmDcDWa0Ya7vtSjp/XfHFGqYJfh+YPC1RkATU71fTac+j1JjCcB3qwSzmlKAighx2WxhLlfhS0RwAN++PFQ== +acorn-import-assertions@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" + integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== + +acorn@^8.8.2: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== + agent-base@6: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" @@ -244,22 +353,24 @@ agent-base@6: dependencies: debug "4" -applicationinsights@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.4.1.tgz#4de4c4dd3c7c4a44445cfbf3d15808fc0dcc423d" - integrity sha512-0n0Ikd0gzSm460xm+M0UTWIwXrhrH/0bqfZatcJjYObWyefxfAxapGEyNnSGd1Tg90neHz+Yhf+Ff/zgvPiQYA== +applicationinsights@^2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.7.3.tgz#8781454d29c0b14c9773f2e892b4cf5e7468ffa5" + integrity sha512-JY8+kTEkjbA+kAVNWDtpfW2lqsrDALfDXuxOs74KLPu2y13fy/9WB52V4LfYVTVcW1/jYOXjTxNS2gPZIDh1iw== dependencies: - "@azure/core-auth" "^1.4.0" - "@azure/core-rest-pipeline" "^1.10.0" + "@azure/core-auth" "^1.5.0" + "@azure/core-rest-pipeline" "1.10.1" + "@azure/core-util" "1.2.0" + "@azure/opentelemetry-instrumentation-azure-sdk" "^1.0.0-beta.5" "@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" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/sdk-trace-base" "^1.15.2" + "@opentelemetry/semantic-conventions" "^1.15.2" cls-hooked "^4.2.2" continuation-local-storage "^3.2.1" - diagnostic-channel "1.1.0" - diagnostic-channel-publishers "1.0.5" + diagnostic-channel "1.1.1" + diagnostic-channel-publishers "1.0.7" argparse@^2.0.1: version "2.0.1" @@ -299,6 +410,11 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +cjs-module-lexer@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" + integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== + cls-hooked@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/cls-hooked/-/cls-hooked-4.2.2.tgz#ad2e9a4092680cdaffeb2d3551da0e225eae1908" @@ -328,7 +444,7 @@ continuation-local-storage@^3.2.1: async-listener "^0.6.0" emitter-listener "^1.1.1" -debug@4: +debug@4, debug@^4.1.1: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -340,22 +456,22 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -diagnostic-channel-publishers@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.5.tgz#df8c317086c50f5727fdfb5d2fce214d2e4130ae" - integrity sha512-dJwUS0915pkjjimPJVDnS/QQHsH0aOYhnZsLJdnZIMOrB+csj8RnZhWTuwnm8R5v3Z7OZs+ksv5luC14DGB7eg== +diagnostic-channel-publishers@1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.7.tgz#9b7f8d5ee1295481aee19c827d917e96fedf2c4a" + integrity sha512-SEECbY5AiVt6DfLkhkaHNeshg1CogdLLANA8xlG/TKvS+XUgvIKl7VspJGYiEdL5OUyzMVnr7o0AwB7f+/Mjtg== -diagnostic-channel@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.0.tgz#6985e9dfedfbc072d91dc4388477e4087147756e" - integrity sha512-fwujyMe1gj6rk6dYi9hMZm0c8Mz8NDMVl2LB4iaYh3+LIAThZC8RKFGXWG0IML2OxAit/ZFRgZhMkhQ3d/bobQ== +diagnostic-channel@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.1.tgz#44b60972de9ee055c16216535b0e9db3f6a0efd0" + integrity sha512-r2HV5qFkUICyoaKlBEpLKHjxMXATUf/l+h8UZPGBHGLy4DDiY2sOLcIctax4eRnTw5wH2jTMExLntGPJ8eOJxw== dependencies: - semver "^5.3.0" + semver "^7.5.3" -dompurify@^2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.4.1.tgz#f9cb1a275fde9af6f2d0a2644ef648dd6847b631" - integrity sha512-ewwFzHzrrneRjxzmK6oVz/rZn9VWspGFRDb4/rRtIsM1n36t9AKma/ye8syCpcw+XJ25kOK/hOG7t1j2I2yBqA== +dompurify@^3.0.5: + version "3.0.5" + resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.0.5.tgz#eb3d9cfa10037b6e73f32c586682c4b2ab01fbed" + integrity sha512-F9e6wPGtY+8KNMRAVfxeCOHU0/NPWMSENNq4pQctuXRqqdEPW7q3CrLbR5Nse044WwacyjHGOMlvNsBe1y6z9A== emitter-listener@^1.0.1, emitter-listener@^1.1.1: version "1.1.2" @@ -378,6 +494,18 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + highlight.js@^11.8.0: version "11.8.0" resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.8.0.tgz#966518ea83257bae2e7c9a48596231856555bb65" @@ -400,6 +528,23 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" +import-in-the-middle@1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/import-in-the-middle/-/import-in-the-middle-1.4.2.tgz#2a266676e3495e72c04bbaa5ec14756ba168391b" + integrity sha512-9WOz1Yh/cvO/p69sxRmhyQwrIGGSp7EIdcb+fFNVi7CzQGQB8U1/1XrKVSbEd/GNOAeM0peJtmi7+qphe7NvAw== + dependencies: + acorn "^8.8.2" + acorn-import-assertions "^1.9.0" + cjs-module-lexer "^1.2.2" + module-details-from-path "^1.0.3" + +is-core-module@^2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" + integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== + dependencies: + has "^1.0.3" + linkify-it@^3.0.1: version "3.0.3" resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-3.0.3.tgz#a98baf44ce45a550efb4d49c769d07524cc2fa2e" @@ -459,6 +604,11 @@ minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" +module-details-from-path@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/module-details-from-path/-/module-details-from-path-1.0.3.tgz#114c949673e2a8a35e9d35788527aa37b679da2b" + integrity sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A== + morphdom@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/morphdom/-/morphdom-2.6.1.tgz#e868e24f989fa3183004b159aed643e628b4306e" @@ -469,24 +619,47 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== +require-in-the-middle@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/require-in-the-middle/-/require-in-the-middle-7.2.0.tgz#b539de8f00955444dc8aed95e17c69b0a4f10fcf" + integrity sha512-3TLx5TGyAY6AOqLBoXmHkNql0HIf2RGbuMgCDT2WO/uGVAPJs6h7Kl+bN6TIZGd9bWhWPwnDnTHGtW8Iu77sdw== + dependencies: + debug "^4.1.1" + module-details-from-path "^1.0.3" + resolve "^1.22.1" + +resolve@^1.22.1: + version "1.22.4" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.4.tgz#1dc40df46554cdaf8948a486a10f6ba1e2026c34" + integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + semver@^5.3.0, semver@^5.4.1: version "5.7.2" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -semver@^7.3.5: +semver@^7.3.5, semver@^7.5.1, semver@^7.5.3: version "7.5.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== dependencies: lru-cache "^6.0.0" -shimmer@^1.1.0, shimmer@^1.2.0: +shimmer@^1.1.0, shimmer@^1.2.0, shimmer@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337" integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw== @@ -496,6 +669,11 @@ stack-chain@^1.3.7: resolved "https://registry.yarnpkg.com/stack-chain/-/stack-chain-1.3.7.tgz#d192c9ff4ea6a22c94c4dd459171e3f00cea1285" integrity sha512-D8cWtWVdIe/jBA7v5p5Hwl5yOSOrmZPWDPe2KxQ5UAGD+nxbxU0lKXA4h85Ta6+qgdKVL3vUxsbIZjc1kBG7ug== +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + tslib@^2.2.0: version "2.4.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e" diff --git a/extensions/media-preview/README.md b/extensions/media-preview/README.md index 48428a684bfc6..8163e01714331 100644 --- a/extensions/media-preview/README.md +++ b/extensions/media-preview/README.md @@ -16,7 +16,6 @@ This extension provides basic preview for images, audio and video files. - `.webp` - `.avif` - ### Supported audio formats - `.mp3` diff --git a/extensions/media-preview/package.json b/extensions/media-preview/package.json index 3107d9d60bf17..6c1b46220b9cf 100644 --- a/extensions/media-preview/package.json +++ b/extensions/media-preview/package.json @@ -126,7 +126,7 @@ "watch-web": "npx webpack-cli --config extension-browser.webpack.config --mode none --watch --info-verbosity verbose" }, "dependencies": { - "@vscode/extension-telemetry": "0.7.5", + "@vscode/extension-telemetry": "^0.8.4", "vscode-uri": "^3.0.6" }, "repository": { diff --git a/extensions/media-preview/yarn.lock b/extensions/media-preview/yarn.lock index 971c4c2c50acf..36b652d7d7b88 100644 --- a/extensions/media-preview/yarn.lock +++ b/extensions/media-preview/yarn.lock @@ -17,7 +17,16 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" -"@azure/core-rest-pipeline@^1.10.0": +"@azure/core-auth@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.5.0.tgz#a41848c5c31cb3b7c84c409885267d55a2c92e44" + integrity sha512-udzoBuYG1VBoHVohDTrvKjyzel34zt77Bhp7dQntVGGD0ehVq48owENbBG8fIgkHRNUBQH5k1r0hpoMu5L8+kw== + dependencies: + "@azure/abort-controller" "^1.0.0" + "@azure/core-util" "^1.1.0" + tslib "^2.2.0" + +"@azure/core-rest-pipeline@1.10.1": version "1.10.1" resolved "https://registry.yarnpkg.com/@azure/core-rest-pipeline/-/core-rest-pipeline-1.10.1.tgz#348290847ca31b9eecf9cf5de7519aaccdd30968" integrity sha512-Kji9k6TOFRDB5ZMTw8qUf2IJ+CeJtsuMdAHox9eqpTf1cefiNMpzrfnF6sINEBZJsaVaWgQ0o48B6kcUH68niA== @@ -33,13 +42,21 @@ tslib "^2.2.0" uuid "^8.3.0" -"@azure/core-tracing@^1.0.1": +"@azure/core-tracing@^1.0.0", "@azure/core-tracing@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.0.1.tgz#352a38cbea438c4a83c86b314f48017d70ba9503" integrity sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw== dependencies: tslib "^2.2.0" +"@azure/core-util@1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.2.0.tgz#3499deba1fc36dda6f1912b791809b6f15d4a392" + integrity sha512-ffGIw+Qs8bNKNLxz5UPkz4/VBM/EZY07mPve1ZYFqYUdPwFqRj0RPk0U7LZMOfT7GCck9YjuT1Rfp1PApNl1ng== + dependencies: + "@azure/abort-controller" "^1.0.0" + tslib "^2.2.0" + "@azure/core-util@^1.0.0": version "1.1.1" resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.1.1.tgz#8f87b3dd468795df0f0849d9f096c3e7b29452c1" @@ -48,6 +65,14 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" +"@azure/core-util@^1.1.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.4.0.tgz#c120a56b3e48a9e4d20619a0b00268ae9de891c7" + integrity sha512-eGAyJpm3skVQoLiRqm/xPa+SXi/NPDdSHMxbRAz2lSprd+Zs+qrpQGQQ2VQ3Nttu+nSZR4XoYQC71LbEI7jsig== + dependencies: + "@azure/abort-controller" "^1.0.0" + tslib "^2.2.0" + "@azure/logger@^1.0.0": version "1.0.3" resolved "https://registry.yarnpkg.com/@azure/logger/-/logger-1.0.3.tgz#6e36704aa51be7d4a1bae24731ea580836293c96" @@ -55,66 +80,100 @@ dependencies: tslib "^2.2.0" -"@microsoft/1ds-core-js@3.2.8", "@microsoft/1ds-core-js@^3.2.8": - version "3.2.8" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.8.tgz#1b6b7d9bb858238c818ccf4e4b58ece7aeae5760" - integrity sha512-9o9SUAamJiTXIYwpkQDuueYt83uZfXp8zp8YFix1IwVPwC9RmE36T2CX9gXOeq1nDckOuOduYpA8qHvdh5BGfQ== +"@azure/opentelemetry-instrumentation-azure-sdk@^1.0.0-beta.5": + version "1.0.0-beta.5" + resolved "https://registry.yarnpkg.com/@azure/opentelemetry-instrumentation-azure-sdk/-/opentelemetry-instrumentation-azure-sdk-1.0.0-beta.5.tgz#78809e6c005d08450701e5d37f087f6fce2f86eb" + integrity sha512-fsUarKQDvjhmBO4nIfaZkfNSApm1hZBzcvpNbSrXdcUBxu7lRvKsV5DnwszX7cnhLyVOW9yl1uigtRQ1yDANjA== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "^2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@azure/core-tracing" "^1.0.0" + "@azure/logger" "^1.0.0" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/instrumentation" "^0.41.2" + tslib "^2.2.0" -"@microsoft/1ds-post-js@^3.2.8": - version "3.2.8" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.8.tgz#46793842cca161bf7a2a5b6053c349f429e55110" - integrity sha512-SjlRoNcXcXBH6WQD/5SkkaCHIVqldH3gDu+bI7YagrOVJ5APxwT1Duw9gm3L1FjFa9S2i81fvJ3EVSKpp9wULA== +"@microsoft/1ds-core-js@3.2.13", "@microsoft/1ds-core-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.13.tgz#0c105ed75091bae3f1555c0334704fa9911c58fb" + integrity sha512-CluYTRWcEk0ObG5EWFNWhs87e2qchJUn0p2D21ZUa3PWojPZfPSBs4//WIE0MYV8Qg1Hdif2ZTwlM7TbYUjfAg== dependencies: - "@microsoft/1ds-core-js" "3.2.8" + "@microsoft/applicationinsights-core-js" "2.8.15" "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@microsoft/applicationinsights-channel-js@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.8.9.tgz#840656f3c716de8b3eb0a98c122aa1b92bb8ebfb" - integrity sha512-fMBsAEB7pWtPn43y72q9Xy5E5y55r6gMuDQqRRccccVoQDPXyS57VCj5IdATblctru0C6A8XpL2vRyNmEsu0Vg== +"@microsoft/1ds-post-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.13.tgz#560aacac8a92fdbb79e8c2ebcb293d56e19f51aa" + integrity sha512-HgS574fdD19Bo2vPguyznL4eDw7Pcm1cVNpvbvBLWiW3x4e1FCQ3VMXChWnAxCae8Hb0XqlA2sz332ZobBavTA== dependencies: - "@microsoft/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" + "@microsoft/1ds-core-js" "3.2.13" + "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@microsoft/applicationinsights-common@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-2.8.9.tgz#a75e4a3143a7fd797687830c0ddd2069fd900827" - integrity sha512-mObn1moElyxZaGIRF/IU3cOaeKMgxghXnYEoHNUCA2e+rNwBIgxjyKkblFIpmGuHf4X7Oz3o3yBWpaC6AoMpig== +"@microsoft/applicationinsights-channel-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-3.0.2.tgz#be49fbf74831c7b8c97950027c5052ea99d2a8a5" + integrity sha512-jDBNKbCHsJgmpv0CKNhJ/uN9ZphvfGdb93Svk+R4LjO8L3apNNMbDDPxBvXXi0uigRmA1TBcmyBG4IRKjabGhw== + dependencies: + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" + +"@microsoft/applicationinsights-common@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-3.0.2.tgz#37670bb07f4858ed41ff9759119e0759007d6e05" + integrity sha512-y+WXWop+OVim954Cu1uyYMnNx6PWO8okHpZIQi/1YSqtqaYdtJVPv4P0AVzwJdohxzVfgzKvqj9nec/VWqE2Zg== + dependencies: + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" + +"@microsoft/applicationinsights-core-js@2.8.15": + version "2.8.15" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.15.tgz#8fa466474260e01967fe649f14dd9e5ff91dcdc8" + integrity sha512-yYAs9MyjGr2YijQdUSN9mVgT1ijI1FPMgcffpaPmYbHAVbQmF7bXudrBWHxmLzJlwl5rfep+Zgjli2e67lwUqQ== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.9" "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/dynamicproto-js" "^1.1.9" -"@microsoft/applicationinsights-core-js@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.9.tgz#0e5d207acfae6986a6fc97249eeb6117e523bf1b" - integrity sha512-HRuIuZ6aOWezcg/G5VyFDDWGL8hDNe/ljPP01J7ImH2kRPEgbtcfPSUMjkamGMefgdq81GZsSoC/NNGTP4pp2w== +"@microsoft/applicationinsights-core-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-3.0.2.tgz#108e20df8c162bec92b1f66f9de2530a25d9f51a" + integrity sha512-WQhVhzlRlLDrQzn3OShCW/pL3BW5WC57t0oywSknX3q7lMzI3jDg7Ihh0iuIcNTzGCTbDkuqr4d6IjEDWIMtJQ== dependencies: - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-shims@2.0.2", "@microsoft/applicationinsights-shims@^2.0.2": version "2.0.2" resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.2.tgz#92b36a09375e2d9cb2b4203383b05772be837085" integrity sha512-PoHEgsnmcqruLNHZ/amACqdJ6YYQpED0KSRe6J7gIJTtpZC1FfFU9b1fmDKDKtFoUSrPzEh1qzO3kmRZP0betg== -"@microsoft/applicationinsights-web-basic@^2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-2.8.9.tgz#eed2f3d1e19069962ed2155915c1656e6936e1d5" - integrity sha512-CH0J8JFOy7MjK8JO4pXXU+EML+Ilix+94PMZTX5EJlBU1in+mrik74/8qSg3UC4ekPi12KwrXaHCQSVC3WseXQ== +"@microsoft/applicationinsights-shims@3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-3.0.1.tgz#3865b73ace8405b9c4618cc5c571f2fe3876f06f" + integrity sha512-DKwboF47H1nb33rSUfjqI6ryX29v+2QWcTrRvcQDA32AZr5Ilkr7whOOSsD1aBzwqX0RJEIP1Z81jfE3NBm/Lg== dependencies: - "@microsoft/applicationinsights-channel-js" "2.8.9" - "@microsoft/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" + +"@microsoft/applicationinsights-web-basic@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-3.0.2.tgz#f777a4d24b79dde3ae396d3b819e1fce06b7240a" + integrity sha512-6Lq0DE/pZp9RvSV+weGbcxN1NDmfczj6gNPhvZKV2YSQ3RK0LZE3+wjTWLXfuStq8a+nCBdsRpWk8tOKgsoxcg== + dependencies: + "@microsoft/applicationinsights-channel-js" "3.0.2" + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-web-snippet@^1.0.1": version "1.0.1" @@ -126,54 +185,104 @@ resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.7.tgz#ede48dd3f85af14ee369c805e5ed5b84222b9fe2" integrity sha512-SK3D3aVt+5vOOccKPnGaJWB5gQ8FuKfjboUJHedMP7gu54HqSCXX5iFXhktGD8nfJb0Go30eDvs/UDoTnR2kOA== -"@opentelemetry/api@^1.0.4": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.2.0.tgz#89ef99401cde6208cff98760b67663726ef26686" - integrity sha512-0nBr+VZNKm9tvNDZFstI3Pq1fCTEDK5OZTnVKNvBNAKgd0yIvmwsP4m61rEv7ZP+tOUjWJhROpxK5MsnlF911g== +"@microsoft/dynamicproto-js@^1.1.9": + version "1.1.9" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.9.tgz#7437db7aa061162ee94e4131b69a62b8dad5dea6" + integrity sha512-n1VPsljTSkthsAFYdiWfC+DKzK2WwcRp83Y1YAqdX552BstvsDjft9YXppjUzp11BPsapDoO1LDgrDB0XVsfNQ== + +"@microsoft/dynamicproto-js@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-2.0.2.tgz#e57fbec2e7067d48b7e8e1e1c1d354028ef718a6" + integrity sha512-MB8trWaFREpmb037k/d0bB7T2BP7Ai24w1e1tbz3ASLB0/lwphsq3Nq8S9I5AsI5vs4zAQT+SB5nC5/dLYTiOg== + dependencies: + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" -"@opentelemetry/core@1.7.0", "@opentelemetry/core@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.7.0.tgz#83bdd1b7a4ceafcdffd6590420657caec5f7b34c" - integrity sha512-AVqAi5uc8DrKJBimCTFUT4iFI+5eXpo4sYmGbQ0CypG0piOTHE2g9c5aSoTGYXu3CzOmJZf7pT6Xh+nwm5d6yQ== +"@nevware21/ts-async@>= 0.2.4 < 2.x": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@nevware21/ts-async/-/ts-async-0.3.0.tgz#a8b97ba01065fc930de9a3f4dd4a05e862becc6c" + integrity sha512-ZUcgUH12LN/F6nzN0cYd0F/rJaMLmXr0EHVTyYfaYmK55bdwE4338uue4UiVoRqHVqNW4KDUrJc49iGogHKeWA== dependencies: - "@opentelemetry/semantic-conventions" "1.7.0" + "@nevware21/ts-utils" ">= 0.10.0 < 2.x" + +"@nevware21/ts-utils@>= 0.10.0 < 2.x", "@nevware21/ts-utils@>= 0.9.4 < 2.x", "@nevware21/ts-utils@>= 0.9.5 < 2.x": + version "0.10.1" + resolved "https://registry.yarnpkg.com/@nevware21/ts-utils/-/ts-utils-0.10.1.tgz#aa65abc71eba06749a396598f22263d26f796ac7" + integrity sha512-pMny25NnF2/MJwdqC3Iyjm2pGIXNxni4AROpcqDeWa+td9JMUY4bUS9uU9XW+BoBRqTLUL+WURF9SOd/6OQzRg== + +"@opentelemetry/api@^1.4.1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.4.1.tgz#ff22eb2e5d476fbc2450a196e40dd243cc20c28f" + integrity sha512-O2yRJce1GOc6PAy3QxFM4NzFiWzvScDC1/5ihYBL6BUEVdq0XMWN01sppE+H6bBXbaFYipjwFLEWLg5PaSOThA== + +"@opentelemetry/core@1.15.2", "@opentelemetry/core@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.15.2.tgz#5b170bf223a2333884bbc2d29d95812cdbda7c9f" + integrity sha512-+gBv15ta96WqkHZaPpcDHiaz0utiiHZVfm2YOYSqFGrUaJpPkMoSuLBB58YFQGi6Rsb9EHos84X6X5+9JspmLw== + dependencies: + "@opentelemetry/semantic-conventions" "1.15.2" -"@opentelemetry/resources@1.7.0": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.7.0.tgz#90ccd3a6a86b4dfba4e833e73944bd64958d78c5" - integrity sha512-u1M0yZotkjyKx8dj+46Sg5thwtOTBmtRieNXqdCRiWUp6SfFiIP0bI+1XK3LhuXqXkBXA1awJZaTqKduNMStRg== +"@opentelemetry/instrumentation@^0.41.2": + version "0.41.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.41.2.tgz#cae11fa64485dcf03dae331f35b315b64bc6189f" + integrity sha512-rxU72E0pKNH6ae2w5+xgVYZLzc5mlxAbGzF4shxMVK8YC2QQsfN38B2GPbj0jvrKWWNUElfclQ+YTykkNg/grw== + dependencies: + "@types/shimmer" "^1.0.2" + import-in-the-middle "1.4.2" + require-in-the-middle "^7.1.1" + semver "^7.5.1" + shimmer "^1.2.1" + +"@opentelemetry/resources@1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.15.2.tgz#0c9e26cb65652a1402834a3c030cce6028d6dd9d" + integrity sha512-xmMRLenT9CXmm5HMbzpZ1hWhaUowQf8UB4jMjFlAxx1QzQcsD3KFNAVX/CAWzFPtllTyTplrA4JrQ7sCH3qmYw== dependencies: - "@opentelemetry/core" "1.7.0" - "@opentelemetry/semantic-conventions" "1.7.0" + "@opentelemetry/core" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" -"@opentelemetry/sdk-trace-base@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.7.0.tgz#b498424e0c6340a9d80de63fd408c5c2130a60a5" - integrity sha512-Iz84C+FVOskmauh9FNnj4+VrA+hG5o+tkMzXuoesvSfunVSioXib0syVFeNXwOm4+M5GdWCuW632LVjqEXStIg== +"@opentelemetry/sdk-trace-base@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.15.2.tgz#4821f94033c55a6c8bbd35ae387b715b6108517a" + integrity sha512-BEaxGZbWtvnSPchV98qqqqa96AOcb41pjgvhfzDij10tkBhIu9m0Jd6tZ1tJB5ZHfHbTffqYVYE0AOGobec/EQ== dependencies: - "@opentelemetry/core" "1.7.0" - "@opentelemetry/resources" "1.7.0" - "@opentelemetry/semantic-conventions" "1.7.0" + "@opentelemetry/core" "1.15.2" + "@opentelemetry/resources" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" -"@opentelemetry/semantic-conventions@1.7.0", "@opentelemetry/semantic-conventions@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.7.0.tgz#af80a1ef7cf110ea3a68242acd95648991bcd763" - integrity sha512-FGBx/Qd09lMaqQcogCHyYrFEpTx4cAjeS+48lMIR12z7LdH+zofGDVQSubN59nL6IpubfKqTeIDu9rNO28iHVA== +"@opentelemetry/semantic-conventions@1.15.2", "@opentelemetry/semantic-conventions@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.15.2.tgz#3bafb5de3e20e841dff6cb3c66f4d6e9694c4241" + integrity sha512-CjbOKwk2s+3xPIMcd5UNYQzsf+v94RczbdNix9/kQh38WiQkM90sUOi3if8eyHFgiBjBjhwXrA7W3ydiSQP9mw== "@tootallnate/once@2": version "2.0.0" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== -"@vscode/extension-telemetry@0.7.5": - version "0.7.5" - resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.7.5.tgz#bf965731816e08c3f146f96d901ec67954fc913b" - integrity sha512-fJ5y3TcpqqkFYHneabYaoB4XAhDdVflVm+TDKshw9VOs77jkgNS4UA7LNXrWeO0eDne3Sh3JgURf+xzc1rk69w== +"@types/shimmer@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/shimmer/-/shimmer-1.0.2.tgz#93eb2c243c351f3f17d5c580c7467ae5d686b65f" + integrity sha512-dKkr1bTxbEsFlh2ARpKzcaAmsYixqt9UyCdoEZk8rHyE4iQYcDCyvSjDSf7JUWJHlJiTtbIoQjxKh6ViywqDAg== + +"@vscode/extension-telemetry@^0.8.4": + version "0.8.4" + resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.8.4.tgz#c078c6f55df1c9e0592de3b4ce0f685dd345bfe7" + integrity sha512-UqM9+KZDDK3MyoHTsg6XNM+XO6pweQxzCpqJz33BoBEYAGsbBviRYcVpJglgay2oReuDD2pOI1Nio3BKNDLhWA== 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" + "@microsoft/1ds-core-js" "^3.2.13" + "@microsoft/1ds-post-js" "^3.2.13" + "@microsoft/applicationinsights-web-basic" "^3.0.2" + applicationinsights "^2.7.1" + +acorn-import-assertions@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" + integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== + +acorn@^8.8.2: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== agent-base@6: version "6.0.2" @@ -182,22 +291,24 @@ agent-base@6: dependencies: debug "4" -applicationinsights@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.4.1.tgz#4de4c4dd3c7c4a44445cfbf3d15808fc0dcc423d" - integrity sha512-0n0Ikd0gzSm460xm+M0UTWIwXrhrH/0bqfZatcJjYObWyefxfAxapGEyNnSGd1Tg90neHz+Yhf+Ff/zgvPiQYA== +applicationinsights@^2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.7.3.tgz#8781454d29c0b14c9773f2e892b4cf5e7468ffa5" + integrity sha512-JY8+kTEkjbA+kAVNWDtpfW2lqsrDALfDXuxOs74KLPu2y13fy/9WB52V4LfYVTVcW1/jYOXjTxNS2gPZIDh1iw== dependencies: - "@azure/core-auth" "^1.4.0" - "@azure/core-rest-pipeline" "^1.10.0" + "@azure/core-auth" "^1.5.0" + "@azure/core-rest-pipeline" "1.10.1" + "@azure/core-util" "1.2.0" + "@azure/opentelemetry-instrumentation-azure-sdk" "^1.0.0-beta.5" "@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" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/sdk-trace-base" "^1.15.2" + "@opentelemetry/semantic-conventions" "^1.15.2" cls-hooked "^4.2.2" continuation-local-storage "^3.2.1" - diagnostic-channel "1.1.0" - diagnostic-channel-publishers "1.0.5" + diagnostic-channel "1.1.1" + diagnostic-channel-publishers "1.0.7" async-hook-jl@^1.7.6: version "1.7.6" @@ -219,6 +330,11 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== +cjs-module-lexer@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" + integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== + cls-hooked@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/cls-hooked/-/cls-hooked-4.2.2.tgz#ad2e9a4092680cdaffeb2d3551da0e225eae1908" @@ -243,7 +359,7 @@ continuation-local-storage@^3.2.1: async-listener "^0.6.0" emitter-listener "^1.1.1" -debug@4: +debug@4, debug@^4.1.1: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -255,17 +371,17 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -diagnostic-channel-publishers@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.5.tgz#df8c317086c50f5727fdfb5d2fce214d2e4130ae" - integrity sha512-dJwUS0915pkjjimPJVDnS/QQHsH0aOYhnZsLJdnZIMOrB+csj8RnZhWTuwnm8R5v3Z7OZs+ksv5luC14DGB7eg== +diagnostic-channel-publishers@1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.7.tgz#9b7f8d5ee1295481aee19c827d917e96fedf2c4a" + integrity sha512-SEECbY5AiVt6DfLkhkaHNeshg1CogdLLANA8xlG/TKvS+XUgvIKl7VspJGYiEdL5OUyzMVnr7o0AwB7f+/Mjtg== -diagnostic-channel@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.0.tgz#6985e9dfedfbc072d91dc4388477e4087147756e" - integrity sha512-fwujyMe1gj6rk6dYi9hMZm0c8Mz8NDMVl2LB4iaYh3+LIAThZC8RKFGXWG0IML2OxAit/ZFRgZhMkhQ3d/bobQ== +diagnostic-channel@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.1.tgz#44b60972de9ee055c16216535b0e9db3f6a0efd0" + integrity sha512-r2HV5qFkUICyoaKlBEpLKHjxMXATUf/l+h8UZPGBHGLy4DDiY2sOLcIctax4eRnTw5wH2jTMExLntGPJ8eOJxw== dependencies: - semver "^5.3.0" + semver "^7.5.3" emitter-listener@^1.0.1, emitter-listener@^1.1.1: version "1.1.2" @@ -283,6 +399,18 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + http-proxy-agent@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" @@ -300,6 +428,30 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" +import-in-the-middle@1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/import-in-the-middle/-/import-in-the-middle-1.4.2.tgz#2a266676e3495e72c04bbaa5ec14756ba168391b" + integrity sha512-9WOz1Yh/cvO/p69sxRmhyQwrIGGSp7EIdcb+fFNVi7CzQGQB8U1/1XrKVSbEd/GNOAeM0peJtmi7+qphe7NvAw== + dependencies: + acorn "^8.8.2" + acorn-import-assertions "^1.9.0" + cjs-module-lexer "^1.2.2" + module-details-from-path "^1.0.3" + +is-core-module@^2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" + integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== + dependencies: + has "^1.0.3" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + mime-db@1.52.0: version "1.52.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" @@ -312,17 +464,52 @@ mime-types@^2.1.12: dependencies: mime-db "1.52.0" +module-details-from-path@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/module-details-from-path/-/module-details-from-path-1.0.3.tgz#114c949673e2a8a35e9d35788527aa37b679da2b" + integrity sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A== + ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +require-in-the-middle@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/require-in-the-middle/-/require-in-the-middle-7.2.0.tgz#b539de8f00955444dc8aed95e17c69b0a4f10fcf" + integrity sha512-3TLx5TGyAY6AOqLBoXmHkNql0HIf2RGbuMgCDT2WO/uGVAPJs6h7Kl+bN6TIZGd9bWhWPwnDnTHGtW8Iu77sdw== + dependencies: + debug "^4.1.1" + module-details-from-path "^1.0.3" + resolve "^1.22.1" + +resolve@^1.22.1: + version "1.22.4" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.4.tgz#1dc40df46554cdaf8948a486a10f6ba1e2026c34" + integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + semver@^5.3.0, semver@^5.4.1: version "5.7.2" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -shimmer@^1.1.0, shimmer@^1.2.0: +semver@^7.5.1, semver@^7.5.3: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +shimmer@^1.1.0, shimmer@^1.2.0, shimmer@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337" integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw== @@ -332,6 +519,11 @@ stack-chain@^1.3.7: resolved "https://registry.yarnpkg.com/stack-chain/-/stack-chain-1.3.7.tgz#d192c9ff4ea6a22c94c4dd459171e3f00cea1285" integrity sha512-D8cWtWVdIe/jBA7v5p5Hwl5yOSOrmZPWDPe2KxQ5UAGD+nxbxU0lKXA4h85Ta6+qgdKVL3vUxsbIZjc1kBG7ug== +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + tslib@^2.2.0: version "2.4.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e" @@ -346,3 +538,8 @@ vscode-uri@^3.0.6: version "3.0.6" resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.0.6.tgz#5e6e2e1a4170543af30151b561a41f71db1d6f91" integrity sha512-fmL7V1eiDBFRRnu+gfRWTzyPpNIHJTc4mWnFkwBUmO9U3KPgJAmTx7oxi2bl/Rh6HLdU7+4C9wlj0k2E4AdKFQ== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== diff --git a/extensions/merge-conflict/package.json b/extensions/merge-conflict/package.json index 3c6c41dab7f5b..751e85c3da254 100644 --- a/extensions/merge-conflict/package.json +++ b/extensions/merge-conflict/package.json @@ -166,10 +166,10 @@ } }, "dependencies": { - "@vscode/extension-telemetry": "0.7.5" + "@vscode/extension-telemetry": "^0.8.4" }, "devDependencies": { - "@types/node": "16.x" + "@types/node": "18.x" }, "repository": { "type": "git", diff --git a/extensions/merge-conflict/yarn.lock b/extensions/merge-conflict/yarn.lock index d07fe97f09948..d214c5e444709 100644 --- a/extensions/merge-conflict/yarn.lock +++ b/extensions/merge-conflict/yarn.lock @@ -17,7 +17,16 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" -"@azure/core-rest-pipeline@^1.10.0": +"@azure/core-auth@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.5.0.tgz#a41848c5c31cb3b7c84c409885267d55a2c92e44" + integrity sha512-udzoBuYG1VBoHVohDTrvKjyzel34zt77Bhp7dQntVGGD0ehVq48owENbBG8fIgkHRNUBQH5k1r0hpoMu5L8+kw== + dependencies: + "@azure/abort-controller" "^1.0.0" + "@azure/core-util" "^1.1.0" + tslib "^2.2.0" + +"@azure/core-rest-pipeline@1.10.1": version "1.10.1" resolved "https://registry.yarnpkg.com/@azure/core-rest-pipeline/-/core-rest-pipeline-1.10.1.tgz#348290847ca31b9eecf9cf5de7519aaccdd30968" integrity sha512-Kji9k6TOFRDB5ZMTw8qUf2IJ+CeJtsuMdAHox9eqpTf1cefiNMpzrfnF6sINEBZJsaVaWgQ0o48B6kcUH68niA== @@ -33,13 +42,21 @@ tslib "^2.2.0" uuid "^8.3.0" -"@azure/core-tracing@^1.0.1": +"@azure/core-tracing@^1.0.0", "@azure/core-tracing@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.0.1.tgz#352a38cbea438c4a83c86b314f48017d70ba9503" integrity sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw== dependencies: tslib "^2.2.0" +"@azure/core-util@1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.2.0.tgz#3499deba1fc36dda6f1912b791809b6f15d4a392" + integrity sha512-ffGIw+Qs8bNKNLxz5UPkz4/VBM/EZY07mPve1ZYFqYUdPwFqRj0RPk0U7LZMOfT7GCck9YjuT1Rfp1PApNl1ng== + dependencies: + "@azure/abort-controller" "^1.0.0" + tslib "^2.2.0" + "@azure/core-util@^1.0.0": version "1.1.1" resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.1.1.tgz#8f87b3dd468795df0f0849d9f096c3e7b29452c1" @@ -48,6 +65,14 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" +"@azure/core-util@^1.1.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.4.0.tgz#c120a56b3e48a9e4d20619a0b00268ae9de891c7" + integrity sha512-eGAyJpm3skVQoLiRqm/xPa+SXi/NPDdSHMxbRAz2lSprd+Zs+qrpQGQQ2VQ3Nttu+nSZR4XoYQC71LbEI7jsig== + dependencies: + "@azure/abort-controller" "^1.0.0" + tslib "^2.2.0" + "@azure/logger@^1.0.0": version "1.0.3" resolved "https://registry.yarnpkg.com/@azure/logger/-/logger-1.0.3.tgz#6e36704aa51be7d4a1bae24731ea580836293c96" @@ -55,66 +80,100 @@ dependencies: tslib "^2.2.0" -"@microsoft/1ds-core-js@3.2.8", "@microsoft/1ds-core-js@^3.2.8": - version "3.2.8" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.8.tgz#1b6b7d9bb858238c818ccf4e4b58ece7aeae5760" - integrity sha512-9o9SUAamJiTXIYwpkQDuueYt83uZfXp8zp8YFix1IwVPwC9RmE36T2CX9gXOeq1nDckOuOduYpA8qHvdh5BGfQ== +"@azure/opentelemetry-instrumentation-azure-sdk@^1.0.0-beta.5": + version "1.0.0-beta.5" + resolved "https://registry.yarnpkg.com/@azure/opentelemetry-instrumentation-azure-sdk/-/opentelemetry-instrumentation-azure-sdk-1.0.0-beta.5.tgz#78809e6c005d08450701e5d37f087f6fce2f86eb" + integrity sha512-fsUarKQDvjhmBO4nIfaZkfNSApm1hZBzcvpNbSrXdcUBxu7lRvKsV5DnwszX7cnhLyVOW9yl1uigtRQ1yDANjA== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "^2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@azure/core-tracing" "^1.0.0" + "@azure/logger" "^1.0.0" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/instrumentation" "^0.41.2" + tslib "^2.2.0" -"@microsoft/1ds-post-js@^3.2.8": - version "3.2.8" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.8.tgz#46793842cca161bf7a2a5b6053c349f429e55110" - integrity sha512-SjlRoNcXcXBH6WQD/5SkkaCHIVqldH3gDu+bI7YagrOVJ5APxwT1Duw9gm3L1FjFa9S2i81fvJ3EVSKpp9wULA== +"@microsoft/1ds-core-js@3.2.13", "@microsoft/1ds-core-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.13.tgz#0c105ed75091bae3f1555c0334704fa9911c58fb" + integrity sha512-CluYTRWcEk0ObG5EWFNWhs87e2qchJUn0p2D21ZUa3PWojPZfPSBs4//WIE0MYV8Qg1Hdif2ZTwlM7TbYUjfAg== dependencies: - "@microsoft/1ds-core-js" "3.2.8" + "@microsoft/applicationinsights-core-js" "2.8.15" "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@microsoft/applicationinsights-channel-js@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.8.9.tgz#840656f3c716de8b3eb0a98c122aa1b92bb8ebfb" - integrity sha512-fMBsAEB7pWtPn43y72q9Xy5E5y55r6gMuDQqRRccccVoQDPXyS57VCj5IdATblctru0C6A8XpL2vRyNmEsu0Vg== +"@microsoft/1ds-post-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.13.tgz#560aacac8a92fdbb79e8c2ebcb293d56e19f51aa" + integrity sha512-HgS574fdD19Bo2vPguyznL4eDw7Pcm1cVNpvbvBLWiW3x4e1FCQ3VMXChWnAxCae8Hb0XqlA2sz332ZobBavTA== dependencies: - "@microsoft/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" + "@microsoft/1ds-core-js" "3.2.13" + "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@microsoft/applicationinsights-common@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-2.8.9.tgz#a75e4a3143a7fd797687830c0ddd2069fd900827" - integrity sha512-mObn1moElyxZaGIRF/IU3cOaeKMgxghXnYEoHNUCA2e+rNwBIgxjyKkblFIpmGuHf4X7Oz3o3yBWpaC6AoMpig== +"@microsoft/applicationinsights-channel-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-3.0.2.tgz#be49fbf74831c7b8c97950027c5052ea99d2a8a5" + integrity sha512-jDBNKbCHsJgmpv0CKNhJ/uN9ZphvfGdb93Svk+R4LjO8L3apNNMbDDPxBvXXi0uigRmA1TBcmyBG4IRKjabGhw== + dependencies: + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" + +"@microsoft/applicationinsights-common@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-3.0.2.tgz#37670bb07f4858ed41ff9759119e0759007d6e05" + integrity sha512-y+WXWop+OVim954Cu1uyYMnNx6PWO8okHpZIQi/1YSqtqaYdtJVPv4P0AVzwJdohxzVfgzKvqj9nec/VWqE2Zg== + dependencies: + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" + +"@microsoft/applicationinsights-core-js@2.8.15": + version "2.8.15" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.15.tgz#8fa466474260e01967fe649f14dd9e5ff91dcdc8" + integrity sha512-yYAs9MyjGr2YijQdUSN9mVgT1ijI1FPMgcffpaPmYbHAVbQmF7bXudrBWHxmLzJlwl5rfep+Zgjli2e67lwUqQ== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.9" "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/dynamicproto-js" "^1.1.9" -"@microsoft/applicationinsights-core-js@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.9.tgz#0e5d207acfae6986a6fc97249eeb6117e523bf1b" - integrity sha512-HRuIuZ6aOWezcg/G5VyFDDWGL8hDNe/ljPP01J7ImH2kRPEgbtcfPSUMjkamGMefgdq81GZsSoC/NNGTP4pp2w== +"@microsoft/applicationinsights-core-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-3.0.2.tgz#108e20df8c162bec92b1f66f9de2530a25d9f51a" + integrity sha512-WQhVhzlRlLDrQzn3OShCW/pL3BW5WC57t0oywSknX3q7lMzI3jDg7Ihh0iuIcNTzGCTbDkuqr4d6IjEDWIMtJQ== dependencies: - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-shims@2.0.2", "@microsoft/applicationinsights-shims@^2.0.2": version "2.0.2" resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.2.tgz#92b36a09375e2d9cb2b4203383b05772be837085" integrity sha512-PoHEgsnmcqruLNHZ/amACqdJ6YYQpED0KSRe6J7gIJTtpZC1FfFU9b1fmDKDKtFoUSrPzEh1qzO3kmRZP0betg== -"@microsoft/applicationinsights-web-basic@^2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-2.8.9.tgz#eed2f3d1e19069962ed2155915c1656e6936e1d5" - integrity sha512-CH0J8JFOy7MjK8JO4pXXU+EML+Ilix+94PMZTX5EJlBU1in+mrik74/8qSg3UC4ekPi12KwrXaHCQSVC3WseXQ== +"@microsoft/applicationinsights-shims@3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-3.0.1.tgz#3865b73ace8405b9c4618cc5c571f2fe3876f06f" + integrity sha512-DKwboF47H1nb33rSUfjqI6ryX29v+2QWcTrRvcQDA32AZr5Ilkr7whOOSsD1aBzwqX0RJEIP1Z81jfE3NBm/Lg== dependencies: - "@microsoft/applicationinsights-channel-js" "2.8.9" - "@microsoft/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" + +"@microsoft/applicationinsights-web-basic@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-3.0.2.tgz#f777a4d24b79dde3ae396d3b819e1fce06b7240a" + integrity sha512-6Lq0DE/pZp9RvSV+weGbcxN1NDmfczj6gNPhvZKV2YSQ3RK0LZE3+wjTWLXfuStq8a+nCBdsRpWk8tOKgsoxcg== + dependencies: + "@microsoft/applicationinsights-channel-js" "3.0.2" + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-web-snippet@^1.0.1": version "1.0.1" @@ -126,59 +185,109 @@ resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.7.tgz#ede48dd3f85af14ee369c805e5ed5b84222b9fe2" integrity sha512-SK3D3aVt+5vOOccKPnGaJWB5gQ8FuKfjboUJHedMP7gu54HqSCXX5iFXhktGD8nfJb0Go30eDvs/UDoTnR2kOA== -"@opentelemetry/api@^1.0.4": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.3.0.tgz#27c6f776ac3c1c616651e506a89f438a0ed6a055" - integrity sha512-YveTnGNsFFixTKJz09Oi4zYkiLT5af3WpZDu4aIUM7xX+2bHAkOJayFTVQd6zB8kkWPpbua4Ha6Ql00grdLlJQ== +"@microsoft/dynamicproto-js@^1.1.9": + version "1.1.9" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.9.tgz#7437db7aa061162ee94e4131b69a62b8dad5dea6" + integrity sha512-n1VPsljTSkthsAFYdiWfC+DKzK2WwcRp83Y1YAqdX552BstvsDjft9YXppjUzp11BPsapDoO1LDgrDB0XVsfNQ== -"@opentelemetry/core@1.8.0", "@opentelemetry/core@^1.0.1": - version "1.8.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.8.0.tgz#cca18594dd48ded6dc0d08c7e789c79af0315934" - integrity sha512-6SDjwBML4Am0AQmy7z1j6HGrWDgeK8awBRUvl1PGw6HayViMk4QpnUXvv4HTHisecgVBy43NE/cstWprm8tIfw== +"@microsoft/dynamicproto-js@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-2.0.2.tgz#e57fbec2e7067d48b7e8e1e1c1d354028ef718a6" + integrity sha512-MB8trWaFREpmb037k/d0bB7T2BP7Ai24w1e1tbz3ASLB0/lwphsq3Nq8S9I5AsI5vs4zAQT+SB5nC5/dLYTiOg== + dependencies: + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" + +"@nevware21/ts-async@>= 0.2.4 < 2.x": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@nevware21/ts-async/-/ts-async-0.3.0.tgz#a8b97ba01065fc930de9a3f4dd4a05e862becc6c" + integrity sha512-ZUcgUH12LN/F6nzN0cYd0F/rJaMLmXr0EHVTyYfaYmK55bdwE4338uue4UiVoRqHVqNW4KDUrJc49iGogHKeWA== + dependencies: + "@nevware21/ts-utils" ">= 0.10.0 < 2.x" + +"@nevware21/ts-utils@>= 0.10.0 < 2.x", "@nevware21/ts-utils@>= 0.9.4 < 2.x", "@nevware21/ts-utils@>= 0.9.5 < 2.x": + version "0.10.1" + resolved "https://registry.yarnpkg.com/@nevware21/ts-utils/-/ts-utils-0.10.1.tgz#aa65abc71eba06749a396598f22263d26f796ac7" + integrity sha512-pMny25NnF2/MJwdqC3Iyjm2pGIXNxni4AROpcqDeWa+td9JMUY4bUS9uU9XW+BoBRqTLUL+WURF9SOd/6OQzRg== + +"@opentelemetry/api@^1.4.1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.4.1.tgz#ff22eb2e5d476fbc2450a196e40dd243cc20c28f" + integrity sha512-O2yRJce1GOc6PAy3QxFM4NzFiWzvScDC1/5ihYBL6BUEVdq0XMWN01sppE+H6bBXbaFYipjwFLEWLg5PaSOThA== + +"@opentelemetry/core@1.15.2", "@opentelemetry/core@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.15.2.tgz#5b170bf223a2333884bbc2d29d95812cdbda7c9f" + integrity sha512-+gBv15ta96WqkHZaPpcDHiaz0utiiHZVfm2YOYSqFGrUaJpPkMoSuLBB58YFQGi6Rsb9EHos84X6X5+9JspmLw== dependencies: - "@opentelemetry/semantic-conventions" "1.8.0" + "@opentelemetry/semantic-conventions" "1.15.2" -"@opentelemetry/resources@1.8.0": - version "1.8.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.8.0.tgz#260be9742cf7bceccc0db928d8ca8d64391acfe3" - integrity sha512-KSyMH6Jvss/PFDy16z5qkCK0ERlpyqixb1xwb73wLMvVq+j7i89lobDjw3JkpCcd1Ws0J6jAI4fw28Zufj2ssg== +"@opentelemetry/instrumentation@^0.41.2": + version "0.41.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.41.2.tgz#cae11fa64485dcf03dae331f35b315b64bc6189f" + integrity sha512-rxU72E0pKNH6ae2w5+xgVYZLzc5mlxAbGzF4shxMVK8YC2QQsfN38B2GPbj0jvrKWWNUElfclQ+YTykkNg/grw== dependencies: - "@opentelemetry/core" "1.8.0" - "@opentelemetry/semantic-conventions" "1.8.0" + "@types/shimmer" "^1.0.2" + import-in-the-middle "1.4.2" + require-in-the-middle "^7.1.1" + semver "^7.5.1" + shimmer "^1.2.1" + +"@opentelemetry/resources@1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.15.2.tgz#0c9e26cb65652a1402834a3c030cce6028d6dd9d" + integrity sha512-xmMRLenT9CXmm5HMbzpZ1hWhaUowQf8UB4jMjFlAxx1QzQcsD3KFNAVX/CAWzFPtllTyTplrA4JrQ7sCH3qmYw== + dependencies: + "@opentelemetry/core" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" -"@opentelemetry/sdk-trace-base@^1.0.1": - version "1.8.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.8.0.tgz#70713aab90978a16dea188c8335209f857be7384" - integrity sha512-iH41m0UTddnCKJzZx3M85vlhKzRcmT48pUeBbnzsGrq4nIay1oWVHKM5nhB5r8qRDGvd/n7f/YLCXClxwM0tvA== +"@opentelemetry/sdk-trace-base@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.15.2.tgz#4821f94033c55a6c8bbd35ae387b715b6108517a" + integrity sha512-BEaxGZbWtvnSPchV98qqqqa96AOcb41pjgvhfzDij10tkBhIu9m0Jd6tZ1tJB5ZHfHbTffqYVYE0AOGobec/EQ== dependencies: - "@opentelemetry/core" "1.8.0" - "@opentelemetry/resources" "1.8.0" - "@opentelemetry/semantic-conventions" "1.8.0" + "@opentelemetry/core" "1.15.2" + "@opentelemetry/resources" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" -"@opentelemetry/semantic-conventions@1.8.0", "@opentelemetry/semantic-conventions@^1.0.1": - version "1.8.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.8.0.tgz#fe2aa90e6df050a11cd57f5c0f47b0641fd2cad3" - integrity sha512-TYh1MRcm4JnvpqtqOwT9WYaBYY4KERHdToxs/suDTLviGRsQkIjS5yYROTYTSJQUnYLOn/TuOh5GoMwfLSU+Ew== +"@opentelemetry/semantic-conventions@1.15.2", "@opentelemetry/semantic-conventions@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.15.2.tgz#3bafb5de3e20e841dff6cb3c66f4d6e9694c4241" + integrity sha512-CjbOKwk2s+3xPIMcd5UNYQzsf+v94RczbdNix9/kQh38WiQkM90sUOi3if8eyHFgiBjBjhwXrA7W3ydiSQP9mw== "@tootallnate/once@2": version "2.0.0" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== -"@types/node@16.x": - version "16.11.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae" - integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w== +"@types/node@18.x": + version "18.15.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" + integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== + +"@types/shimmer@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/shimmer/-/shimmer-1.0.2.tgz#93eb2c243c351f3f17d5c580c7467ae5d686b65f" + integrity sha512-dKkr1bTxbEsFlh2ARpKzcaAmsYixqt9UyCdoEZk8rHyE4iQYcDCyvSjDSf7JUWJHlJiTtbIoQjxKh6ViywqDAg== -"@vscode/extension-telemetry@0.7.5": - version "0.7.5" - resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.7.5.tgz#bf965731816e08c3f146f96d901ec67954fc913b" - integrity sha512-fJ5y3TcpqqkFYHneabYaoB4XAhDdVflVm+TDKshw9VOs77jkgNS4UA7LNXrWeO0eDne3Sh3JgURf+xzc1rk69w== +"@vscode/extension-telemetry@^0.8.4": + version "0.8.4" + resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.8.4.tgz#c078c6f55df1c9e0592de3b4ce0f685dd345bfe7" + integrity sha512-UqM9+KZDDK3MyoHTsg6XNM+XO6pweQxzCpqJz33BoBEYAGsbBviRYcVpJglgay2oReuDD2pOI1Nio3BKNDLhWA== 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" + "@microsoft/1ds-core-js" "^3.2.13" + "@microsoft/1ds-post-js" "^3.2.13" + "@microsoft/applicationinsights-web-basic" "^3.0.2" + applicationinsights "^2.7.1" + +acorn-import-assertions@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" + integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== + +acorn@^8.8.2: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== agent-base@6: version "6.0.2" @@ -187,22 +296,24 @@ agent-base@6: dependencies: debug "4" -applicationinsights@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.4.1.tgz#4de4c4dd3c7c4a44445cfbf3d15808fc0dcc423d" - integrity sha512-0n0Ikd0gzSm460xm+M0UTWIwXrhrH/0bqfZatcJjYObWyefxfAxapGEyNnSGd1Tg90neHz+Yhf+Ff/zgvPiQYA== +applicationinsights@^2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.7.3.tgz#8781454d29c0b14c9773f2e892b4cf5e7468ffa5" + integrity sha512-JY8+kTEkjbA+kAVNWDtpfW2lqsrDALfDXuxOs74KLPu2y13fy/9WB52V4LfYVTVcW1/jYOXjTxNS2gPZIDh1iw== dependencies: - "@azure/core-auth" "^1.4.0" - "@azure/core-rest-pipeline" "^1.10.0" + "@azure/core-auth" "^1.5.0" + "@azure/core-rest-pipeline" "1.10.1" + "@azure/core-util" "1.2.0" + "@azure/opentelemetry-instrumentation-azure-sdk" "^1.0.0-beta.5" "@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" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/sdk-trace-base" "^1.15.2" + "@opentelemetry/semantic-conventions" "^1.15.2" cls-hooked "^4.2.2" continuation-local-storage "^3.2.1" - diagnostic-channel "1.1.0" - diagnostic-channel-publishers "1.0.5" + diagnostic-channel "1.1.1" + diagnostic-channel-publishers "1.0.7" async-hook-jl@^1.7.6: version "1.7.6" @@ -224,6 +335,11 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== +cjs-module-lexer@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" + integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== + cls-hooked@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/cls-hooked/-/cls-hooked-4.2.2.tgz#ad2e9a4092680cdaffeb2d3551da0e225eae1908" @@ -248,7 +364,7 @@ continuation-local-storage@^3.2.1: async-listener "^0.6.0" emitter-listener "^1.1.1" -debug@4: +debug@4, debug@^4.1.1: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -260,17 +376,17 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -diagnostic-channel-publishers@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.5.tgz#df8c317086c50f5727fdfb5d2fce214d2e4130ae" - integrity sha512-dJwUS0915pkjjimPJVDnS/QQHsH0aOYhnZsLJdnZIMOrB+csj8RnZhWTuwnm8R5v3Z7OZs+ksv5luC14DGB7eg== +diagnostic-channel-publishers@1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.7.tgz#9b7f8d5ee1295481aee19c827d917e96fedf2c4a" + integrity sha512-SEECbY5AiVt6DfLkhkaHNeshg1CogdLLANA8xlG/TKvS+XUgvIKl7VspJGYiEdL5OUyzMVnr7o0AwB7f+/Mjtg== -diagnostic-channel@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.0.tgz#6985e9dfedfbc072d91dc4388477e4087147756e" - integrity sha512-fwujyMe1gj6rk6dYi9hMZm0c8Mz8NDMVl2LB4iaYh3+LIAThZC8RKFGXWG0IML2OxAit/ZFRgZhMkhQ3d/bobQ== +diagnostic-channel@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.1.tgz#44b60972de9ee055c16216535b0e9db3f6a0efd0" + integrity sha512-r2HV5qFkUICyoaKlBEpLKHjxMXATUf/l+h8UZPGBHGLy4DDiY2sOLcIctax4eRnTw5wH2jTMExLntGPJ8eOJxw== dependencies: - semver "^5.3.0" + semver "^7.5.3" emitter-listener@^1.0.1, emitter-listener@^1.1.1: version "1.1.2" @@ -288,6 +404,18 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + http-proxy-agent@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" @@ -305,6 +433,30 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" +import-in-the-middle@1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/import-in-the-middle/-/import-in-the-middle-1.4.2.tgz#2a266676e3495e72c04bbaa5ec14756ba168391b" + integrity sha512-9WOz1Yh/cvO/p69sxRmhyQwrIGGSp7EIdcb+fFNVi7CzQGQB8U1/1XrKVSbEd/GNOAeM0peJtmi7+qphe7NvAw== + dependencies: + acorn "^8.8.2" + acorn-import-assertions "^1.9.0" + cjs-module-lexer "^1.2.2" + module-details-from-path "^1.0.3" + +is-core-module@^2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" + integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== + dependencies: + has "^1.0.3" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + mime-db@1.52.0: version "1.52.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" @@ -317,17 +469,52 @@ mime-types@^2.1.12: dependencies: mime-db "1.52.0" +module-details-from-path@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/module-details-from-path/-/module-details-from-path-1.0.3.tgz#114c949673e2a8a35e9d35788527aa37b679da2b" + integrity sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A== + ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +require-in-the-middle@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/require-in-the-middle/-/require-in-the-middle-7.2.0.tgz#b539de8f00955444dc8aed95e17c69b0a4f10fcf" + integrity sha512-3TLx5TGyAY6AOqLBoXmHkNql0HIf2RGbuMgCDT2WO/uGVAPJs6h7Kl+bN6TIZGd9bWhWPwnDnTHGtW8Iu77sdw== + dependencies: + debug "^4.1.1" + module-details-from-path "^1.0.3" + resolve "^1.22.1" + +resolve@^1.22.1: + version "1.22.4" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.4.tgz#1dc40df46554cdaf8948a486a10f6ba1e2026c34" + integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + semver@^5.3.0, semver@^5.4.1: version "5.7.2" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -shimmer@^1.1.0, shimmer@^1.2.0: +semver@^7.5.1, semver@^7.5.3: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +shimmer@^1.1.0, shimmer@^1.2.0, shimmer@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337" integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw== @@ -337,6 +524,11 @@ stack-chain@^1.3.7: resolved "https://registry.yarnpkg.com/stack-chain/-/stack-chain-1.3.7.tgz#d192c9ff4ea6a22c94c4dd459171e3f00cea1285" integrity sha512-D8cWtWVdIe/jBA7v5p5Hwl5yOSOrmZPWDPe2KxQ5UAGD+nxbxU0lKXA4h85Ta6+qgdKVL3vUxsbIZjc1kBG7ug== +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + tslib@^2.2.0: version "2.4.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e" @@ -346,3 +538,8 @@ uuid@^8.3.0: version "8.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== diff --git a/extensions/microsoft-authentication/package.json b/extensions/microsoft-authentication/package.json index ecd2573ebf693..8747c4a1df8f8 100644 --- a/extensions/microsoft-authentication/package.json +++ b/extensions/microsoft-authentication/package.json @@ -109,7 +109,7 @@ "watch-web": "npx webpack-cli --config extension-browser.webpack.config --mode none --watch --info-verbosity verbose" }, "devDependencies": { - "@types/node": "16.x", + "@types/node": "18.x", "@types/node-fetch": "^2.5.7", "@types/randombytes": "^2.0.0", "@types/sha.js": "^2.4.0", @@ -118,7 +118,7 @@ "dependencies": { "node-fetch": "2.6.7", "@azure/ms-rest-azure-env": "^2.0.0", - "@vscode/extension-telemetry": "0.7.5" + "@vscode/extension-telemetry": "^0.8.4" }, "repository": { "type": "git", diff --git a/extensions/microsoft-authentication/src/AADHelper.ts b/extensions/microsoft-authentication/src/AADHelper.ts index 187cbf21a485c..d7e92e104fb9f 100644 --- a/extensions/microsoft-authentication/src/AADHelper.ts +++ b/extensions/microsoft-authentication/src/AADHelper.ts @@ -310,9 +310,7 @@ export class AzureActiveDirectoryService { } try { - const session = await this.createSessionWithLocalServer(scopeData); - this._sessionChangeEmitter.fire({ added: [session], removed: [], changed: [] }); - return session; + return await this.createSessionWithLocalServer(scopeData); } catch (e) { this._logger.error(`Error creating session for scopes: ${scopeData.scopeStr} Error: ${e}`); @@ -354,6 +352,7 @@ export class AzureActiveDirectoryService { } const session = await this.exchangeCodeForSession(codeToExchange, codeVerifier, scopeData); + this._sessionChangeEmitter.fire({ added: [session], removed: [], changed: [] }); return session; } @@ -690,6 +689,7 @@ export class AzureActiveDirectoryService { } const session = await this.exchangeCodeForSession(code, verifier, scopeData); + this._sessionChangeEmitter.fire({ added: [session], removed: [], changed: [] }); resolve(session); } catch (err) { reject(err); @@ -716,6 +716,7 @@ export class AzureActiveDirectoryService { if (code) { inputBox.dispose(); const session = await this.exchangeCodeForSession(code, verifier, scopeData); + this._sessionChangeEmitter.fire({ added: [session], removed: [], changed: [] }); resolve(session); } }); diff --git a/extensions/microsoft-authentication/yarn.lock b/extensions/microsoft-authentication/yarn.lock index cd9ae79d10013..68b4aa00b84ab 100644 --- a/extensions/microsoft-authentication/yarn.lock +++ b/extensions/microsoft-authentication/yarn.lock @@ -17,7 +17,16 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" -"@azure/core-rest-pipeline@^1.10.0": +"@azure/core-auth@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.5.0.tgz#a41848c5c31cb3b7c84c409885267d55a2c92e44" + integrity sha512-udzoBuYG1VBoHVohDTrvKjyzel34zt77Bhp7dQntVGGD0ehVq48owENbBG8fIgkHRNUBQH5k1r0hpoMu5L8+kw== + dependencies: + "@azure/abort-controller" "^1.0.0" + "@azure/core-util" "^1.1.0" + tslib "^2.2.0" + +"@azure/core-rest-pipeline@1.10.1": version "1.10.1" resolved "https://registry.yarnpkg.com/@azure/core-rest-pipeline/-/core-rest-pipeline-1.10.1.tgz#348290847ca31b9eecf9cf5de7519aaccdd30968" integrity sha512-Kji9k6TOFRDB5ZMTw8qUf2IJ+CeJtsuMdAHox9eqpTf1cefiNMpzrfnF6sINEBZJsaVaWgQ0o48B6kcUH68niA== @@ -33,13 +42,21 @@ tslib "^2.2.0" uuid "^8.3.0" -"@azure/core-tracing@^1.0.1": +"@azure/core-tracing@^1.0.0", "@azure/core-tracing@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.0.1.tgz#352a38cbea438c4a83c86b314f48017d70ba9503" integrity sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw== dependencies: tslib "^2.2.0" +"@azure/core-util@1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.2.0.tgz#3499deba1fc36dda6f1912b791809b6f15d4a392" + integrity sha512-ffGIw+Qs8bNKNLxz5UPkz4/VBM/EZY07mPve1ZYFqYUdPwFqRj0RPk0U7LZMOfT7GCck9YjuT1Rfp1PApNl1ng== + dependencies: + "@azure/abort-controller" "^1.0.0" + tslib "^2.2.0" + "@azure/core-util@^1.0.0": version "1.1.1" resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.1.1.tgz#8f87b3dd468795df0f0849d9f096c3e7b29452c1" @@ -48,6 +65,14 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" +"@azure/core-util@^1.1.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.4.0.tgz#c120a56b3e48a9e4d20619a0b00268ae9de891c7" + integrity sha512-eGAyJpm3skVQoLiRqm/xPa+SXi/NPDdSHMxbRAz2lSprd+Zs+qrpQGQQ2VQ3Nttu+nSZR4XoYQC71LbEI7jsig== + dependencies: + "@azure/abort-controller" "^1.0.0" + tslib "^2.2.0" + "@azure/logger@^1.0.0": version "1.0.3" resolved "https://registry.yarnpkg.com/@azure/logger/-/logger-1.0.3.tgz#6e36704aa51be7d4a1bae24731ea580836293c96" @@ -60,66 +85,100 @@ resolved "https://registry.yarnpkg.com/@azure/ms-rest-azure-env/-/ms-rest-azure-env-2.0.0.tgz#45809f89763a480924e21d3c620cd40866771625" integrity sha512-dG76W7ElfLi+fbTjnZVGj+M9e0BIEJmRxU6fHaUQ12bZBe8EJKYb2GV50YWNaP2uJiVQ5+7nXEVj1VN1UQtaEw== -"@microsoft/1ds-core-js@3.2.8", "@microsoft/1ds-core-js@^3.2.8": - version "3.2.8" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.8.tgz#1b6b7d9bb858238c818ccf4e4b58ece7aeae5760" - integrity sha512-9o9SUAamJiTXIYwpkQDuueYt83uZfXp8zp8YFix1IwVPwC9RmE36T2CX9gXOeq1nDckOuOduYpA8qHvdh5BGfQ== +"@azure/opentelemetry-instrumentation-azure-sdk@^1.0.0-beta.5": + version "1.0.0-beta.5" + resolved "https://registry.yarnpkg.com/@azure/opentelemetry-instrumentation-azure-sdk/-/opentelemetry-instrumentation-azure-sdk-1.0.0-beta.5.tgz#78809e6c005d08450701e5d37f087f6fce2f86eb" + integrity sha512-fsUarKQDvjhmBO4nIfaZkfNSApm1hZBzcvpNbSrXdcUBxu7lRvKsV5DnwszX7cnhLyVOW9yl1uigtRQ1yDANjA== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "^2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@azure/core-tracing" "^1.0.0" + "@azure/logger" "^1.0.0" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/instrumentation" "^0.41.2" + tslib "^2.2.0" -"@microsoft/1ds-post-js@^3.2.8": - version "3.2.8" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.8.tgz#46793842cca161bf7a2a5b6053c349f429e55110" - integrity sha512-SjlRoNcXcXBH6WQD/5SkkaCHIVqldH3gDu+bI7YagrOVJ5APxwT1Duw9gm3L1FjFa9S2i81fvJ3EVSKpp9wULA== +"@microsoft/1ds-core-js@3.2.13", "@microsoft/1ds-core-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.13.tgz#0c105ed75091bae3f1555c0334704fa9911c58fb" + integrity sha512-CluYTRWcEk0ObG5EWFNWhs87e2qchJUn0p2D21ZUa3PWojPZfPSBs4//WIE0MYV8Qg1Hdif2ZTwlM7TbYUjfAg== dependencies: - "@microsoft/1ds-core-js" "3.2.8" + "@microsoft/applicationinsights-core-js" "2.8.15" "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@microsoft/applicationinsights-channel-js@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.8.9.tgz#840656f3c716de8b3eb0a98c122aa1b92bb8ebfb" - integrity sha512-fMBsAEB7pWtPn43y72q9Xy5E5y55r6gMuDQqRRccccVoQDPXyS57VCj5IdATblctru0C6A8XpL2vRyNmEsu0Vg== +"@microsoft/1ds-post-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.13.tgz#560aacac8a92fdbb79e8c2ebcb293d56e19f51aa" + integrity sha512-HgS574fdD19Bo2vPguyznL4eDw7Pcm1cVNpvbvBLWiW3x4e1FCQ3VMXChWnAxCae8Hb0XqlA2sz332ZobBavTA== dependencies: - "@microsoft/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" + "@microsoft/1ds-core-js" "3.2.13" + "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@microsoft/applicationinsights-common@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-2.8.9.tgz#a75e4a3143a7fd797687830c0ddd2069fd900827" - integrity sha512-mObn1moElyxZaGIRF/IU3cOaeKMgxghXnYEoHNUCA2e+rNwBIgxjyKkblFIpmGuHf4X7Oz3o3yBWpaC6AoMpig== +"@microsoft/applicationinsights-channel-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-3.0.2.tgz#be49fbf74831c7b8c97950027c5052ea99d2a8a5" + integrity sha512-jDBNKbCHsJgmpv0CKNhJ/uN9ZphvfGdb93Svk+R4LjO8L3apNNMbDDPxBvXXi0uigRmA1TBcmyBG4IRKjabGhw== + dependencies: + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" + +"@microsoft/applicationinsights-common@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-3.0.2.tgz#37670bb07f4858ed41ff9759119e0759007d6e05" + integrity sha512-y+WXWop+OVim954Cu1uyYMnNx6PWO8okHpZIQi/1YSqtqaYdtJVPv4P0AVzwJdohxzVfgzKvqj9nec/VWqE2Zg== + dependencies: + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" + +"@microsoft/applicationinsights-core-js@2.8.15": + version "2.8.15" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.15.tgz#8fa466474260e01967fe649f14dd9e5ff91dcdc8" + integrity sha512-yYAs9MyjGr2YijQdUSN9mVgT1ijI1FPMgcffpaPmYbHAVbQmF7bXudrBWHxmLzJlwl5rfep+Zgjli2e67lwUqQ== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.9" "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/dynamicproto-js" "^1.1.9" -"@microsoft/applicationinsights-core-js@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.9.tgz#0e5d207acfae6986a6fc97249eeb6117e523bf1b" - integrity sha512-HRuIuZ6aOWezcg/G5VyFDDWGL8hDNe/ljPP01J7ImH2kRPEgbtcfPSUMjkamGMefgdq81GZsSoC/NNGTP4pp2w== +"@microsoft/applicationinsights-core-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-3.0.2.tgz#108e20df8c162bec92b1f66f9de2530a25d9f51a" + integrity sha512-WQhVhzlRlLDrQzn3OShCW/pL3BW5WC57t0oywSknX3q7lMzI3jDg7Ihh0iuIcNTzGCTbDkuqr4d6IjEDWIMtJQ== dependencies: - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-shims@2.0.2", "@microsoft/applicationinsights-shims@^2.0.2": version "2.0.2" resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.2.tgz#92b36a09375e2d9cb2b4203383b05772be837085" integrity sha512-PoHEgsnmcqruLNHZ/amACqdJ6YYQpED0KSRe6J7gIJTtpZC1FfFU9b1fmDKDKtFoUSrPzEh1qzO3kmRZP0betg== -"@microsoft/applicationinsights-web-basic@^2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-2.8.9.tgz#eed2f3d1e19069962ed2155915c1656e6936e1d5" - integrity sha512-CH0J8JFOy7MjK8JO4pXXU+EML+Ilix+94PMZTX5EJlBU1in+mrik74/8qSg3UC4ekPi12KwrXaHCQSVC3WseXQ== +"@microsoft/applicationinsights-shims@3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-3.0.1.tgz#3865b73ace8405b9c4618cc5c571f2fe3876f06f" + integrity sha512-DKwboF47H1nb33rSUfjqI6ryX29v+2QWcTrRvcQDA32AZr5Ilkr7whOOSsD1aBzwqX0RJEIP1Z81jfE3NBm/Lg== dependencies: - "@microsoft/applicationinsights-channel-js" "2.8.9" - "@microsoft/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" + +"@microsoft/applicationinsights-web-basic@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-3.0.2.tgz#f777a4d24b79dde3ae396d3b819e1fce06b7240a" + integrity sha512-6Lq0DE/pZp9RvSV+weGbcxN1NDmfczj6gNPhvZKV2YSQ3RK0LZE3+wjTWLXfuStq8a+nCBdsRpWk8tOKgsoxcg== + dependencies: + "@microsoft/applicationinsights-channel-js" "3.0.2" + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-web-snippet@^1.0.1": version "1.0.1" @@ -131,39 +190,74 @@ resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.7.tgz#ede48dd3f85af14ee369c805e5ed5b84222b9fe2" integrity sha512-SK3D3aVt+5vOOccKPnGaJWB5gQ8FuKfjboUJHedMP7gu54HqSCXX5iFXhktGD8nfJb0Go30eDvs/UDoTnR2kOA== -"@opentelemetry/api@^1.0.4": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.2.0.tgz#89ef99401cde6208cff98760b67663726ef26686" - integrity sha512-0nBr+VZNKm9tvNDZFstI3Pq1fCTEDK5OZTnVKNvBNAKgd0yIvmwsP4m61rEv7ZP+tOUjWJhROpxK5MsnlF911g== +"@microsoft/dynamicproto-js@^1.1.9": + version "1.1.9" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.9.tgz#7437db7aa061162ee94e4131b69a62b8dad5dea6" + integrity sha512-n1VPsljTSkthsAFYdiWfC+DKzK2WwcRp83Y1YAqdX552BstvsDjft9YXppjUzp11BPsapDoO1LDgrDB0XVsfNQ== -"@opentelemetry/core@1.7.0", "@opentelemetry/core@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.7.0.tgz#83bdd1b7a4ceafcdffd6590420657caec5f7b34c" - integrity sha512-AVqAi5uc8DrKJBimCTFUT4iFI+5eXpo4sYmGbQ0CypG0piOTHE2g9c5aSoTGYXu3CzOmJZf7pT6Xh+nwm5d6yQ== +"@microsoft/dynamicproto-js@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-2.0.2.tgz#e57fbec2e7067d48b7e8e1e1c1d354028ef718a6" + integrity sha512-MB8trWaFREpmb037k/d0bB7T2BP7Ai24w1e1tbz3ASLB0/lwphsq3Nq8S9I5AsI5vs4zAQT+SB5nC5/dLYTiOg== dependencies: - "@opentelemetry/semantic-conventions" "1.7.0" + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" -"@opentelemetry/resources@1.7.0": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.7.0.tgz#90ccd3a6a86b4dfba4e833e73944bd64958d78c5" - integrity sha512-u1M0yZotkjyKx8dj+46Sg5thwtOTBmtRieNXqdCRiWUp6SfFiIP0bI+1XK3LhuXqXkBXA1awJZaTqKduNMStRg== +"@nevware21/ts-async@>= 0.2.4 < 2.x": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@nevware21/ts-async/-/ts-async-0.3.0.tgz#a8b97ba01065fc930de9a3f4dd4a05e862becc6c" + integrity sha512-ZUcgUH12LN/F6nzN0cYd0F/rJaMLmXr0EHVTyYfaYmK55bdwE4338uue4UiVoRqHVqNW4KDUrJc49iGogHKeWA== dependencies: - "@opentelemetry/core" "1.7.0" - "@opentelemetry/semantic-conventions" "1.7.0" + "@nevware21/ts-utils" ">= 0.10.0 < 2.x" + +"@nevware21/ts-utils@>= 0.10.0 < 2.x", "@nevware21/ts-utils@>= 0.9.4 < 2.x", "@nevware21/ts-utils@>= 0.9.5 < 2.x": + version "0.10.1" + resolved "https://registry.yarnpkg.com/@nevware21/ts-utils/-/ts-utils-0.10.1.tgz#aa65abc71eba06749a396598f22263d26f796ac7" + integrity sha512-pMny25NnF2/MJwdqC3Iyjm2pGIXNxni4AROpcqDeWa+td9JMUY4bUS9uU9XW+BoBRqTLUL+WURF9SOd/6OQzRg== + +"@opentelemetry/api@^1.4.1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.4.1.tgz#ff22eb2e5d476fbc2450a196e40dd243cc20c28f" + integrity sha512-O2yRJce1GOc6PAy3QxFM4NzFiWzvScDC1/5ihYBL6BUEVdq0XMWN01sppE+H6bBXbaFYipjwFLEWLg5PaSOThA== -"@opentelemetry/sdk-trace-base@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.7.0.tgz#b498424e0c6340a9d80de63fd408c5c2130a60a5" - integrity sha512-Iz84C+FVOskmauh9FNnj4+VrA+hG5o+tkMzXuoesvSfunVSioXib0syVFeNXwOm4+M5GdWCuW632LVjqEXStIg== +"@opentelemetry/core@1.15.2", "@opentelemetry/core@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.15.2.tgz#5b170bf223a2333884bbc2d29d95812cdbda7c9f" + integrity sha512-+gBv15ta96WqkHZaPpcDHiaz0utiiHZVfm2YOYSqFGrUaJpPkMoSuLBB58YFQGi6Rsb9EHos84X6X5+9JspmLw== dependencies: - "@opentelemetry/core" "1.7.0" - "@opentelemetry/resources" "1.7.0" - "@opentelemetry/semantic-conventions" "1.7.0" + "@opentelemetry/semantic-conventions" "1.15.2" -"@opentelemetry/semantic-conventions@1.7.0", "@opentelemetry/semantic-conventions@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.7.0.tgz#af80a1ef7cf110ea3a68242acd95648991bcd763" - integrity sha512-FGBx/Qd09lMaqQcogCHyYrFEpTx4cAjeS+48lMIR12z7LdH+zofGDVQSubN59nL6IpubfKqTeIDu9rNO28iHVA== +"@opentelemetry/instrumentation@^0.41.2": + version "0.41.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.41.2.tgz#cae11fa64485dcf03dae331f35b315b64bc6189f" + integrity sha512-rxU72E0pKNH6ae2w5+xgVYZLzc5mlxAbGzF4shxMVK8YC2QQsfN38B2GPbj0jvrKWWNUElfclQ+YTykkNg/grw== + dependencies: + "@types/shimmer" "^1.0.2" + import-in-the-middle "1.4.2" + require-in-the-middle "^7.1.1" + semver "^7.5.1" + shimmer "^1.2.1" + +"@opentelemetry/resources@1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.15.2.tgz#0c9e26cb65652a1402834a3c030cce6028d6dd9d" + integrity sha512-xmMRLenT9CXmm5HMbzpZ1hWhaUowQf8UB4jMjFlAxx1QzQcsD3KFNAVX/CAWzFPtllTyTplrA4JrQ7sCH3qmYw== + dependencies: + "@opentelemetry/core" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" + +"@opentelemetry/sdk-trace-base@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.15.2.tgz#4821f94033c55a6c8bbd35ae387b715b6108517a" + integrity sha512-BEaxGZbWtvnSPchV98qqqqa96AOcb41pjgvhfzDij10tkBhIu9m0Jd6tZ1tJB5ZHfHbTffqYVYE0AOGobec/EQ== + dependencies: + "@opentelemetry/core" "1.15.2" + "@opentelemetry/resources" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" + +"@opentelemetry/semantic-conventions@1.15.2", "@opentelemetry/semantic-conventions@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.15.2.tgz#3bafb5de3e20e841dff6cb3c66f4d6e9694c4241" + integrity sha512-CjbOKwk2s+3xPIMcd5UNYQzsf+v94RczbdNix9/kQh38WiQkM90sUOi3if8eyHFgiBjBjhwXrA7W3ydiSQP9mw== "@tootallnate/once@2": version "2.0.0" @@ -183,10 +277,10 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.23.tgz#676fa0883450ed9da0bb24156213636290892806" integrity sha512-Z4U8yDAl5TFkmYsZdFPdjeMa57NOvnaf1tljHzhouaPEp7LCj2JKkejpI1ODviIAQuW4CcQmxkQ77rnLsOOoKw== -"@types/node@16.x": - version "16.11.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae" - integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w== +"@types/node@18.x": + version "18.15.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" + integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== "@types/randombytes@^2.0.0": version "2.0.0" @@ -202,20 +296,35 @@ dependencies: "@types/node" "*" +"@types/shimmer@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/shimmer/-/shimmer-1.0.2.tgz#93eb2c243c351f3f17d5c580c7467ae5d686b65f" + integrity sha512-dKkr1bTxbEsFlh2ARpKzcaAmsYixqt9UyCdoEZk8rHyE4iQYcDCyvSjDSf7JUWJHlJiTtbIoQjxKh6ViywqDAg== + "@types/uuid@8.0.0": version "8.0.0" resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.0.0.tgz#165aae4819ad2174a17476dbe66feebd549556c0" integrity sha512-xSQfNcvOiE5f9dyd4Kzxbof1aTrLobL278pGLKOZI6esGfZ7ts9Ka16CzIN6Y8hFHE1C7jIBZokULhK1bOgjRw== -"@vscode/extension-telemetry@0.7.5": - version "0.7.5" - resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.7.5.tgz#bf965731816e08c3f146f96d901ec67954fc913b" - integrity sha512-fJ5y3TcpqqkFYHneabYaoB4XAhDdVflVm+TDKshw9VOs77jkgNS4UA7LNXrWeO0eDne3Sh3JgURf+xzc1rk69w== +"@vscode/extension-telemetry@^0.8.4": + version "0.8.4" + resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.8.4.tgz#c078c6f55df1c9e0592de3b4ce0f685dd345bfe7" + integrity sha512-UqM9+KZDDK3MyoHTsg6XNM+XO6pweQxzCpqJz33BoBEYAGsbBviRYcVpJglgay2oReuDD2pOI1Nio3BKNDLhWA== 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" + "@microsoft/1ds-core-js" "^3.2.13" + "@microsoft/1ds-post-js" "^3.2.13" + "@microsoft/applicationinsights-web-basic" "^3.0.2" + applicationinsights "^2.7.1" + +acorn-import-assertions@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" + integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== + +acorn@^8.8.2: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== agent-base@6: version "6.0.2" @@ -224,22 +333,24 @@ agent-base@6: dependencies: debug "4" -applicationinsights@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.4.1.tgz#4de4c4dd3c7c4a44445cfbf3d15808fc0dcc423d" - integrity sha512-0n0Ikd0gzSm460xm+M0UTWIwXrhrH/0bqfZatcJjYObWyefxfAxapGEyNnSGd1Tg90neHz+Yhf+Ff/zgvPiQYA== +applicationinsights@^2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.7.3.tgz#8781454d29c0b14c9773f2e892b4cf5e7468ffa5" + integrity sha512-JY8+kTEkjbA+kAVNWDtpfW2lqsrDALfDXuxOs74KLPu2y13fy/9WB52V4LfYVTVcW1/jYOXjTxNS2gPZIDh1iw== dependencies: - "@azure/core-auth" "^1.4.0" - "@azure/core-rest-pipeline" "^1.10.0" + "@azure/core-auth" "^1.5.0" + "@azure/core-rest-pipeline" "1.10.1" + "@azure/core-util" "1.2.0" + "@azure/opentelemetry-instrumentation-azure-sdk" "^1.0.0-beta.5" "@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" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/sdk-trace-base" "^1.15.2" + "@opentelemetry/semantic-conventions" "^1.15.2" cls-hooked "^4.2.2" continuation-local-storage "^3.2.1" - diagnostic-channel "1.1.0" - diagnostic-channel-publishers "1.0.5" + diagnostic-channel "1.1.1" + diagnostic-channel-publishers "1.0.7" async-hook-jl@^1.7.6: version "1.7.6" @@ -261,6 +372,11 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= +cjs-module-lexer@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" + integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== + cls-hooked@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/cls-hooked/-/cls-hooked-4.2.2.tgz#ad2e9a4092680cdaffeb2d3551da0e225eae1908" @@ -285,7 +401,7 @@ continuation-local-storage@^3.2.1: async-listener "^0.6.0" emitter-listener "^1.1.1" -debug@4: +debug@4, debug@^4.1.1: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -297,17 +413,17 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= -diagnostic-channel-publishers@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.5.tgz#df8c317086c50f5727fdfb5d2fce214d2e4130ae" - integrity sha512-dJwUS0915pkjjimPJVDnS/QQHsH0aOYhnZsLJdnZIMOrB+csj8RnZhWTuwnm8R5v3Z7OZs+ksv5luC14DGB7eg== +diagnostic-channel-publishers@1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.7.tgz#9b7f8d5ee1295481aee19c827d917e96fedf2c4a" + integrity sha512-SEECbY5AiVt6DfLkhkaHNeshg1CogdLLANA8xlG/TKvS+XUgvIKl7VspJGYiEdL5OUyzMVnr7o0AwB7f+/Mjtg== -diagnostic-channel@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.0.tgz#6985e9dfedfbc072d91dc4388477e4087147756e" - integrity sha512-fwujyMe1gj6rk6dYi9hMZm0c8Mz8NDMVl2LB4iaYh3+LIAThZC8RKFGXWG0IML2OxAit/ZFRgZhMkhQ3d/bobQ== +diagnostic-channel@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.1.tgz#44b60972de9ee055c16216535b0e9db3f6a0efd0" + integrity sha512-r2HV5qFkUICyoaKlBEpLKHjxMXATUf/l+h8UZPGBHGLy4DDiY2sOLcIctax4eRnTw5wH2jTMExLntGPJ8eOJxw== dependencies: - semver "^5.3.0" + semver "^7.5.3" emitter-listener@^1.0.1, emitter-listener@^1.1.1: version "1.1.2" @@ -334,6 +450,18 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + http-proxy-agent@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" @@ -351,6 +479,30 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" +import-in-the-middle@1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/import-in-the-middle/-/import-in-the-middle-1.4.2.tgz#2a266676e3495e72c04bbaa5ec14756ba168391b" + integrity sha512-9WOz1Yh/cvO/p69sxRmhyQwrIGGSp7EIdcb+fFNVi7CzQGQB8U1/1XrKVSbEd/GNOAeM0peJtmi7+qphe7NvAw== + dependencies: + acorn "^8.8.2" + acorn-import-assertions "^1.9.0" + cjs-module-lexer "^1.2.2" + module-details-from-path "^1.0.3" + +is-core-module@^2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" + integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== + dependencies: + has "^1.0.3" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + mime-db@1.44.0: version "1.44.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" @@ -363,6 +515,11 @@ mime-types@^2.1.12: dependencies: mime-db "1.44.0" +module-details-from-path@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/module-details-from-path/-/module-details-from-path-1.0.3.tgz#114c949673e2a8a35e9d35788527aa37b679da2b" + integrity sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A== + ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" @@ -375,12 +532,42 @@ node-fetch@2.6.7: dependencies: whatwg-url "^5.0.0" +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +require-in-the-middle@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/require-in-the-middle/-/require-in-the-middle-7.2.0.tgz#b539de8f00955444dc8aed95e17c69b0a4f10fcf" + integrity sha512-3TLx5TGyAY6AOqLBoXmHkNql0HIf2RGbuMgCDT2WO/uGVAPJs6h7Kl+bN6TIZGd9bWhWPwnDnTHGtW8Iu77sdw== + dependencies: + debug "^4.1.1" + module-details-from-path "^1.0.3" + resolve "^1.22.1" + +resolve@^1.22.1: + version "1.22.4" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.4.tgz#1dc40df46554cdaf8948a486a10f6ba1e2026c34" + integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + semver@^5.3.0, semver@^5.4.1: version "5.7.2" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -shimmer@^1.1.0, shimmer@^1.2.0: +semver@^7.5.1, semver@^7.5.3: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +shimmer@^1.1.0, shimmer@^1.2.0, shimmer@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337" integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw== @@ -390,6 +577,11 @@ stack-chain@^1.3.7: resolved "https://registry.yarnpkg.com/stack-chain/-/stack-chain-1.3.7.tgz#d192c9ff4ea6a22c94c4dd459171e3f00cea1285" integrity sha512-D8cWtWVdIe/jBA7v5p5Hwl5yOSOrmZPWDPe2KxQ5UAGD+nxbxU0lKXA4h85Ta6+qgdKVL3vUxsbIZjc1kBG7ug== +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + tr46@~0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" @@ -417,3 +609,8 @@ whatwg-url@^5.0.0: dependencies: tr46 "~0.0.3" webidl-conversions "^3.0.0" + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== diff --git a/extensions/notebook-renderers/src/ansi.ts b/extensions/notebook-renderers/src/ansi.ts index bf3516b02521e..d09e7b73edbaa 100644 --- a/extensions/notebook-renderers/src/ansi.ts +++ b/extensions/notebook-renderers/src/ansi.ts @@ -5,7 +5,6 @@ import { RGBA, Color } from './color'; import { ansiColorIdentifiers } from './colorMap'; -import { ttPolicy } from './htmlHelper'; import { linkify } from './linkify'; @@ -396,14 +395,9 @@ function appendStylizedStringToContainer( let container = document.createElement('span'); - if (trustHtml) { - const trustedHtml = ttPolicy?.createHTML(stringContent) ?? stringContent; - container.innerHTML = trustedHtml as string; - } - if (container.childElementCount === 0) { // plain text - container = linkify(stringContent, true, workspaceFolder); + container = linkify(stringContent, true, workspaceFolder, trustHtml); } container.className = cssClasses.join(' '); diff --git a/extensions/notebook-renderers/src/index.ts b/extensions/notebook-renderers/src/index.ts index df67435363384..c5b4a631afcdf 100644 --- a/extensions/notebook-renderers/src/index.ts +++ b/extensions/notebook-renderers/src/index.ts @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ import type { ActivationFunction, OutputItem, RendererContext } from 'vscode-notebook-renderer'; -import { createOutputContent, scrollableClass } from './textHelper'; -import { HtmlRenderingHook, IDisposable, IRichRenderContext, JavaScriptRenderingHook, RenderOptions } from './rendererTypes'; +import { createOutputContent, appendOutput, scrollableClass } from './textHelper'; +import { HtmlRenderingHook, IDisposable, IRichRenderContext, JavaScriptRenderingHook, OutputWithAppend, RenderOptions } from './rendererTypes'; import { ttPolicy } from './htmlHelper'; function clearContainer(container: HTMLElement) { @@ -37,6 +37,7 @@ function renderImage(outputInfo: OutputItem, element: HTMLElement): IDisposable if (alt) { image.alt = alt; } + image.setAttribute('data-vscode-context', JSON.stringify({ webviewSection: 'image', outputId: outputInfo.id, 'preventDefaultContextMenuItems': true })); const display = document.createElement('div'); display.classList.add('display'); display.appendChild(image); @@ -152,7 +153,7 @@ function renderError( outputInfo: OutputItem, outputElement: HTMLElement, ctx: IRichRenderContext, - trustHTML: boolean + trustHtml: boolean ): IDisposable { const disposableStore = createDisposableStore(); @@ -172,7 +173,7 @@ function renderError( outputElement.classList.add('traceback'); const outputScrolling = scrollingEnabled(outputInfo, ctx.settings); - const content = createOutputContent(outputInfo.id, [err.stack ?? ''], ctx.settings.lineLimit, outputScrolling, trustHTML); + const content = createOutputContent(outputInfo.id, err.stack ?? '', { linesLimit: ctx.settings.lineLimit, scrollable: outputScrolling, trustHtml }); const contentParent = document.createElement('div'); contentParent.classList.toggle('word-wrap', ctx.settings.outputWordWrap); disposableStore.push(ctx.onDidChangeSettings(e => { @@ -270,19 +271,13 @@ function scrollingEnabled(output: OutputItem, options: RenderOptions) { // div.output.output-stream <-- outputElement parameter // div.scrollable? tabindex="0" <-- contentParent // div output-item-id="{guid}" <-- content from outputItem parameter -function renderStream(outputInfo: OutputItem, outputElement: HTMLElement, error: boolean, ctx: IRichRenderContext): IDisposable { +function renderStream(outputInfo: OutputWithAppend, outputElement: HTMLElement, error: boolean, ctx: IRichRenderContext): IDisposable { const disposableStore = createDisposableStore(); const outputScrolling = scrollingEnabled(outputInfo, ctx.settings); + const outputOptions = { linesLimit: ctx.settings.lineLimit, scrollable: outputScrolling, trustHtml: false, error }; outputElement.classList.add('output-stream'); - const text = outputInfo.text(); - const newContent = createOutputContent(outputInfo.id, [text], ctx.settings.lineLimit, outputScrolling, false); - newContent.setAttribute('output-item-id', outputInfo.id); - if (error) { - newContent.classList.add('error'); - } - const scrollTop = outputScrolling ? findScrolledHeight(outputElement) : undefined; const previousOutputParent = getPreviousMatchingContentGroup(outputElement); @@ -290,9 +285,9 @@ function renderStream(outputInfo: OutputItem, outputElement: HTMLElement, error: if (previousOutputParent) { const existingContent = previousOutputParent.querySelector(`[output-item-id="${outputInfo.id}"]`) as HTMLElement | null; if (existingContent) { - existingContent.replaceWith(newContent); - + appendOutput(outputInfo, existingContent, outputOptions); } else { + const newContent = createOutputContent(outputInfo.id, outputInfo.text(), outputOptions); previousOutputParent.appendChild(newContent); } previousOutputParent.classList.toggle('scrollbar-visible', previousOutputParent.scrollHeight > previousOutputParent.clientHeight); @@ -301,12 +296,9 @@ function renderStream(outputInfo: OutputItem, outputElement: HTMLElement, error: const existingContent = outputElement.querySelector(`[output-item-id="${outputInfo.id}"]`) as HTMLElement | null; let contentParent = existingContent?.parentElement; if (existingContent && contentParent) { - existingContent.replaceWith(newContent); - while (newContent.nextSibling) { - // clear out any stale content if we had previously combined streaming outputs into this one - newContent.nextSibling.remove(); - } + appendOutput(outputInfo, existingContent, outputOptions); } else { + const newContent = createOutputContent(outputInfo.id, outputInfo.text(), outputOptions); contentParent = document.createElement('div'); contentParent.appendChild(newContent); while (outputElement.firstChild) { @@ -333,7 +325,7 @@ function renderText(outputInfo: OutputItem, outputElement: HTMLElement, ctx: IRi const text = outputInfo.text(); const outputScrolling = scrollingEnabled(outputInfo, ctx.settings); - const content = createOutputContent(outputInfo.id, [text], ctx.settings.lineLimit, outputScrolling, false); + const content = createOutputContent(outputInfo.id, text, { linesLimit: ctx.settings.lineLimit, scrollable: outputScrolling, trustHtml: false }); content.classList.add('output-plaintext'); if (ctx.settings.outputWordWrap) { content.classList.add('word-wrap'); diff --git a/extensions/notebook-renderers/src/linkify.ts b/extensions/notebook-renderers/src/linkify.ts index c466c9e8c65fb..ec7415a44b93b 100644 --- a/extensions/notebook-renderers/src/linkify.ts +++ b/extensions/notebook-renderers/src/linkify.ts @@ -3,6 +3,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { ttPolicy } from './htmlHelper'; + const CONTROL_CODES = '\\u0000-\\u0020\\u007f-\\u009f'; const WEB_LINK_REGEX = new RegExp('(?:[a-zA-Z][a-zA-Z0-9+.-]{2,}:\\/\\/|data:|www\\.)[^\\s' + CONTROL_CODES + '"]{2,}[^\\s' + CONTROL_CODES + '"\')}\\],:;.!?]', 'ug'); @@ -13,10 +15,11 @@ const POSIX_PATH = /(?<=^|\s)((?:\~|\.)?(?:\/[\w\.-]*)+)/; const LINE_COLUMN = /(?:\:([\d]+))?(?:\:([\d]+))?/; const isWindows = (typeof navigator !== 'undefined') ? navigator.userAgent && navigator.userAgent.indexOf('Windows') >= 0 : false; const PATH_LINK_REGEX = new RegExp(`${isWindows ? WIN_PATH.source : POSIX_PATH.source}${LINE_COLUMN.source}`, 'g'); +const HTML_LINK_REGEX = /]*?\s+)?href=(["'])(.*?)\1[^>]*?>.*?<\/a>/gi; const MAX_LENGTH = 2000; -type LinkKind = 'web' | 'path' | 'text'; +type LinkKind = 'web' | 'path' | 'html' | 'text'; type LinkPart = { kind: LinkKind; value: string; @@ -36,7 +39,7 @@ export class LinkDetector { * When splitLines is true, each line of the text, even if it contains no links, is wrapped in a * and added as a child of the returned . */ - linkify(text: string, splitLines?: boolean, workspaceFolder?: string): HTMLElement { + linkify(text: string, splitLines?: boolean, workspaceFolder?: string, trustHtml?: boolean): HTMLElement { if (splitLines) { const lines = text.split('\n'); for (let i = 0; i < lines.length - 1; i++) { @@ -46,7 +49,7 @@ export class LinkDetector { // Remove the last element ('') that split added. lines.pop(); } - const elements = lines.map(line => this.linkify(line, false, workspaceFolder)); + const elements = lines.map(line => this.linkify(line, false, workspaceFolder, trustHtml)); if (elements.length === 1) { // Do not wrap single line with extra span. return elements[0]; @@ -67,6 +70,15 @@ export class LinkDetector { case 'path': container.appendChild(this.createWebLink(part.value)); break; + case 'html': + if (ttPolicy && trustHtml) { + const span = document.createElement('span'); + span.innerHTML = ttPolicy.createHTML(part.value).toString(); + container.appendChild(span); + } else { + container.appendChild(document.createTextNode(part.value)); + } + break; } } catch (e) { container.appendChild(document.createTextNode(part.value)); @@ -130,8 +142,8 @@ export class LinkDetector { return [{ kind: 'text', value: text, captures: [] }]; } - const regexes: RegExp[] = [WEB_LINK_REGEX, PATH_LINK_REGEX]; - const kinds: LinkKind[] = ['web', 'path']; + const regexes: RegExp[] = [WEB_LINK_REGEX, PATH_LINK_REGEX, HTML_LINK_REGEX]; + const kinds: LinkKind[] = ['web', 'path', 'html']; const result: LinkPart[] = []; const splitOne = (text: string, regexIndex: number) => { @@ -168,6 +180,6 @@ export class LinkDetector { } const linkDetector = new LinkDetector(); -export function linkify(text: string, splitLines?: boolean, workspaceFolder?: string) { - return linkDetector.linkify(text, splitLines, workspaceFolder); +export function linkify(text: string, splitLines?: boolean, workspaceFolder?: string, trustHtml = false) { + return linkDetector.linkify(text, splitLines, workspaceFolder, trustHtml); } diff --git a/extensions/notebook-renderers/src/rendererTypes.ts b/extensions/notebook-renderers/src/rendererTypes.ts index 9da94aeef5dcd..ded12bdcaccb2 100644 --- a/extensions/notebook-renderers/src/rendererTypes.ts +++ b/extensions/notebook-renderers/src/rendererTypes.ts @@ -35,3 +35,14 @@ export interface RenderOptions { } export type IRichRenderContext = RendererContext & { readonly settings: RenderOptions; readonly onDidChangeSettings: Event }; + +export type OutputElementOptions = { + linesLimit: number; + scrollable?: boolean; + error?: boolean; + trustHtml?: boolean; +}; + +export interface OutputWithAppend extends OutputItem { + appendedText?(): string | undefined; +} diff --git a/extensions/notebook-renderers/src/test/notebookRenderer.test.ts b/extensions/notebook-renderers/src/test/notebookRenderer.test.ts index e67d1d8ce260a..0f747900377c5 100644 --- a/extensions/notebook-renderers/src/test/notebookRenderer.test.ts +++ b/extensions/notebook-renderers/src/test/notebookRenderer.test.ts @@ -5,8 +5,8 @@ import * as assert from 'assert'; import { activate } from '..'; -import { OutputItem, RendererApi } from 'vscode-notebook-renderer'; -import { IDisposable, IRichRenderContext, RenderOptions } from '../rendererTypes'; +import { RendererApi } from 'vscode-notebook-renderer'; +import { IDisposable, IRichRenderContext, OutputWithAppend, RenderOptions } from '../rendererTypes'; import { JSDOM } from "jsdom"; const dom = new JSDOM(); @@ -116,10 +116,13 @@ suite('Notebook builtin output renderer', () => { } } - function createOutputItem(text: string, mime: string, id: string = '123'): OutputItem { + function createOutputItem(text: string, mime: string, id: string = '123', appendedText?: string): OutputWithAppend { return { id: id, mime: mime, + appendedText() { + return appendedText; + }, text() { return text; }, @@ -177,9 +180,9 @@ suite('Notebook builtin output renderer', () => { assert.ok(renderer, 'Renderer not created'); const outputElement = new OutputHtml().getFirstOuputElement(); - const outputItem = createOutputItem('content', 'text/plain'); + const outputItem = createOutputItem('content', mimeType); await renderer!.renderOutputItem(outputItem, outputElement); - const outputItem2 = createOutputItem('replaced content', 'text/plain'); + const outputItem2 = createOutputItem('replaced content', mimeType); await renderer!.renderOutputItem(outputItem2, outputElement); const inserted = outputElement.firstChild as HTMLElement; @@ -189,6 +192,87 @@ suite('Notebook builtin output renderer', () => { }); + test('Append streaming output', async () => { + const context = createContext({ outputWordWrap: false, outputScrolling: true }); + const renderer = await activate(context); + assert.ok(renderer, 'Renderer not created'); + + const outputElement = new OutputHtml().getFirstOuputElement(); + const outputItem = createOutputItem('content', stdoutMimeType, '123', 'ignoredAppend'); + await renderer!.renderOutputItem(outputItem, outputElement); + const outputItem2 = createOutputItem('content\nappended', stdoutMimeType, '123', '\nappended'); + await renderer!.renderOutputItem(outputItem2, outputElement); + + const inserted = outputElement.firstChild as HTMLElement; + assert.ok(inserted.innerHTML.indexOf('>contentappendedcontentcontent { + const context = createContext({ outputScrolling: true }); + const renderer = await activate(context); + assert.ok(renderer, 'Renderer not created'); + + const outputHtml = new OutputHtml(); + const firstOutputElement = outputHtml.getFirstOuputElement(); + const outputItem1 = createOutputItem('first stream content', stdoutMimeType, '1'); + const outputItem2 = createOutputItem(JSON.stringify(error), errorMimeType, '2'); + const outputItem3 = createOutputItem('second stream content', stdoutMimeType, '3'); + await renderer!.renderOutputItem(outputItem1, firstOutputElement); + const secondOutputElement = outputHtml.appendOutputElement(); + await renderer!.renderOutputItem(outputItem2, secondOutputElement); + const thirdOutputElement = outputHtml.appendOutputElement(); + await renderer!.renderOutputItem(outputItem3, thirdOutputElement); + + const appendedItem1 = createOutputItem('', stdoutMimeType, '1', ' appended1'); + await renderer!.renderOutputItem(appendedItem1, firstOutputElement); + const appendedItem3 = createOutputItem('', stdoutMimeType, '3', ' appended3'); + await renderer!.renderOutputItem(appendedItem3, thirdOutputElement); + + assert.ok(firstOutputElement.innerHTML.indexOf('>first stream content') > -1, `Content was not added to output element: ${outputHtml.cellElement.innerHTML}`); + assert.ok(firstOutputElement.innerHTML.indexOf('appended1') > -1, `Content was not appended to output element: ${outputHtml.cellElement.innerHTML}`); + assert.ok(secondOutputElement.innerHTML.indexOf('>NameError -1, `Content was not added to output element: ${outputHtml.cellElement.innerHTML}`); + assert.ok(thirdOutputElement.innerHTML.indexOf('>second stream content') > -1, `Content was not added to output element: ${outputHtml.cellElement.innerHTML}`); + assert.ok(thirdOutputElement.innerHTML.indexOf('appended3') > -1, `Content was not appended to output element: ${outputHtml.cellElement.innerHTML}`); + }); + + test('Append large streaming outputs', async () => { + const context = createContext({ outputWordWrap: false, outputScrolling: true }); + const renderer = await activate(context); + assert.ok(renderer, 'Renderer not created'); + + const outputElement = new OutputHtml().getFirstOuputElement(); + const lotsOfLines = new Array(4998).fill('line').join('\n'); + const firstOuput = lotsOfLines + 'expected1'; + const outputItem = createOutputItem(firstOuput, stdoutMimeType, '123'); + await renderer!.renderOutputItem(outputItem, outputElement); + const appended = '\n' + lotsOfLines + 'expectedAppend'; + const outputItem2 = createOutputItem(firstOuput + appended, stdoutMimeType, '123', appended); + await renderer!.renderOutputItem(outputItem2, outputElement); + + const inserted = outputElement.firstChild as HTMLElement; + assert.ok(inserted.innerHTML.indexOf('expected1') !== -1, `Last bit of previous content should still exist`); + assert.ok(inserted.innerHTML.indexOf('expectedAppend') !== -1, `Content was not appended to output element`); + }); + + test('Streaming outputs larger than the line limit are truncated', async () => { + const context = createContext({ outputWordWrap: false, outputScrolling: true }); + const renderer = await activate(context); + assert.ok(renderer, 'Renderer not created'); + + const outputElement = new OutputHtml().getFirstOuputElement(); + const lotsOfLines = new Array(11000).fill('line').join('\n'); + const firstOuput = 'shouldBeTruncated' + lotsOfLines + 'expected1'; + const outputItem = createOutputItem(firstOuput, stdoutMimeType, '123'); + await renderer!.renderOutputItem(outputItem, outputElement); + + const inserted = outputElement.firstChild as HTMLElement; + assert.ok(inserted.innerHTML.indexOf('expected1') !== -1, `Last bit of content should exist`); + assert.ok(inserted.innerHTML.indexOf('shouldBeTruncated') === -1, `Beginning content should be truncated`); + }); + test(`Render with wordwrap and scrolling for error output`, async () => { const context = createContext({ outputWordWrap: true, outputScrolling: true }); const renderer = await activate(context); @@ -268,6 +352,29 @@ suite('Notebook builtin output renderer', () => { assert.ok(inserted.innerHTML.indexOf('>second stream content { + const context = createContext({ outputScrolling: true }); + const renderer = await activate(context); + assert.ok(renderer, 'Renderer not created'); + + const outputHtml = new OutputHtml(); + const outputElement = outputHtml.getFirstOuputElement(); + const outputItem1 = createOutputItem('first stream content', stdoutMimeType, '1'); + const outputItem2 = createOutputItem('second stream content', stdoutMimeType, '2'); + await renderer!.renderOutputItem(outputItem1, outputElement); + const secondOutput = outputHtml.appendOutputElement(); + await renderer!.renderOutputItem(outputItem2, secondOutput); + const appendingOutput = createOutputItem('', stdoutMimeType, '2', ' appended'); + await renderer!.renderOutputItem(appendingOutput, secondOutput); + + + const inserted = outputElement.firstChild as HTMLElement; + assert.ok(inserted, `nothing appended to output element: ${outputElement.innerHTML}`); + assert.ok(inserted.innerHTML.indexOf('>first stream content -1, `Content was not added to output element: ${outputHtml.cellElement.innerHTML}`); + assert.ok(inserted.innerHTML.indexOf('>second stream content') > -1, `Second content was not added to ouptut element: ${outputHtml.cellElement.innerHTML}`); + assert.ok(inserted.innerHTML.indexOf('appended') > -1, `Content was not appended to ouptut element: ${outputHtml.cellElement.innerHTML}`); + }); + test(`Streaming outputs interleaved with other mime types will produce separate outputs`, async () => { const context = createContext({ outputScrolling: false }); const renderer = await activate(context); diff --git a/extensions/notebook-renderers/src/textHelper.ts b/extensions/notebook-renderers/src/textHelper.ts index 8cc03fd543e40..5cf0e24eb96ab 100644 --- a/extensions/notebook-renderers/src/textHelper.ts +++ b/extensions/notebook-renderers/src/textHelper.ts @@ -4,9 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { handleANSIOutput } from './ansi'; - +import { OutputElementOptions, OutputWithAppend } from './rendererTypes'; export const scrollableClass = 'scrollable'; +const softScrollableLineLimit = 5000; +const hardScrollableLineLimit = 8000; + /** * Output is Truncated. View as a [scrollable element] or open in a [text editor]. Adjust cell output [settings...] */ @@ -91,22 +94,70 @@ function truncatedArrayOfString(id: string, buffer: string[], linesLimit: number function scrollableArrayOfString(id: string, buffer: string[], trustHtml: boolean) { const element = document.createElement('div'); - if (buffer.length > 5000) { + if (buffer.length > softScrollableLineLimit) { element.appendChild(generateNestedViewAllElement(id)); } - element.appendChild(handleANSIOutput(buffer.slice(-5000).join('\n'), trustHtml)); + element.appendChild(handleANSIOutput(buffer.slice(-1 * softScrollableLineLimit).join('\n'), trustHtml)); return element; } -export function createOutputContent(id: string, outputs: string[], linesLimit: number, scrollable: boolean, trustHtml: boolean): HTMLElement { +const outputLengths: Record = {}; - const buffer = outputs.join('\n').split(/\r\n|\r|\n/g); +function appendScrollableOutput(element: HTMLElement, id: string, appended: string, trustHtml: boolean) { + if (!outputLengths[id]) { + outputLengths[id] = 0; + } + const buffer = appended.split(/\r\n|\r|\n/g); + const appendedLength = buffer.length + outputLengths[id]; + // Only append outputs up to the hard limit of lines, then replace it with the last softLimit number of lines + if (appendedLength > hardScrollableLineLimit) { + return false; + } + else { + element.appendChild(handleANSIOutput(buffer.join('\n'), trustHtml)); + outputLengths[id] = appendedLength; + } + return true; +} + +export function createOutputContent(id: string, outputText: string, options: OutputElementOptions): HTMLElement { + const { linesLimit, error, scrollable, trustHtml } = options; + const buffer = outputText.split(/\r\n|\r|\n/g); + outputLengths[id] = outputLengths[id] = Math.min(buffer.length, softScrollableLineLimit); + + let outputElement: HTMLElement; if (scrollable) { - return scrollableArrayOfString(id, buffer, trustHtml); + outputElement = scrollableArrayOfString(id, buffer, !!trustHtml); } else { - return truncatedArrayOfString(id, buffer, linesLimit, trustHtml); + outputElement = truncatedArrayOfString(id, buffer, linesLimit, !!trustHtml); + } + + outputElement.setAttribute('output-item-id', id); + if (error) { + outputElement.classList.add('error'); } + + return outputElement; } + +export function appendOutput(outputInfo: OutputWithAppend, existingContent: HTMLElement, options: OutputElementOptions) { + const appendedText = outputInfo.appendedText?.(); + // appending output only supported for scrollable ouputs currently + if (appendedText && options.scrollable) { + if (appendScrollableOutput(existingContent, outputInfo.id, appendedText, false)) { + return; + } + } + + const newContent = createOutputContent(outputInfo.id, outputInfo.text(), options); + existingContent.replaceWith(newContent); + while (newContent.nextSibling) { + // clear out any stale content if we had previously combined streaming outputs into this one + newContent.nextSibling.remove(); + } + +} + diff --git a/extensions/npm/README.md b/extensions/npm/README.md index 82730c7e82a67..296bf03f73e0c 100644 --- a/extensions/npm/README.md +++ b/extensions/npm/README.md @@ -28,7 +28,7 @@ The extension supports running a script as a task from a folder in the Explorer. ### Others -The extension fetches data from https://registry.npmjs.org and https://registry.bower.io to provide auto-completion and information on hover features on npm dependencies. +The extension fetches data from and to provide auto-completion and information on hover features on npm dependencies. ## Settings @@ -40,5 +40,3 @@ The extension fetches data from https://registry.npmjs.org and https://registry. - `npm.scriptExplorerAction` - The default click action: `open` or `run`, the default is `open`. - `npm.enableRunFromFolder` - Enable running npm scripts from the context menu of folders in Explorer, the default is `false`. - `npm.scriptCodeLens.enable` - Enable/disable the code lenses to run a script, the default is `false`. - - diff --git a/extensions/npm/package.json b/extensions/npm/package.json index d87e2f1d016c1..e3dbfcfe26adb 100644 --- a/extensions/npm/package.json +++ b/extensions/npm/package.json @@ -30,7 +30,7 @@ }, "devDependencies": { "@types/minimatch": "^3.0.3", - "@types/node": "16.x", + "@types/node": "18.x", "@types/which": "^2.0.0" }, "resolutions": { diff --git a/extensions/npm/src/npmMain.ts b/extensions/npm/src/npmMain.ts index 26c6412b2d792..a066aac1e9667 100644 --- a/extensions/npm/src/npmMain.ts +++ b/extensions/npm/src/npmMain.ts @@ -78,7 +78,7 @@ export async function activate(context: vscode.ExtensionContext): Promise } const lines = outputMatch.regexMatch[1]; - const fixes: vscode.TerminalQuickFixCommand[] = []; + const fixes: vscode.TerminalQuickFixExecuteTerminalCommand[] = []; for (const line of lines.split('\n')) { // search from the second char, since the lines might be prefixed with // "npm ERR!" which comes before the actual command suggestion. diff --git a/extensions/npm/yarn.lock b/extensions/npm/yarn.lock index cb1d071021000..cd465e173e646 100644 --- a/extensions/npm/yarn.lock +++ b/extensions/npm/yarn.lock @@ -7,10 +7,10 @@ resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== -"@types/node@16.x": - version "16.11.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae" - integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w== +"@types/node@18.x": + version "18.15.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" + integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== "@types/which@^2.0.0": version "2.0.0" diff --git a/extensions/package.json b/extensions/package.json index f5f0b7e6197b8..02a1f822e7d2a 100644 --- a/extensions/package.json +++ b/extensions/package.json @@ -4,7 +4,7 @@ "license": "MIT", "description": "Dependencies shared by all extensions", "dependencies": { - "typescript": "5.1.6" + "typescript": "^5.2.1-rc" }, "scripts": { "postinstall": "node ./postinstall.mjs" diff --git a/extensions/php-language-features/README.md b/extensions/php-language-features/README.md index c00be6a964e78..e0d28f5254fc3 100644 --- a/extensions/php-language-features/README.md +++ b/extensions/php-language-features/README.md @@ -4,4 +4,4 @@ ## Features -See [PHP in Visual Studio Code](https://code.visualstudio.com/docs/languages/php) to learn about the features of this extension. \ No newline at end of file +See [PHP in Visual Studio Code](https://code.visualstudio.com/docs/languages/php) to learn about the features of this extension. diff --git a/extensions/php-language-features/package.json b/extensions/php-language-features/package.json index 8f9723197b299..8963fc796f4d0 100644 --- a/extensions/php-language-features/package.json +++ b/extensions/php-language-features/package.json @@ -77,7 +77,7 @@ "which": "^2.0.2" }, "devDependencies": { - "@types/node": "16.x", + "@types/node": "18.x", "@types/which": "^2.0.0" }, "repository": { diff --git a/extensions/php-language-features/yarn.lock b/extensions/php-language-features/yarn.lock index a418ca9f82329..4c2e01e4b71ef 100644 --- a/extensions/php-language-features/yarn.lock +++ b/extensions/php-language-features/yarn.lock @@ -2,10 +2,10 @@ # yarn lockfile v1 -"@types/node@16.x": - version "16.11.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae" - integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w== +"@types/node@18.x": + version "18.15.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" + integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== "@types/which@^2.0.0": version "2.0.0" diff --git a/extensions/references-view/package.json b/extensions/references-view/package.json index ba4cabed96a52..a14e5a60ec08d 100644 --- a/extensions/references-view/package.json +++ b/extensions/references-view/package.json @@ -402,6 +402,6 @@ "watch": "npx gulp watch-extension:references-view" }, "devDependencies": { - "@types/node": "16.x" + "@types/node": "18.x" } } diff --git a/extensions/references-view/yarn.lock b/extensions/references-view/yarn.lock index 4b3f8a1f7a011..8a3d10f2b65cf 100644 --- a/extensions/references-view/yarn.lock +++ b/extensions/references-view/yarn.lock @@ -2,7 +2,7 @@ # yarn lockfile v1 -"@types/node@16.x": - version "16.11.33" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.33.tgz#566713b1b626f781c5c58fe3531307283e00720c" - integrity sha512-0PJ0vg+JyU0MIan58IOIFRtSvsb7Ri+7Wltx2qAg94eMOrpg4+uuP3aUHCpxXc1i0jCXiC+zIamSZh3l9AbcQA== +"@types/node@18.x": + version "18.15.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" + integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== diff --git a/extensions/shared.webpack.config.js b/extensions/shared.webpack.config.js index 4b0ec1cb0abf1..19e76a9d35f61 100644 --- a/extensions/shared.webpack.config.js +++ b/extensions/shared.webpack.config.js @@ -60,6 +60,7 @@ function withNodeDefaults(/**@type WebpackConfig & { context: string }*/extConfi externals: { 'vscode': 'commonjs vscode', // ignored because it doesn't exist, 'applicationinsights-native-metrics': 'commonjs applicationinsights-native-metrics', // ignored because we don't ship native module + '@azure/functions-core': 'commonjs azure/functions-core', // optioinal dependency of appinsights that we don't use '@opentelemetry/tracing': 'commonjs @opentelemetry/tracing', // ignored because we don't ship this module '@opentelemetry/instrumentation': 'commonjs @opentelemetry/instrumentation', // ignored because we don't ship this module '@azure/opentelemetry-instrumentation-azure-sdk': 'commonjs @azure/opentelemetry-instrumentation-azure-sdk', // ignored because we don't ship this module @@ -146,6 +147,7 @@ function withBrowserDefaults(/**@type WebpackConfig & { context: string }*/extCo externals: { 'vscode': 'commonjs vscode', // ignored because it doesn't exist, 'applicationinsights-native-metrics': 'commonjs applicationinsights-native-metrics', // ignored because we don't ship native module + '@azure/functions-core': 'commonjs azure/functions-core', // optioinal dependency of appinsights that we don't use '@opentelemetry/tracing': 'commonjs @opentelemetry/tracing', // ignored because we don't ship this module '@opentelemetry/instrumentation': 'commonjs @opentelemetry/instrumentation', // ignored because we don't ship this module '@azure/opentelemetry-instrumentation-azure-sdk': 'commonjs @azure/opentelemetry-instrumentation-azure-sdk', // ignored because we don't ship this module diff --git a/extensions/shellscript/cgmanifest.json b/extensions/shellscript/cgmanifest.json index 87be4976392e7..f246d45fe21b4 100644 --- a/extensions/shellscript/cgmanifest.json +++ b/extensions/shellscript/cgmanifest.json @@ -6,11 +6,11 @@ "git": { "name": "jeff-hykin/better-shell-syntax", "repositoryUrl": "https://github.com/jeff-hykin/better-shell-syntax", - "commitHash": "1bad17d8badf6283125aaa7c31be06ba64146a0f" + "commitHash": "ce62ea59e8e522f8a07d8d8a2d1f992c6c600b91" } }, "license": "MIT", - "version": "1.5.4" + "version": "1.6.2" } ], "version": 1 diff --git a/extensions/shellscript/syntaxes/shell-unix-bash.tmLanguage.json b/extensions/shellscript/syntaxes/shell-unix-bash.tmLanguage.json index e132b9e5699cb..68055eb7b29ef 100644 --- a/extensions/shellscript/syntaxes/shell-unix-bash.tmLanguage.json +++ b/extensions/shellscript/syntaxes/shell-unix-bash.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/jeff-hykin/better-shell-syntax/commit/1bad17d8badf6283125aaa7c31be06ba64146a0f", + "version": "https://github.com/jeff-hykin/better-shell-syntax/commit/ce62ea59e8e522f8a07d8d8a2d1f992c6c600b91", "name": "Shell Script", "scopeName": "source.shell", "patterns": [ @@ -14,7 +14,7 @@ ], "repository": { "alias_statement": { - "begin": "(alias)[ \\t]*+[ \\t]*+(?:((?<=^|;|&|[ \\t])(?:export|declare|typeset|local|readonly)(?=[ \\t]|;|&|$))[ \\t]*+)?((?|#|\\n|$|;|[ \\t]))(?!foreach\\b(?!\\/)|select\\b(?!\\/)|repeat\\b(?!\\/)|until\\b(?!\\/)|while\\b(?!\\/)|case\\b(?!\\/)|done\\b(?!\\/)|elif\\b(?!\\/)|else\\b(?!\\/)|esac\\b(?!\\/)|then\\b(?!\\/)|for\\b(?!\\/)|end\\b(?!\\/)|in\\b(?!\\/)|fi\\b(?!\\/)|do\\b(?!\\/)|if\\b(?!\\/))(?:((?<=^|;|&|[ \\t])(?:export|declare|typeset|local|readonly)(?=[ \\t]|;|&|$))|((?!\"|'|\\\\\\n?$)[^!'\" \\t\\n\\r]+?))(?:(?= |\\t)|(?=;|\\||&|\\n|\\)|\\`|\\{|\\}|[ \\t]*#|\\])(?|#|\\n|$|;|[ \\t]))(?!foreach\\b(?!\\/)|select\\b(?!\\/)|repeat\\b(?!\\/)|until\\b(?!\\/)|while\\b(?!\\/)|case\\b(?!\\/)|done\\b(?!\\/)|elif\\b(?!\\/)|else\\b(?!\\/)|esac\\b(?!\\/)|then\\b(?!\\/)|for\\b(?!\\/)|end\\b(?!\\/)|in\\b(?!\\/)|fi\\b(?!\\/)|do\\b(?!\\/)|if\\b(?!\\/))(?:((?<=^|;|&|[ \\t])(?:readonly|declare|typeset|export|local)(?=[ \\t]|;|&|$))|((?!\"|'|\\\\\\n?$)[^!'\" \\t\\n\\r]+?))(?:(?= |\\t)|(?=;|\\||&|\\n|\\)|\\`|\\{|\\}|[ \\t]*#|\\])(?= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" + +"@microsoft/applicationinsights-common@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-3.0.2.tgz#37670bb07f4858ed41ff9759119e0759007d6e05" + integrity sha512-y+WXWop+OVim954Cu1uyYMnNx6PWO8okHpZIQi/1YSqtqaYdtJVPv4P0AVzwJdohxzVfgzKvqj9nec/VWqE2Zg== + dependencies: + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" + +"@microsoft/applicationinsights-core-js@2.8.15": + version "2.8.15" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.15.tgz#8fa466474260e01967fe649f14dd9e5ff91dcdc8" + integrity sha512-yYAs9MyjGr2YijQdUSN9mVgT1ijI1FPMgcffpaPmYbHAVbQmF7bXudrBWHxmLzJlwl5rfep+Zgjli2e67lwUqQ== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.9" "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/dynamicproto-js" "^1.1.9" -"@microsoft/applicationinsights-core-js@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.9.tgz#0e5d207acfae6986a6fc97249eeb6117e523bf1b" - integrity sha512-HRuIuZ6aOWezcg/G5VyFDDWGL8hDNe/ljPP01J7ImH2kRPEgbtcfPSUMjkamGMefgdq81GZsSoC/NNGTP4pp2w== +"@microsoft/applicationinsights-core-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-3.0.2.tgz#108e20df8c162bec92b1f66f9de2530a25d9f51a" + integrity sha512-WQhVhzlRlLDrQzn3OShCW/pL3BW5WC57t0oywSknX3q7lMzI3jDg7Ihh0iuIcNTzGCTbDkuqr4d6IjEDWIMtJQ== dependencies: - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-shims@2.0.2", "@microsoft/applicationinsights-shims@^2.0.2": version "2.0.2" resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.2.tgz#92b36a09375e2d9cb2b4203383b05772be837085" integrity sha512-PoHEgsnmcqruLNHZ/amACqdJ6YYQpED0KSRe6J7gIJTtpZC1FfFU9b1fmDKDKtFoUSrPzEh1qzO3kmRZP0betg== -"@microsoft/applicationinsights-web-basic@^2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-2.8.9.tgz#eed2f3d1e19069962ed2155915c1656e6936e1d5" - integrity sha512-CH0J8JFOy7MjK8JO4pXXU+EML+Ilix+94PMZTX5EJlBU1in+mrik74/8qSg3UC4ekPi12KwrXaHCQSVC3WseXQ== +"@microsoft/applicationinsights-shims@3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-3.0.1.tgz#3865b73ace8405b9c4618cc5c571f2fe3876f06f" + integrity sha512-DKwboF47H1nb33rSUfjqI6ryX29v+2QWcTrRvcQDA32AZr5Ilkr7whOOSsD1aBzwqX0RJEIP1Z81jfE3NBm/Lg== dependencies: - "@microsoft/applicationinsights-channel-js" "2.8.9" - "@microsoft/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" + +"@microsoft/applicationinsights-web-basic@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-3.0.2.tgz#f777a4d24b79dde3ae396d3b819e1fce06b7240a" + integrity sha512-6Lq0DE/pZp9RvSV+weGbcxN1NDmfczj6gNPhvZKV2YSQ3RK0LZE3+wjTWLXfuStq8a+nCBdsRpWk8tOKgsoxcg== + dependencies: + "@microsoft/applicationinsights-channel-js" "3.0.2" + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-web-snippet@^1.0.1": version "1.0.1" @@ -126,59 +185,109 @@ resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.7.tgz#ede48dd3f85af14ee369c805e5ed5b84222b9fe2" integrity sha512-SK3D3aVt+5vOOccKPnGaJWB5gQ8FuKfjboUJHedMP7gu54HqSCXX5iFXhktGD8nfJb0Go30eDvs/UDoTnR2kOA== -"@opentelemetry/api@^1.0.4": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.2.0.tgz#89ef99401cde6208cff98760b67663726ef26686" - integrity sha512-0nBr+VZNKm9tvNDZFstI3Pq1fCTEDK5OZTnVKNvBNAKgd0yIvmwsP4m61rEv7ZP+tOUjWJhROpxK5MsnlF911g== +"@microsoft/dynamicproto-js@^1.1.9": + version "1.1.9" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.9.tgz#7437db7aa061162ee94e4131b69a62b8dad5dea6" + integrity sha512-n1VPsljTSkthsAFYdiWfC+DKzK2WwcRp83Y1YAqdX552BstvsDjft9YXppjUzp11BPsapDoO1LDgrDB0XVsfNQ== + +"@microsoft/dynamicproto-js@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-2.0.2.tgz#e57fbec2e7067d48b7e8e1e1c1d354028ef718a6" + integrity sha512-MB8trWaFREpmb037k/d0bB7T2BP7Ai24w1e1tbz3ASLB0/lwphsq3Nq8S9I5AsI5vs4zAQT+SB5nC5/dLYTiOg== + dependencies: + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" -"@opentelemetry/core@1.7.0", "@opentelemetry/core@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.7.0.tgz#83bdd1b7a4ceafcdffd6590420657caec5f7b34c" - integrity sha512-AVqAi5uc8DrKJBimCTFUT4iFI+5eXpo4sYmGbQ0CypG0piOTHE2g9c5aSoTGYXu3CzOmJZf7pT6Xh+nwm5d6yQ== +"@nevware21/ts-async@>= 0.2.4 < 2.x": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@nevware21/ts-async/-/ts-async-0.3.0.tgz#a8b97ba01065fc930de9a3f4dd4a05e862becc6c" + integrity sha512-ZUcgUH12LN/F6nzN0cYd0F/rJaMLmXr0EHVTyYfaYmK55bdwE4338uue4UiVoRqHVqNW4KDUrJc49iGogHKeWA== dependencies: - "@opentelemetry/semantic-conventions" "1.7.0" + "@nevware21/ts-utils" ">= 0.10.0 < 2.x" + +"@nevware21/ts-utils@>= 0.10.0 < 2.x", "@nevware21/ts-utils@>= 0.9.4 < 2.x", "@nevware21/ts-utils@>= 0.9.5 < 2.x": + version "0.10.1" + resolved "https://registry.yarnpkg.com/@nevware21/ts-utils/-/ts-utils-0.10.1.tgz#aa65abc71eba06749a396598f22263d26f796ac7" + integrity sha512-pMny25NnF2/MJwdqC3Iyjm2pGIXNxni4AROpcqDeWa+td9JMUY4bUS9uU9XW+BoBRqTLUL+WURF9SOd/6OQzRg== + +"@opentelemetry/api@^1.4.1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.4.1.tgz#ff22eb2e5d476fbc2450a196e40dd243cc20c28f" + integrity sha512-O2yRJce1GOc6PAy3QxFM4NzFiWzvScDC1/5ihYBL6BUEVdq0XMWN01sppE+H6bBXbaFYipjwFLEWLg5PaSOThA== + +"@opentelemetry/core@1.15.2", "@opentelemetry/core@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.15.2.tgz#5b170bf223a2333884bbc2d29d95812cdbda7c9f" + integrity sha512-+gBv15ta96WqkHZaPpcDHiaz0utiiHZVfm2YOYSqFGrUaJpPkMoSuLBB58YFQGi6Rsb9EHos84X6X5+9JspmLw== + dependencies: + "@opentelemetry/semantic-conventions" "1.15.2" -"@opentelemetry/resources@1.7.0": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.7.0.tgz#90ccd3a6a86b4dfba4e833e73944bd64958d78c5" - integrity sha512-u1M0yZotkjyKx8dj+46Sg5thwtOTBmtRieNXqdCRiWUp6SfFiIP0bI+1XK3LhuXqXkBXA1awJZaTqKduNMStRg== +"@opentelemetry/instrumentation@^0.41.2": + version "0.41.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.41.2.tgz#cae11fa64485dcf03dae331f35b315b64bc6189f" + integrity sha512-rxU72E0pKNH6ae2w5+xgVYZLzc5mlxAbGzF4shxMVK8YC2QQsfN38B2GPbj0jvrKWWNUElfclQ+YTykkNg/grw== + dependencies: + "@types/shimmer" "^1.0.2" + import-in-the-middle "1.4.2" + require-in-the-middle "^7.1.1" + semver "^7.5.1" + shimmer "^1.2.1" + +"@opentelemetry/resources@1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.15.2.tgz#0c9e26cb65652a1402834a3c030cce6028d6dd9d" + integrity sha512-xmMRLenT9CXmm5HMbzpZ1hWhaUowQf8UB4jMjFlAxx1QzQcsD3KFNAVX/CAWzFPtllTyTplrA4JrQ7sCH3qmYw== dependencies: - "@opentelemetry/core" "1.7.0" - "@opentelemetry/semantic-conventions" "1.7.0" + "@opentelemetry/core" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" -"@opentelemetry/sdk-trace-base@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.7.0.tgz#b498424e0c6340a9d80de63fd408c5c2130a60a5" - integrity sha512-Iz84C+FVOskmauh9FNnj4+VrA+hG5o+tkMzXuoesvSfunVSioXib0syVFeNXwOm4+M5GdWCuW632LVjqEXStIg== +"@opentelemetry/sdk-trace-base@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.15.2.tgz#4821f94033c55a6c8bbd35ae387b715b6108517a" + integrity sha512-BEaxGZbWtvnSPchV98qqqqa96AOcb41pjgvhfzDij10tkBhIu9m0Jd6tZ1tJB5ZHfHbTffqYVYE0AOGobec/EQ== dependencies: - "@opentelemetry/core" "1.7.0" - "@opentelemetry/resources" "1.7.0" - "@opentelemetry/semantic-conventions" "1.7.0" + "@opentelemetry/core" "1.15.2" + "@opentelemetry/resources" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" -"@opentelemetry/semantic-conventions@1.7.0", "@opentelemetry/semantic-conventions@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.7.0.tgz#af80a1ef7cf110ea3a68242acd95648991bcd763" - integrity sha512-FGBx/Qd09lMaqQcogCHyYrFEpTx4cAjeS+48lMIR12z7LdH+zofGDVQSubN59nL6IpubfKqTeIDu9rNO28iHVA== +"@opentelemetry/semantic-conventions@1.15.2", "@opentelemetry/semantic-conventions@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.15.2.tgz#3bafb5de3e20e841dff6cb3c66f4d6e9694c4241" + integrity sha512-CjbOKwk2s+3xPIMcd5UNYQzsf+v94RczbdNix9/kQh38WiQkM90sUOi3if8eyHFgiBjBjhwXrA7W3ydiSQP9mw== "@tootallnate/once@2": version "2.0.0" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== +"@types/shimmer@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/shimmer/-/shimmer-1.0.2.tgz#93eb2c243c351f3f17d5c580c7467ae5d686b65f" + integrity sha512-dKkr1bTxbEsFlh2ARpKzcaAmsYixqt9UyCdoEZk8rHyE4iQYcDCyvSjDSf7JUWJHlJiTtbIoQjxKh6ViywqDAg== + "@types/vscode-webview@^1.57.0": version "1.57.0" resolved "https://registry.yarnpkg.com/@types/vscode-webview/-/vscode-webview-1.57.0.tgz#bad5194d45ae8d03afc1c0f67f71ff5e7a243bbf" integrity sha512-x3Cb/SMa1IwRHfSvKaZDZOTh4cNoG505c3NjTqGlMC082m++x/ETUmtYniDsw6SSmYzZXO8KBNhYxR0+VqymqA== -"@vscode/extension-telemetry@0.7.5": - version "0.7.5" - resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.7.5.tgz#bf965731816e08c3f146f96d901ec67954fc913b" - integrity sha512-fJ5y3TcpqqkFYHneabYaoB4XAhDdVflVm+TDKshw9VOs77jkgNS4UA7LNXrWeO0eDne3Sh3JgURf+xzc1rk69w== +"@vscode/extension-telemetry@^0.8.4": + version "0.8.4" + resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.8.4.tgz#c078c6f55df1c9e0592de3b4ce0f685dd345bfe7" + integrity sha512-UqM9+KZDDK3MyoHTsg6XNM+XO6pweQxzCpqJz33BoBEYAGsbBviRYcVpJglgay2oReuDD2pOI1Nio3BKNDLhWA== 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" + "@microsoft/1ds-core-js" "^3.2.13" + "@microsoft/1ds-post-js" "^3.2.13" + "@microsoft/applicationinsights-web-basic" "^3.0.2" + applicationinsights "^2.7.1" + +acorn-import-assertions@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" + integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== + +acorn@^8.8.2: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== agent-base@6: version "6.0.2" @@ -187,22 +296,24 @@ agent-base@6: dependencies: debug "4" -applicationinsights@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.4.1.tgz#4de4c4dd3c7c4a44445cfbf3d15808fc0dcc423d" - integrity sha512-0n0Ikd0gzSm460xm+M0UTWIwXrhrH/0bqfZatcJjYObWyefxfAxapGEyNnSGd1Tg90neHz+Yhf+Ff/zgvPiQYA== +applicationinsights@^2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.7.3.tgz#8781454d29c0b14c9773f2e892b4cf5e7468ffa5" + integrity sha512-JY8+kTEkjbA+kAVNWDtpfW2lqsrDALfDXuxOs74KLPu2y13fy/9WB52V4LfYVTVcW1/jYOXjTxNS2gPZIDh1iw== dependencies: - "@azure/core-auth" "^1.4.0" - "@azure/core-rest-pipeline" "^1.10.0" + "@azure/core-auth" "^1.5.0" + "@azure/core-rest-pipeline" "1.10.1" + "@azure/core-util" "1.2.0" + "@azure/opentelemetry-instrumentation-azure-sdk" "^1.0.0-beta.5" "@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" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/sdk-trace-base" "^1.15.2" + "@opentelemetry/semantic-conventions" "^1.15.2" cls-hooked "^4.2.2" continuation-local-storage "^3.2.1" - diagnostic-channel "1.1.0" - diagnostic-channel-publishers "1.0.5" + diagnostic-channel "1.1.1" + diagnostic-channel-publishers "1.0.7" async-hook-jl@^1.7.6: version "1.7.6" @@ -224,6 +335,11 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== +cjs-module-lexer@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" + integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== + cls-hooked@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/cls-hooked/-/cls-hooked-4.2.2.tgz#ad2e9a4092680cdaffeb2d3551da0e225eae1908" @@ -248,7 +364,7 @@ continuation-local-storage@^3.2.1: async-listener "^0.6.0" emitter-listener "^1.1.1" -debug@4: +debug@4, debug@^4.1.1: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -260,17 +376,17 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -diagnostic-channel-publishers@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.5.tgz#df8c317086c50f5727fdfb5d2fce214d2e4130ae" - integrity sha512-dJwUS0915pkjjimPJVDnS/QQHsH0aOYhnZsLJdnZIMOrB+csj8RnZhWTuwnm8R5v3Z7OZs+ksv5luC14DGB7eg== +diagnostic-channel-publishers@1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.7.tgz#9b7f8d5ee1295481aee19c827d917e96fedf2c4a" + integrity sha512-SEECbY5AiVt6DfLkhkaHNeshg1CogdLLANA8xlG/TKvS+XUgvIKl7VspJGYiEdL5OUyzMVnr7o0AwB7f+/Mjtg== -diagnostic-channel@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.0.tgz#6985e9dfedfbc072d91dc4388477e4087147756e" - integrity sha512-fwujyMe1gj6rk6dYi9hMZm0c8Mz8NDMVl2LB4iaYh3+LIAThZC8RKFGXWG0IML2OxAit/ZFRgZhMkhQ3d/bobQ== +diagnostic-channel@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.1.tgz#44b60972de9ee055c16216535b0e9db3f6a0efd0" + integrity sha512-r2HV5qFkUICyoaKlBEpLKHjxMXATUf/l+h8UZPGBHGLy4DDiY2sOLcIctax4eRnTw5wH2jTMExLntGPJ8eOJxw== dependencies: - semver "^5.3.0" + semver "^7.5.3" emitter-listener@^1.0.1, emitter-listener@^1.1.1: version "1.1.2" @@ -288,6 +404,18 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + http-proxy-agent@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" @@ -305,6 +433,30 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" +import-in-the-middle@1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/import-in-the-middle/-/import-in-the-middle-1.4.2.tgz#2a266676e3495e72c04bbaa5ec14756ba168391b" + integrity sha512-9WOz1Yh/cvO/p69sxRmhyQwrIGGSp7EIdcb+fFNVi7CzQGQB8U1/1XrKVSbEd/GNOAeM0peJtmi7+qphe7NvAw== + dependencies: + acorn "^8.8.2" + acorn-import-assertions "^1.9.0" + cjs-module-lexer "^1.2.2" + module-details-from-path "^1.0.3" + +is-core-module@^2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" + integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== + dependencies: + has "^1.0.3" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + mime-db@1.52.0: version "1.52.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" @@ -317,17 +469,52 @@ mime-types@^2.1.12: dependencies: mime-db "1.52.0" +module-details-from-path@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/module-details-from-path/-/module-details-from-path-1.0.3.tgz#114c949673e2a8a35e9d35788527aa37b679da2b" + integrity sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A== + ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +require-in-the-middle@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/require-in-the-middle/-/require-in-the-middle-7.2.0.tgz#b539de8f00955444dc8aed95e17c69b0a4f10fcf" + integrity sha512-3TLx5TGyAY6AOqLBoXmHkNql0HIf2RGbuMgCDT2WO/uGVAPJs6h7Kl+bN6TIZGd9bWhWPwnDnTHGtW8Iu77sdw== + dependencies: + debug "^4.1.1" + module-details-from-path "^1.0.3" + resolve "^1.22.1" + +resolve@^1.22.1: + version "1.22.4" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.4.tgz#1dc40df46554cdaf8948a486a10f6ba1e2026c34" + integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + semver@^5.3.0, semver@^5.4.1: version "5.7.2" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -shimmer@^1.1.0, shimmer@^1.2.0: +semver@^7.5.1, semver@^7.5.3: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +shimmer@^1.1.0, shimmer@^1.2.0, shimmer@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337" integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw== @@ -337,6 +524,11 @@ stack-chain@^1.3.7: resolved "https://registry.yarnpkg.com/stack-chain/-/stack-chain-1.3.7.tgz#d192c9ff4ea6a22c94c4dd459171e3f00cea1285" integrity sha512-D8cWtWVdIe/jBA7v5p5Hwl5yOSOrmZPWDPe2KxQ5UAGD+nxbxU0lKXA4h85Ta6+qgdKVL3vUxsbIZjc1kBG7ug== +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + tslib@^2.2.0: version "2.4.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e" @@ -351,3 +543,8 @@ vscode-codicons@^0.0.14: version "0.0.14" resolved "https://registry.yarnpkg.com/vscode-codicons/-/vscode-codicons-0.0.14.tgz#e0d05418e2e195564ff6f6a2199d70415911c18f" integrity sha512-6CEH5KT9ct5WMw7n5dlX7rB8ya4CUI2FSq1Wk36XaW+c5RglFtAanUV0T+gvZVVFhl/WxfjTvFHq06Hz9c1SLA== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== diff --git a/extensions/sql/cgmanifest.json b/extensions/sql/cgmanifest.json index a3092ba903e0a..732474f0dc5ea 100644 --- a/extensions/sql/cgmanifest.json +++ b/extensions/sql/cgmanifest.json @@ -6,7 +6,7 @@ "git": { "name": "microsoft/vscode-mssql", "repositoryUrl": "https://github.com/microsoft/vscode-mssql", - "commitHash": "cb5940297a8cef76daaf4a6b63c4968c9a12d17a" + "commitHash": "9cb3529a978ddf599bf5bdd228f21bbcfe2914f5" } }, "license": "MIT", diff --git a/extensions/sql/syntaxes/sql.tmLanguage.json b/extensions/sql/syntaxes/sql.tmLanguage.json index f05df61a7a045..ba6fac581923d 100644 --- a/extensions/sql/syntaxes/sql.tmLanguage.json +++ b/extensions/sql/syntaxes/sql.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/microsoft/vscode-mssql/commit/cb5940297a8cef76daaf4a6b63c4968c9a12d17a", + "version": "https://github.com/microsoft/vscode-mssql/commit/9cb3529a978ddf599bf5bdd228f21bbcfe2914f5", "name": "SQL", "scopeName": "source.sql", "patterns": [ @@ -372,7 +372,7 @@ "include": "#regexps" }, { - "match": "\\b(?i)(abort|abort_after_wait|absent|absolute|accent_sensitivity|acceptable_cursopt|acp|action|activation|add|address|admin|aes_128|aes_192|aes_256|affinity|after|aggregate|algorithm|all_constraints|all_errormsgs|all_indexes|all_levels|all_results|allow_connections|allow_dup_row|allow_encrypted_value_modifications|allow_page_locks|allow_row_locks|allow_snapshot_isolation|alter|altercolumn|always|anonymous|ansi_defaults|ansi_null_default|ansi_null_dflt_off|ansi_null_dflt_on|ansi_nulls|ansi_padding|ansi_warnings|appdomain|append|application|apply|arithabort|arithignore|array|assembly|asymmetric|asynchronous_commit|at|atan2|atomic|attach|attach_force_rebuild_log|attach_rebuild_log|audit|auth_realm|authentication|auto|auto_cleanup|auto_close|auto_create_statistics|auto_drop|auto_shrink|auto_update_statistics|auto_update_statistics_async|automated_backup_preference|automatic|autopilot|availability|availability_mode|backup|backup_priority|base64|basic|batches|batchsize|before|between|bigint|binary|binding|bit|block|blockers|blocksize|bmk|both|break|broker|broker_instance|bucket_count|buffer|buffercount|bulk_logged|by|call|caller|card|case|catalog|catch|cert|certificate|change_retention|change_tracking|change_tracking_context|changes|char|character|character_set|check_expiration|check_policy|checkconstraints|checkindex|checkpoint|checksum|cleanup_policy|clear|clear_port|close|clustered|codepage|collection|column_encryption_key|column_master_key|columnstore|columnstore_archive|colv_80_to_100|colv_100_to_80|commit_differential_base|committed|compatibility_level|compress_all_row_groups|compression|compression_delay|concat_null_yields_null|concatenate|configuration|connect|continue|continue_after_error|contract|contract_name|control|conversation|conversation_group_id|conversation_handle|copy|copy_only|count_rows|counter|create(\\\\s+or\\\\s+alter)?|credential|cross|cryptographic|cryptographic_provider|cube|cursor|cursor_close_on_commit|cursor_default|data|data_compression|data_flush_interval_seconds|data_mirroring|data_purity|data_source|database|database_name|database_snapshot|datafiletype|date_correlation_optimization|date|datefirst|dateformat|date_format|datetime|datetime2|datetimeoffset|day(s)?|db_chaining|dbid|dbidexec|dbo_only|deadlock_priority|deallocate|dec|decimal|declare|decrypt|decrypt_a|decryption|default_database|default_language|default_logon_domain|default_schema|definition|delay|delayed_durability|delimitedtext|density_vector|dependent|des|description|desired_state|desx|differential|digest|disable|disable_broker|disable_def_cnst_chk|disabled|disk|distinct|distributed|distribution|drop|drop_existing|dts_buffers|dump|durability|dynamic|edition|elements|else|emergency|empty|enable|enable_broker|enabled|encoding|encrypted|encrypted_value|encryption|encryption_type|end|endpoint|endpoint_url|enhancedintegrity|entry|error_broker_conversations|errorfile|estimateonly|event|except|exec|executable|execute|exists|expand|expiredate|expiry_date|explicit|external|external_access|failover|failover_mode|failure_condition_level|fast|fast_forward|fastfirstrow|federated_service_account|fetch|field_terminator|fieldterminator|file|filelistonly|filegroup|filename|filestream|filestream_log|filestream_on|filetable|file_format|filter|first_row|fips_flagger|fire_triggers|first|firstrow|float|flush_interval_seconds|fmtonly|following|force|force_failover_allow_data_loss|force_service_allow_data_loss|forced|forceplan|formatfile|format_options|format_type|formsof|forward_only|free_cursors|free_exec_context|fullscan|fulltext|fulltextall|fulltextkey|function|generated|get|geography|geometry|global|go|goto|governor|guid|hadoop|hardening|hash|hashed|header_limit|headeronly|health_check_timeout|hidden|hierarchyid|histogram|histogram_steps|hits_cursors|hits_exec_context|hour(s)?|http|identity|identity_value|if|ifnull|ignore|ignore_constraints|ignore_dup_key|ignore_dup_row|ignore_triggers|image|immediate|implicit_transactions|include|include_null_values|index|inflectional|init|initiator|insensitive|insert|instead|int|integer|integrated|intersect|intermediate|interval_length_minutes|into|inuse_cursors|inuse_exec_context|io|is|isabout|iso_week|isolation|job_tracker_location|json|keep|keep_nulls|keep_replication|keepdefaults|keepfixed|keepidentity|keepnulls|kerberos|key|key_path|key_source|key_store_provider_name|keyset|kill|kilobytes_per_batch|labelonly|langid|language|last|lastrow|leading|legacy_cardinality_estimation|length|level|lifetime|lineage_80_to_100|lineage_100_to_80|listener_ip|listener_port|load|loadhistory|lob_compaction|local|local_service_name|locate|location|lock_escalation|lock_timeout|lockres|log|login|login_type|loop|manual|mark_in_use_for_removal|masked|master|matched|max_queue_readers|max_duration|max_outstanding_io_per_volume|maxdop|maxerrors|maxlength|maxtransfersize|max_plans_per_query|max_storage_size_mb|mediadescription|medianame|mediapassword|memogroup|memory_optimized|merge|message|message_forward_size|message_forwarding|microsecond|millisecond|minute(s)?|mirror_address|misses_cursors|misses_exec_context|mixed|modify|money|month|move|multi_user|must_change|name|namespace|nanosecond|native|native_compilation|nchar|ncharacter|never|new_account|new_broker|newname|next|no|no_browsetable|no_checksum|no_compression|no_infomsgs|no_triggers|no_truncate|nocount|noexec|noexpand|noformat|noinit|nolock|nonatomic|nonclustered|nondurable|none|norecompute|norecovery|noreset|norewind|noskip|not|notification|nounload|now|nowait|ntext|ntlm|nulls|numeric|numeric_roundabort|nvarchar|object|objid|oem|offline|old_account|online|operation_mode|open|openjson|optimistic|option|orc|out|outer|output|over|override|owner|ownership|pad_index|page|page_checksum|page_verify|pagecount|paglock|param|parameter_sniffing|parameter_type_expansion|parameterization|parquet|parseonly|partial|partition|partner|password|path|pause|percentage|permission_set|persisted|period|physical_only|plan_forcing_mode|policy|pool|population|ports|preceding|precision|predicate|presume_abort|primary|primary_role|print|prior|priority |priority_level|private|proc(edure)?|procedure_name|profile|provider|quarter|query_capture_mode|query_governor_cost_limit|query_optimizer_hotfixes|query_store|queue|quoted_identifier|raiserror|range|raw|rcfile|rc2|rc4|rc4_128|rdbms|read_committed_snapshot|read|read_only|read_write|readcommitted|readcommittedlock|readonly|readpast|readuncommitted|readwrite|real|rebuild|receive|recmodel_70backcomp|recompile|reconfigure|recovery|recursive|recursive_triggers|redo_queue|reject_sample_value|reject_type|reject_value|relative|remote|remote_data_archive|remote_proc_transactions|remote_service_name|remove|removed_cursors|removed_exec_context|reorganize|repeat|repeatable|repeatableread|replace|replica|replicated|replnick_100_to_80|replnickarray_80_to_100|replnickarray_100_to_80|required|required_cursopt|resample|reset|resource|resource_manager_location|respect|restart|restore|restricted_user|resume|retaindays|retention|return|revert|rewind|rewindonly|returns|robust|role|rollup|root|round_robin|route|row|rowdump|rowguidcol|rowlock|row_terminator|rows|rows_per_batch|rowsets_only|rowterminator|rowversion|rsa_1024|rsa_2048|rsa_3072|rsa_4096|rsa_512|safe|safety|sample|save|scalar|schema|schemabinding|scoped|scroll|scroll_locks|sddl|second|secexpr|secondary|secondary_only|secondary_role|secret|security|securityaudit|selective|self|send|sent|sequence|serde_method|serializable|server|service|service_broker|service_name|service_objective|session_timeout|session|sessions|seterror|setopts|sets|shard_map_manager|shard_map_name|sharded|shared_memory|show_statistics|showplan_all|showplan_text|showplan_xml|showplan_xml_with_recompile|shrinkdb|shutdown|sid|signature|simple|single_blob|single_clob|single_nclob|single_user|singleton|site|size_based_cleanup_mode|skip|smalldatetime|smallint|smallmoney|snapshot|snapshot_import|snapshotrestorephase|soap|softnuma|sort_in_tempdb|sorted_data|sorted_data_reorg|spatial|sql|sql_bigint|sql_binary|sql_bit|sql_char|sql_date|sql_decimal|sql_double|sql_float|sql_guid|sql_handle|sql_longvarbinary|sql_longvarchar|sql_numeric|sql_real|sql_smallint|sql_time|sql_timestamp|sql_tinyint|sql_tsi_day|sql_tsi_frac_second|sql_tsi_hour|sql_tsi_minute|sql_tsi_month|sql_tsi_quarter|sql_tsi_second|sql_tsi_week|sql_tsi_year|sql_type_date|sql_type_time|sql_type_timestamp|sql_varbinary|sql_varchar|sql_variant|sql_wchar|sql_wlongvarchar|ssl|ssl_port|standard|standby|start|start_date|started|stat_header|state|statement|static|statistics|statistics_incremental|statistics_norecompute|statistics_only|statman|stats|stats_stream|status|stop|stop_on_error|stopat|stopatmark|stopbeforemark|stoplist|stopped|string_delimiter|subject|supplemental_logging|supported|suspend|symmetric|synchronous_commit|synonym|sysname|system|system_time|system_versioning|table|tableresults|tablock|tablockx|take|tape|target|target_index|target_partition|tcp|temporal_history_retention|text|textimage_on|then|thesaurus|throw|time|timeout|timestamp|tinyint|to|top|torn_page_detection|track_columns_updated|trailing|tran|transaction|transfer|triple_des|triple_des_3key|truncate|trustworthy|try|tsql|type|type_desc|type_warning|tzoffset|uid|unbounded|uncommitted|unique|uniqueidentifier|unlimited|unload|unlock|unsafe|updlock|url|use|useplan|useroptions|use_type_default|using|utcdatetime|valid_xml|validation|value|values|varbinary|varchar|verbose|verifyonly|version|view_metadata|virtual_device|visiblity|wait_at_low_priority|waitfor|webmethod|week|weekday|weight|well_formed_xml|when|while|widechar|widechar_ansi|widenative|window|windows|with|within|within group|witness|without|without_array_wrapper|workload|wsdl|xact_abort|xlock|xml|xmlschema|xquery|xsinil|year|zone)\\b", + "match": "\\b(?i)(abort|abort_after_wait|absent|absolute|accent_sensitivity|acceptable_cursopt|acp|action|activation|add|address|admin|aes_128|aes_192|aes_256|affinity|after|aggregate|algorithm|all_constraints|all_errormsgs|all_indexes|all_levels|all_results|allow_connections|allow_dup_row|allow_encrypted_value_modifications|allow_page_locks|allow_row_locks|allow_snapshot_isolation|alter|altercolumn|always|anonymous|ansi_defaults|ansi_null_default|ansi_null_dflt_off|ansi_null_dflt_on|ansi_nulls|ansi_padding|ansi_warnings|appdomain|append|application|apply|arithabort|arithignore|array|assembly|asymmetric|asynchronous_commit|at|atan2|atomic|attach|attach_force_rebuild_log|attach_rebuild_log|audit|auth_realm|authentication|auto|auto_cleanup|auto_close|auto_create_statistics|auto_drop|auto_shrink|auto_update_statistics|auto_update_statistics_async|automated_backup_preference|automatic|autopilot|availability|availability_mode|backup|backup_priority|base64|basic|batches|batchsize|before|between|bigint|binary|binding|bit|block|blockers|blocksize|bmk|both|break|broker|broker_instance|bucket_count|buffer|buffercount|bulk_logged|by|call|caller|card|case|catalog|catch|cert|certificate|change_retention|change_tracking|change_tracking_context|changes|char|character|character_set|check_expiration|check_policy|checkconstraints|checkindex|checkpoint|checksum|cleanup_policy|clear|clear_port|close|clustered|codepage|collection|column_encryption_key|column_master_key|columnstore|columnstore_archive|colv_80_to_100|colv_100_to_80|commit_differential_base|committed|compatibility_level|compress_all_row_groups|compression|compression_delay|concat_null_yields_null|concatenate|configuration|connect|containment|continue|continue_after_error|contract|contract_name|control|conversation|conversation_group_id|conversation_handle|copy|copy_only|count_rows|counter|create(\\\\s+or\\\\s+alter)?|credential|cross|cryptographic|cryptographic_provider|cube|cursor|cursor_close_on_commit|cursor_default|data|data_compression|data_flush_interval_seconds|data_mirroring|data_purity|data_source|database|database_name|database_snapshot|datafiletype|date_correlation_optimization|date|datefirst|dateformat|date_format|datetime|datetime2|datetimeoffset|day(s)?|db_chaining|dbid|dbidexec|dbo_only|deadlock_priority|deallocate|dec|decimal|declare|decrypt|decrypt_a|decryption|default_database|default_fulltext_language|default_language|default_logon_domain|default_schema|definition|delay|delayed_durability|delimitedtext|density_vector|dependent|des|description|desired_state|desx|differential|digest|disable|disable_broker|disable_def_cnst_chk|disabled|disk|distinct|distributed|distribution|drop|drop_existing|dts_buffers|dump|durability|dynamic|edition|elements|else|emergency|empty|enable|enable_broker|enabled|encoding|encrypted|encrypted_value|encryption|encryption_type|end|endpoint|endpoint_url|enhancedintegrity|entry|error_broker_conversations|errorfile|estimateonly|event|except|exec|executable|execute|exists|expand|expiredate|expiry_date|explicit|external|external_access|failover|failover_mode|failure_condition_level|fast|fast_forward|fastfirstrow|federated_service_account|fetch|field_terminator|fieldterminator|file|filelistonly|filegroup|filegrowth|filename|filestream|filestream_log|filestream_on|filetable|file_format|filter|first_row|fips_flagger|fire_triggers|first|firstrow|float|flush_interval_seconds|fmtonly|following|for|force|force_failover_allow_data_loss|force_service_allow_data_loss|forced|forceplan|formatfile|format_options|format_type|formsof|forward_only|free_cursors|free_exec_context|fullscan|fulltext|fulltextall|fulltextkey|function|generated|get|geography|geometry|global|go|goto|governor|guid|hadoop|hardening|hash|hashed|header_limit|headeronly|health_check_timeout|hidden|hierarchyid|histogram|histogram_steps|hits_cursors|hits_exec_context|hour(s)?|http|identity|identity_value|if|ifnull|ignore|ignore_constraints|ignore_dup_key|ignore_dup_row|ignore_triggers|image|immediate|implicit_transactions|include|include_null_values|incremental|index|inflectional|init|initiator|insensitive|insert|instead|int|integer|integrated|intersect|intermediate|interval_length_minutes|into|inuse_cursors|inuse_exec_context|io|is|isabout|iso_week|isolation|job_tracker_location|json|keep|keep_nulls|keep_replication|keepdefaults|keepfixed|keepidentity|keepnulls|kerberos|key|key_path|key_source|key_store_provider_name|keyset|kill|kilobytes_per_batch|labelonly|langid|language|last|lastrow|leading|legacy_cardinality_estimation|length|level|lifetime|lineage_80_to_100|lineage_100_to_80|listener_ip|listener_port|load|loadhistory|lob_compaction|local|local_service_name|locate|location|lock_escalation|lock_timeout|lockres|log|login|login_type|loop|manual|mark_in_use_for_removal|masked|master|matched|max_queue_readers|max_duration|max_outstanding_io_per_volume|maxdop|maxerrors|maxlength|maxtransfersize|max_plans_per_query|max_storage_size_mb|mediadescription|medianame|mediapassword|memogroup|memory_optimized|merge|message|message_forward_size|message_forwarding|microsecond|millisecond|minute(s)?|mirror_address|misses_cursors|misses_exec_context|mixed|modify|money|month|move|multi_user|must_change|name|namespace|nanosecond|native|native_compilation|nchar|ncharacter|nested_triggers|never|new_account|new_broker|newname|next|no|no_browsetable|no_checksum|no_compression|no_infomsgs|no_triggers|no_truncate|nocount|noexec|noexpand|noformat|noinit|nolock|nonatomic|nonclustered|nondurable|none|norecompute|norecovery|noreset|norewind|noskip|not|notification|nounload|now|nowait|ntext|ntlm|nulls|numeric|numeric_roundabort|nvarchar|object|objid|oem|offline|old_account|online|operation_mode|open|openjson|optimistic|option|orc|out|outer|output|over|override|owner|ownership|pad_index|page|page_checksum|page_verify|pagecount|paglock|param|parameter_sniffing|parameter_type_expansion|parameterization|parquet|parseonly|partial|partition|partner|password|path|pause|percentage|permission_set|persisted|period|physical_only|plan_forcing_mode|policy|pool|population|ports|preceding|precision|predicate|presume_abort|primary|primary_role|print|prior|priority |priority_level|private|proc(edure)?|procedure_name|profile|provider|quarter|query_capture_mode|query_governor_cost_limit|query_optimizer_hotfixes|query_store|queue|quoted_identifier|raiserror|range|raw|rcfile|rc2|rc4|rc4_128|rdbms|read_committed_snapshot|read|read_only|read_write|readcommitted|readcommittedlock|readonly|readpast|readuncommitted|readwrite|real|rebuild|receive|recmodel_70backcomp|recompile|reconfigure|recovery|recursive|recursive_triggers|redo_queue|reject_sample_value|reject_type|reject_value|relative|remote|remote_data_archive|remote_proc_transactions|remote_service_name|remove|removed_cursors|removed_exec_context|reorganize|repeat|repeatable|repeatableread|replace|replica|replicated|replnick_100_to_80|replnickarray_80_to_100|replnickarray_100_to_80|required|required_cursopt|resample|reset|resource|resource_manager_location|respect|restart|restore|restricted_user|resume|retaindays|retention|return|revert|rewind|rewindonly|returns|robust|role|rollup|root|round_robin|route|row|rowdump|rowguidcol|rowlock|row_terminator|rows|rows_per_batch|rowsets_only|rowterminator|rowversion|rsa_1024|rsa_2048|rsa_3072|rsa_4096|rsa_512|safe|safety|sample|save|scalar|schema|schemabinding|scoped|scroll|scroll_locks|sddl|second|secexpr|seconds|secondary|secondary_only|secondary_role|secret|security|securityaudit|selective|self|send|sent|sequence|serde_method|serializable|server|service|service_broker|service_name|service_objective|session_timeout|session|sessions|seterror|setopts|sets|shard_map_manager|shard_map_name|sharded|shared_memory|show_statistics|showplan_all|showplan_text|showplan_xml|showplan_xml_with_recompile|shrinkdb|shutdown|sid|signature|simple|single_blob|single_clob|single_nclob|single_user|singleton|site|size|size_based_cleanup_mode|skip|smalldatetime|smallint|smallmoney|snapshot|snapshot_import|snapshotrestorephase|soap|softnuma|sort_in_tempdb|sorted_data|sorted_data_reorg|spatial|sql|sql_bigint|sql_binary|sql_bit|sql_char|sql_date|sql_decimal|sql_double|sql_float|sql_guid|sql_handle|sql_longvarbinary|sql_longvarchar|sql_numeric|sql_real|sql_smallint|sql_time|sql_timestamp|sql_tinyint|sql_tsi_day|sql_tsi_frac_second|sql_tsi_hour|sql_tsi_minute|sql_tsi_month|sql_tsi_quarter|sql_tsi_second|sql_tsi_week|sql_tsi_year|sql_type_date|sql_type_time|sql_type_timestamp|sql_varbinary|sql_varchar|sql_variant|sql_wchar|sql_wlongvarchar|ssl|ssl_port|standard|standby|start|start_date|started|stat_header|state|statement|static|statistics|statistics_incremental|statistics_norecompute|statistics_only|statman|stats|stats_stream|status|stop|stop_on_error|stopat|stopatmark|stopbeforemark|stoplist|stopped|string_delimiter|subject|supplemental_logging|supported|suspend|symmetric|synchronous_commit|synonym|sysname|system|system_time|system_versioning|table|tableresults|tablock|tablockx|take|tape|target|target_index|target_partition|target_recovery_time|tcp|temporal_history_retention|text|textimage_on|then|thesaurus|throw|time|timeout|timestamp|tinyint|to|top|torn_page_detection|track_columns_updated|trailing|tran|transaction|transfer|transform_noise_words|triple_des|triple_des_3key|truncate|trustworthy|try|tsql|two_digit_year_cutoff|type|type_desc|type_warning|tzoffset|uid|unbounded|uncommitted|unique|uniqueidentifier|unlimited|unload|unlock|unsafe|updlock|url|use|useplan|useroptions|use_type_default|using|utcdatetime|valid_xml|validation|value|values|varbinary|varchar|verbose|verifyonly|version|view_metadata|virtual_device|visiblity|wait_at_low_priority|waitfor|webmethod|week|weekday|weight|well_formed_xml|when|while|widechar|widechar_ansi|widenative|window|windows|with|within|within group|witness|without|without_array_wrapper|workload|wsdl|xact_abort|xlock|xml|xmlschema|xquery|xsinil|year|zone)\\b", "name": "keyword.other.sql" }, { diff --git a/extensions/theme-defaults/themes/dark_modern.json b/extensions/theme-defaults/themes/dark_modern.json index 14fc09e91c1da..e1055e8a4e2b2 100644 --- a/extensions/theme-defaults/themes/dark_modern.json +++ b/extensions/theme-defaults/themes/dark_modern.json @@ -3,136 +3,124 @@ "name": "Default Dark Modern", "include": "./dark_plus.json", "colors": { - "activityBar.activeBorder": "#0078d4", + "activityBar.activeBorder": "#0078D4", "activityBar.background": "#181818", - "activityBar.border": "#ffffff15", - "activityBar.foreground": "#d7d7d7", - "activityBar.inactiveForeground": "#ffffff80", - "activityBarBadge.background": "#0078d4", - "activityBarBadge.foreground": "#ffffff", - "badge.background": "#0078d4", - "badge.foreground": "#ffffff", - "button.background": "#0078d4", - "button.border": "#ffffff12", - "button.foreground": "#ffffff", - "button.hoverBackground": "#0078d4e6", - "button.secondaryBackground": "#FFFFFF0F", - "button.secondaryForeground": "#cccccc", - "button.secondaryHoverBackground": "#ffffff15", + "activityBar.border": "#2B2B2B", + "activityBar.foreground": "#D7D7D7", + "activityBar.inactiveForeground": "#868686", + "activityBarBadge.background": "#0078D4", + "activityBarBadge.foreground": "#FFFFFF", + "badge.background": "#616161", + "badge.foreground": "#F8F8F8", + "button.background": "#0078D4", + "button.border": "#FFFFFF12", + "button.foreground": "#FFFFFF", + "button.hoverBackground": "#026EC1", + "button.secondaryBackground": "#313131", + "button.secondaryForeground": "#CCCCCC", + "button.secondaryHoverBackground": "#3C3C3C", + "chat.slashCommandBackground": "#34414B", + "chat.slashCommandForeground": "#40A6FF", "checkbox.background": "#313131", - "checkbox.border": "#ffffff1f", + "checkbox.border": "#3C3C3C", "debugToolBar.background": "#181818", - "descriptionForeground": "#8b949e", - "diffEditor.insertedLineBackground": "#23863633", - "diffEditor.insertedTextBackground": "#2386364d", - "diffEditor.removedLineBackground": "#da363333", - "diffEditor.removedTextBackground": "#da36334d", + "descriptionForeground": "#9D9D9D", "dropdown.background": "#313131", - "dropdown.border": "#ffffff1f", - "dropdown.foreground": "#cccccc", - "dropdown.listBackground": "#1f1f1f", - "editor.background": "#1f1f1f", - "editor.findMatchBackground": "#9e6a03", - "editor.foreground": "#cccccc", - "editorGroup.border": "#ffffff17", + "dropdown.border": "#3C3C3C", + "dropdown.foreground": "#CCCCCC", + "dropdown.listBackground": "#1F1F1F", + "editor.background": "#1F1F1F", + "editor.findMatchBackground": "#9E6A03", + "editor.foreground": "#CCCCCC", + "editorGroup.border": "#FFFFFF17", "editorGroupHeader.tabsBackground": "#181818", - "editorGroupHeader.tabsBorder": "#ffffff15", - "editorGutter.addedBackground": "#2ea043", - "editorGutter.deletedBackground": "#f85149", - "editorGutter.modifiedBackground": "#0078d4", - "editorInlayHint.background": "#8b949e1b", - "editorInlayHint.typeBackground": "#8b949e1b", - "editorLineNumber.activeForeground": "#cccccc", - "editorLineNumber.foreground": "#6e7681", + "editorGroupHeader.tabsBorder": "#2B2B2B", + "editorGutter.addedBackground": "#2EA043", + "editorGutter.deletedBackground": "#F85149", + "editorGutter.modifiedBackground": "#0078D4", + "editorLineNumber.activeForeground": "#CCCCCC", + "editorLineNumber.foreground": "#6E7681", "editorOverviewRuler.border": "#010409", - "editorWidget.background": "#1f1f1f", - "errorForeground": "#f85149", - "focusBorder": "#0078d4", - "foreground": "#cccccc", - "icon.foreground": "#cccccc", - "input.background": "#2a2a2a", - "input.border": "#ffffff1f", - "input.foreground": "#cccccc", - "input.placeholderForeground": "#ffffff79", - "inputOption.activeBackground": "#2489db82", - "inputOption.activeBorder": "#2488db", - "keybindingLabel.foreground": "#cccccc", - "list.activeSelectionBackground": "#323232", - "list.activeSelectionIconForeground": "#ffffff", - "list.activeSelectionForeground": "#ffffff", - "menu.background": "#1f1f1f", - "notificationCenterHeader.background": "#1f1f1f", - "notificationCenterHeader.foreground": "#cccccc", - "notifications.background": "#1f1f1f", - "notifications.border": "#ffffff15", - "notifications.foreground": "#cccccc", + "editorWidget.background": "#202020", + "errorForeground": "#F85149", + "focusBorder": "#0078D4", + "foreground": "#CCCCCC", + "icon.foreground": "#CCCCCC", + "input.background": "#313131", + "input.border": "#3C3C3C", + "input.foreground": "#CCCCCC", + "input.placeholderForeground": "#9D9D9D", + "inputOption.activeBackground": "#2489DB82", + "inputOption.activeBorder": "#2488DB", + "keybindingLabel.foreground": "#CCCCCC", + "menu.background": "#1F1F1F", + "notificationCenterHeader.background": "#1F1F1F", + "notificationCenterHeader.foreground": "#CCCCCC", + "notifications.background": "#1F1F1F", + "notifications.border": "#2B2B2B", + "notifications.foreground": "#CCCCCC", "panel.background": "#181818", - "panel.border": "#ffffff15", - "panelInput.border": "#ffffff15", - "panelTitle.activeBorder": "#0078d4", - "panelTitle.activeForeground": "#cccccc", - "panelTitle.inactiveForeground": "#8b949e", - "peekViewEditor.background": "#1f1f1f", - "peekViewEditor.matchHighlightBackground": "#bb800966", - "peekViewResult.background": "#1f1f1f", - "peekViewResult.matchHighlightBackground": "#bb800966", - "pickerGroup.border": "#ffffff15", - "pickerGroup.foreground": "#8b949e", - "progressBar.background": "#0078d4", - "quickInput.background": "#1f1f1f", - "quickInput.foreground": "#cccccc", - "scrollbar.shadow": "#484f5833", - "scrollbarSlider.activeBackground": "#6e768187", - "scrollbarSlider.background": "#6e768133", - "scrollbarSlider.hoverBackground": "#6e768145", + "panel.border": "#2B2B2B", + "panelInput.border": "#2B2B2B", + "panelTitle.activeBorder": "#0078D4", + "panelTitle.activeForeground": "#CCCCCC", + "panelTitle.inactiveForeground": "#9D9D9D", + "peekViewEditor.background": "#1F1F1F", + "peekViewEditor.matchHighlightBackground": "#BB800966", + "peekViewResult.background": "#1F1F1F", + "peekViewResult.matchHighlightBackground": "#BB800966", + "pickerGroup.border": "#3C3C3C", + "progressBar.background": "#0078D4", + "quickInput.background": "#222222", + "quickInput.foreground": "#CCCCCC", "settings.dropdownBackground": "#313131", - "settings.dropdownBorder": "#ffffff1f", - "settings.headerForeground": "#ffffff", - "settings.modifiedItemIndicator": "#bb800966", + "settings.dropdownBorder": "#3C3C3C", + "settings.headerForeground": "#FFFFFF", + "settings.modifiedItemIndicator": "#BB800966", "sideBar.background": "#181818", - "sideBar.border": "#ffffff15", - "sideBar.foreground": "#cccccc", + "sideBar.border": "#2B2B2B", + "sideBar.foreground": "#CCCCCC", "sideBarSectionHeader.background": "#181818", - "sideBarSectionHeader.border": "#ffffff15", - "sideBarSectionHeader.foreground": "#cccccc", - "sideBarTitle.foreground": "#cccccc", + "sideBarSectionHeader.border": "#2B2B2B", + "sideBarSectionHeader.foreground": "#CCCCCC", + "sideBarTitle.foreground": "#CCCCCC", "statusBar.background": "#181818", - "statusBar.border": "#ffffff15", - "statusBar.debuggingBackground": "#0078d4", - "statusBar.debuggingForeground": "#ffffff", - "statusBar.focusBorder": "#0078d4", - "statusBar.foreground": "#cccccc", - "statusBar.noFolderBackground": "#1f1f1f", - "statusBarItem.focusBorder": "#0078d4", - "statusBarItem.prominentBackground": "#6e768166", - "statusBarItem.remoteBackground": "#0078d4", - "statusBarItem.remoteForeground": "#ffffff", - "tab.activeBackground": "#1f1f1f", - "tab.activeBorder": "#1f1f1f", - "tab.activeBorderTop": "#0078d4", - "tab.activeForeground": "#ffffff", - "tab.border": "#ffffff15", - "tab.hoverBackground": "#1f1f1f", + "statusBar.border": "#2B2B2B", + "statusBar.debuggingBackground": "#0078D4", + "statusBar.debuggingForeground": "#FFFFFF", + "statusBar.focusBorder": "#0078D4", + "statusBar.foreground": "#CCCCCC", + "statusBar.noFolderBackground": "#1F1F1F", + "statusBarItem.focusBorder": "#0078D4", + "statusBarItem.prominentBackground": "#6E768166", + "statusBarItem.remoteBackground": "#0078D4", + "statusBarItem.remoteForeground": "#FFFFFF", + "tab.activeBackground": "#1F1F1F", + "tab.activeBorder": "#1F1F1F", + "tab.activeBorderTop": "#0078D4", + "tab.activeForeground": "#FFFFFF", + "tab.border": "#2B2B2B", + "tab.hoverBackground": "#1F1F1F", "tab.inactiveBackground": "#181818", - "tab.inactiveForeground": "#ffffff80", - "tab.unfocusedActiveBorder": "#1f1f1f", - "tab.unfocusedActiveBorderTop": "#ffffff15", - "tab.unfocusedHoverBackground": "#6e76811a", - "terminal.foreground": "#cccccc", - "terminal.tab.activeBorder": "#0078d4", - "textBlockQuote.background": "#010409", - "textBlockQuote.border": "#ffffff14", - "textCodeBlock.background": "#6e768166", + "tab.inactiveForeground": "#9D9D9D", + "tab.unfocusedActiveBorder": "#1F1F1F", + "tab.unfocusedActiveBorderTop": "#2B2B2B", + "tab.unfocusedHoverBackground": "#1F1F1F", + "terminal.foreground": "#CCCCCC", + "terminal.tab.activeBorder": "#0078D4", + "textBlockQuote.background": "#2B2B2B", + "textBlockQuote.border": "#616161", + "textCodeBlock.background": "#2B2B2B", "textLink.activeForeground": "#40A6FF", "textLink.foreground": "#40A6FF", - "textSeparator.foreground": "#21262d", + "textSeparator.foreground": "#21262D", "titleBar.activeBackground": "#181818", - "titleBar.activeForeground": "#cccccc", - "titleBar.border": "#ffffff15", - "titleBar.inactiveBackground": "#1f1f1f", - "titleBar.inactiveForeground": "#8b949e", - "welcomePage.tileBackground": "#ffffff0f", - "welcomePage.progress.foreground": "#0078d4", - "widget.border": "#ffffff15", + "titleBar.activeForeground": "#CCCCCC", + "titleBar.border": "#2B2B2B", + "titleBar.inactiveBackground": "#1F1F1F", + "titleBar.inactiveForeground": "#9D9D9D", + "welcomePage.tileBackground": "#2B2B2B", + "welcomePage.progress.foreground": "#0078D4", + "widget.border": "#313131", }, } diff --git a/extensions/theme-defaults/themes/dark_vs.json b/extensions/theme-defaults/themes/dark_vs.json index 38af44cd2c164..2b9f0d5a5ab7b 100644 --- a/extensions/theme-defaults/themes/dark_vs.json +++ b/extensions/theme-defaults/themes/dark_vs.json @@ -26,6 +26,7 @@ "list.activeSelectionIconForeground": "#FFF", "terminal.inactiveSelectionBackground": "#3A3D41", "widget.border": "#303031", + "actionBar.toggledBackground": "#383a49" }, "tokenColors": [ { @@ -33,6 +34,7 @@ "meta.embedded", "source.groovy.embedded", "string meta.image.inline.markdown", + "variable.legacy.builtin.python" ], "settings": { "foreground": "#D4D4D4" diff --git a/extensions/theme-defaults/themes/hc_black.json b/extensions/theme-defaults/themes/hc_black.json index b8eda7974b731..816fbf9395add 100644 --- a/extensions/theme-defaults/themes/hc_black.json +++ b/extensions/theme-defaults/themes/hc_black.json @@ -11,14 +11,16 @@ "editor.selectionBackground": "#FFFFFF", "statusBarItem.remoteBackground": "#00000000", "ports.iconRunningProcessForeground": "#FFFFFF", - "editorWhitespace.foreground": "#7c7c7c" + "editorWhitespace.foreground": "#7c7c7c", + "actionBar.toggledBackground": "#383a49" }, "tokenColors": [ { "scope": [ "meta.embedded", "source.groovy.embedded", - "string meta.image.inline.markdown" + "string meta.image.inline.markdown", + "variable.legacy.builtin.python" ], "settings": { "foreground": "#FFFFFF" diff --git a/extensions/theme-defaults/themes/hc_light.json b/extensions/theme-defaults/themes/hc_light.json index 83a4083f90b83..17c1af9ef346c 100644 --- a/extensions/theme-defaults/themes/hc_light.json +++ b/extensions/theme-defaults/themes/hc_light.json @@ -3,7 +3,11 @@ "name": "Light High Contrast", "tokenColors": [ { - "scope": ["meta.embedded", "source.groovy.embedded"], + "scope": [ + "meta.embedded", + "source.groovy.embedded", + "variable.legacy.builtin.python" + ], "settings": { "foreground": "#292929" } @@ -562,5 +566,8 @@ "foreground": "#800080" } } - ] + ], + "colors": { + "actionBar.toggledBackground": "#dddddd" + } } diff --git a/extensions/theme-defaults/themes/light_modern.json b/extensions/theme-defaults/themes/light_modern.json index 5640a255dc156..d5bf68ba831cf 100644 --- a/extensions/theme-defaults/themes/light_modern.json +++ b/extensions/theme-defaults/themes/light_modern.json @@ -4,147 +4,140 @@ "include": "./light_plus.json", "colors": { "activityBar.activeBorder": "#005FB8", - "activityBar.background": "#f8f8f8", - "activityBar.border": "#0000001a", - "activityBar.foreground": "#1f1f1f", - "activityBar.inactiveForeground": "#0000009e", + "activityBar.background": "#F8F8F8", + "activityBar.border": "#E5E5E5", + "activityBar.foreground": "#1F1F1F", + "activityBar.inactiveForeground": "#616161", "activityBarBadge.background": "#005FB8", - "activityBarBadge.foreground": "#ffffff", - "badge.background": "#005FB8", - "badge.foreground": "#ffffff", + "activityBarBadge.foreground": "#FFFFFF", + "badge.background": "#CCCCCC", + "badge.foreground": "#3B3B3B", "button.background": "#005FB8", "button.border": "#0000001a", - "button.foreground": "#ffffff", - "button.hoverBackground": "#005FB8e6", - "button.secondaryBackground": "#0000001a", - "button.secondaryForeground": "#3b3b3b", - "button.secondaryHoverBackground": "#00000034", - "checkbox.background": "#f8f8f8", + "button.foreground": "#FFFFFF", + "button.hoverBackground": "#0258A8", + "button.secondaryBackground": "#E5E5E5", + "button.secondaryForeground": "#3B3B3B", + "button.secondaryHoverBackground": "#CCCCCC", + "chat.slashCommandBackground": "#D2ECFF", + "chat.slashCommandForeground": "#306CA2", + "checkbox.background": "#F8F8F8", "checkbox.border": "#CECECE", - "descriptionForeground": "#3b3b3b", - "diffEditor.insertedLineBackground": "#23863633", - "diffEditor.insertedTextBackground": "#2386364d", - "diffEditor.removedLineBackground": "#da363333", - "diffEditor.removedTextBackground": "#da36334d", - "dropdown.background": "#ffffff", + "descriptionForeground": "#3B3B3B", + "dropdown.background": "#FFFFFF", "dropdown.border": "#CECECE", - "dropdown.foreground": "#3b3b3b", - "dropdown.listBackground": "#ffffff", - "editor.background": "#ffffff", - "editor.foreground": "#3b3b3b", + "dropdown.foreground": "#3B3B3B", + "dropdown.listBackground": "#FFFFFF", + "editor.background": "#FFFFFF", + "editor.foreground": "#3B3B3B", "editor.inactiveSelectionBackground": "#E5EBF1", "editor.selectionHighlightBackground": "#ADD6FF80", - "editorGroup.border": "#0000001a", - "editorGroupHeader.tabsBackground": "#f8f8f8", - "editorGroupHeader.tabsBorder": "#0000001a", - "editorGutter.addedBackground": "#2ea043", - "editorGutter.deletedBackground": "#f85149", + "editorGroup.border": "#E5E5E5", + "editorGroupHeader.tabsBackground": "#F8F8F8", + "editorGroupHeader.tabsBorder": "#E5E5E5", + "editorGutter.addedBackground": "#2EA043", + "editorGutter.deletedBackground": "#F85149", "editorGutter.modifiedBackground": "#005FB8", "editorIndentGuide.background": "#D3D3D3", - "editorInlayHint.background": "#8b949e1b", - "editorInlayHint.typeBackground": "#8b949e1b", "editorLineNumber.activeForeground": "#171184", - "editorLineNumber.foreground": "#6e7681", - "editorOverviewRuler.border": "#0000001a", - "editorSuggestWidget.background": "#f8f8f8", - "editorWidget.background": "#ffffff", - "errorForeground": "#f85149", + "editorLineNumber.foreground": "#6E7681", + "editorOverviewRuler.border": "#E5E5E5", + "editorSuggestWidget.background": "#F8F8F8", + "editorWidget.background": "#F8F8F8", + "errorForeground": "#F85149", "focusBorder": "#005FB8", - "foreground": "#3b3b3b", - "icon.foreground": "#3b3b3b", - "input.background": "#ffffff", + "foreground": "#3B3B3B", + "icon.foreground": "#3B3B3B", + "input.background": "#FFFFFF", "input.border": "#CECECE", - "input.foreground": "#3b3b3b", - "input.placeholderForeground": "#00000079", - "inputOption.activeBackground": "#005fb841", + "input.foreground": "#3B3B3B", + "input.placeholderForeground": "#868686", + "inputOption.activeBackground": "#BED6ED", "inputOption.activeBorder": "#005FB8", "inputOption.activeForeground": "#000000", - "keybindingLabel.foreground": "#3b3b3b", - "list.activeSelectionBackground": "#e8e8e8", + "keybindingLabel.foreground": "#3B3B3B", + "list.activeSelectionBackground": "#E8E8E8", "list.activeSelectionForeground": "#000000", "list.activeSelectionIconForeground": "#000000", - "list.hoverBackground": "#f2f2f2", - "menu.border": "#D4D4D4", - "notebook.cellBorderColor": "#E8E8E8", - "notebook.selectedCellBackground": "#c8ddf150", - "notificationCenterHeader.background": "#ffffff", - "notificationCenterHeader.foreground": "#3b3b3b", - "notifications.background": "#ffffff", - "notifications.border": "#0000001a", - "notifications.foreground": "#3b3b3b", - "panel.background": "#f8f8f8", - "panel.border": "#0000001a", - "panelInput.border": "#0000001a", + "list.hoverBackground": "#F2F2F2", + "list.focusAndSelectionOutline": "#005FB8", + "menu.border": "#CECECE", + "notebook.cellBorderColor": "#E5E5E5", + "notebook.selectedCellBackground": "#C8DDF150", + "notificationCenterHeader.background": "#FFFFFF", + "notificationCenterHeader.foreground": "#3B3B3B", + "notifications.background": "#FFFFFF", + "notifications.border": "#E5E5E5", + "notifications.foreground": "#3B3B3B", + "panel.background": "#F8F8F8", + "panel.border": "#E5E5E5", + "panelInput.border": "#E5E5E5", "panelTitle.activeBorder": "#005FB8", - "panelTitle.activeForeground": "#3b3b3b", - "panelTitle.inactiveForeground": "#3b3b3b", - "peekViewEditor.matchHighlightBackground": "#bb800966", - "peekViewResult.background": "#ffffff", - "peekViewResult.matchHighlightBackground": "#bb800966", - "pickerGroup.border": "#0000001a", - "pickerGroup.foreground": "#8b949e", + "panelTitle.activeForeground": "#3B3B3B", + "panelTitle.inactiveForeground": "#3B3B3B", + "peekViewEditor.matchHighlightBackground": "#BB800966", + "peekViewResult.background": "#FFFFFF", + "peekViewResult.matchHighlightBackground": "#BB800966", + "pickerGroup.border": "#E5E5E5", + "pickerGroup.foreground": "#8B949E", "ports.iconRunningProcessForeground": "#369432", "progressBar.background": "#005FB8", - "quickInput.background": "#ffffff", - "quickInput.foreground": "#3b3b3b", - "scrollbar.shadow": "#484f5833", - "scrollbarSlider.activeBackground": "#6e768187", - "scrollbarSlider.background": "#6e768133", - "scrollbarSlider.hoverBackground": "#6e768145", + "quickInput.background": "#F8F8F8", + "quickInput.foreground": "#3B3B3B", "searchEditor.textInputBorder": "#CECECE", - "settings.dropdownBackground": "#ffffff", + "settings.dropdownBackground": "#FFFFFF", "settings.dropdownBorder": "#CECECE", - "settings.headerForeground": "#1f1f1f", - "settings.modifiedItemIndicator": "#bb800966", + "settings.headerForeground": "#1F1F1F", + "settings.modifiedItemIndicator": "#BB800966", "settings.numberInputBorder": "#CECECE", "settings.textInputBorder": "#CECECE", - "sideBar.background": "#f8f8f8", - "sideBar.border": "#0000001a", - "sideBar.foreground": "#3b3b3b", - "sideBarSectionHeader.background": "#f8f8f8", - "sideBarSectionHeader.border": "#0000001a", - "sideBarSectionHeader.foreground": "#3b3b3b", - "sideBarTitle.foreground": "#3b3b3b", - "statusBar.background": "#f8f8f8", - "statusBar.foreground": "#3b3b3b", - "statusBar.border": "#0000001a", - "statusBar.debuggingBackground": "#fd716c", + "sideBar.background": "#F8F8F8", + "sideBar.border": "#E5E5E5", + "sideBar.foreground": "#3B3B3B", + "sideBarSectionHeader.background": "#F8F8F8", + "sideBarSectionHeader.border": "#E5E5E5", + "sideBarSectionHeader.foreground": "#3B3B3B", + "sideBarTitle.foreground": "#3B3B3B", + "statusBar.background": "#F8F8F8", + "statusBar.foreground": "#3B3B3B", + "statusBar.border": "#E5E5E5", + "statusBar.debuggingBackground": "#FD716C", "statusBar.debuggingForeground": "#000000", "statusBar.focusBorder": "#005FB8", - "statusBar.noFolderBackground": "#f8f8f8", - "statusBarItem.errorBackground": "#c72e0f", + "statusBar.noFolderBackground": "#F8F8F8", + "statusBarItem.errorBackground": "#C72E0F", "statusBarItem.focusBorder": "#005FB8", - "statusBarItem.prominentBackground": "#6e768166", + "statusBarItem.prominentBackground": "#6E768166", "statusBarItem.remoteBackground": "#005FB8", - "statusBarItem.remoteForeground": "#ffffff", - "tab.activeBackground": "#ffffff", - "tab.activeBorder": "#f8f8f8", + "statusBarItem.remoteForeground": "#FFFFFF", + "tab.activeBackground": "#FFFFFF", + "tab.activeBorder": "#F8F8F8", "tab.activeBorderTop": "#005FB8", - "tab.activeForeground": "#3b3b3b", - "tab.border": "#0000001a", - "tab.hoverBackground": "#ffffff", - "tab.inactiveBackground": "#f8f8f8", - "tab.inactiveForeground": "#00000080", - "tab.lastPinnedBorder": "#3b3b3b30", - "tab.unfocusedActiveBorder": "#f8f8f8", - "tab.unfocusedActiveBorderTop": "#00000015", - "tab.unfocusedHoverBackground": "#6e76811a", + "tab.activeForeground": "#3B3B3B", + "tab.border": "#E5E5E5", + "tab.hoverBackground": "#FFFFFF", + "tab.inactiveBackground": "#F8F8F8", + "tab.inactiveForeground": "#868686", + "tab.lastPinnedBorder": "#D4D4D4", + "tab.unfocusedActiveBorder": "#F8F8F8", + "tab.unfocusedActiveBorderTop": "#E5E5E5", + "tab.unfocusedHoverBackground": "#F8F8F8", "terminalCursor.foreground": "#005FB8", - "terminal.foreground": "#3b3b3b", + "terminal.foreground": "#3B3B3B", "terminal.inactiveSelectionBackground": "#E5EBF1", - "terminal.tab.activeBorder": "#005fb8", - "textBlockQuote.background": "#f8f8f8", - "textBlockQuote.border": "#0000001a", - "textCodeBlock.background": "#f2f2f2", + "terminal.tab.activeBorder": "#005FB8", + "textBlockQuote.background": "#F8F8F8", + "textBlockQuote.border": "#E5E5E5", + "textCodeBlock.background": "#F8F8F8", "textLink.activeForeground": "#005FB8", "textLink.foreground": "#005FB8", - "textSeparator.foreground": "#21262d", - "titleBar.activeBackground": "#f8f8f8", - "titleBar.activeForeground": "#1e1e1e", - "titleBar.border": "#0000001a", - "titleBar.inactiveBackground": "#f8f8f8", - "titleBar.inactiveForeground": "#8b949e", - "welcomePage.tileBackground": "#f3f3f3", - "widget.border": "#0000001a", + "textSeparator.foreground": "#21262D", + "titleBar.activeBackground": "#F8F8F8", + "titleBar.activeForeground": "#1E1E1E", + "titleBar.border": "#E5E5E5", + "titleBar.inactiveBackground": "#F8F8F8", + "titleBar.inactiveForeground": "#8B949E", + "welcomePage.tileBackground": "#F3F3F3", + "widget.border": "#E5E5E5" }, } diff --git a/extensions/theme-defaults/themes/light_vs.json b/extensions/theme-defaults/themes/light_vs.json index 89589bb0e74ff..5e2d5a7889e9f 100644 --- a/extensions/theme-defaults/themes/light_vs.json +++ b/extensions/theme-defaults/themes/light_vs.json @@ -30,14 +30,16 @@ "list.activeSelectionIconForeground": "#FFF", "list.focusAndSelectionOutline": "#90C2F9", "terminal.inactiveSelectionBackground": "#E5EBF1", - "widget.border": "#d4d4d4" + "widget.border": "#d4d4d4", + "actionBar.toggledBackground": "#dddddd" }, "tokenColors": [ { "scope": [ "meta.embedded", "source.groovy.embedded", - "string meta.image.inline.markdown" + "string meta.image.inline.markdown", + "variable.legacy.builtin.python" ], "settings": { "foreground": "#000000ff" diff --git a/extensions/theme-kimbie-dark/themes/kimbie-dark-color-theme.json b/extensions/theme-kimbie-dark/themes/kimbie-dark-color-theme.json index eeb4eeb6b881b..3554c486209b8 100644 --- a/extensions/theme-kimbie-dark/themes/kimbie-dark-color-theme.json +++ b/extensions/theme-kimbie-dark/themes/kimbie-dark-color-theme.json @@ -64,7 +64,8 @@ "scope": [ "meta.embedded", "source.groovy.embedded", - "string meta.image.inline.markdown" + "string meta.image.inline.markdown", + "variable.legacy.builtin.python" ], "settings": { "foreground": "#d3af86" diff --git a/extensions/theme-monokai-dimmed/themes/dimmed-monokai-color-theme.json b/extensions/theme-monokai-dimmed/themes/dimmed-monokai-color-theme.json index ea84bededd50b..691680512a48f 100644 --- a/extensions/theme-monokai-dimmed/themes/dimmed-monokai-color-theme.json +++ b/extensions/theme-monokai-dimmed/themes/dimmed-monokai-color-theme.json @@ -71,7 +71,8 @@ { "scope": [ "meta.embedded", - "source.groovy.embedded" + "source.groovy.embedded", + "variable.legacy.builtin.python" ], "settings": { "foreground": "#C5C8C6" diff --git a/extensions/theme-monokai/themes/monokai-color-theme.json b/extensions/theme-monokai/themes/monokai-color-theme.json index 6489b0dd39c33..9a51074871465 100644 --- a/extensions/theme-monokai/themes/monokai-color-theme.json +++ b/extensions/theme-monokai/themes/monokai-color-theme.json @@ -111,7 +111,8 @@ "scope": [ "meta.embedded", "source.groovy.embedded", - "string meta.image.inline.markdown" + "string meta.image.inline.markdown", + "variable.legacy.builtin.python" ], "settings": { "foreground": "#F8F8F2" diff --git a/extensions/theme-quietlight/themes/quietlight-color-theme.json b/extensions/theme-quietlight/themes/quietlight-color-theme.json index 9d55f2e362bc7..3705ed486088d 100644 --- a/extensions/theme-quietlight/themes/quietlight-color-theme.json +++ b/extensions/theme-quietlight/themes/quietlight-color-theme.json @@ -10,7 +10,8 @@ "scope": [ "meta.embedded", "source.groovy.embedded", - "string meta.image.inline.markdown" + "string meta.image.inline.markdown", + "variable.legacy.builtin.python" ], "settings": { "foreground": "#333333" diff --git a/extensions/theme-red/themes/Red-color-theme.json b/extensions/theme-red/themes/Red-color-theme.json index c139400dc562d..233fd9e83da27 100644 --- a/extensions/theme-red/themes/Red-color-theme.json +++ b/extensions/theme-red/themes/Red-color-theme.json @@ -70,7 +70,8 @@ "scope": [ "meta.embedded", "source.groovy.embedded", - "string meta.image.inline.markdown" + "string meta.image.inline.markdown", + "variable.legacy.builtin.python" ], "settings": { "foreground": "#F8F8F8" diff --git a/extensions/theme-solarized-dark/themes/solarized-dark-color-theme.json b/extensions/theme-solarized-dark/themes/solarized-dark-color-theme.json index e10c6e6740335..e67135a9d99ce 100644 --- a/extensions/theme-solarized-dark/themes/solarized-dark-color-theme.json +++ b/extensions/theme-solarized-dark/themes/solarized-dark-color-theme.json @@ -10,7 +10,8 @@ "scope": [ "meta.embedded", "source.groovy.embedded", - "string meta.image.inline.markdown" + "string meta.image.inline.markdown", + "variable.legacy.builtin.python" ], "settings": { "foreground": "#839496" diff --git a/extensions/theme-solarized-light/themes/solarized-light-color-theme.json b/extensions/theme-solarized-light/themes/solarized-light-color-theme.json index 8b4074c9a072d..d5f6dc11bf036 100644 --- a/extensions/theme-solarized-light/themes/solarized-light-color-theme.json +++ b/extensions/theme-solarized-light/themes/solarized-light-color-theme.json @@ -10,7 +10,8 @@ "scope": [ "meta.embedded", "source.groovy.embedded", - "string meta.image.inline.markdown" + "string meta.image.inline.markdown", + "variable.legacy.builtin.python" ], "settings": { "foreground": "#657B83" diff --git a/extensions/theme-tomorrow-night-blue/themes/tomorrow-night-blue-color-theme.json b/extensions/theme-tomorrow-night-blue/themes/tomorrow-night-blue-color-theme.json index 8e24e6fe4de03..b0bdf8e90a9fa 100644 --- a/extensions/theme-tomorrow-night-blue/themes/tomorrow-night-blue-color-theme.json +++ b/extensions/theme-tomorrow-night-blue/themes/tomorrow-night-blue-color-theme.json @@ -70,7 +70,8 @@ "meta.embedded", "source.groovy.embedded", "meta.jsx.children", - "string meta.image.inline.markdown" + "string meta.image.inline.markdown", + "variable.legacy.builtin.python" ], "settings": { //"background": "#002451", diff --git a/extensions/tunnel-forwarding/.vscode/launch.json b/extensions/tunnel-forwarding/.vscode/launch.json new file mode 100644 index 0000000000000..d3fabaa1a94cc --- /dev/null +++ b/extensions/tunnel-forwarding/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Extension", + "type": "extensionHost", + "request": "launch", + "args": ["--extensionDevelopmentPath=${workspaceFolder}"], + "env": { "VSCODE_FORWARDING_IS_DEV": "1" } // load the CLI from OSS + } + ] +} diff --git a/extensions/tunnel-forwarding/.vscodeignore b/extensions/tunnel-forwarding/.vscodeignore new file mode 100644 index 0000000000000..36e8b0714faf4 --- /dev/null +++ b/extensions/tunnel-forwarding/.vscodeignore @@ -0,0 +1,5 @@ +src/** +tsconfig.json +out/** +extension.webpack.config.js +yarn.lock \ No newline at end of file diff --git a/extensions/tunnel-forwarding/extension.webpack.config.js b/extensions/tunnel-forwarding/extension.webpack.config.js new file mode 100644 index 0000000000000..b474e65cbb130 --- /dev/null +++ b/extensions/tunnel-forwarding/extension.webpack.config.js @@ -0,0 +1,20 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +//@ts-check + +'use strict'; + +const withDefaults = require('../shared.webpack.config'); + +module.exports = withDefaults({ + context: __dirname, + entry: { + extension: './src/extension.ts', + }, + resolve: { + mainFields: ['module', 'main'] + } +}); diff --git a/extensions/tunnel-forwarding/media/icon.png b/extensions/tunnel-forwarding/media/icon.png new file mode 100644 index 0000000000000..2c90d30a1f054 Binary files /dev/null and b/extensions/tunnel-forwarding/media/icon.png differ diff --git a/extensions/tunnel-forwarding/package.json b/extensions/tunnel-forwarding/package.json new file mode 100644 index 0000000000000..76c61e4dad95a --- /dev/null +++ b/extensions/tunnel-forwarding/package.json @@ -0,0 +1,59 @@ +{ + "name": "tunnel-forwarding", + "displayName": "%displayName%", + "description": "%description%", + "version": "1.0.0", + "publisher": "vscode", + "license": "MIT", + "engines": { + "vscode": "^1.82.0" + }, + "icon": "media/icon.png", + "capabilities": { + "virtualWorkspaces": false, + "untrustedWorkspaces": { + "supported": true + } + }, + "enabledApiProposals": [ + "resolvers", + "tunnelFactory" + ], + "activationEvents": [ + "onTunnel" + ], + "contributes": { + "commands": [ + { + "category": "%category%", + "command": "tunnel-forwarding.showLog", + "title": "%command.showLog%", + "enablement": "tunnelForwardingHasLog" + }, + { + "category": "%category%", + "command": "tunnel-forwarding.restart", + "title": "%command.restart%", + "enablement": "tunnelForwardingIsRunning" + } + ] + }, + "main": "./out/extension", + "scripts": { + "compile": "gulp compile-extension:tunnel-forwarding", + "watch": "gulp watch-extension:tunnel-forwarding" + }, + "devDependencies": { + "@types/node": "18.x" + }, + "prettier": { + "printWidth": 100, + "trailingComma": "all", + "singleQuote": true, + "arrowParens": "avoid" + }, + "repository": { + "type": "git", + "url": "https://github.com/microsoft/vscode.git" + } +} diff --git a/extensions/tunnel-forwarding/package.nls.json b/extensions/tunnel-forwarding/package.nls.json new file mode 100644 index 0000000000000..1102147e8efb6 --- /dev/null +++ b/extensions/tunnel-forwarding/package.nls.json @@ -0,0 +1,7 @@ +{ + "displayName": "Local Tunnel Port Forwarding", + "description": "Allows forwarding local ports to be accessible over the internet.", + "category": "Port Forwarding", + "command.showLog": "Show Log", + "command.restart": "Restart Forwarding System" +} diff --git a/extensions/tunnel-forwarding/src/deferredPromise.ts b/extensions/tunnel-forwarding/src/deferredPromise.ts new file mode 100644 index 0000000000000..54b0737f3c0d2 --- /dev/null +++ b/extensions/tunnel-forwarding/src/deferredPromise.ts @@ -0,0 +1,62 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +export type ValueCallback = (value: T | Promise) => void; + +const enum DeferredOutcome { + Resolved, + Rejected +} + +/** + * Copied from src\vs\base\common\async.ts + */ +export class DeferredPromise { + + private completeCallback!: ValueCallback; + private errorCallback!: (err: unknown) => void; + private outcome?: { outcome: DeferredOutcome.Rejected; value: any } | { outcome: DeferredOutcome.Resolved; value: T }; + + public get isRejected() { + return this.outcome?.outcome === DeferredOutcome.Rejected; + } + + public get isResolved() { + return this.outcome?.outcome === DeferredOutcome.Resolved; + } + + public get isSettled() { + return !!this.outcome; + } + + public get value() { + return this.outcome?.outcome === DeferredOutcome.Resolved ? this.outcome?.value : undefined; + } + + public readonly p: Promise; + + constructor() { + this.p = new Promise((c, e) => { + this.completeCallback = c; + this.errorCallback = e; + }); + } + + public complete(value: T) { + return new Promise(resolve => { + this.completeCallback(value); + this.outcome = { outcome: DeferredOutcome.Resolved, value }; + resolve(); + }); + } + + public error(err: unknown) { + return new Promise(resolve => { + this.errorCallback(err); + this.outcome = { outcome: DeferredOutcome.Rejected, value: err }; + resolve(); + }); + } +} diff --git a/extensions/tunnel-forwarding/src/extension.ts b/extensions/tunnel-forwarding/src/extension.ts new file mode 100644 index 0000000000000..3dd6fdfef1981 --- /dev/null +++ b/extensions/tunnel-forwarding/src/extension.ts @@ -0,0 +1,297 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { ChildProcessWithoutNullStreams, spawn } from 'child_process'; +import * as path from 'path'; +import * as vscode from 'vscode'; +import { DeferredPromise } from './deferredPromise'; +import { splitNewLines } from './split'; + +export const enum TunnelPrivacyId { + Private = 'private', + Public = 'public', +} + +/** + * Timeout after the last port forwarding is disposed before we'll tear down + * the CLI. This is primarily used since privacy changes to port will appear + * as a dispose+re-create call, and we don't want to have to restart the CLI. + */ +const CLEANUP_TIMEOUT = 10_000; + +const cliPath = process.env.VSCODE_FORWARDING_IS_DEV + ? path.join(__dirname, '../../../cli/target/debug/code') + : path.join( + vscode.env.appRoot, + process.platform === 'win32' ? '../../bin' : 'bin', + vscode.env.appQuality === 'stable' ? 'code-tunnel' : 'code-tunnel-insiders', + ) + (process.platform === 'win32' ? '.exe' : ''); + +class Tunnel implements vscode.Tunnel { + private readonly disposeEmitter = new vscode.EventEmitter(); + public readonly onDidDispose = this.disposeEmitter.event; + public localAddress!: string; + + constructor( + public readonly remoteAddress: { port: number; host: string }, + public readonly privacy: TunnelPrivacyId, + ) { } + + public setPortFormat(formatString: string) { + this.localAddress = formatString.replace('{port}', String(this.remoteAddress.port)); + } + + dispose() { + this.disposeEmitter.fire(); + } +} + +const enum State { + Starting, + Active, + Inactive, + Error, +} + +type StateT = + | { state: State.Inactive } + | { state: State.Starting; process: ChildProcessWithoutNullStreams; cleanupTimeout?: NodeJS.Timeout } + | { state: State.Active; portFormat: string; process: ChildProcessWithoutNullStreams; cleanupTimeout?: NodeJS.Timeout } + | { state: State.Error; error: string }; + +export async function activate(context: vscode.ExtensionContext) { + if (vscode.env.remoteAuthority) { + return; // forwarding is local-only at the moment + } + + const logger = new Logger(vscode.l10n.t('Port Forwarding')); + const provider = new TunnelProvider(logger); + + context.subscriptions.push( + vscode.commands.registerCommand('tunnel-forwarding.showLog', () => logger.show()), + vscode.commands.registerCommand('tunnel-forwarding.restart', () => provider.restart()), + + provider.onDidStateChange(s => { + vscode.commands.executeCommand('setContext', 'tunnelForwardingIsRunning', s.state !== State.Inactive); + }), + + await vscode.workspace.registerTunnelProvider( + provider, + { + tunnelFeatures: { + elevation: false, + privacyOptions: [ + { themeIcon: 'globe', id: TunnelPrivacyId.Public, label: vscode.l10n.t('Public') }, + { themeIcon: 'lock', id: TunnelPrivacyId.Private, label: vscode.l10n.t('Private') }, + ], + }, + }, + ), + ); +} + +export function deactivate() { } + +class Logger { + private outputChannel?: vscode.LogOutputChannel; + + constructor(private readonly label: string) { } + + public show(): void { + return this.outputChannel?.show(); + } + + public clear() { + this.outputChannel?.clear(); + } + + public log( + logLevel: 'trace' | 'debug' | 'info' | 'warn' | 'error', + message: string, + ...args: unknown[] + ) { + if (!this.outputChannel) { + this.outputChannel = vscode.window.createOutputChannel(this.label, { log: true }); + vscode.commands.executeCommand('setContext', 'tunnelForwardingHasLog', true); + } + this.outputChannel[logLevel](message, ...args); + } +} + +class TunnelProvider implements vscode.TunnelProvider { + private readonly tunnels = new Set(); + private readonly stateChange = new vscode.EventEmitter(); + private _state: StateT = { state: State.Inactive }; + + private get state(): StateT { + return this._state; + } + + private set state(state: StateT) { + this._state = state; + this.stateChange.fire(state); + } + + public readonly onDidStateChange = this.stateChange.event; + + constructor(private readonly logger: Logger) { } + + /** @inheritdoc */ + public async provideTunnel(tunnelOptions: vscode.TunnelOptions): Promise { + const tunnel = new Tunnel( + tunnelOptions.remoteAddress, + (tunnelOptions.privacy as TunnelPrivacyId) || TunnelPrivacyId.Private, + ); + + this.tunnels.add(tunnel); + tunnel.onDidDispose(() => { + this.tunnels.delete(tunnel); + this.updateActivePortsIfRunning(); + }); + + switch (this.state.state) { + case State.Error: + case State.Inactive: + await this.setupPortForwardingProcess(); + // fall through since state is now starting + case State.Starting: + this.updateActivePortsIfRunning(); + return new Promise((resolve, reject) => { + const l = this.stateChange.event(state => { + if (state.state === State.Active) { + tunnel.setPortFormat(state.portFormat); + l.dispose(); + resolve(tunnel); + } else if (state.state === State.Error) { + l.dispose(); + reject(new Error(state.error)); + } + }); + }); + case State.Active: + tunnel.setPortFormat(this.state.portFormat); + this.updateActivePortsIfRunning(); + return tunnel; + } + } + + /** Re/starts the port forwarding system. */ + public async restart() { + this.killRunningProcess(); + await this.setupPortForwardingProcess(); // will show progress + this.updateActivePortsIfRunning(); + } + + private isInStateWithProcess(process: ChildProcessWithoutNullStreams) { + return ( + (this.state.state === State.Starting || this.state.state === State.Active) && + this.state.process === process + ); + } + + private killRunningProcess() { + if (this.state.state === State.Starting || this.state.state === State.Active) { + this.logger.log('info', '[forwarding] no more ports, stopping forwarding CLI'); + this.state.process.kill(); + this.state = { state: State.Inactive }; + } + } + + private updateActivePortsIfRunning() { + if (this.state.state !== State.Starting && this.state.state !== State.Active) { + return; + } + + const ports = [...this.tunnels].map(t => ({ number: t.remoteAddress.port, privacy: t.privacy })); + this.state.process.stdin.write(`${JSON.stringify(ports)}\n`); + + if (ports.length === 0 && !this.state.cleanupTimeout) { + this.state.cleanupTimeout = setTimeout(() => this.killRunningProcess(), CLEANUP_TIMEOUT); + } else if (ports.length > 0 && this.state.cleanupTimeout) { + clearTimeout(this.state.cleanupTimeout); + this.state.cleanupTimeout = undefined; + } + } + + private async setupPortForwardingProcess() { + const session = await vscode.authentication.getSession('github', ['user:email', 'read:org'], { + createIfNone: true, + }); + + const args = [ + '--verbose', + 'tunnel', + 'forward-internal', + '--provider', + 'github', + '--access-token', + session.accessToken, + ]; + + this.logger.log('info', '[forwarding] starting CLI'); + const process = spawn(cliPath, args, { stdio: 'pipe' }); + this.state = { state: State.Starting, process }; + + const progressP = new DeferredPromise(); + vscode.window.withProgress( + { + location: vscode.ProgressLocation.Notification, + title: vscode.l10n.t({ + comment: ['do not change link format [Show Log](command), only change the text "Show Log"'], + message: 'Starting port forwarding system ([Show Log]({0}))', + args: ['command:tunnel-forwarding.showLog'] + }), + }, + () => progressP.p, + ); + + let lastPortFormat: string | undefined; + process.on('exit', status => { + const msg = `[forwarding] exited with code ${status}`; + this.logger.log('info', msg); + progressP.complete(); // make sure to clear progress on unexpected exit + if (this.isInStateWithProcess(process)) { + this.state = { state: State.Error, error: msg }; + } + }); + + process.on('error', err => { + this.logger.log('error', `[forwarding] ${err}`); + progressP.complete(); // make sure to clear progress on unexpected exit + if (this.isInStateWithProcess(process)) { + this.state = { state: State.Error, error: String(err) }; + } + }); + + process.stdout + .pipe(splitNewLines()) + .on('data', line => this.logger.log('info', `[forwarding] ${line}`)) + .resume(); + + process.stderr + .pipe(splitNewLines()) + .on('data', line => { + try { + const l: { port_format: string } = JSON.parse(line); + if (l.port_format && l.port_format !== lastPortFormat) { + this.state = { + state: State.Active, + portFormat: l.port_format, process, + cleanupTimeout: 'cleanupTimeout' in this.state ? this.state.cleanupTimeout : undefined, + }; + progressP.complete(); + } + } catch (e) { + this.logger.log('error', `[forwarding] ${line}`); + } + }) + .resume(); + + await new Promise((resolve, reject) => { + process.on('spawn', resolve); + process.on('error', reject); + }); + } +} diff --git a/extensions/tunnel-forwarding/src/split.ts b/extensions/tunnel-forwarding/src/split.ts new file mode 100644 index 0000000000000..6e9d7474604f9 --- /dev/null +++ b/extensions/tunnel-forwarding/src/split.ts @@ -0,0 +1,49 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Transform } from 'stream'; + +export const splitNewLines = () => new StreamSplitter('\n'.charCodeAt(0)); + +/** + * Copied and simplified from src\vs\base\node\nodeStreams.ts + */ +export class StreamSplitter extends Transform { + private buffer: Buffer | undefined; + + constructor(private readonly splitter: number) { + super(); + } + + override _transform(chunk: Buffer, _encoding: string, callback: (error?: Error | null, data?: any) => void): void { + if (!this.buffer) { + this.buffer = chunk; + } else { + this.buffer = Buffer.concat([this.buffer, chunk]); + } + + let offset = 0; + while (offset < this.buffer.length) { + const index = this.buffer.indexOf(this.splitter, offset); + if (index === -1) { + break; + } + + this.push(this.buffer.subarray(offset, index + 1)); + offset = index + 1; + } + + this.buffer = offset === this.buffer.length ? undefined : this.buffer.subarray(offset); + callback(); + } + + override _flush(callback: (error?: Error | null, data?: any) => void): void { + if (this.buffer) { + this.push(this.buffer); + } + + callback(); + } +} diff --git a/extensions/tunnel-forwarding/tsconfig.json b/extensions/tunnel-forwarding/tsconfig.json new file mode 100644 index 0000000000000..4769a9faec8f9 --- /dev/null +++ b/extensions/tunnel-forwarding/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "../tsconfig.base.json", + "compilerOptions": { + "outDir": "./out", + "downlevelIteration": true, + "types": [ + "node" + ] + }, + "include": [ + "src/**/*", + "../../src/vscode-dts/vscode.d.ts", + "../../src/vscode-dts/vscode.proposed.resolvers.d.ts", + "../../src/vscode-dts/vscode.proposed.tunnelFactory.d.ts" + ] +} diff --git a/extensions/tunnel-forwarding/yarn.lock b/extensions/tunnel-forwarding/yarn.lock new file mode 100644 index 0000000000000..8a3d10f2b65cf --- /dev/null +++ b/extensions/tunnel-forwarding/yarn.lock @@ -0,0 +1,8 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@types/node@18.x": + version "18.15.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" + integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== diff --git a/extensions/typescript-basics/package.json b/extensions/typescript-basics/package.json index 07631abc414f7..63c07e75b6d73 100644 --- a/extensions/typescript-basics/package.json +++ b/extensions/typescript-basics/package.json @@ -55,8 +55,8 @@ }, { "id": "json", - "filenames": [ - "tsconfig.tsbuildinfo" + "extensions": [ + ".tsbuildinfo" ] } ], diff --git a/extensions/typescript-basics/syntaxes/Readme.md b/extensions/typescript-basics/syntaxes/Readme.md index 2f9c2b95ee24c..fa05c28d970bd 100644 --- a/extensions/typescript-basics/syntaxes/Readme.md +++ b/extensions/typescript-basics/syntaxes/Readme.md @@ -1,6 +1,7 @@ The file `TypeScript.tmLanguage.json` and `TypeScriptReact.tmLanguage.json` are derived from [TypeScript.tmLanguage](https://github.com/microsoft/TypeScript-TmLanguage/blob/master/TypeScript.tmLanguage) and [TypeScriptReact.tmLanguage](https://github.com/microsoft/TypeScript-TmLanguage/blob/master/TypeScriptReact.tmLanguage). To update to the latest version: + - `cd extensions/typescript` and run `npm run update-grammars` - don't forget to run the integration tests at `./scripts/test-integration.sh` diff --git a/extensions/typescript-language-features/package.json b/extensions/typescript-language-features/package.json index 1d793c89db3b5..05975bb2d7874 100644 --- a/extensions/typescript-language-features/package.json +++ b/extensions/typescript-language-features/package.json @@ -33,7 +33,10 @@ "Programming Languages" ], "dependencies": { - "@vscode/extension-telemetry": "0.7.5", + "@vscode/extension-telemetry": "^0.8.4", + "jsonc-parser": "^3.2.0", + "semver": "7.5.2", + "vscode-tas-client": "^0.1.63", "@vscode/sync-api-client": "^0.7.2", "@vscode/sync-api-common": "^0.7.2", "@vscode/sync-api-service": "^0.7.3", @@ -43,7 +46,7 @@ "vscode-uri": "^3.0.3" }, "devDependencies": { - "@types/node": "16.x", + "@types/node": "18.x", "@types/semver": "^5.5.0" }, "scripts": { @@ -145,7 +148,7 @@ "properties": { "typescript.experimental.aiQuickFix": { "type": "boolean", - "default": true, + "default": false, "description": "%typescript.experimental.aiQuickFix%", "scope": "resource" }, diff --git a/extensions/typescript-language-features/package.nls.json b/extensions/typescript-language-features/package.nls.json index 950f09552efe1..641a4092870de 100644 --- a/extensions/typescript-language-features/package.nls.json +++ b/extensions/typescript-language-features/package.nls.json @@ -152,7 +152,7 @@ "typescript.preferences.includePackageJsonAutoImports.auto": "Search dependencies based on estimated performance impact.", "typescript.preferences.includePackageJsonAutoImports.on": "Always search dependencies.", "typescript.preferences.includePackageJsonAutoImports.off": "Never search dependencies.", - "typescript.preferences.autoImportFileExcludePatterns": "Specify glob patterns of files to exclude from auto imports. Requires using TypeScript 4.8 or newer in the workspace.", + "typescript.preferences.autoImportFileExcludePatterns": "Specify glob patterns of files to exclude from auto imports. Relative paths are resolved relative to the workspace root. Patterns are evaluated using tsconfig.json [`exclude`](https://www.typescriptlang.org/tsconfig#exclude) semantics. Requires using TypeScript 4.8 or newer in the workspace.", "typescript.updateImportsOnFileMove.enabled": "Enable/disable automatic updating of import paths when you rename or move a file in VS Code.", "typescript.updateImportsOnFileMove.enabled.prompt": "Prompt on each rename.", "typescript.updateImportsOnFileMove.enabled.always": "Always update paths automatically.", diff --git a/extensions/typescript-language-features/src/languageFeatures/fileConfigurationManager.ts b/extensions/typescript-language-features/src/languageFeatures/fileConfigurationManager.ts index ebf0131fcedfd..e3ef52002a52a 100644 --- a/extensions/typescript-language-features/src/languageFeatures/fileConfigurationManager.ts +++ b/extensions/typescript-language-features/src/languageFeatures/fileConfigurationManager.ts @@ -195,6 +195,7 @@ export default class FileConfigurationManager extends Disposable { allowIncompleteCompletions: true, displayPartsForJSDoc: true, disableLineTextInReferences: true, + interactiveInlayHints: true, ...getInlayHintsPreferences(config), }; diff --git a/extensions/typescript-language-features/src/languageFeatures/inlayHints.ts b/extensions/typescript-language-features/src/languageFeatures/inlayHints.ts index 263f8f3bd72be..4fa38e4986b9a 100644 --- a/extensions/typescript-language-features/src/languageFeatures/inlayHints.ts +++ b/extensions/typescript-language-features/src/languageFeatures/inlayHints.ts @@ -6,9 +6,10 @@ import * as vscode from 'vscode'; import { DocumentSelector } from '../configuration/documentSelector'; import { LanguageDescription } from '../configuration/languageDescription'; +import { TelemetryReporter } from '../logging/telemetry'; import { API } from '../tsServer/api'; import type * as Proto from '../tsServer/protocol/protocol'; -import { Position } from '../typeConverters'; +import { Location, Position } from '../typeConverters'; import { ClientCapability, ITypeScriptServiceClient } from '../typescriptService'; import { Disposable } from '../utils/dispose'; import FileConfigurationManager, { InlayHintSettingNames, getInlayHintsPreferences } from './fileConfigurationManager'; @@ -29,13 +30,16 @@ class TypeScriptInlayHintsProvider extends Disposable implements vscode.InlayHin public static readonly minVersion = API.v440; - private readonly _onDidChangeInlayHints = new vscode.EventEmitter(); + private readonly _onDidChangeInlayHints = this._register(new vscode.EventEmitter()); public readonly onDidChangeInlayHints = this._onDidChangeInlayHints.event; + private hasReportedTelemetry = false; + constructor( private readonly language: LanguageDescription, private readonly client: ITypeScriptServiceClient, - private readonly fileConfigurationManager: FileConfigurationManager + private readonly fileConfigurationManager: FileConfigurationManager, + private readonly telemetryReporter: TelemetryReporter, ) { super(); @@ -54,37 +58,67 @@ class TypeScriptInlayHintsProvider extends Disposable implements vscode.InlayHin })); } - async provideInlayHints(model: vscode.TextDocument, range: vscode.Range, token: vscode.CancellationToken): Promise { + async provideInlayHints(model: vscode.TextDocument, range: vscode.Range, token: vscode.CancellationToken): Promise { const filepath = this.client.toOpenTsFilePath(model); if (!filepath) { - return []; + return; } if (!areInlayHintsEnabledForFile(this.language, model)) { - return []; + return; } const start = model.offsetAt(range.start); const length = model.offsetAt(range.end) - start; await this.fileConfigurationManager.ensureConfigurationForDocument(model, token); + if (token.isCancellationRequested) { + return; + } + + if (!this.hasReportedTelemetry) { + this.hasReportedTelemetry = true; + /* __GDPR__ + "inlayHints.provide" : { + "owner": "mjbvz", + "${include}": [ + "${TypeScriptCommonProperties}" + ] + } + */ + this.telemetryReporter.logTelemetry('inlayHints.provide', {}); + } const response = await this.client.execute('provideInlayHints', { file: filepath, start, length }, token); if (response.type !== 'response' || !response.success || !response.body) { - return []; + return; } return response.body.map(hint => { const result = new vscode.InlayHint( Position.fromLocation(hint.position), - hint.text, - hint.kind && fromProtocolInlayHintKind(hint.kind) + this.convertInlayHintText(hint), + fromProtocolInlayHintKind(hint.kind) ); result.paddingLeft = hint.whitespaceBefore; result.paddingRight = hint.whitespaceAfter; return result; }); } + + private convertInlayHintText(tsHint: Proto.InlayHintItem): string | vscode.InlayHintLabelPart[] { + if (tsHint.displayParts) { + return tsHint.displayParts.map((part): vscode.InlayHintLabelPart => { + const out = new vscode.InlayHintLabelPart(part.text); + if (part.span) { + out.location = Location.fromTextSpan(this.client.toResource(part.span.file), part.span); + } + return out; + }); + } + + return tsHint.text; + } } function fromProtocolInlayHintKind(kind: Proto.InlayHintKind): vscode.InlayHintKind | undefined { @@ -113,13 +147,14 @@ export function register( selector: DocumentSelector, language: LanguageDescription, client: ITypeScriptServiceClient, - fileConfigurationManager: FileConfigurationManager + fileConfigurationManager: FileConfigurationManager, + telemetryReporter: TelemetryReporter, ) { return conditionalRegistration([ requireMinVersion(client, TypeScriptInlayHintsProvider.minVersion), requireSomeCapability(client, ClientCapability.Semantic), ], () => { - const provider = new TypeScriptInlayHintsProvider(language, client, fileConfigurationManager); + const provider = new TypeScriptInlayHintsProvider(language, client, fileConfigurationManager, telemetryReporter); return vscode.languages.registerInlayHintsProvider(selector.semantic, provider); }); } diff --git a/extensions/typescript-language-features/src/languageFeatures/refactor.ts b/extensions/typescript-language-features/src/languageFeatures/refactor.ts index a99b92685fc17..ae36fbffb22af 100644 --- a/extensions/typescript-language-features/src/languageFeatures/refactor.ts +++ b/extensions/typescript-language-features/src/languageFeatures/refactor.ts @@ -175,47 +175,80 @@ class MoveToFileRefactorCommand implements Command { if (response.type !== 'response' || !response.body) { return; } + const body = response.body; - const selectExistingFileItem: vscode.QuickPickItem = { - label: vscode.l10n.t("Select existing file..."), - }; - const selectNewFileItem: vscode.QuickPickItem = { - label: vscode.l10n.t("Enter new file path..."), - }; - - type DestinationItem = vscode.QuickPickItem & { readonly file: string }; + type DestinationItem = vscode.QuickPickItem & { readonly file?: string }; + const selectExistingFileItem: vscode.QuickPickItem = { label: vscode.l10n.t("Select existing file...") }; + const selectNewFileItem: vscode.QuickPickItem = { label: vscode.l10n.t("Enter new file path...") }; const workspaceFolder = vscode.workspace.getWorkspaceFolder(document.uri); - const destinationItems = response.body.files.map((file): DestinationItem => { - const uri = this.client.toResource(file); - const parentDir = Utils.dirname(uri); - - let description; - if (workspaceFolder) { - if (uri.scheme === Schemes.file) { - description = path.relative(workspaceFolder.uri.fsPath, parentDir.fsPath); + const quickPick = vscode.window.createQuickPick(); + quickPick.ignoreFocusOut = true; + + // true so we don't skip computing in the first call + let quickPickInRelativeMode = true; + const updateItems = () => { + const relativeQuery = ['./', '../'].find(str => quickPick.value.startsWith(str)); + if (quickPickInRelativeMode === false && !!relativeQuery === false) { + return; + } + quickPickInRelativeMode = !!relativeQuery; + const destinationItems = body.files.map((file): DestinationItem | undefined => { + const uri = this.client.toResource(file); + const parentDir = Utils.dirname(uri); + const filename = Utils.basename(uri); + + let description: string | undefined; + if (workspaceFolder) { + if (uri.scheme === Schemes.file) { + description = path.relative(workspaceFolder.uri.fsPath, parentDir.fsPath); + } else { + description = path.posix.relative(workspaceFolder.uri.path, parentDir.path); + } + if (relativeQuery) { + const convertRelativePath = (str: string) => { + return !str.startsWith('../') ? `./${str}` : str; + }; + + const relativePath = convertRelativePath(path.relative(path.dirname(document.uri.fsPath), uri.fsPath)); + if (!relativePath.startsWith(relativeQuery)) { + return; + } + description = relativePath; + } } else { - description = path.posix.relative(workspaceFolder.uri.path, parentDir.path); + description = parentDir.fsPath; } - } else { - description = parentDir.fsPath; - } - return { - file, - label: Utils.basename(uri), - description, - }; - }); - - const picked = await vscode.window.showQuickPick([ - selectExistingFileItem, - selectNewFileItem, - { label: vscode.l10n.t("Destination Files"), kind: vscode.QuickPickItemKind.Separator }, - ...destinationItems - ], { - title: vscode.l10n.t("Move to File"), - placeHolder: vscode.l10n.t("Select move destination"), + return { + file, + label: Utils.basename(uri), + description: relativeQuery ? description : path.join(description, filename), + }; + }); + quickPick.items = [ + selectExistingFileItem, + selectNewFileItem, + { label: vscode.l10n.t("Destination Files"), kind: vscode.QuickPickItemKind.Separator }, + ...coalesce(destinationItems) + ]; + }; + quickPick.title = vscode.l10n.t("Move to File"); + quickPick.placeholder = vscode.l10n.t("Enter file path"); + quickPick.matchOnDescription = true; + quickPick.onDidChangeValue(updateItems); + updateItems(); + + const picked = await new Promise(resolve => { + quickPick.onDidAccept(() => { + resolve(quickPick.selectedItems[0]); + quickPick.dispose(); + }); + quickPick.onDidHide(() => { + resolve(undefined); + quickPick.dispose(); + }); + quickPick.show(); }); if (!picked) { return; @@ -236,7 +269,7 @@ class MoveToFileRefactorCommand implements Command { }); return picked ? this.client.toTsFilePath(picked) : undefined; } else { - return (picked as DestinationItem).file; + return picked.file; } } } diff --git a/extensions/typescript-language-features/src/languageFeatures/util/textRendering.ts b/extensions/typescript-language-features/src/languageFeatures/util/textRendering.ts index bc4b7ad1b5f90..fe26dd6402951 100644 --- a/extensions/typescript-language-features/src/languageFeatures/util/textRendering.ts +++ b/extensions/typescript-language-features/src/languageFeatures/util/textRendering.ts @@ -49,9 +49,13 @@ function getTagBodyText( return '```\n' + text + '\n```'; } - const text = convertLinkTags(tag.text, filePathConverter); + let text = convertLinkTags(tag.text, filePathConverter); switch (tag.name) { case 'example': { + // Example text does not support `{@link}` as it is considered code. + // TODO: should we support it if it appears outside of an explicit code block? + text = asPlainText(tag.text); + // check for caption tags, fix for #79704 const captionTagMatches = text.match(/(.*?)<\/caption>\s*(\r\n|\n)/); if (captionTagMatches && captionTagMatches.index === 0) { @@ -132,6 +136,13 @@ function getTagBody(tag: Proto.JSDocTagInfo, filePathConverter: IFilePathToResou return (convertLinkTags(tag.text, filePathConverter)).split(/^(\S+)\s*-?\s*/); } +function asPlainText(parts: readonly Proto.SymbolDisplayPart[] | string): string { + if (typeof parts === 'string') { + return parts; + } + return parts.map(part => part.text).join(''); +} + export function asPlainTextWithLinks( parts: readonly Proto.SymbolDisplayPart[] | string, filePathConverter: IFilePathToResourceConverter, @@ -177,10 +188,10 @@ function convertLinkTags( if (/^https?:/.test(text)) { const parts = text.split(' '); if (parts.length === 1) { - out.push(parts[0]); + out.push(`<${parts[0]}>`); } else if (parts.length > 1) { - const linkText = escapeMarkdownSyntaxTokensForCode(parts.slice(1).join(' ')); - out.push(`[${currentLink.linkcode ? '`' + linkText + '`' : linkText}](${parts[0]})`); + const linkText = parts.slice(1).join(' '); + out.push(`[${currentLink.linkcode ? '`' + escapeMarkdownSyntaxTokensForCode(linkText) + '`' : linkText}](${parts[0]})`); } } else { out.push(escapeMarkdownSyntaxTokensForCode(text)); diff --git a/extensions/typescript-language-features/src/languageProvider.ts b/extensions/typescript-language-features/src/languageProvider.ts index 1de34c6998ce5..7acbf733f0cea 100644 --- a/extensions/typescript-language-features/src/languageProvider.ts +++ b/extensions/typescript-language-features/src/languageProvider.ts @@ -74,7 +74,7 @@ export default class LanguageProvider extends Disposable { import('./languageFeatures/formatting').then(provider => this._register(provider.register(selector, this.description, this.client, this.fileConfigurationManager))), import('./languageFeatures/hover').then(provider => this._register(provider.register(selector, this.client, this.fileConfigurationManager))), import('./languageFeatures/implementations').then(provider => this._register(provider.register(selector, this.client))), - import('./languageFeatures/inlayHints').then(provider => this._register(provider.register(selector, this.description, this.client, this.fileConfigurationManager))), + import('./languageFeatures/inlayHints').then(provider => this._register(provider.register(selector, this.description, this.client, this.fileConfigurationManager, this.telemetryReporter))), import('./languageFeatures/jsDocCompletions').then(provider => this._register(provider.register(selector, this.description, this.client, this.fileConfigurationManager))), import('./languageFeatures/linkedEditing').then(provider => this._register(provider.register(selector, this.client))), import('./languageFeatures/organizeImports').then(provider => this._register(provider.register(selector, this.client, this.commandManager, this.fileConfigurationManager, this.telemetryReporter))), diff --git a/extensions/typescript-language-features/src/test/unit/textRendering.test.ts b/extensions/typescript-language-features/src/test/unit/textRendering.test.ts index 2354bb7f5892d..b13f682f71507 100644 --- a/extensions/typescript-language-features/src/test/unit/textRendering.test.ts +++ b/extensions/typescript-language-features/src/test/unit/textRendering.test.ts @@ -14,7 +14,7 @@ const noopToResource: IFilePathToResourceConverter = { }; suite('typescript.previewer', () => { - test('Should ignore hyphens after a param tag', async () => { + test('Should ignore hyphens after a param tag', () => { assert.strictEqual( tagsToMarkdown([ { @@ -25,7 +25,7 @@ suite('typescript.previewer', () => { '*@param* `a` ā€” b'); }); - test('Should parse url jsdoc @link', async () => { + test('Should parse url jsdoc @link', () => { assert.strictEqual( documentationToMarkdown( 'x {@link http://www.example.com/foo} y {@link https://api.jquery.com/bind/#bind-eventType-eventData-handler} z', @@ -35,7 +35,7 @@ suite('typescript.previewer', () => { 'x [http://www.example.com/foo](http://www.example.com/foo) y [https://api.jquery.com/bind/#bind-eventType-eventData-handler](https://api.jquery.com/bind/#bind-eventType-eventData-handler) z'); }); - test('Should parse url jsdoc @link with text', async () => { + test('Should parse url jsdoc @link with text', () => { assert.strictEqual( documentationToMarkdown( 'x {@link http://www.example.com/foo abc xyz} y {@link http://www.example.com/bar|b a z} z', @@ -45,7 +45,7 @@ suite('typescript.previewer', () => { 'x [abc xyz](http://www.example.com/foo) y [b a z](http://www.example.com/bar) z'); }); - test('Should treat @linkcode jsdocs links as monospace', async () => { + test('Should treat @linkcode jsdocs links as monospace', () => { assert.strictEqual( documentationToMarkdown( 'x {@linkcode http://www.example.com/foo} y {@linkplain http://www.example.com/bar} z', @@ -55,7 +55,7 @@ suite('typescript.previewer', () => { 'x [`http://www.example.com/foo`](http://www.example.com/foo) y [http://www.example.com/bar](http://www.example.com/bar) z'); }); - test('Should parse url jsdoc @link in param tag', async () => { + test('Should parse url jsdoc @link in param tag', () => { assert.strictEqual( tagsToMarkdown([ { @@ -66,7 +66,7 @@ suite('typescript.previewer', () => { '*@param* `a` ā€” x [abc xyz](http://www.example.com/foo) y [b a z](http://www.example.com/bar) z'); }); - test('Should ignore unclosed jsdocs @link', async () => { + test('Should ignore unclosed jsdocs @link', () => { assert.strictEqual( documentationToMarkdown( 'x {@link http://www.example.com/foo y {@link http://www.example.com/bar bar} z', @@ -76,7 +76,7 @@ suite('typescript.previewer', () => { 'x {@link http://www.example.com/foo y [bar](http://www.example.com/bar) z'); }); - test('Should support non-ascii characters in parameter name (#90108)', async () => { + test('Should support non-ascii characters in parameter name (#90108)', () => { assert.strictEqual( tagsToMarkdown([ { @@ -135,7 +135,35 @@ suite('typescript.previewer', () => { ); }); - test('Should render @linkcode symbol name as code', async () => { + test('Should not render @link inside of @example #187768', () => { + assert.strictEqual( + tagsToMarkdown([ + { + "name": "example", + "text": [ + { + "text": "1 + 1 ", + "kind": "text" + }, + { + "text": "{@link ", + "kind": "link" + }, + { + "text": "foo", + "kind": "linkName" + }, + { + "text": "}", + "kind": "link" + } + ] + } + ], noopToResource), + '*@example* \n```\n1 + 1 {@link foo}\n```'); + }); + + test('Should render @linkcode symbol name as code', () => { assert.strictEqual( asPlainTextWithLinks([ { "text": "a ", "kind": "text" }, @@ -155,7 +183,7 @@ suite('typescript.previewer', () => { 'a [`dog`](command:_typescript.openJsDocLink?%5B%7B%22file%22%3A%7B%22path%22%3A%22%2Fpath%2Ffile.ts%22%2C%22scheme%22%3A%22file%22%7D%2C%22position%22%3A%7B%22line%22%3A6%2C%22character%22%3A4%7D%7D%5D) b'); }); - test('Should render @linkcode text as code', async () => { + test('Should render @linkcode text as code', () => { assert.strictEqual( asPlainTextWithLinks([ { "text": "a ", "kind": "text" }, diff --git a/extensions/typescript-language-features/src/typescriptServiceClient.ts b/extensions/typescript-language-features/src/typescriptServiceClient.ts index 984356f17b484..86c6bb8d9f1f0 100644 --- a/extensions/typescript-language-features/src/typescriptServiceClient.ts +++ b/extensions/typescript-language-features/src/typescriptServiceClient.ts @@ -29,6 +29,7 @@ import { PluginManager, TypeScriptServerPlugin } from './tsServer/plugins'; import { TelemetryProperties, TelemetryReporter, VSCodeTelemetryReporter } from './logging/telemetry'; import Tracer from './logging/tracer'; import { ProjectType, inferredProjectCompilerOptions } from './tsconfig'; +import { Schemes } from './configuration/schemes'; export interface TsDiagnostics { @@ -762,6 +763,18 @@ export default class TypeScriptServiceClient extends Disposable implements IType return undefined; } + // For notebook cells, we need to use the notebook document to look up the workspace + if (resource.scheme === Schemes.notebookCell) { + for (const notebook of vscode.workspace.notebookDocuments) { + for (const cell of notebook.getCells()) { + if (cell.document.uri.toString() === resource.toString()) { + resource = notebook.uri; + break; + } + } + } + } + for (const root of roots.sort((a, b) => a.uri.fsPath.length - b.uri.fsPath.length)) { if (root.uri.scheme === resource.scheme && root.uri.authority === resource.authority) { if (resource.fsPath.startsWith(root.uri.fsPath + path.sep)) { @@ -770,7 +783,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType } } - return undefined; + return vscode.workspace.getWorkspaceFolder(resource)?.uri; } public execute(command: keyof TypeScriptRequests, args: any, token: vscode.CancellationToken, config?: ExecConfig): Promise> { diff --git a/extensions/typescript-language-features/web/webServer.ts b/extensions/typescript-language-features/web/webServer.ts index 35aed40ea4f1e..191c2d03f6321 100644 --- a/extensions/typescript-language-features/web/webServer.ts +++ b/extensions/typescript-language-features/web/webServer.ts @@ -78,6 +78,15 @@ function toTsWatcherKind(event: 'create' | 'change' | 'delete') { throw new Error(`Unknown event: ${event}`); } +class AccessOutsideOfRootError extends Error { + constructor( + public readonly filepath: string, + public readonly projectRootPaths: readonly string[] + ) { + super(`Could not read file outside of project root ${filepath}`); + } +} + type ServerHostWithImport = ts.server.ServerHost & { importPlugin(root: string, moduleName: string): Promise }; function createServerHost(extensionUri: URI, logger: ts.server.Logger, apiClient: ApiClient | undefined, args: string[], fsWatcher: MessagePort, enabledExperimentalTypeAcquisition: boolean): ServerHostWithImport { @@ -549,7 +558,7 @@ function createServerHost(extensionUri: URI, logger: ts.server.Logger, apiClient } if (allowRead === 'block') { - throw new Error(`Could not read file outside of project root ${filepath}`); + throw new AccessOutsideOfRootError(filepath, Array.from(projectRootPaths.keys())); } return uri; diff --git a/extensions/typescript-language-features/yarn.lock b/extensions/typescript-language-features/yarn.lock index 556e97b33197b..f8accf4b5acef 100644 --- a/extensions/typescript-language-features/yarn.lock +++ b/extensions/typescript-language-features/yarn.lock @@ -17,7 +17,16 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" -"@azure/core-rest-pipeline@^1.10.0": +"@azure/core-auth@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.5.0.tgz#a41848c5c31cb3b7c84c409885267d55a2c92e44" + integrity sha512-udzoBuYG1VBoHVohDTrvKjyzel34zt77Bhp7dQntVGGD0ehVq48owENbBG8fIgkHRNUBQH5k1r0hpoMu5L8+kw== + dependencies: + "@azure/abort-controller" "^1.0.0" + "@azure/core-util" "^1.1.0" + tslib "^2.2.0" + +"@azure/core-rest-pipeline@1.10.1": version "1.10.1" resolved "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.10.1.tgz" integrity sha512-Kji9k6TOFRDB5ZMTw8qUf2IJ+CeJtsuMdAHox9eqpTf1cefiNMpzrfnF6sINEBZJsaVaWgQ0o48B6kcUH68niA== @@ -33,13 +42,21 @@ tslib "^2.2.0" uuid "^8.3.0" -"@azure/core-tracing@^1.0.1": +"@azure/core-tracing@^1.0.0", "@azure/core-tracing@^1.0.1": version "1.0.1" resolved "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.1.tgz" integrity sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw== dependencies: tslib "^2.2.0" +"@azure/core-util@1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.2.0.tgz#3499deba1fc36dda6f1912b791809b6f15d4a392" + integrity sha512-ffGIw+Qs8bNKNLxz5UPkz4/VBM/EZY07mPve1ZYFqYUdPwFqRj0RPk0U7LZMOfT7GCck9YjuT1Rfp1PApNl1ng== + dependencies: + "@azure/abort-controller" "^1.0.0" + tslib "^2.2.0" + "@azure/core-util@^1.0.0": version "1.1.1" resolved "https://registry.npmjs.org/@azure/core-util/-/core-util-1.1.1.tgz" @@ -48,6 +65,14 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" +"@azure/core-util@^1.1.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.4.0.tgz#c120a56b3e48a9e4d20619a0b00268ae9de891c7" + integrity sha512-eGAyJpm3skVQoLiRqm/xPa+SXi/NPDdSHMxbRAz2lSprd+Zs+qrpQGQQ2VQ3Nttu+nSZR4XoYQC71LbEI7jsig== + dependencies: + "@azure/abort-controller" "^1.0.0" + tslib "^2.2.0" + "@azure/logger@^1.0.0": version "1.0.3" resolved "https://registry.npmjs.org/@azure/logger/-/logger-1.0.3.tgz" @@ -55,66 +80,142 @@ dependencies: tslib "^2.2.0" +<<<<<<< HEAD "@microsoft/1ds-core-js@3.2.8", "@microsoft/1ds-core-js@^3.2.8": version "3.2.8" resolved "https://registry.npmjs.org/@microsoft/1ds-core-js/-/1ds-core-js-3.2.8.tgz" integrity sha512-9o9SUAamJiTXIYwpkQDuueYt83uZfXp8zp8YFix1IwVPwC9RmE36T2CX9gXOeq1nDckOuOduYpA8qHvdh5BGfQ== +======= +"@azure/opentelemetry-instrumentation-azure-sdk@^1.0.0-beta.5": + version "1.0.0-beta.5" + resolved "https://registry.yarnpkg.com/@azure/opentelemetry-instrumentation-azure-sdk/-/opentelemetry-instrumentation-azure-sdk-1.0.0-beta.5.tgz#78809e6c005d08450701e5d37f087f6fce2f86eb" + integrity sha512-fsUarKQDvjhmBO4nIfaZkfNSApm1hZBzcvpNbSrXdcUBxu7lRvKsV5DnwszX7cnhLyVOW9yl1uigtRQ1yDANjA== +>>>>>>> main + dependencies: + "@azure/core-tracing" "^1.0.0" + "@azure/logger" "^1.0.0" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/instrumentation" "^0.41.2" + tslib "^2.2.0" + +"@microsoft/1ds-core-js@3.2.13", "@microsoft/1ds-core-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.13.tgz#0c105ed75091bae3f1555c0334704fa9911c58fb" + integrity sha512-CluYTRWcEk0ObG5EWFNWhs87e2qchJUn0p2D21ZUa3PWojPZfPSBs4//WIE0MYV8Qg1Hdif2ZTwlM7TbYUjfAg== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.9" + "@microsoft/applicationinsights-core-js" "2.8.15" "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" +<<<<<<< HEAD "@microsoft/1ds-post-js@^3.2.8": version "3.2.8" resolved "https://registry.npmjs.org/@microsoft/1ds-post-js/-/1ds-post-js-3.2.8.tgz" integrity sha512-SjlRoNcXcXBH6WQD/5SkkaCHIVqldH3gDu+bI7YagrOVJ5APxwT1Duw9gm3L1FjFa9S2i81fvJ3EVSKpp9wULA== - dependencies: - "@microsoft/1ds-core-js" "3.2.8" +======= +"@microsoft/1ds-post-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.13.tgz#560aacac8a92fdbb79e8c2ebcb293d56e19f51aa" + integrity sha512-HgS574fdD19Bo2vPguyznL4eDw7Pcm1cVNpvbvBLWiW3x4e1FCQ3VMXChWnAxCae8Hb0XqlA2sz332ZobBavTA== +>>>>>>> main + dependencies: + "@microsoft/1ds-core-js" "3.2.13" "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" +<<<<<<< HEAD "@microsoft/applicationinsights-channel-js@2.8.9": version "2.8.9" resolved "https://registry.npmjs.org/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.8.9.tgz" integrity sha512-fMBsAEB7pWtPn43y72q9Xy5E5y55r6gMuDQqRRccccVoQDPXyS57VCj5IdATblctru0C6A8XpL2vRyNmEsu0Vg== - dependencies: - "@microsoft/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" - +======= +"@microsoft/applicationinsights-channel-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-3.0.2.tgz#be49fbf74831c7b8c97950027c5052ea99d2a8a5" + integrity sha512-jDBNKbCHsJgmpv0CKNhJ/uN9ZphvfGdb93Svk+R4LjO8L3apNNMbDDPxBvXXi0uigRmA1TBcmyBG4IRKjabGhw== +>>>>>>> main + dependencies: + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" + +<<<<<<< HEAD "@microsoft/applicationinsights-common@2.8.9": version "2.8.9" resolved "https://registry.npmjs.org/@microsoft/applicationinsights-common/-/applicationinsights-common-2.8.9.tgz" integrity sha512-mObn1moElyxZaGIRF/IU3cOaeKMgxghXnYEoHNUCA2e+rNwBIgxjyKkblFIpmGuHf4X7Oz3o3yBWpaC6AoMpig== - dependencies: - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" - +======= +"@microsoft/applicationinsights-common@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-3.0.2.tgz#37670bb07f4858ed41ff9759119e0759007d6e05" + integrity sha512-y+WXWop+OVim954Cu1uyYMnNx6PWO8okHpZIQi/1YSqtqaYdtJVPv4P0AVzwJdohxzVfgzKvqj9nec/VWqE2Zg== +>>>>>>> main + dependencies: + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" + +<<<<<<< HEAD "@microsoft/applicationinsights-core-js@2.8.9": version "2.8.9" resolved "https://registry.npmjs.org/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.9.tgz" integrity sha512-HRuIuZ6aOWezcg/G5VyFDDWGL8hDNe/ljPP01J7ImH2kRPEgbtcfPSUMjkamGMefgdq81GZsSoC/NNGTP4pp2w== +======= +"@microsoft/applicationinsights-core-js@2.8.15": + version "2.8.15" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.15.tgz#8fa466474260e01967fe649f14dd9e5ff91dcdc8" + integrity sha512-yYAs9MyjGr2YijQdUSN9mVgT1ijI1FPMgcffpaPmYbHAVbQmF7bXudrBWHxmLzJlwl5rfep+Zgjli2e67lwUqQ== +>>>>>>> main dependencies: "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/dynamicproto-js" "^1.1.9" + +"@microsoft/applicationinsights-core-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-3.0.2.tgz#108e20df8c162bec92b1f66f9de2530a25d9f51a" + integrity sha512-WQhVhzlRlLDrQzn3OShCW/pL3BW5WC57t0oywSknX3q7lMzI3jDg7Ihh0iuIcNTzGCTbDkuqr4d6IjEDWIMtJQ== + dependencies: + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-shims@2.0.2", "@microsoft/applicationinsights-shims@^2.0.2": version "2.0.2" resolved "https://registry.npmjs.org/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.2.tgz" integrity sha512-PoHEgsnmcqruLNHZ/amACqdJ6YYQpED0KSRe6J7gIJTtpZC1FfFU9b1fmDKDKtFoUSrPzEh1qzO3kmRZP0betg== +<<<<<<< HEAD "@microsoft/applicationinsights-web-basic@^2.8.9": version "2.8.9" resolved "https://registry.npmjs.org/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-2.8.9.tgz" integrity sha512-CH0J8JFOy7MjK8JO4pXXU+EML+Ilix+94PMZTX5EJlBU1in+mrik74/8qSg3UC4ekPi12KwrXaHCQSVC3WseXQ== - dependencies: - "@microsoft/applicationinsights-channel-js" "2.8.9" - "@microsoft/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" +======= +"@microsoft/applicationinsights-shims@3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-3.0.1.tgz#3865b73ace8405b9c4618cc5c571f2fe3876f06f" + integrity sha512-DKwboF47H1nb33rSUfjqI6ryX29v+2QWcTrRvcQDA32AZr5Ilkr7whOOSsD1aBzwqX0RJEIP1Z81jfE3NBm/Lg== +>>>>>>> main + dependencies: + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" + +"@microsoft/applicationinsights-web-basic@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-3.0.2.tgz#f777a4d24b79dde3ae396d3b819e1fce06b7240a" + integrity sha512-6Lq0DE/pZp9RvSV+weGbcxN1NDmfczj6gNPhvZKV2YSQ3RK0LZE3+wjTWLXfuStq8a+nCBdsRpWk8tOKgsoxcg== + dependencies: + "@microsoft/applicationinsights-channel-js" "3.0.2" + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-web-snippet@^1.0.1": version "1.0.1" @@ -126,6 +227,7 @@ resolved "https://registry.npmjs.org/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.7.tgz" integrity sha512-SK3D3aVt+5vOOccKPnGaJWB5gQ8FuKfjboUJHedMP7gu54HqSCXX5iFXhktGD8nfJb0Go30eDvs/UDoTnR2kOA== +<<<<<<< HEAD "@opentelemetry/api@^1.0.4": version "1.2.0" resolved "https://registry.npmjs.org/@opentelemetry/api/-/api-1.2.0.tgz" @@ -135,55 +237,141 @@ version "1.7.0" resolved "https://registry.npmjs.org/@opentelemetry/core/-/core-1.7.0.tgz" integrity sha512-AVqAi5uc8DrKJBimCTFUT4iFI+5eXpo4sYmGbQ0CypG0piOTHE2g9c5aSoTGYXu3CzOmJZf7pT6Xh+nwm5d6yQ== +======= +"@microsoft/dynamicproto-js@^1.1.9": + version "1.1.9" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.9.tgz#7437db7aa061162ee94e4131b69a62b8dad5dea6" + integrity sha512-n1VPsljTSkthsAFYdiWfC+DKzK2WwcRp83Y1YAqdX552BstvsDjft9YXppjUzp11BPsapDoO1LDgrDB0XVsfNQ== + +"@microsoft/dynamicproto-js@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-2.0.2.tgz#e57fbec2e7067d48b7e8e1e1c1d354028ef718a6" + integrity sha512-MB8trWaFREpmb037k/d0bB7T2BP7Ai24w1e1tbz3ASLB0/lwphsq3Nq8S9I5AsI5vs4zAQT+SB5nC5/dLYTiOg== +>>>>>>> main dependencies: - "@opentelemetry/semantic-conventions" "1.7.0" + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" +<<<<<<< HEAD "@opentelemetry/resources@1.7.0": version "1.7.0" resolved "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.7.0.tgz" integrity sha512-u1M0yZotkjyKx8dj+46Sg5thwtOTBmtRieNXqdCRiWUp6SfFiIP0bI+1XK3LhuXqXkBXA1awJZaTqKduNMStRg== +======= +"@nevware21/ts-async@>= 0.2.4 < 2.x": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@nevware21/ts-async/-/ts-async-0.3.0.tgz#a8b97ba01065fc930de9a3f4dd4a05e862becc6c" + integrity sha512-ZUcgUH12LN/F6nzN0cYd0F/rJaMLmXr0EHVTyYfaYmK55bdwE4338uue4UiVoRqHVqNW4KDUrJc49iGogHKeWA== +>>>>>>> main dependencies: - "@opentelemetry/core" "1.7.0" - "@opentelemetry/semantic-conventions" "1.7.0" + "@nevware21/ts-utils" ">= 0.10.0 < 2.x" +<<<<<<< HEAD "@opentelemetry/sdk-trace-base@^1.0.1": version "1.7.0" resolved "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.7.0.tgz" integrity sha512-Iz84C+FVOskmauh9FNnj4+VrA+hG5o+tkMzXuoesvSfunVSioXib0syVFeNXwOm4+M5GdWCuW632LVjqEXStIg== - dependencies: - "@opentelemetry/core" "1.7.0" - "@opentelemetry/resources" "1.7.0" - "@opentelemetry/semantic-conventions" "1.7.0" - +======= +"@nevware21/ts-utils@>= 0.10.0 < 2.x", "@nevware21/ts-utils@>= 0.9.4 < 2.x", "@nevware21/ts-utils@>= 0.9.5 < 2.x": + version "0.10.1" + resolved "https://registry.yarnpkg.com/@nevware21/ts-utils/-/ts-utils-0.10.1.tgz#aa65abc71eba06749a396598f22263d26f796ac7" + integrity sha512-pMny25NnF2/MJwdqC3Iyjm2pGIXNxni4AROpcqDeWa+td9JMUY4bUS9uU9XW+BoBRqTLUL+WURF9SOd/6OQzRg== + +"@opentelemetry/api@^1.4.1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.4.1.tgz#ff22eb2e5d476fbc2450a196e40dd243cc20c28f" + integrity sha512-O2yRJce1GOc6PAy3QxFM4NzFiWzvScDC1/5ihYBL6BUEVdq0XMWN01sppE+H6bBXbaFYipjwFLEWLg5PaSOThA== + +"@opentelemetry/core@1.15.2", "@opentelemetry/core@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.15.2.tgz#5b170bf223a2333884bbc2d29d95812cdbda7c9f" + integrity sha512-+gBv15ta96WqkHZaPpcDHiaz0utiiHZVfm2YOYSqFGrUaJpPkMoSuLBB58YFQGi6Rsb9EHos84X6X5+9JspmLw== +>>>>>>> main + dependencies: + "@opentelemetry/semantic-conventions" "1.15.2" + +<<<<<<< HEAD "@opentelemetry/semantic-conventions@1.7.0", "@opentelemetry/semantic-conventions@^1.0.1": version "1.7.0" resolved "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.7.0.tgz" integrity sha512-FGBx/Qd09lMaqQcogCHyYrFEpTx4cAjeS+48lMIR12z7LdH+zofGDVQSubN59nL6IpubfKqTeIDu9rNO28iHVA== +======= +"@opentelemetry/instrumentation@^0.41.2": + version "0.41.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.41.2.tgz#cae11fa64485dcf03dae331f35b315b64bc6189f" + integrity sha512-rxU72E0pKNH6ae2w5+xgVYZLzc5mlxAbGzF4shxMVK8YC2QQsfN38B2GPbj0jvrKWWNUElfclQ+YTykkNg/grw== + dependencies: + "@types/shimmer" "^1.0.2" + import-in-the-middle "1.4.2" + require-in-the-middle "^7.1.1" + semver "^7.5.1" + shimmer "^1.2.1" + +"@opentelemetry/resources@1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.15.2.tgz#0c9e26cb65652a1402834a3c030cce6028d6dd9d" + integrity sha512-xmMRLenT9CXmm5HMbzpZ1hWhaUowQf8UB4jMjFlAxx1QzQcsD3KFNAVX/CAWzFPtllTyTplrA4JrQ7sCH3qmYw== + dependencies: + "@opentelemetry/core" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" + +"@opentelemetry/sdk-trace-base@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.15.2.tgz#4821f94033c55a6c8bbd35ae387b715b6108517a" + integrity sha512-BEaxGZbWtvnSPchV98qqqqa96AOcb41pjgvhfzDij10tkBhIu9m0Jd6tZ1tJB5ZHfHbTffqYVYE0AOGobec/EQ== + dependencies: + "@opentelemetry/core" "1.15.2" + "@opentelemetry/resources" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" + +"@opentelemetry/semantic-conventions@1.15.2", "@opentelemetry/semantic-conventions@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.15.2.tgz#3bafb5de3e20e841dff6cb3c66f4d6e9694c4241" + integrity sha512-CjbOKwk2s+3xPIMcd5UNYQzsf+v94RczbdNix9/kQh38WiQkM90sUOi3if8eyHFgiBjBjhwXrA7W3ydiSQP9mw== +>>>>>>> main "@tootallnate/once@2": version "2.0.0" resolved "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz" integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== +<<<<<<< HEAD "@types/node@16.x": version "16.11.6" resolved "https://registry.npmjs.org/@types/node/-/node-16.11.6.tgz" integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w== +======= +"@types/node@18.x": + version "18.15.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" + integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== +>>>>>>> main "@types/semver@^5.5.0": version "5.5.0" resolved "https://registry.npmjs.org/@types/semver/-/semver-5.5.0.tgz" integrity sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ== +<<<<<<< HEAD "@vscode/extension-telemetry@0.7.5": version "0.7.5" resolved "https://registry.npmjs.org/@vscode/extension-telemetry/-/extension-telemetry-0.7.5.tgz" integrity sha512-fJ5y3TcpqqkFYHneabYaoB4XAhDdVflVm+TDKshw9VOs77jkgNS4UA7LNXrWeO0eDne3Sh3JgURf+xzc1rk69w== - 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" +======= +"@types/shimmer@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/shimmer/-/shimmer-1.0.2.tgz#93eb2c243c351f3f17d5c580c7467ae5d686b65f" + integrity sha512-dKkr1bTxbEsFlh2ARpKzcaAmsYixqt9UyCdoEZk8rHyE4iQYcDCyvSjDSf7JUWJHlJiTtbIoQjxKh6ViywqDAg== + +"@vscode/extension-telemetry@^0.8.4": + version "0.8.4" + resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.8.4.tgz#c078c6f55df1c9e0592de3b4ce0f685dd345bfe7" + integrity sha512-UqM9+KZDDK3MyoHTsg6XNM+XO6pweQxzCpqJz33BoBEYAGsbBviRYcVpJglgay2oReuDD2pOI1Nio3BKNDLhWA== +>>>>>>> main + dependencies: + "@microsoft/1ds-core-js" "^3.2.13" + "@microsoft/1ds-post-js" "^3.2.13" + "@microsoft/applicationinsights-web-basic" "^3.0.2" + applicationinsights "^2.7.1" "@vscode/sync-api-client@^0.7.2": version "0.7.2" @@ -206,6 +394,16 @@ "@vscode/sync-api-common" "0.7.2" vscode-uri "3.0.3" +acorn-import-assertions@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" + integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== + +acorn@^8.8.2: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== + agent-base@6: version "6.0.2" resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz" @@ -213,22 +411,31 @@ agent-base@6: dependencies: debug "4" +<<<<<<< HEAD applicationinsights@2.4.1: version "2.4.1" resolved "https://registry.npmjs.org/applicationinsights/-/applicationinsights-2.4.1.tgz" integrity sha512-0n0Ikd0gzSm460xm+M0UTWIwXrhrH/0bqfZatcJjYObWyefxfAxapGEyNnSGd1Tg90neHz+Yhf+Ff/zgvPiQYA== - dependencies: - "@azure/core-auth" "^1.4.0" - "@azure/core-rest-pipeline" "^1.10.0" +======= +applicationinsights@^2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.7.3.tgz#8781454d29c0b14c9773f2e892b4cf5e7468ffa5" + integrity sha512-JY8+kTEkjbA+kAVNWDtpfW2lqsrDALfDXuxOs74KLPu2y13fy/9WB52V4LfYVTVcW1/jYOXjTxNS2gPZIDh1iw== +>>>>>>> main + dependencies: + "@azure/core-auth" "^1.5.0" + "@azure/core-rest-pipeline" "1.10.1" + "@azure/core-util" "1.2.0" + "@azure/opentelemetry-instrumentation-azure-sdk" "^1.0.0-beta.5" "@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" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/sdk-trace-base" "^1.15.2" + "@opentelemetry/semantic-conventions" "^1.15.2" cls-hooked "^4.2.2" continuation-local-storage "^3.2.1" - diagnostic-channel "1.1.0" - diagnostic-channel-publishers "1.0.5" + diagnostic-channel "1.1.1" + diagnostic-channel-publishers "1.0.7" async-hook-jl@^1.7.6: version "1.7.6" @@ -257,6 +464,11 @@ axios@^0.26.1: dependencies: follow-redirects "^1.14.8" +cjs-module-lexer@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" + integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== + cls-hooked@^4.2.2: version "4.2.2" resolved "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz" @@ -281,7 +493,7 @@ continuation-local-storage@^3.2.1: async-listener "^0.6.0" emitter-listener "^1.1.1" -debug@4: +debug@4, debug@^4.1.1: version "4.3.4" resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -293,6 +505,7 @@ delayed-stream@~1.0.0: resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== +<<<<<<< HEAD diagnostic-channel-publishers@1.0.5: version "1.0.5" resolved "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.5.tgz" @@ -302,8 +515,19 @@ diagnostic-channel@1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-1.1.0.tgz" integrity sha512-fwujyMe1gj6rk6dYi9hMZm0c8Mz8NDMVl2LB4iaYh3+LIAThZC8RKFGXWG0IML2OxAit/ZFRgZhMkhQ3d/bobQ== +======= +diagnostic-channel-publishers@1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.7.tgz#9b7f8d5ee1295481aee19c827d917e96fedf2c4a" + integrity sha512-SEECbY5AiVt6DfLkhkaHNeshg1CogdLLANA8xlG/TKvS+XUgvIKl7VspJGYiEdL5OUyzMVnr7o0AwB7f+/Mjtg== + +diagnostic-channel@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.1.tgz#44b60972de9ee055c16216535b0e9db3f6a0efd0" + integrity sha512-r2HV5qFkUICyoaKlBEpLKHjxMXATUf/l+h8UZPGBHGLy4DDiY2sOLcIctax4eRnTw5wH2jTMExLntGPJ8eOJxw== +>>>>>>> main dependencies: - semver "^5.3.0" + semver "^7.5.3" emitter-listener@^1.0.1, emitter-listener@^1.1.1: version "1.1.2" @@ -326,6 +550,18 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + http-proxy-agent@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz" @@ -343,6 +579,23 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" +import-in-the-middle@1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/import-in-the-middle/-/import-in-the-middle-1.4.2.tgz#2a266676e3495e72c04bbaa5ec14756ba168391b" + integrity sha512-9WOz1Yh/cvO/p69sxRmhyQwrIGGSp7EIdcb+fFNVi7CzQGQB8U1/1XrKVSbEd/GNOAeM0peJtmi7+qphe7NvAw== + dependencies: + acorn "^8.8.2" + acorn-import-assertions "^1.9.0" + cjs-module-lexer "^1.2.2" + module-details-from-path "^1.0.3" + +is-core-module@^2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" + integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== + dependencies: + has "^1.0.3" + jsonc-parser@^3.2.0: version "3.2.0" resolved "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz" @@ -367,11 +620,39 @@ mime-types@^2.1.12: dependencies: mime-db "1.52.0" +module-details-from-path@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/module-details-from-path/-/module-details-from-path-1.0.3.tgz#114c949673e2a8a35e9d35788527aa37b679da2b" + integrity sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A== + ms@2.1.2: version "2.1.2" resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +require-in-the-middle@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/require-in-the-middle/-/require-in-the-middle-7.2.0.tgz#b539de8f00955444dc8aed95e17c69b0a4f10fcf" + integrity sha512-3TLx5TGyAY6AOqLBoXmHkNql0HIf2RGbuMgCDT2WO/uGVAPJs6h7Kl+bN6TIZGd9bWhWPwnDnTHGtW8Iu77sdw== + dependencies: + debug "^4.1.1" + module-details-from-path "^1.0.3" + resolve "^1.22.1" + +resolve@^1.22.1: + version "1.22.4" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.4.tgz#1dc40df46554cdaf8948a486a10f6ba1e2026c34" + integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + semver@7.5.2: version "7.5.2" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.2.tgz#5b851e66d1be07c1cdaf37dfc856f543325a2beb" @@ -384,7 +665,14 @@ semver@^5.3.0, semver@^5.4.1: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -shimmer@^1.1.0, shimmer@^1.2.0: +semver@^7.5.1, semver@^7.5.3: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +shimmer@^1.1.0, shimmer@^1.2.0, shimmer@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz" integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw== @@ -394,6 +682,11 @@ stack-chain@^1.3.7: resolved "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz" integrity sha512-D8cWtWVdIe/jBA7v5p5Hwl5yOSOrmZPWDPe2KxQ5UAGD+nxbxU0lKXA4h85Ta6+qgdKVL3vUxsbIZjc1kBG7ug== +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + tas-client@0.1.58: version "0.1.58" resolved "https://registry.npmjs.org/tas-client/-/tas-client-0.1.58.tgz" diff --git a/extensions/vscode-api-tests/package.json b/extensions/vscode-api-tests/package.json index b230a1a4897ff..1fd9a7577acb4 100644 --- a/extensions/vscode-api-tests/package.json +++ b/extensions/vscode-api-tests/package.json @@ -19,6 +19,7 @@ "fileSearchProvider", "findTextInFiles", "fsChunks", + "mappedEditsProvider", "notebookCellExecutionState", "notebookDeprecated", "notebookLiveShare", @@ -40,17 +41,16 @@ "envShellEvent", "testCoverage", "testObserver", + "testMessageContextValue", "textSearchProvider", "timeline", "tokenInformation", - "treeItemCheckbox", + "treeViewActiveItem", "treeViewReveal", - "testInvalidateResults", "workspaceTrust", "telemetry", "windowActivity", "interactiveUserActions", - "envCollectionWorkspace", "envCollectionOptions" ], "private": true, @@ -214,7 +214,7 @@ }, "devDependencies": { "@types/mocha": "^9.1.1", - "@types/node": "16.x" + "@types/node": "18.x" }, "repository": { "type": "git", diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/documentPaste.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/documentPaste.test.ts index dd5b9eae41c47..c2cdd073d7443 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/documentPaste.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/documentPaste.test.ts @@ -37,7 +37,7 @@ suite.skip('vscode API - Copy Paste', function () { dataTransfer.set(textPlain, new vscode.DataTransferItem(reversed)); } } - }, { copyMimeTypes: [textPlain] })); + }, { id: 'test', copyMimeTypes: [textPlain] })); await vscode.commands.executeCommand('editor.action.clipboardCopyAction'); const newDocContent = getNextDocumentText(testDisposables, doc); @@ -62,7 +62,7 @@ suite.skip('vscode API - Copy Paste', function () { dataTransfer.set(textPlain, new vscode.DataTransferItem(reversed + '\n')); } } - }, { copyMimeTypes: [textPlain] })); + }, { id: 'test', copyMimeTypes: [textPlain] })); await vscode.commands.executeCommand('editor.action.clipboardCopyAction'); const newDocContent = getNextDocumentText(testDisposables, doc); @@ -88,7 +88,7 @@ suite.skip('vscode API - Copy Paste', function () { dataTransfer.set(textPlain, new vscode.DataTransferItem(`(${ranges.length})${selections.join(' ')}`)); } } - }, { copyMimeTypes: [textPlain] })); + }, { id: 'test', copyMimeTypes: [textPlain] })); await vscode.commands.executeCommand('editor.action.clipboardCopyAction'); editor.selections = [new vscode.Selection(0, 0, 0, 0)]; @@ -118,7 +118,7 @@ suite.skip('vscode API - Copy Paste', function () { dataTransfer.set(textPlain, new vscode.DataTransferItem('a')); providerAResolve(); } - }, { copyMimeTypes: [textPlain] })); + }, { id: 'test', copyMimeTypes: [textPlain] })); // Later registered providers will be called first testDisposables.push(vscode.languages.registerDocumentPasteEditProvider({ language: 'plaintext' }, new class implements vscode.DocumentPasteEditProvider { @@ -132,7 +132,7 @@ suite.skip('vscode API - Copy Paste', function () { dataTransfer.set(textPlain, new vscode.DataTransferItem('b')); } - }, { copyMimeTypes: [textPlain] })); + }, { id: 'test', copyMimeTypes: [textPlain] })); await vscode.commands.executeCommand('editor.action.clipboardCopyAction'); const newDocContent = getNextDocumentText(testDisposables, doc); @@ -159,7 +159,7 @@ suite.skip('vscode API - Copy Paste', function () { dataTransfer.set(textPlain, new vscode.DataTransferItem('xyz')); providerAResolve(); } - }, { copyMimeTypes: [textPlain] })); + }, { id: 'test', copyMimeTypes: [textPlain] })); testDisposables.push(vscode.languages.registerDocumentPasteEditProvider({ language: 'plaintext' }, new class implements vscode.DocumentPasteEditProvider { async prepareDocumentPaste(_document: vscode.TextDocument, _ranges: readonly vscode.Range[], dataTransfer: vscode.DataTransfer, _token: vscode.CancellationToken): Promise { @@ -172,7 +172,7 @@ suite.skip('vscode API - Copy Paste', function () { const str = await entry!.asString(); dataTransfer.set(textPlain, new vscode.DataTransferItem(reverseString(str))); } - }, { copyMimeTypes: [textPlain] })); + }, { id: 'test', copyMimeTypes: [textPlain] })); await vscode.commands.executeCommand('editor.action.clipboardCopyAction'); const newDocContent = getNextDocumentText(testDisposables, doc); @@ -192,13 +192,13 @@ suite.skip('vscode API - Copy Paste', function () { async prepareDocumentPaste(_document: vscode.TextDocument, _ranges: readonly vscode.Range[], dataTransfer: vscode.DataTransfer, _token: vscode.CancellationToken): Promise { dataTransfer.set(textPlain, new vscode.DataTransferItem('xyz')); } - }, { copyMimeTypes: [textPlain] })); + }, { id: 'test', copyMimeTypes: [textPlain] })); testDisposables.push(vscode.languages.registerDocumentPasteEditProvider({ language: 'plaintext' }, new class implements vscode.DocumentPasteEditProvider { async prepareDocumentPaste(_document: vscode.TextDocument, _ranges: readonly vscode.Range[], _dataTransfer: vscode.DataTransfer, _token: vscode.CancellationToken): Promise { throw new Error('Expected testing error from bad provider'); } - }, { copyMimeTypes: [textPlain] })); + }, { id: 'test', copyMimeTypes: [textPlain] })); await vscode.commands.executeCommand('editor.action.clipboardCopyAction'); const newDocContent = getNextDocumentText(testDisposables, doc); diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/mappedEdits.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/mappedEdits.test.ts new file mode 100644 index 0000000000000..f4fc349f115e9 --- /dev/null +++ b/extensions/vscode-api-tests/src/singlefolder-tests/mappedEdits.test.ts @@ -0,0 +1,102 @@ +/*--------------------------------------------------------------------------------------------- + * 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 * as assert from 'assert'; + +suite('mapped edits provider', () => { + + test('mapped edits does not provide edits for unregistered langs', async function () { + + const uri = vscode.Uri.file(path.join(vscode.workspace.rootPath || '', './myFile.ts')); + + const tsDocFilter = [{ language: 'json' }]; + + const r1 = vscode.chat.registerMappedEditsProvider(tsDocFilter, { + provideMappedEdits: (_doc: vscode.TextDocument, codeBlocks: string[], context: vscode.MappedEditsContext, _token: vscode.CancellationToken) => { + + assert(context.selections.length === 1); + assert(context.related.length === 1); + assert('uri' in context.related[0] && 'range' in context.related[0]); + + const edit = new vscode.WorkspaceEdit(); + const text = codeBlocks.join('\n//----\n'); + edit.replace(uri, context.selections[0], text); + return edit; + } + }); + await vscode.workspace.openTextDocument(uri); + const result = await vscode.commands.executeCommand>( + 'vscode.executeMappedEditsProvider', + uri, + [ + '// hello', + `function foo() {\n\treturn 1;\n}`, + ], + { + selections: [new vscode.Selection(0, 0, 1, 0)], + related: [ + { + uri, + range: new vscode.Range(new vscode.Position(0, 0), new vscode.Position(1, 0)) + } + ] + } + ); + r1.dispose(); + + assert(result === null, 'returned null'); + }); + + test('mapped edits provides a single edit replacing the selection', async function () { + + const uri = vscode.Uri.file(path.join(vscode.workspace.rootPath || '', './myFile.ts')); + + const tsDocFilter = [{ language: 'typescript' }]; + + const r1 = vscode.chat.registerMappedEditsProvider(tsDocFilter, { + provideMappedEdits: (_doc: vscode.TextDocument, codeBlocks: string[], context: vscode.MappedEditsContext, _token: vscode.CancellationToken) => { + + assert(context.selections.length === 1); + assert(context.related.length === 1); + assert('uri' in context.related[0] && 'range' in context.related[0]); + + const edit = new vscode.WorkspaceEdit(); + const text = codeBlocks.join('\n//----\n'); + edit.replace(uri, context.selections[0], text); + return edit; + } + }); + + await vscode.workspace.openTextDocument(uri); + const result = await vscode.commands.executeCommand>( + 'vscode.executeMappedEditsProvider', + uri, + [ + '// hello', + `function foo() {\n\treturn 1;\n}`, + ], + { + selections: [new vscode.Selection(0, 0, 1, 0)], + related: [ + { + uri, + range: new vscode.Range(new vscode.Position(0, 0), new vscode.Position(1, 0)) + } + ] + } + ); + r1.dispose(); + + assert(result, 'non null response'); + const edits = result.get(uri); + assert(edits.length === 1); + assert(edits[0].range.start.line === 0); + assert(edits[0].range.start.character === 0); + assert(edits[0].range.end.line === 1); + assert(edits[0].range.end.character === 0); + }); +}); diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts index b2a8bb3a9cc8c..4275898e24458 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { deepStrictEqual, doesNotThrow, equal, ok, strictEqual, throws } from 'assert'; -import { ConfigurationTarget, Disposable, env, EnvironmentVariableCollection, EnvironmentVariableMutator, EnvironmentVariableMutatorOptions, EnvironmentVariableMutatorType, EnvironmentVariableScope, EventEmitter, ExtensionContext, extensions, ExtensionTerminalOptions, Pseudoterminal, Terminal, TerminalDimensions, TerminalExitReason, TerminalOptions, TerminalState, UIKind, Uri, window, workspace } from 'vscode'; +import { commands, ConfigurationTarget, Disposable, env, EnvironmentVariableMutator, EnvironmentVariableMutatorOptions, EnvironmentVariableMutatorType, EventEmitter, ExtensionContext, extensions, ExtensionTerminalOptions, Pseudoterminal, Terminal, TerminalDimensions, TerminalExitReason, TerminalOptions, TerminalState, UIKind, Uri, window, workspace } from 'vscode'; import { assertNoRpc, poll } from '../utils'; // Disable terminal tests: @@ -347,8 +347,52 @@ import { assertNoRpc, poll } from '../utils'; }); }); + suite('selection', () => { + test('should be undefined immediately after creation', async () => { + const terminal = window.createTerminal({ name: 'selection test' }); + terminal.show(); + equal(terminal.selection, undefined); + terminal.dispose(); + }); + test('should be defined after selecting all content', async () => { + const terminal = window.createTerminal({ name: 'selection test' }); + terminal.show(); + // Wait for some terminal data + await new Promise(r => { + const disposable = window.onDidWriteTerminalData(() => { + disposable.dispose(); + r(); + }); + }); + await commands.executeCommand('workbench.action.terminal.selectAll'); + await poll(() => Promise.resolve(), () => terminal.selection !== undefined, 'selection should be defined'); + terminal.dispose(); + }); + test('should be undefined after clearing a selection', async () => { + const terminal = window.createTerminal({ name: 'selection test' }); + terminal.show(); + // Wait for some terminal data + await new Promise(r => { + const disposable = window.onDidWriteTerminalData(() => { + disposable.dispose(); + r(); + }); + }); + await commands.executeCommand('workbench.action.terminal.selectAll'); + await poll(() => Promise.resolve(), () => terminal.selection !== undefined, 'selection should be defined'); + await commands.executeCommand('workbench.action.terminal.clearSelection'); + await poll(() => Promise.resolve(), () => terminal.selection === undefined, 'selection should not be defined'); + terminal.dispose(); + }); + }); + suite('window.onDidWriteTerminalData', () => { - test('should listen to all future terminal data events', (done) => { + test('should listen to all future terminal data events', function (done) { + // This test has been flaky in the past but it's not clear why, possibly because + // events from previous tests polluting the event recording in this test. Retries + // was added so we continue to have coverage of the onDidWriteTerminalData API. + this.retries(3); + const openEvents: string[] = []; const dataEvents: { name: string; data: string }[] = []; const closeEvents: string[] = []; @@ -868,11 +912,10 @@ import { assertNoRpc, poll } from '../utils'; }); test('get and forEach should work (scope)', () => { - // TODO: Remove cast once `envCollectionWorkspace` API is finalized. - const collection = extensionContext.environmentVariableCollection as (EnvironmentVariableCollection & { getScopedEnvironmentVariableCollection(scope: EnvironmentVariableScope): EnvironmentVariableCollection }); + const collection = extensionContext.environmentVariableCollection; disposables.push({ dispose: () => collection.clear() }); const scope = { workspaceFolder: { uri: Uri.file('workspace1'), name: 'workspace1', index: 0 } }; - const scopedCollection = collection.getScopedEnvironmentVariableCollection(scope); + const scopedCollection = collection.getScoped(scope); scopedCollection.replace('A', 'scoped~a2~'); scopedCollection.append('B', 'scoped~b2~'); scopedCollection.prepend('C', 'scoped~c2~'); @@ -884,7 +927,7 @@ import { assertNoRpc, poll } from '../utils'; applyAtProcessCreation: true, applyAtShellIntegration: false }; - const expectedScopedCollection = collection.getScopedEnvironmentVariableCollection(scope); + const expectedScopedCollection = collection.getScoped(scope); deepStrictEqual(expectedScopedCollection.get('A'), { value: 'scoped~a2~', type: EnvironmentVariableMutatorType.Replace, options: defaultOptions }); deepStrictEqual(expectedScopedCollection.get('B'), { value: 'scoped~b2~', type: EnvironmentVariableMutatorType.Append, options: defaultOptions }); deepStrictEqual(expectedScopedCollection.get('C'), { value: 'scoped~c2~', type: EnvironmentVariableMutatorType.Prepend, options: defaultOptions }); @@ -897,6 +940,7 @@ import { assertNoRpc, poll } from '../utils'; { value: 'scoped~b2~', type: EnvironmentVariableMutatorType.Append, options: defaultOptions }, { value: 'scoped~c2~', type: EnvironmentVariableMutatorType.Prepend, options: defaultOptions } ]); + deepStrictEqual(entries.map(v => v[0]), ['A', 'B', 'C']); }); }); }); diff --git a/extensions/vscode-api-tests/testWorkspace/myFile.ts b/extensions/vscode-api-tests/testWorkspace/myFile.ts new file mode 100644 index 0000000000000..2a2a4927869a9 --- /dev/null +++ b/extensions/vscode-api-tests/testWorkspace/myFile.ts @@ -0,0 +1,3 @@ +// 1 +// 2 +// 3 diff --git a/extensions/vscode-api-tests/yarn.lock b/extensions/vscode-api-tests/yarn.lock index b856762f8e3ee..3c35048cdc7f7 100644 --- a/extensions/vscode-api-tests/yarn.lock +++ b/extensions/vscode-api-tests/yarn.lock @@ -7,7 +7,7 @@ resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-9.1.1.tgz#e7c4f1001eefa4b8afbd1eee27a237fee3bf29c4" integrity sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw== -"@types/node@16.x": - version "16.11.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae" - integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w== +"@types/node@18.x": + version "18.15.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" + integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== diff --git a/extensions/vscode-colorize-tests/package.json b/extensions/vscode-colorize-tests/package.json index e2517c811f2bc..8cb8442b6f2be 100644 --- a/extensions/vscode-colorize-tests/package.json +++ b/extensions/vscode-colorize-tests/package.json @@ -20,7 +20,7 @@ "jsonc-parser": "2.2.1" }, "devDependencies": { - "@types/node": "16.x" + "@types/node": "18.x" }, "contributes": { "semanticTokenTypes": [ diff --git a/extensions/vscode-colorize-tests/test/colorize-fixtures/test.code-snippets b/extensions/vscode-colorize-tests/test/colorize-fixtures/test.code-snippets new file mode 100644 index 0000000000000..fb3df23dd42d2 --- /dev/null +++ b/extensions/vscode-colorize-tests/test/colorize-fixtures/test.code-snippets @@ -0,0 +1,40 @@ +{ + // Each snippet is defined under a snippet name and has a scope, prefix, body and + // description. The scope defines in watch languages the snippet is applicable. The prefix is what is + // used to trigger the snippet and the body will be expanded and inserted.Possible variables are: + // $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders. + // Placeholders with the same ids are connected. + // Example: + "MSFT Copyright Header": { + "scope": "javascript,typescript,css", + "prefix": [ + "header", + "stub", + "copyright" + ], + "body": [ + "/*---------------------------------------------------------------------------------------------", + " * Copyright (c) Microsoft Corporation. All rights reserved.", + " * Licensed under the MIT License. See License.txt in the project root for license information.", + " *--------------------------------------------------------------------------------------------*/", + "", + "$0" + ], + "description": "Insert Copyright Statement" + }, + "TS -> Inject Service": { + "scope": "typescript", + "description": "Constructor Injection Pattern", + "prefix": "@inject", + "body": "@$1 private readonly _$2: ${1},$0" + }, + "TS -> Event & Emitter": { + "scope": "typescript", + "prefix": "emitter", + "description": "Add emitter and event properties", + "body": [ + "private readonly _onDid$1 = new Emitter<$2>();", + "readonly onDid$1: Event<$2> = this._onDid$1.event;" + ], + } +} diff --git a/extensions/vscode-colorize-tests/test/colorize-fixtures/test.md b/extensions/vscode-colorize-tests/test/colorize-fixtures/test.md index 28f3590536e5f..309aa6de7935c 100644 --- a/extensions/vscode-colorize-tests/test/colorize-fixtures/test.md +++ b/extensions/vscode-colorize-tests/test/colorize-fixtures/test.md @@ -103,4 +103,4 @@ Pop * Multiple definitions and terms are possible * Definitions can include multiple paragraphs too -*[ABBR]: Markdown plus abbreviations (produces an tag) \ No newline at end of file +*[ABBR]: Markdown plus abbreviations (produces an tag) diff --git a/extensions/vscode-colorize-tests/test/colorize-results/test_code-snippets.json b/extensions/vscode-colorize-tests/test/colorize-results/test_code-snippets.json new file mode 100644 index 0000000000000..5403d20a7d894 --- /dev/null +++ b/extensions/vscode-colorize-tests/test/colorize-results/test_code-snippets.json @@ -0,0 +1,3460 @@ +[ + { + "c": "{", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets punctuation.definition.dictionary.begin.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "//", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets comment.line.double-slash.js punctuation.definition.comment.json.comments.snippets", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668", + "dark_modern": "comment: #6A9955", + "hc_light": "comment: #515151", + "light_modern": "comment: #008000" + } + }, + { + "c": " Each snippet is defined under a snippet name and has a scope, prefix, body and", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets comment.line.double-slash.js", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668", + "dark_modern": "comment: #6A9955", + "hc_light": "comment: #515151", + "light_modern": "comment: #008000" + } + }, + { + "c": "\t", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "//", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets comment.line.double-slash.js punctuation.definition.comment.json.comments.snippets", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668", + "dark_modern": "comment: #6A9955", + "hc_light": "comment: #515151", + "light_modern": "comment: #008000" + } + }, + { + "c": " description. The scope defines in watch languages the snippet is applicable. The prefix is what is", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets comment.line.double-slash.js", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668", + "dark_modern": "comment: #6A9955", + "hc_light": "comment: #515151", + "light_modern": "comment: #008000" + } + }, + { + "c": "\t", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "//", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets comment.line.double-slash.js punctuation.definition.comment.json.comments.snippets", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668", + "dark_modern": "comment: #6A9955", + "hc_light": "comment: #515151", + "light_modern": "comment: #008000" + } + }, + { + "c": " used to trigger the snippet and the body will be expanded and inserted.Possible variables are:", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets comment.line.double-slash.js", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668", + "dark_modern": "comment: #6A9955", + "hc_light": "comment: #515151", + "light_modern": "comment: #008000" + } + }, + { + "c": "\t", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "//", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets comment.line.double-slash.js punctuation.definition.comment.json.comments.snippets", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668", + "dark_modern": "comment: #6A9955", + "hc_light": "comment: #515151", + "light_modern": "comment: #008000" + } + }, + { + "c": " $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders.", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets comment.line.double-slash.js", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668", + "dark_modern": "comment: #6A9955", + "hc_light": "comment: #515151", + "light_modern": "comment: #008000" + } + }, + { + "c": "\t", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "//", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets comment.line.double-slash.js punctuation.definition.comment.json.comments.snippets", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668", + "dark_modern": "comment: #6A9955", + "hc_light": "comment: #515151", + "light_modern": "comment: #008000" + } + }, + { + "c": " Placeholders with the same ids are connected.", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets comment.line.double-slash.js", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668", + "dark_modern": "comment: #6A9955", + "hc_light": "comment: #515151", + "light_modern": "comment: #008000" + } + }, + { + "c": "\t", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "//", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets comment.line.double-slash.js punctuation.definition.comment.json.comments.snippets", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668", + "dark_modern": "comment: #6A9955", + "hc_light": "comment: #515151", + "light_modern": "comment: #008000" + } + }, + { + "c": " Example:", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets comment.line.double-slash.js", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668", + "dark_modern": "comment: #6A9955", + "hc_light": "comment: #515151", + "light_modern": "comment: #008000" + } + }, + { + "c": "\t", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets punctuation.support.type.property-name.begin.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": "MSFT Copyright Header", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets punctuation.support.type.property-name.end.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": ":", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets punctuation.separator.dictionary.key-value.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "{", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets punctuation.definition.dictionary.begin.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t\t", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets punctuation.support.type.property-name.begin.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": "scope", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets punctuation.support.type.property-name.end.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": ":", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets punctuation.separator.dictionary.key-value.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.begin.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "javascript,typescript,css", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.end.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": ",", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets punctuation.separator.dictionary.pair.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t\t", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets punctuation.support.type.property-name.begin.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": "prefix", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets punctuation.support.type.property-name.end.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": ":", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets punctuation.separator.dictionary.key-value.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "[", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets punctuation.definition.array.begin.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t\t\t", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.begin.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "header", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.end.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": ",", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets punctuation.separator.array.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t\t\t", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.begin.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "stub", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.end.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": ",", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets punctuation.separator.array.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t\t\t", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.begin.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "copyright", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.end.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "\t\t", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "]", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets punctuation.definition.array.end.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": ",", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets punctuation.separator.dictionary.pair.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t\t", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets punctuation.support.type.property-name.begin.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": "body", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets punctuation.support.type.property-name.begin.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": ":", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets punctuation.separator.dictionary.key-value.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "[", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets punctuation.definition.array.begin.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t\t\t", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.begin.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "/*---------------------------------------------------------------------------------------------", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets meta.any.json.comments.snippets string.quoted.double.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.end.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": ",", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets punctuation.separator.array.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t\t\t", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.begin.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": " * Copyright (c) Microsoft Corporation. All rights reserved.", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets meta.any.json.comments.snippets string.quoted.double.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.end.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": ",", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets punctuation.separator.array.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t\t\t", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.begin.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": " * Licensed under the MIT License. See License.txt in the project root for license information.", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets meta.any.json.comments.snippets string.quoted.double.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.end.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": ",", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets punctuation.separator.array.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t\t\t", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.begin.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": " *--------------------------------------------------------------------------------------------*/", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets meta.any.json.comments.snippets string.quoted.double.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.end.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": ",", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets punctuation.separator.array.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t\t\t", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.begin.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.end.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": ",", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets punctuation.separator.array.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t\t\t", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.begin.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "$", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets meta.any.json.comments.snippets meta.insertion.simple.numeric.json.comments.snippets meta.insertion.tabstop.simple.json.comments.snippets punctuation.section.insertion.dollar.simple.json.comments.snippets keyword.operator.insertion.json.comments.snippets custom.punctuation.section.insertion.dollar.simple.json.comments.snippets", + "r": { + "dark_plus": "keyword.operator: #D4D4D4", + "light_plus": "keyword.operator: #000000", + "dark_vs": "keyword.operator: #D4D4D4", + "light_vs": "keyword.operator: #000000", + "hc_black": "keyword.operator: #D4D4D4", + "dark_modern": "keyword.operator: #D4D4D4", + "hc_light": "keyword.operator: #000000", + "light_modern": "keyword.operator: #000000" + } + }, + { + "c": "0", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets meta.any.json.comments.snippets meta.insertion.simple.numeric.json.comments.snippets meta.insertion.tabstop.simple.json.comments.snippets variable.other.normal.json.comments.snippets keyword.operator.insertion.json.comments.snippets custom.variable.other.normal.numeric.json.comments.snippets", + "r": { + "dark_plus": "keyword.operator: #D4D4D4", + "light_plus": "keyword.operator: #000000", + "dark_vs": "keyword.operator: #D4D4D4", + "light_vs": "keyword.operator: #000000", + "hc_black": "keyword.operator: #D4D4D4", + "dark_modern": "keyword.operator: #D4D4D4", + "hc_light": "keyword.operator: #000000", + "light_modern": "keyword.operator: #000000" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.end.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "\t\t", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "]", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets punctuation.definition.array.end.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": ",", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets punctuation.separator.dictionary.pair.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t\t", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets punctuation.support.type.property-name.begin.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": "description", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets punctuation.support.type.property-name.end.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": ":", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets punctuation.separator.dictionary.key-value.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.begin.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "Insert Copyright Statement", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.end.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "\t", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "}", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets punctuation.definition.dictionary.end.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": ",", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets punctuation.separator.dictionary.pair.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets punctuation.support.type.property-name.begin.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": "TS -> Inject Service", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets punctuation.support.type.property-name.end.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": ":", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets punctuation.separator.dictionary.key-value.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "{", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets punctuation.definition.dictionary.begin.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t\t", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets punctuation.support.type.property-name.begin.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": "scope", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets punctuation.support.type.property-name.end.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": ":", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets punctuation.separator.dictionary.key-value.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.begin.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "typescript", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.end.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": ",", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets punctuation.separator.dictionary.pair.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t\t", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets punctuation.support.type.property-name.begin.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": "description", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets punctuation.support.type.property-name.end.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": ":", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets punctuation.separator.dictionary.key-value.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.begin.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "Constructor Injection Pattern", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.end.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": ",", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets punctuation.separator.dictionary.pair.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t\t", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets punctuation.support.type.property-name.begin.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": "prefix", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets punctuation.support.type.property-name.end.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": ":", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets punctuation.separator.dictionary.key-value.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.begin.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "@inject", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.end.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": ",", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets punctuation.separator.dictionary.pair.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t\t", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets punctuation.support.type.property-name.begin.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": "body", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets punctuation.support.type.property-name.begin.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": ":", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets punctuation.separator.dictionary.key-value.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.begin.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "@", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets meta.any.json.comments.snippets string.quoted.double.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "$", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets meta.any.json.comments.snippets meta.insertion.simple.numeric.json.comments.snippets meta.insertion.tabstop.simple.json.comments.snippets punctuation.section.insertion.dollar.simple.json.comments.snippets keyword.operator.insertion.json.comments.snippets custom.punctuation.section.insertion.dollar.simple.json.comments.snippets", + "r": { + "dark_plus": "keyword.operator: #D4D4D4", + "light_plus": "keyword.operator: #000000", + "dark_vs": "keyword.operator: #D4D4D4", + "light_vs": "keyword.operator: #000000", + "hc_black": "keyword.operator: #D4D4D4", + "dark_modern": "keyword.operator: #D4D4D4", + "hc_light": "keyword.operator: #000000", + "light_modern": "keyword.operator: #000000" + } + }, + { + "c": "1", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets meta.any.json.comments.snippets meta.insertion.simple.numeric.json.comments.snippets meta.insertion.tabstop.simple.json.comments.snippets variable.other.normal.json.comments.snippets keyword.operator.insertion.json.comments.snippets custom.variable.other.normal.numeric.json.comments.snippets", + "r": { + "dark_plus": "keyword.operator: #D4D4D4", + "light_plus": "keyword.operator: #000000", + "dark_vs": "keyword.operator: #D4D4D4", + "light_vs": "keyword.operator: #000000", + "hc_black": "keyword.operator: #D4D4D4", + "dark_modern": "keyword.operator: #D4D4D4", + "hc_light": "keyword.operator: #000000", + "light_modern": "keyword.operator: #000000" + } + }, + { + "c": " private readonly _", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets meta.any.json.comments.snippets string.quoted.double.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "$", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets meta.any.json.comments.snippets meta.insertion.simple.numeric.json.comments.snippets meta.insertion.tabstop.simple.json.comments.snippets punctuation.section.insertion.dollar.simple.json.comments.snippets keyword.operator.insertion.json.comments.snippets custom.punctuation.section.insertion.dollar.simple.json.comments.snippets", + "r": { + "dark_plus": "keyword.operator: #D4D4D4", + "light_plus": "keyword.operator: #000000", + "dark_vs": "keyword.operator: #D4D4D4", + "light_vs": "keyword.operator: #000000", + "hc_black": "keyword.operator: #D4D4D4", + "dark_modern": "keyword.operator: #D4D4D4", + "hc_light": "keyword.operator: #000000", + "light_modern": "keyword.operator: #000000" + } + }, + { + "c": "2", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets meta.any.json.comments.snippets meta.insertion.simple.numeric.json.comments.snippets meta.insertion.tabstop.simple.json.comments.snippets variable.other.normal.json.comments.snippets keyword.operator.insertion.json.comments.snippets custom.variable.other.normal.numeric.json.comments.snippets", + "r": { + "dark_plus": "keyword.operator: #D4D4D4", + "light_plus": "keyword.operator: #000000", + "dark_vs": "keyword.operator: #D4D4D4", + "light_vs": "keyword.operator: #000000", + "hc_black": "keyword.operator: #D4D4D4", + "dark_modern": "keyword.operator: #D4D4D4", + "hc_light": "keyword.operator: #000000", + "light_modern": "keyword.operator: #000000" + } + }, + { + "c": ": ", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets meta.any.json.comments.snippets string.quoted.double.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "$", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets meta.any.json.comments.snippets meta.insertion.brackets.json.comments.snippets meta.insertion.tabstop.bracket.json.comments.snippets punctuation.section.insertion.dollar.brackets.json.comments.snippets keyword.operator.insertion.json.comments.snippets custom.punctuation.section.insertion.dollar.brackets.json.comments.snippets", + "r": { + "dark_plus": "keyword.operator: #D4D4D4", + "light_plus": "keyword.operator: #000000", + "dark_vs": "keyword.operator: #D4D4D4", + "light_vs": "keyword.operator: #000000", + "hc_black": "keyword.operator: #D4D4D4", + "dark_modern": "keyword.operator: #D4D4D4", + "hc_light": "keyword.operator: #000000", + "light_modern": "keyword.operator: #000000" + } + }, + { + "c": "{", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets meta.any.json.comments.snippets meta.insertion.brackets.json.comments.snippets meta.insertion.tabstop.bracket.json.comments.snippets punctuation.section.insertion.bracket.json.comments.snippets keyword.operator.insertion.json.comments.snippets custom.punctuation.section.insertion.bracket.json.comments.snippets", + "r": { + "dark_plus": "keyword.operator: #D4D4D4", + "light_plus": "keyword.operator: #000000", + "dark_vs": "keyword.operator: #D4D4D4", + "light_vs": "keyword.operator: #000000", + "hc_black": "keyword.operator: #D4D4D4", + "dark_modern": "keyword.operator: #D4D4D4", + "hc_light": "keyword.operator: #000000", + "light_modern": "keyword.operator: #000000" + } + }, + { + "c": "1", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets meta.any.json.comments.snippets meta.insertion.brackets.json.comments.snippets meta.insertion.tabstop.bracket.json.comments.snippets variable.other.normal.json.comments.snippets keyword.operator.insertion.json.comments.snippets custom.variable.other.normal.numeric.json.comments.snippets", + "r": { + "dark_plus": "keyword.operator: #D4D4D4", + "light_plus": "keyword.operator: #000000", + "dark_vs": "keyword.operator: #D4D4D4", + "light_vs": "keyword.operator: #000000", + "hc_black": "keyword.operator: #D4D4D4", + "dark_modern": "keyword.operator: #D4D4D4", + "hc_light": "keyword.operator: #000000", + "light_modern": "keyword.operator: #000000" + } + }, + { + "c": "}", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets meta.any.json.comments.snippets meta.insertion.brackets.json.comments.snippets meta.insertion.tabstop.bracket.json.comments.snippets punctuation.section.insertion.bracket.json.comments.snippets keyword.operator.insertion.json.comments.snippets custom.punctuation.section.insertion.bracket.json.comments.snippets", + "r": { + "dark_plus": "keyword.operator: #D4D4D4", + "light_plus": "keyword.operator: #000000", + "dark_vs": "keyword.operator: #D4D4D4", + "light_vs": "keyword.operator: #000000", + "hc_black": "keyword.operator: #D4D4D4", + "dark_modern": "keyword.operator: #D4D4D4", + "hc_light": "keyword.operator: #000000", + "light_modern": "keyword.operator: #000000" + } + }, + { + "c": ",", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets meta.any.json.comments.snippets string.quoted.double.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "$", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets meta.any.json.comments.snippets meta.insertion.simple.numeric.json.comments.snippets meta.insertion.tabstop.simple.json.comments.snippets punctuation.section.insertion.dollar.simple.json.comments.snippets keyword.operator.insertion.json.comments.snippets custom.punctuation.section.insertion.dollar.simple.json.comments.snippets", + "r": { + "dark_plus": "keyword.operator: #D4D4D4", + "light_plus": "keyword.operator: #000000", + "dark_vs": "keyword.operator: #D4D4D4", + "light_vs": "keyword.operator: #000000", + "hc_black": "keyword.operator: #D4D4D4", + "dark_modern": "keyword.operator: #D4D4D4", + "hc_light": "keyword.operator: #000000", + "light_modern": "keyword.operator: #000000" + } + }, + { + "c": "0", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets meta.any.json.comments.snippets meta.insertion.simple.numeric.json.comments.snippets meta.insertion.tabstop.simple.json.comments.snippets variable.other.normal.json.comments.snippets keyword.operator.insertion.json.comments.snippets custom.variable.other.normal.numeric.json.comments.snippets", + "r": { + "dark_plus": "keyword.operator: #D4D4D4", + "light_plus": "keyword.operator: #000000", + "dark_vs": "keyword.operator: #D4D4D4", + "light_vs": "keyword.operator: #000000", + "hc_black": "keyword.operator: #D4D4D4", + "dark_modern": "keyword.operator: #D4D4D4", + "hc_light": "keyword.operator: #000000", + "light_modern": "keyword.operator: #000000" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.end.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "\t", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "}", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets punctuation.definition.dictionary.end.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": ",", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets punctuation.separator.dictionary.pair.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets punctuation.support.type.property-name.begin.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": "TS -> Event & Emitter", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets punctuation.support.type.property-name.end.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": ":", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets punctuation.separator.dictionary.key-value.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "{", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets punctuation.definition.dictionary.begin.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t\t", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets punctuation.support.type.property-name.begin.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": "scope", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets punctuation.support.type.property-name.end.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": ":", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets punctuation.separator.dictionary.key-value.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.begin.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "typescript", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.end.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": ",", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets punctuation.separator.dictionary.pair.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t\t", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets punctuation.support.type.property-name.begin.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": "prefix", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets punctuation.support.type.property-name.end.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": ":", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets punctuation.separator.dictionary.key-value.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.begin.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "emitter", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.end.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": ",", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets punctuation.separator.dictionary.pair.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t\t", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets punctuation.support.type.property-name.begin.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": "description", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets punctuation.support.type.property-name.end.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": ":", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets punctuation.separator.dictionary.key-value.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.begin.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "Add emitter and event properties", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.end.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": ",", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets punctuation.separator.dictionary.pair.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t\t", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets punctuation.support.type.property-name.begin.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": "body", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets string.json.comments.snippets support.type.property-name.json.comments.snippets punctuation.support.type.property-name.begin.json.comments.snippets", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name.json: #0451A5", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name.json: #0451A5", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name.json: #0451A5", + "light_modern": "support.type.property-name.json: #0451A5" + } + }, + { + "c": ":", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets punctuation.separator.dictionary.key-value.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "[", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets punctuation.definition.array.begin.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t\t\t", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.begin.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "private readonly _onDid", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets meta.any.json.comments.snippets string.quoted.double.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "$", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets meta.any.json.comments.snippets meta.insertion.simple.numeric.json.comments.snippets meta.insertion.tabstop.simple.json.comments.snippets punctuation.section.insertion.dollar.simple.json.comments.snippets keyword.operator.insertion.json.comments.snippets custom.punctuation.section.insertion.dollar.simple.json.comments.snippets", + "r": { + "dark_plus": "keyword.operator: #D4D4D4", + "light_plus": "keyword.operator: #000000", + "dark_vs": "keyword.operator: #D4D4D4", + "light_vs": "keyword.operator: #000000", + "hc_black": "keyword.operator: #D4D4D4", + "dark_modern": "keyword.operator: #D4D4D4", + "hc_light": "keyword.operator: #000000", + "light_modern": "keyword.operator: #000000" + } + }, + { + "c": "1", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets meta.any.json.comments.snippets meta.insertion.simple.numeric.json.comments.snippets meta.insertion.tabstop.simple.json.comments.snippets variable.other.normal.json.comments.snippets keyword.operator.insertion.json.comments.snippets custom.variable.other.normal.numeric.json.comments.snippets", + "r": { + "dark_plus": "keyword.operator: #D4D4D4", + "light_plus": "keyword.operator: #000000", + "dark_vs": "keyword.operator: #D4D4D4", + "light_vs": "keyword.operator: #000000", + "hc_black": "keyword.operator: #D4D4D4", + "dark_modern": "keyword.operator: #D4D4D4", + "hc_light": "keyword.operator: #000000", + "light_modern": "keyword.operator: #000000" + } + }, + { + "c": " = new Emitter<", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets meta.any.json.comments.snippets string.quoted.double.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "$", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets meta.any.json.comments.snippets meta.insertion.simple.numeric.json.comments.snippets meta.insertion.tabstop.simple.json.comments.snippets punctuation.section.insertion.dollar.simple.json.comments.snippets keyword.operator.insertion.json.comments.snippets custom.punctuation.section.insertion.dollar.simple.json.comments.snippets", + "r": { + "dark_plus": "keyword.operator: #D4D4D4", + "light_plus": "keyword.operator: #000000", + "dark_vs": "keyword.operator: #D4D4D4", + "light_vs": "keyword.operator: #000000", + "hc_black": "keyword.operator: #D4D4D4", + "dark_modern": "keyword.operator: #D4D4D4", + "hc_light": "keyword.operator: #000000", + "light_modern": "keyword.operator: #000000" + } + }, + { + "c": "2", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets meta.any.json.comments.snippets meta.insertion.simple.numeric.json.comments.snippets meta.insertion.tabstop.simple.json.comments.snippets variable.other.normal.json.comments.snippets keyword.operator.insertion.json.comments.snippets custom.variable.other.normal.numeric.json.comments.snippets", + "r": { + "dark_plus": "keyword.operator: #D4D4D4", + "light_plus": "keyword.operator: #000000", + "dark_vs": "keyword.operator: #D4D4D4", + "light_vs": "keyword.operator: #000000", + "hc_black": "keyword.operator: #D4D4D4", + "dark_modern": "keyword.operator: #D4D4D4", + "hc_light": "keyword.operator: #000000", + "light_modern": "keyword.operator: #000000" + } + }, + { + "c": ">();", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets meta.any.json.comments.snippets string.quoted.double.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.end.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": ",", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets punctuation.separator.array.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t\t\t", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.begin.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "readonly onDid", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets meta.any.json.comments.snippets string.quoted.double.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "$", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets meta.any.json.comments.snippets meta.insertion.simple.numeric.json.comments.snippets meta.insertion.tabstop.simple.json.comments.snippets punctuation.section.insertion.dollar.simple.json.comments.snippets keyword.operator.insertion.json.comments.snippets custom.punctuation.section.insertion.dollar.simple.json.comments.snippets", + "r": { + "dark_plus": "keyword.operator: #D4D4D4", + "light_plus": "keyword.operator: #000000", + "dark_vs": "keyword.operator: #D4D4D4", + "light_vs": "keyword.operator: #000000", + "hc_black": "keyword.operator: #D4D4D4", + "dark_modern": "keyword.operator: #D4D4D4", + "hc_light": "keyword.operator: #000000", + "light_modern": "keyword.operator: #000000" + } + }, + { + "c": "1", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets meta.any.json.comments.snippets meta.insertion.simple.numeric.json.comments.snippets meta.insertion.tabstop.simple.json.comments.snippets variable.other.normal.json.comments.snippets keyword.operator.insertion.json.comments.snippets custom.variable.other.normal.numeric.json.comments.snippets", + "r": { + "dark_plus": "keyword.operator: #D4D4D4", + "light_plus": "keyword.operator: #000000", + "dark_vs": "keyword.operator: #D4D4D4", + "light_vs": "keyword.operator: #000000", + "hc_black": "keyword.operator: #D4D4D4", + "dark_modern": "keyword.operator: #D4D4D4", + "hc_light": "keyword.operator: #000000", + "light_modern": "keyword.operator: #000000" + } + }, + { + "c": ": Event<", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets meta.any.json.comments.snippets string.quoted.double.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "$", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets meta.any.json.comments.snippets meta.insertion.simple.numeric.json.comments.snippets meta.insertion.tabstop.simple.json.comments.snippets punctuation.section.insertion.dollar.simple.json.comments.snippets keyword.operator.insertion.json.comments.snippets custom.punctuation.section.insertion.dollar.simple.json.comments.snippets", + "r": { + "dark_plus": "keyword.operator: #D4D4D4", + "light_plus": "keyword.operator: #000000", + "dark_vs": "keyword.operator: #D4D4D4", + "light_vs": "keyword.operator: #000000", + "hc_black": "keyword.operator: #D4D4D4", + "dark_modern": "keyword.operator: #D4D4D4", + "hc_light": "keyword.operator: #000000", + "light_modern": "keyword.operator: #000000" + } + }, + { + "c": "2", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets meta.any.json.comments.snippets meta.insertion.simple.numeric.json.comments.snippets meta.insertion.tabstop.simple.json.comments.snippets variable.other.normal.json.comments.snippets keyword.operator.insertion.json.comments.snippets custom.variable.other.normal.numeric.json.comments.snippets", + "r": { + "dark_plus": "keyword.operator: #D4D4D4", + "light_plus": "keyword.operator: #000000", + "dark_vs": "keyword.operator: #D4D4D4", + "light_vs": "keyword.operator: #000000", + "hc_black": "keyword.operator: #D4D4D4", + "dark_modern": "keyword.operator: #D4D4D4", + "hc_light": "keyword.operator: #000000", + "light_modern": "keyword.operator: #000000" + } + }, + { + "c": "> = this._onDid", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets meta.any.json.comments.snippets string.quoted.double.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "$", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets meta.any.json.comments.snippets meta.insertion.simple.numeric.json.comments.snippets meta.insertion.tabstop.simple.json.comments.snippets punctuation.section.insertion.dollar.simple.json.comments.snippets keyword.operator.insertion.json.comments.snippets custom.punctuation.section.insertion.dollar.simple.json.comments.snippets", + "r": { + "dark_plus": "keyword.operator: #D4D4D4", + "light_plus": "keyword.operator: #000000", + "dark_vs": "keyword.operator: #D4D4D4", + "light_vs": "keyword.operator: #000000", + "hc_black": "keyword.operator: #D4D4D4", + "dark_modern": "keyword.operator: #D4D4D4", + "hc_light": "keyword.operator: #000000", + "light_modern": "keyword.operator: #000000" + } + }, + { + "c": "1", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets meta.any.json.comments.snippets meta.insertion.simple.numeric.json.comments.snippets meta.insertion.tabstop.simple.json.comments.snippets variable.other.normal.json.comments.snippets keyword.operator.insertion.json.comments.snippets custom.variable.other.normal.numeric.json.comments.snippets", + "r": { + "dark_plus": "keyword.operator: #D4D4D4", + "light_plus": "keyword.operator: #000000", + "dark_vs": "keyword.operator: #D4D4D4", + "light_vs": "keyword.operator: #000000", + "hc_black": "keyword.operator: #D4D4D4", + "dark_modern": "keyword.operator: #D4D4D4", + "hc_light": "keyword.operator: #000000", + "light_modern": "keyword.operator: #000000" + } + }, + { + "c": ".event;", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets meta.any.json.comments.snippets string.quoted.double.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "\"", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets string.quoted.double.json.comments.snippets punctuation.definition.string.end.json.comments.snippets", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" + } + }, + { + "c": "\t\t", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "]", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.array.json.comments.snippets punctuation.definition.array.end.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": ",", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets punctuation.separator.dictionary.pair.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "}", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets meta.structure.dictionary.value.json.comments.snippets meta.structure.dictionary.json.comments.snippets punctuation.definition.dictionary.end.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "}", + "t": "source.json.comments.snippets meta.structure.dictionary.json.comments.snippets punctuation.definition.dictionary.end.json.comments.snippets", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + } +] \ No newline at end of file diff --git a/extensions/vscode-colorize-tests/test/colorize-results/test_md.json b/extensions/vscode-colorize-tests/test/colorize-results/test_md.json index d28d9c74747df..648feab845afb 100644 --- a/extensions/vscode-colorize-tests/test/colorize-results/test_md.json +++ b/extensions/vscode-colorize-tests/test/colorize-results/test_md.json @@ -2842,8 +2842,8 @@ } }, { - "c": "| Header | Header | Right |", - "t": "text.html.markdown meta.paragraph.markdown", + "c": "|", + "t": "text.html.markdown markup.table.markdown punctuation.definition.table.markdown", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2856,8 +2856,8 @@ } }, { - "c": "| ------ | ------ | -----: |", - "t": "text.html.markdown meta.paragraph.markdown", + "c": " Header ", + "t": "text.html.markdown markup.table.markdown", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2870,8 +2870,8 @@ } }, { - "c": "| Cell | Cell | $10 |", - "t": "text.html.markdown meta.paragraph.markdown", + "c": "|", + "t": "text.html.markdown markup.table.markdown punctuation.definition.table.markdown", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2884,8 +2884,428 @@ } }, { - "c": "| Cell | Cell | $20 |", - "t": "text.html.markdown meta.paragraph.markdown", + "c": " Header ", + "t": "text.html.markdown markup.table.markdown", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "|", + "t": "text.html.markdown markup.table.markdown punctuation.definition.table.markdown", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " Right ", + "t": "text.html.markdown markup.table.markdown", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "|", + "t": "text.html.markdown markup.table.markdown punctuation.definition.table.markdown", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "|", + "t": "text.html.markdown markup.table.markdown punctuation.definition.table.markdown", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "text.html.markdown markup.table.markdown", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "------", + "t": "text.html.markdown markup.table.markdown punctuation.separator.table.markdown", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "text.html.markdown markup.table.markdown", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "|", + "t": "text.html.markdown markup.table.markdown punctuation.definition.table.markdown", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "text.html.markdown markup.table.markdown", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "------", + "t": "text.html.markdown markup.table.markdown punctuation.separator.table.markdown", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "text.html.markdown markup.table.markdown", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "|", + "t": "text.html.markdown markup.table.markdown punctuation.definition.table.markdown", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "text.html.markdown markup.table.markdown", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "-----:", + "t": "text.html.markdown markup.table.markdown punctuation.separator.table.markdown", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "text.html.markdown markup.table.markdown", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "|", + "t": "text.html.markdown markup.table.markdown punctuation.definition.table.markdown", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "|", + "t": "text.html.markdown markup.table.markdown punctuation.definition.table.markdown", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " Cell ", + "t": "text.html.markdown markup.table.markdown", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "|", + "t": "text.html.markdown markup.table.markdown punctuation.definition.table.markdown", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " Cell ", + "t": "text.html.markdown markup.table.markdown", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "|", + "t": "text.html.markdown markup.table.markdown punctuation.definition.table.markdown", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " $10 ", + "t": "text.html.markdown markup.table.markdown", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "|", + "t": "text.html.markdown markup.table.markdown punctuation.definition.table.markdown", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "|", + "t": "text.html.markdown markup.table.markdown punctuation.definition.table.markdown", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " Cell ", + "t": "text.html.markdown markup.table.markdown", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "|", + "t": "text.html.markdown markup.table.markdown punctuation.definition.table.markdown", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " Cell ", + "t": "text.html.markdown markup.table.markdown", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "|", + "t": "text.html.markdown markup.table.markdown punctuation.definition.table.markdown", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " $20 ", + "t": "text.html.markdown markup.table.markdown", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "|", + "t": "text.html.markdown markup.table.markdown punctuation.definition.table.markdown", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", diff --git a/extensions/vscode-colorize-tests/test/colorize-results/test_py.json b/extensions/vscode-colorize-tests/test/colorize-results/test_py.json index e858cd5f2013f..e8d718cad729f 100644 --- a/extensions/vscode-colorize-tests/test/colorize-results/test_py.json +++ b/extensions/vscode-colorize-tests/test/colorize-results/test_py.json @@ -1907,14 +1907,14 @@ "c": "reduce", "t": "source.python meta.function-call.python variable.legacy.builtin.python", "r": { - "dark_plus": "variable: #9CDCFE", - "light_plus": "variable: #001080", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "variable: #9CDCFE", - "dark_modern": "variable: #9CDCFE", - "hc_light": "variable: #001080", - "light_modern": "variable: #001080" + "dark_plus": "variable.legacy.builtin.python: #D4D4D4", + "light_plus": "variable.legacy.builtin.python: #000000", + "dark_vs": "variable.legacy.builtin.python: #D4D4D4", + "light_vs": "variable.legacy.builtin.python: #000000", + "hc_black": "variable.legacy.builtin.python: #FFFFFF", + "dark_modern": "variable.legacy.builtin.python: #D4D4D4", + "hc_light": "variable.legacy.builtin.python: #292929", + "light_modern": "variable.legacy.builtin.python: #000000" } }, { @@ -6233,14 +6233,14 @@ "c": "raw_input", "t": "source.python meta.function-call.python variable.legacy.builtin.python", "r": { - "dark_plus": "variable: #9CDCFE", - "light_plus": "variable: #001080", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "variable: #9CDCFE", - "dark_modern": "variable: #9CDCFE", - "hc_light": "variable: #001080", - "light_modern": "variable: #001080" + "dark_plus": "variable.legacy.builtin.python: #D4D4D4", + "light_plus": "variable.legacy.builtin.python: #000000", + "dark_vs": "variable.legacy.builtin.python: #D4D4D4", + "light_vs": "variable.legacy.builtin.python: #000000", + "hc_black": "variable.legacy.builtin.python: #FFFFFF", + "dark_modern": "variable.legacy.builtin.python: #D4D4D4", + "hc_light": "variable.legacy.builtin.python: #292929", + "light_modern": "variable.legacy.builtin.python: #000000" } }, { diff --git a/extensions/vscode-colorize-tests/yarn.lock b/extensions/vscode-colorize-tests/yarn.lock index 44d4327771ea8..4c166d0a3c829 100644 --- a/extensions/vscode-colorize-tests/yarn.lock +++ b/extensions/vscode-colorize-tests/yarn.lock @@ -2,10 +2,10 @@ # yarn lockfile v1 -"@types/node@16.x": - version "16.11.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae" - integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w== +"@types/node@18.x": + version "18.15.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" + integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== jsonc-parser@2.2.1: version "2.2.1" diff --git a/extensions/vscode-test-resolver/package.json b/extensions/vscode-test-resolver/package.json index e721c65567ad1..e538d43f21bf0 100644 --- a/extensions/vscode-test-resolver/package.json +++ b/extensions/vscode-test-resolver/package.json @@ -33,7 +33,7 @@ "main": "./out/extension", "browser": "./dist/browser/testResolverMain", "devDependencies": { - "@types/node": "16.x" + "@types/node": "18.x" }, "capabilities": { "untrustedWorkspaces": { diff --git a/extensions/vscode-test-resolver/yarn.lock b/extensions/vscode-test-resolver/yarn.lock index e724e7fffa317..8a3d10f2b65cf 100644 --- a/extensions/vscode-test-resolver/yarn.lock +++ b/extensions/vscode-test-resolver/yarn.lock @@ -2,7 +2,7 @@ # yarn lockfile v1 -"@types/node@16.x": - version "16.11.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae" - integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w== +"@types/node@18.x": + version "18.15.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" + integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== diff --git a/extensions/yarn.lock b/extensions/yarn.lock index 18507f58b594f..08ae5fb06c38f 100644 --- a/extensions/yarn.lock +++ b/extensions/yarn.lock @@ -228,10 +228,10 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -typescript@5.1.6: - version "5.1.6" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" - integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== +typescript@^5.2.1-rc: + version "5.2.1-rc" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.1-rc.tgz#9cf33ff6bc39ba9e1fa59761124f596ecf5e0c07" + integrity sha512-gsOdmedQZEWLrYhNqHuzPmcV+4wX7UujzYqszDC5mVMjcN6Nm7lN2eAtndmjWl24aGdAwJqL2ooywkxpaTx8QQ== vscode-grammar-updater@^1.1.0: version "1.1.0" diff --git a/package.json b/package.json index 9fba1bf8246b4..2e5dcf01a2eb8 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", - "version": "1.81.0", - "distro": "bed7b201bc6ebbfc63268cb4c390d788a86b0192", + "version": "1.82.0", + "distro": "56bfb9ce4a8d2298f475a1b8d9c7a7b5a72204f2", "author": { "name": "Microsoft Corporation" }, @@ -65,14 +65,14 @@ "perf": "node scripts/code-perf.js" }, "dependencies": { - "@microsoft/1ds-core-js": "^3.2.2", - "@microsoft/1ds-post-js": "^3.2.2", + "@microsoft/1ds-core-js": "^3.2.13", + "@microsoft/1ds-post-js": "^3.2.13", "@parcel/watcher": "2.1.0", "@vscode/iconv-lite-umd": "0.7.0", "@vscode/policy-watcher": "^1.1.4", - "@vscode/proxy-agent": "^0.15.0", + "@vscode/proxy-agent": "^0.17.2", "@vscode/ripgrep": "^1.15.5", - "@vscode/spdlog": "^0.13.10", + "@vscode/spdlog": "^0.13.11", "@vscode/sqlite3": "5.1.6-vscode", "@vscode/sudo-prompt": "9.3.1", "@vscode/vscode-languagedetection": "1.0.21", @@ -83,10 +83,11 @@ "http-proxy-agent": "^2.1.0", "https-proxy-agent": "^2.2.3", "jschardet": "3.0.0", + "kerberos": "^2.0.1", "keytar": "7.9.0", "minimist": "^1.2.6", "native-is-elevated": "0.7.0", - "native-keymap": "^3.3.2", + "native-keymap": "^3.3.4", "native-watchdog": "^1.4.1", "node-pty": "1.1.0-beta1", "tas-client-umd": "0.1.8", @@ -94,14 +95,14 @@ "vscode-oniguruma": "1.7.0", "vscode-regexpp": "^3.1.0", "vscode-textmate": "9.0.0", - "xterm": "5.3.0-beta.7", - "xterm-addon-canvas": "0.5.0-beta.2", - "xterm-addon-image": "0.4.2", - "xterm-addon-search": "0.13.0-beta.2", - "xterm-addon-serialize": "0.11.0-beta.2", - "xterm-addon-unicode11": "0.5.0", - "xterm-addon-webgl": "0.16.0-beta.2", - "xterm-headless": "5.3.0-beta.7", + "xterm": "5.3.0-beta.61", + "xterm-addon-canvas": "0.5.0-beta.22", + "xterm-addon-image": "0.6.0-beta.14", + "xterm-addon-search": "0.13.0-beta.20", + "xterm-addon-serialize": "0.11.0-beta.20", + "xterm-addon-unicode11": "0.6.0-beta.12", + "xterm-addon-webgl": "0.16.0-beta.30", + "xterm-headless": "5.3.0-beta.61", "yauzl": "^2.9.2", "yazl": "^2.4.3" }, @@ -116,10 +117,11 @@ "@types/gulp-postcss": "^8.0.0", "@types/gulp-svgmin": "^1.2.1", "@types/http-proxy-agent": "^2.0.1", + "@types/kerberos": "^1.1.2", "@types/keytar": "^4.4.0", "@types/minimist": "^1.2.1", "@types/mocha": "^9.1.1", - "@types/node": "16.x", + "@types/node": "18.x", "@types/sinon": "^10.0.2", "@types/sinon-test": "^2.4.2", "@types/trusted-types": "^1.0.6", @@ -148,7 +150,7 @@ "cssnano": "^4.1.11", "debounce": "^1.0.0", "deemon": "^1.8.0", - "electron": "22.3.14", + "electron": "25.5.0", "eslint": "8.36.0", "eslint-plugin-header": "3.1.1", "eslint-plugin-jsdoc": "^39.3.2", @@ -210,7 +212,7 @@ "ts-loader": "^9.4.2", "ts-node": "^10.9.1", "tsec": "0.2.7", - "typescript": "^5.2.0-dev.20230710", + "typescript": "^5.3.0-dev.20230816", "typescript-formatter": "7.1.0", "underscore": "^1.12.1", "util": "^0.12.4", diff --git a/product.json b/product.json index 6d015e98bd050..2ae3ee8f0f873 100644 --- a/product.json +++ b/product.json @@ -52,8 +52,8 @@ }, { "name": "ms-vscode.js-debug", - "version": "1.80.0", - "sha256": "ac75e4ecf79efafa2bb0e6c8c548a6c8359555623f677a386cbcea80630aee4f", + "version": "1.81.0", + "sha256": "6d1c7ee89881afd65e8fee47445b6a1c5fb345bf30e2bdf70cd2fdd8d1ff6dec", "repo": "https://github.com/microsoft/vscode-js-debug", "metadata": { "id": "25629058-ddac-4e17-abba-74678e126c5d", diff --git a/remote/.yarnrc b/remote/.yarnrc index 29d716339bf1b..c44215812460c 100644 --- a/remote/.yarnrc +++ b/remote/.yarnrc @@ -1,5 +1,5 @@ -disturl "http://nodejs.org/dist" -target "16.17.1" -ms_build_id "220517" +disturl "https://nodejs.org/dist" +target "18.15.0" +ms_build_id "223745" runtime "node" build_from_source "true" diff --git a/remote/package.json b/remote/package.json index 9b92d007a4704..8fe0e55c1dedb 100644 --- a/remote/package.json +++ b/remote/package.json @@ -3,13 +3,13 @@ "version": "0.0.0", "private": true, "dependencies": { - "@microsoft/1ds-core-js": "^3.2.2", - "@microsoft/1ds-post-js": "^3.2.2", + "@microsoft/1ds-core-js": "^3.2.13", + "@microsoft/1ds-post-js": "^3.2.13", "@parcel/watcher": "2.1.0", "@vscode/iconv-lite-umd": "0.7.0", - "@vscode/proxy-agent": "^0.15.0", + "@vscode/proxy-agent": "^0.17.2", "@vscode/ripgrep": "^1.15.5", - "@vscode/spdlog": "^0.13.10", + "@vscode/spdlog": "^0.13.11", "@vscode/vscode-languagedetection": "1.0.21", "@vscode/windows-process-tree": "^0.5.0", "@vscode/windows-registry": "^1.1.0", @@ -18,6 +18,7 @@ "http-proxy-agent": "^2.1.0", "https-proxy-agent": "^2.2.3", "jschardet": "3.0.0", + "kerberos": "^2.0.1", "keytar": "7.9.0", "minimist": "^1.2.6", "native-watchdog": "^1.4.1", @@ -26,14 +27,14 @@ "vscode-oniguruma": "1.7.0", "vscode-regexpp": "^3.1.0", "vscode-textmate": "9.0.0", - "xterm": "5.3.0-beta.7", - "xterm-addon-canvas": "0.5.0-beta.2", - "xterm-addon-image": "0.4.2", - "xterm-addon-search": "0.13.0-beta.2", - "xterm-addon-serialize": "0.11.0-beta.2", - "xterm-addon-unicode11": "0.5.0", - "xterm-addon-webgl": "0.16.0-beta.2", - "xterm-headless": "5.3.0-beta.7", + "xterm": "5.3.0-beta.61", + "xterm-addon-canvas": "0.5.0-beta.22", + "xterm-addon-image": "0.6.0-beta.14", + "xterm-addon-search": "0.13.0-beta.20", + "xterm-addon-serialize": "0.11.0-beta.20", + "xterm-addon-unicode11": "0.6.0-beta.12", + "xterm-addon-webgl": "0.16.0-beta.30", + "xterm-headless": "5.3.0-beta.61", "yauzl": "^2.9.2", "yazl": "^2.4.3" } diff --git a/remote/web/package.json b/remote/web/package.json index 64b5c92997035..6075a563e3497 100644 --- a/remote/web/package.json +++ b/remote/web/package.json @@ -3,19 +3,19 @@ "version": "0.0.0", "private": true, "dependencies": { - "@microsoft/1ds-core-js": "^3.2.2", - "@microsoft/1ds-post-js": "^3.2.2", + "@microsoft/1ds-core-js": "^3.2.13", + "@microsoft/1ds-post-js": "^3.2.13", "@vscode/iconv-lite-umd": "0.7.0", "@vscode/vscode-languagedetection": "1.0.21", "jschardet": "3.0.0", "tas-client-umd": "0.1.8", "vscode-oniguruma": "1.7.0", "vscode-textmate": "9.0.0", - "xterm": "5.3.0-beta.7", - "xterm-addon-canvas": "0.5.0-beta.2", - "xterm-addon-image": "0.4.2", - "xterm-addon-search": "0.13.0-beta.2", - "xterm-addon-unicode11": "0.5.0", - "xterm-addon-webgl": "0.16.0-beta.2" + "xterm": "5.3.0-beta.61", + "xterm-addon-canvas": "0.5.0-beta.22", + "xterm-addon-image": "0.6.0-beta.14", + "xterm-addon-search": "0.13.0-beta.20", + "xterm-addon-unicode11": "0.6.0-beta.12", + "xterm-addon-webgl": "0.16.0-beta.30" } } diff --git a/remote/web/yarn.lock b/remote/web/yarn.lock index e2a8a2d0fbe7e..b56fac51a4541 100644 --- a/remote/web/yarn.lock +++ b/remote/web/yarn.lock @@ -2,41 +2,41 @@ # yarn lockfile v1 -"@microsoft/1ds-core-js@3.2.3", "@microsoft/1ds-core-js@^3.2.2": - version "3.2.3" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.3.tgz#2217d92ec8b073caa4577a13f40ea3a5c4c4d4e7" - integrity sha512-796A8fd90oUKDRO7UXUT9BwZ3G+a9XzJj5v012FcCN/2qRhEsIV3x/0wkx2S08T4FiQEUPkB2uoYHpEjEneM7g== +"@microsoft/1ds-core-js@3.2.13", "@microsoft/1ds-core-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.13.tgz#0c105ed75091bae3f1555c0334704fa9911c58fb" + integrity sha512-CluYTRWcEk0ObG5EWFNWhs87e2qchJUn0p2D21ZUa3PWojPZfPSBs4//WIE0MYV8Qg1Hdif2ZTwlM7TbYUjfAg== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.4" - "@microsoft/applicationinsights-shims" "^2.0.1" - "@microsoft/dynamicproto-js" "^1.1.6" - -"@microsoft/1ds-post-js@^3.2.2": - version "3.2.3" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.3.tgz#1fa7d51615a44f289632ae8c588007ba943db216" - integrity sha512-tcGJQXXr2LYoBbIXPoUVe1KCF3OtBsuKDFL7BXfmNtuSGtWF0yejm6H83DrR8/cUIGMRMUP9lqNlqFGwDYiwAQ== + "@microsoft/applicationinsights-core-js" "2.8.15" + "@microsoft/applicationinsights-shims" "^2.0.2" + "@microsoft/dynamicproto-js" "^1.1.7" + +"@microsoft/1ds-post-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.13.tgz#560aacac8a92fdbb79e8c2ebcb293d56e19f51aa" + integrity sha512-HgS574fdD19Bo2vPguyznL4eDw7Pcm1cVNpvbvBLWiW3x4e1FCQ3VMXChWnAxCae8Hb0XqlA2sz332ZobBavTA== dependencies: - "@microsoft/1ds-core-js" "3.2.3" - "@microsoft/applicationinsights-shims" "^2.0.1" - "@microsoft/dynamicproto-js" "^1.1.6" - -"@microsoft/applicationinsights-core-js@2.8.4": - version "2.8.4" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.4.tgz#607e531bb241a8920d43960f68a7c76a6f9af596" - integrity sha512-FoA0FNOsFbJnLyTyQlYs6+HR7HMEa6nAOE6WOm9WVejBHMHQ/Bdb+hfVFi6slxwCimr/ner90jchi4/sIYdnyQ== + "@microsoft/1ds-core-js" "3.2.13" + "@microsoft/applicationinsights-shims" "^2.0.2" + "@microsoft/dynamicproto-js" "^1.1.7" + +"@microsoft/applicationinsights-core-js@2.8.15": + version "2.8.15" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.15.tgz#8fa466474260e01967fe649f14dd9e5ff91dcdc8" + integrity sha512-yYAs9MyjGr2YijQdUSN9mVgT1ijI1FPMgcffpaPmYbHAVbQmF7bXudrBWHxmLzJlwl5rfep+Zgjli2e67lwUqQ== dependencies: - "@microsoft/applicationinsights-shims" "2.0.1" - "@microsoft/dynamicproto-js" "^1.1.6" + "@microsoft/applicationinsights-shims" "2.0.2" + "@microsoft/dynamicproto-js" "^1.1.9" -"@microsoft/applicationinsights-shims@2.0.1", "@microsoft/applicationinsights-shims@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.1.tgz#5d72fb7aaf4056c4fda54f9d7c93ccf8ca9bcbfd" - integrity sha512-G0MXf6R6HndRbDy9BbEj0zrLeuhwt2nsXk2zKtF0TnYo39KgYqhYC2ayIzKPTm2KAE+xzD7rgyLdZnrcRvt9WQ== +"@microsoft/applicationinsights-shims@2.0.2", "@microsoft/applicationinsights-shims@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.2.tgz#92b36a09375e2d9cb2b4203383b05772be837085" + integrity sha512-PoHEgsnmcqruLNHZ/amACqdJ6YYQpED0KSRe6J7gIJTtpZC1FfFU9b1fmDKDKtFoUSrPzEh1qzO3kmRZP0betg== -"@microsoft/dynamicproto-js@^1.1.6": - version "1.1.6" - resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.6.tgz#6fe03468862861f5f88ac4c3959a652b3797f1bc" - integrity sha512-D1Oivw1A4bIXhzBIy3/BBPn3p2On+kpO2NiYt9shICDK7L/w+cR6FFBUsBZ05l6iqzTeL+Jm8lAYn0g6G7DmDg== +"@microsoft/dynamicproto-js@^1.1.7", "@microsoft/dynamicproto-js@^1.1.9": + version "1.1.9" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.9.tgz#7437db7aa061162ee94e4131b69a62b8dad5dea6" + integrity sha512-n1VPsljTSkthsAFYdiWfC+DKzK2WwcRp83Y1YAqdX552BstvsDjft9YXppjUzp11BPsapDoO1LDgrDB0XVsfNQ== "@vscode/iconv-lite-umd@0.7.0": version "0.7.0" @@ -68,32 +68,32 @@ vscode-textmate@9.0.0: resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-9.0.0.tgz#313c6c8792b0507aef35aeb81b6b370b37c44d6c" integrity sha512-Cl65diFGxz7gpwbav10HqiY/eVYTO1sjQpmRmV991Bj7wAoOAjGQ97PpQcXorDE2Uc4hnGWLY17xme+5t6MlSg== -xterm-addon-canvas@0.5.0-beta.2: - version "0.5.0-beta.2" - resolved "https://registry.yarnpkg.com/xterm-addon-canvas/-/xterm-addon-canvas-0.5.0-beta.2.tgz#1b83c2a9a306766c47a4f80b8c65cc9ee5f5a5c4" - integrity sha512-oTb/2krdbHYGxH2X6yiBZzAB/1WB+apUu4nXHdhBnht20bl8E+YVWqg95D4o0Gl+QJI+XOfB3mqmWaBx1x531A== - -xterm-addon-image@0.4.2: - version "0.4.2" - resolved "https://registry.yarnpkg.com/xterm-addon-image/-/xterm-addon-image-0.4.2.tgz#d25bb3a8c543d014accbfbbc875927f54d5f43b9" - integrity sha512-QVuH5CGlValtFMVorb71TnMV7kQLqc9+V5oyOMNvFqW1NiOBNo/d0WVvMU8qOd2vsAdTbhjvUO8SPptZ5TJHYw== - -xterm-addon-search@0.13.0-beta.2: - version "0.13.0-beta.2" - resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.13.0-beta.2.tgz#c984a35312acad4ce768d17bc49adffa90eece61" - integrity sha512-+VoPhIRmfiX2uh2t6xD/RJtBYjVjrkNa3dKQnOYEp4UbYzDjK57rZX652mnZ82TQfk/juxf7v+jV5aRdNLZVbA== - -xterm-addon-unicode11@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/xterm-addon-unicode11/-/xterm-addon-unicode11-0.5.0.tgz#41c0d96acc1e3bb6c6596eee64e163b6bca74be7" - integrity sha512-Jm4/g4QiTxiKiTbYICQgC791ubhIZyoIwxAIgOW8z8HWFNY+lwk+dwaKEaEeGBfM48Vk8fklsUW9u/PlenYEBg== - -xterm-addon-webgl@0.16.0-beta.2: - version "0.16.0-beta.2" - resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.16.0-beta.2.tgz#30489ef235405255ee54077002c90553531870d8" - integrity sha512-DAt4E/QI1w34ToBhcDj0vaZOAHOO+ffwMt2HGDAB7amPXRcMb0LBIjLpyZhB9sD4tbIgsE0vuqZi1R9vKxZwbg== - -xterm@5.3.0-beta.7: - version "5.3.0-beta.7" - resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.3.0-beta.7.tgz#ee638fe60382e6b13f36dec2355c3530ff1c4c34" - integrity sha512-wd+QHHfCVSZMSH7ah8WSeCu7VAqZcAD5pEAOiQxCg4VfXu+L//QOycqlWecgr0SFui2X9LshfD+cI9J3FcHRNA== +xterm-addon-canvas@0.5.0-beta.22: + version "0.5.0-beta.22" + resolved "https://registry.yarnpkg.com/xterm-addon-canvas/-/xterm-addon-canvas-0.5.0-beta.22.tgz#513f0c2b7cf96073f47627b27e8965c1b1a22431" + integrity sha512-9F6ZI0DMRgffVfHkLkDwl5n8VscvCaV10tWI3skXOX7Y7Aws6OEeglkOPoU3IllofCU792kHKM4pPoToUxTltg== + +xterm-addon-image@0.6.0-beta.14: + version "0.6.0-beta.14" + resolved "https://registry.yarnpkg.com/xterm-addon-image/-/xterm-addon-image-0.6.0-beta.14.tgz#75fc3f824123183a4bbb5306e22f8b2c6966b0a6" + integrity sha512-D5Gh5JTKhHaPt1KwQNf6diF37KA4eToJw3XId1wy62tWmSqfq+QflhOGTfd+SnSQYCktU05ETzM+0tncIU62pQ== + +xterm-addon-search@0.13.0-beta.20: + version "0.13.0-beta.20" + resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.13.0-beta.20.tgz#8ddd0513e2a70fcefa325722100d2e1bfaf3b9cb" + integrity sha512-wrx6187cJ1UenGL6ZeYv3jFvRPhhENTfbC+Hv1Fnww8LmsKhcj+0+Pm6yInNjX/9hNVsNzdqKyqNeEMoykyoyA== + +xterm-addon-unicode11@0.6.0-beta.12: + version "0.6.0-beta.12" + resolved "https://registry.yarnpkg.com/xterm-addon-unicode11/-/xterm-addon-unicode11-0.6.0-beta.12.tgz#ac6df9d635325dc692e4c602e74a2fc27a09405c" + integrity sha512-9wWWf/5nFafYgq0pn9EgAWnXaXGleVxfjNOqavpLRYFv0nw42QbaYyGvnGcxyYHM5Aqx/8rYE/DDVWZBqQZdYA== + +xterm-addon-webgl@0.16.0-beta.30: + version "0.16.0-beta.30" + resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.16.0-beta.30.tgz#820d5c65f868b14ec4177bfb8a294931a53616bf" + integrity sha512-39qPHPFmNENxcHf8/CzGHS6wzKMMegoRkHB1+scqtBhSxFaD8tX5Ye33HZIEdQ9nXe9xtr4FWVp77T+n9hdrew== + +xterm@5.3.0-beta.61: + version "5.3.0-beta.61" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.3.0-beta.61.tgz#a6c27d90a5314da51d80deeb32f3bd77f1e1c8f6" + integrity sha512-rJHpCc48GSpHnu0SSERynQ80D5ikvFVsqhv6JdmeONTrnAFRr134OglJRIpbi2YK8UPbV6F6Dfqm/AQh+9GZzA== diff --git a/remote/yarn.lock b/remote/yarn.lock index 8084ab6e27a49..4716df355d54d 100644 --- a/remote/yarn.lock +++ b/remote/yarn.lock @@ -2,41 +2,41 @@ # yarn lockfile v1 -"@microsoft/1ds-core-js@3.2.3", "@microsoft/1ds-core-js@^3.2.2": - version "3.2.3" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.3.tgz#2217d92ec8b073caa4577a13f40ea3a5c4c4d4e7" - integrity sha512-796A8fd90oUKDRO7UXUT9BwZ3G+a9XzJj5v012FcCN/2qRhEsIV3x/0wkx2S08T4FiQEUPkB2uoYHpEjEneM7g== - dependencies: - "@microsoft/applicationinsights-core-js" "2.8.4" - "@microsoft/applicationinsights-shims" "^2.0.1" - "@microsoft/dynamicproto-js" "^1.1.6" - -"@microsoft/1ds-post-js@^3.2.2": - version "3.2.3" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.3.tgz#1fa7d51615a44f289632ae8c588007ba943db216" - integrity sha512-tcGJQXXr2LYoBbIXPoUVe1KCF3OtBsuKDFL7BXfmNtuSGtWF0yejm6H83DrR8/cUIGMRMUP9lqNlqFGwDYiwAQ== - dependencies: - "@microsoft/1ds-core-js" "3.2.3" - "@microsoft/applicationinsights-shims" "^2.0.1" - "@microsoft/dynamicproto-js" "^1.1.6" - -"@microsoft/applicationinsights-core-js@2.8.4": - version "2.8.4" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.4.tgz#607e531bb241a8920d43960f68a7c76a6f9af596" - integrity sha512-FoA0FNOsFbJnLyTyQlYs6+HR7HMEa6nAOE6WOm9WVejBHMHQ/Bdb+hfVFi6slxwCimr/ner90jchi4/sIYdnyQ== - dependencies: - "@microsoft/applicationinsights-shims" "2.0.1" - "@microsoft/dynamicproto-js" "^1.1.6" - -"@microsoft/applicationinsights-shims@2.0.1", "@microsoft/applicationinsights-shims@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.1.tgz#5d72fb7aaf4056c4fda54f9d7c93ccf8ca9bcbfd" - integrity sha512-G0MXf6R6HndRbDy9BbEj0zrLeuhwt2nsXk2zKtF0TnYo39KgYqhYC2ayIzKPTm2KAE+xzD7rgyLdZnrcRvt9WQ== - -"@microsoft/dynamicproto-js@^1.1.6": - version "1.1.6" - resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.6.tgz#6fe03468862861f5f88ac4c3959a652b3797f1bc" - integrity sha512-D1Oivw1A4bIXhzBIy3/BBPn3p2On+kpO2NiYt9shICDK7L/w+cR6FFBUsBZ05l6iqzTeL+Jm8lAYn0g6G7DmDg== +"@microsoft/1ds-core-js@3.2.13", "@microsoft/1ds-core-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.13.tgz#0c105ed75091bae3f1555c0334704fa9911c58fb" + integrity sha512-CluYTRWcEk0ObG5EWFNWhs87e2qchJUn0p2D21ZUa3PWojPZfPSBs4//WIE0MYV8Qg1Hdif2ZTwlM7TbYUjfAg== + dependencies: + "@microsoft/applicationinsights-core-js" "2.8.15" + "@microsoft/applicationinsights-shims" "^2.0.2" + "@microsoft/dynamicproto-js" "^1.1.7" + +"@microsoft/1ds-post-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.13.tgz#560aacac8a92fdbb79e8c2ebcb293d56e19f51aa" + integrity sha512-HgS574fdD19Bo2vPguyznL4eDw7Pcm1cVNpvbvBLWiW3x4e1FCQ3VMXChWnAxCae8Hb0XqlA2sz332ZobBavTA== + dependencies: + "@microsoft/1ds-core-js" "3.2.13" + "@microsoft/applicationinsights-shims" "^2.0.2" + "@microsoft/dynamicproto-js" "^1.1.7" + +"@microsoft/applicationinsights-core-js@2.8.15": + version "2.8.15" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.15.tgz#8fa466474260e01967fe649f14dd9e5ff91dcdc8" + integrity sha512-yYAs9MyjGr2YijQdUSN9mVgT1ijI1FPMgcffpaPmYbHAVbQmF7bXudrBWHxmLzJlwl5rfep+Zgjli2e67lwUqQ== + dependencies: + "@microsoft/applicationinsights-shims" "2.0.2" + "@microsoft/dynamicproto-js" "^1.1.9" + +"@microsoft/applicationinsights-shims@2.0.2", "@microsoft/applicationinsights-shims@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.2.tgz#92b36a09375e2d9cb2b4203383b05772be837085" + integrity sha512-PoHEgsnmcqruLNHZ/amACqdJ6YYQpED0KSRe6J7gIJTtpZC1FfFU9b1fmDKDKtFoUSrPzEh1qzO3kmRZP0betg== + +"@microsoft/dynamicproto-js@^1.1.7", "@microsoft/dynamicproto-js@^1.1.9": + version "1.1.9" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.9.tgz#7437db7aa061162ee94e4131b69a62b8dad5dea6" + integrity sha512-n1VPsljTSkthsAFYdiWfC+DKzK2WwcRp83Y1YAqdX552BstvsDjft9YXppjUzp11BPsapDoO1LDgrDB0XVsfNQ== "@parcel/watcher@2.1.0": version "2.1.0" @@ -48,27 +48,27 @@ node-addon-api "^3.2.1" node-gyp-build "^4.3.0" -"@tootallnate/once@1", "@tootallnate/once@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" - integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== +"@tootallnate/once@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-3.0.0.tgz#d52238c9052d746c9689523e650160e70786bc9a" + integrity sha512-OAdBVB7rlwvLD+DiecSAyVKzKVmSfXbouCyM5I6wHGi4MGXIyFqErg1IvyJ7PI1e+GYZuZh7cCHV/c4LA8SKMw== "@vscode/iconv-lite-umd@0.7.0": version "0.7.0" resolved "https://registry.yarnpkg.com/@vscode/iconv-lite-umd/-/iconv-lite-umd-0.7.0.tgz#d2f1e0664ee6036408f9743fee264ea0699b0e48" integrity sha512-bRRFxLfg5dtAyl5XyiVWz/ZBPahpOpPrNYnnHpOpUZvam4tKH35wdhP4Kj6PbM0+KdliOsPzbGWpkxcdpNB/sg== -"@vscode/proxy-agent@^0.15.0": - version "0.15.0" - resolved "https://registry.yarnpkg.com/@vscode/proxy-agent/-/proxy-agent-0.15.0.tgz#b8fb8b89180a71295a8f8682775f69ab1dcf6860" - integrity sha512-HpD4A9CUOwKbC6vLa0+MEsCo/qlgbue9U9s8Z7NzJDdf2YEGjUaYf9Mvj5T1LhJX20Hv1COvkGcc7zPhtIbgbA== - dependencies: - "@tootallnate/once" "^1.1.2" - agent-base "^6.0.2" - debug "^4.3.1" - http-proxy-agent "^4.0.1" - https-proxy-agent "^5.0.0" - socks-proxy-agent "^5.0.0" +"@vscode/proxy-agent@^0.17.2": + version "0.17.2" + resolved "https://registry.yarnpkg.com/@vscode/proxy-agent/-/proxy-agent-0.17.2.tgz#0e0dac24478e2d71a4fd1b2bb5f84dc61add79e2" + integrity sha512-aKRo1YfUCsgEjHvr2HXfM6dwHhieyO6G+WHly7jewyyTJ1nANWEocS3JRnRbC4KjlajKhSUEOx838cdnY/vRtA== + dependencies: + "@tootallnate/once" "^3.0.0" + agent-base "^7.0.1" + debug "^4.3.4" + http-proxy-agent "^7.0.0" + https-proxy-agent "^7.0.1" + socks-proxy-agent "^8.0.1" optionalDependencies: "@vscode/windows-ca-certs" "^0.3.1" @@ -80,10 +80,10 @@ https-proxy-agent "^5.0.0" proxy-from-env "^1.1.0" -"@vscode/spdlog@^0.13.10": - version "0.13.10" - resolved "https://registry.yarnpkg.com/@vscode/spdlog/-/spdlog-0.13.10.tgz#5476853b968a1bcc389b92175d11e636464858e8" - integrity sha512-BHJN/r2XurLDR0doBhyQ5b+DUjFjqwnOcD4ZjW/7MkuShO+Wn5KVKOl6x/xQLCAlOlQqVVe42n2A7FwuIFpkWw== +"@vscode/spdlog@^0.13.11": + version "0.13.11" + resolved "https://registry.yarnpkg.com/@vscode/spdlog/-/spdlog-0.13.11.tgz#1c65c3527dd8e9679ada7f427c4d9e4af2ea097a" + integrity sha512-4qk6G3XKTJNsrqsGwmo9lr8NPaH84WeLsoFVPrpvoEC1t1tFu7H6l4RRMgzKNeE92nwRbjejLv1nATJNoabRfA== dependencies: bindings "^1.5.0" mkdirp "^0.5.5" @@ -120,7 +120,7 @@ agent-base@4: dependencies: es6-promisify "^5.0.0" -agent-base@6, agent-base@^6.0.2: +agent-base@6: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== @@ -134,6 +134,13 @@ agent-base@^4.3.0: dependencies: es6-promisify "^5.0.0" +agent-base@^7.0.1, agent-base@^7.0.2, agent-base@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.0.tgz#536802b76bc0b34aa50195eb2442276d613e3434" + integrity sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg== + dependencies: + debug "^4.3.4" + ansi-regex@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" @@ -237,10 +244,10 @@ debug@4: dependencies: ms "^2.1.1" -debug@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" - integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== +debug@^4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" @@ -356,14 +363,13 @@ http-proxy-agent@^2.1.0: agent-base "4" debug "3.1.0" -http-proxy-agent@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" - integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== +http-proxy-agent@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz#e9096c5afd071a3fce56e6252bb321583c124673" + integrity sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ== dependencies: - "@tootallnate/once" "1" - agent-base "6" - debug "4" + agent-base "^7.1.0" + debug "^4.3.4" https-proxy-agent@^2.2.3: version "2.2.4" @@ -381,6 +387,14 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" +https-proxy-agent@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.1.tgz#0277e28f13a07d45c663633841e20a40aaafe0ab" + integrity sha512-Eun8zV0kcYS1g19r78osiQLEFIRspRUDd9tIfBCTBPBeMieF/EsJNL8VI3xOIdYRDEkjQnqOYPsZ2DsWsVsFwQ== + dependencies: + agent-base "^7.0.2" + debug "4" + ieee754@^1.1.13: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" @@ -396,10 +410,10 @@ ini@~1.3.0: resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== -ip@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" - integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= +ip@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da" + integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ== is-extglob@^2.1.1: version "2.1.1" @@ -440,6 +454,15 @@ jschardet@3.0.0: resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-3.0.0.tgz#898d2332e45ebabbdb6bf2feece9feea9a99e882" integrity sha512-lJH6tJ77V8Nzd5QWRkFYCLc13a3vADkh3r/Fi8HupZGWk2OVVDfnZP8V/VgQgZ+lzW0kG2UGb5hFgt3V3ndotQ== +kerberos@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/kerberos/-/kerberos-2.0.1.tgz#663b0b46883b4da84495f60f2e9e399a43a33ef5" + integrity sha512-O/jIgbdGK566eUhFwIcgalbqirYU/r76MW7/UFw06Fd9x5bSwgyZWL/Vm26aAmezQww/G9KYkmmJBkEkPk5HLw== + dependencies: + bindings "^1.5.0" + node-addon-api "^4.3.0" + prebuild-install "7.1.1" + keytar@7.9.0: version "7.9.0" resolved "https://registry.yarnpkg.com/keytar/-/keytar-7.9.0.tgz#4c6225708f51b50cbf77c5aae81721964c2918cb" @@ -581,6 +604,24 @@ picomatch@^2.3.1: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== +prebuild-install@7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.1.tgz#de97d5b34a70a0c81334fd24641f2a1702352e45" + integrity sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw== + dependencies: + detect-libc "^2.0.0" + expand-template "^2.0.3" + github-from-package "0.0.0" + minimist "^1.2.3" + mkdirp-classic "^0.5.3" + napi-build-utils "^1.0.1" + node-abi "^3.3.0" + pump "^3.0.0" + rc "^1.2.7" + simple-get "^4.0.0" + tar-fs "^2.0.0" + tunnel-agent "^0.6.0" + prebuild-install@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.0.1.tgz#c10075727c318efe72412f333e0ef625beaf3870" @@ -691,27 +732,27 @@ simple-get@^4.0.0: once "^1.3.1" simple-concat "^1.0.0" -smart-buffer@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.1.0.tgz#91605c25d91652f4661ea69ccf45f1b331ca21ba" - integrity sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw== +smart-buffer@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" + integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== -socks-proxy-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-5.0.0.tgz#7c0f364e7b1cf4a7a437e71253bed72e9004be60" - integrity sha512-lEpa1zsWCChxiynk+lCycKuC502RxDWLKJZoIhnxrWNjLSDGYRFflHA1/228VkRcnv9TIb8w98derGbpKxJRgA== +socks-proxy-agent@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-8.0.1.tgz#ffc5859a66dac89b0c4dab90253b96705f3e7120" + integrity sha512-59EjPbbgg8U3x62hhKOFVAmySQUcfRQ4C7Q/D5sEHnZTQRrQlNKINks44DMR1gwXp0p4LaVIeccX2KHTTcHVqQ== dependencies: - agent-base "6" - debug "4" - socks "^2.3.3" + agent-base "^7.0.1" + debug "^4.3.4" + socks "^2.7.1" -socks@^2.3.3: - version "2.6.1" - resolved "https://registry.yarnpkg.com/socks/-/socks-2.6.1.tgz#989e6534a07cf337deb1b1c94aaa44296520d30e" - integrity sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA== +socks@^2.7.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.7.1.tgz#d8e651247178fde79c0663043e07240196857d55" + integrity sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ== dependencies: - ip "^1.1.5" - smart-buffer "^4.1.0" + ip "^2.0.0" + smart-buffer "^4.2.0" string-width@^1.0.1: version "1.0.2" @@ -836,45 +877,45 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -xterm-addon-canvas@0.5.0-beta.2: - version "0.5.0-beta.2" - resolved "https://registry.yarnpkg.com/xterm-addon-canvas/-/xterm-addon-canvas-0.5.0-beta.2.tgz#1b83c2a9a306766c47a4f80b8c65cc9ee5f5a5c4" - integrity sha512-oTb/2krdbHYGxH2X6yiBZzAB/1WB+apUu4nXHdhBnht20bl8E+YVWqg95D4o0Gl+QJI+XOfB3mqmWaBx1x531A== - -xterm-addon-image@0.4.2: - version "0.4.2" - resolved "https://registry.yarnpkg.com/xterm-addon-image/-/xterm-addon-image-0.4.2.tgz#d25bb3a8c543d014accbfbbc875927f54d5f43b9" - integrity sha512-QVuH5CGlValtFMVorb71TnMV7kQLqc9+V5oyOMNvFqW1NiOBNo/d0WVvMU8qOd2vsAdTbhjvUO8SPptZ5TJHYw== - -xterm-addon-search@0.13.0-beta.2: - version "0.13.0-beta.2" - resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.13.0-beta.2.tgz#c984a35312acad4ce768d17bc49adffa90eece61" - integrity sha512-+VoPhIRmfiX2uh2t6xD/RJtBYjVjrkNa3dKQnOYEp4UbYzDjK57rZX652mnZ82TQfk/juxf7v+jV5aRdNLZVbA== - -xterm-addon-serialize@0.11.0-beta.2: - version "0.11.0-beta.2" - resolved "https://registry.yarnpkg.com/xterm-addon-serialize/-/xterm-addon-serialize-0.11.0-beta.2.tgz#fff924decfbf1bc08434317894f985fef7bb260b" - integrity sha512-tN4IT2e+EIpsoFpMONUh1OAuoVAcV7AYOLsqMKgH6GNWB1D/LKGo3cwjpw1vwRZzDJJcCcLxYgxlUzhPbDbLxQ== - -xterm-addon-unicode11@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/xterm-addon-unicode11/-/xterm-addon-unicode11-0.5.0.tgz#41c0d96acc1e3bb6c6596eee64e163b6bca74be7" - integrity sha512-Jm4/g4QiTxiKiTbYICQgC791ubhIZyoIwxAIgOW8z8HWFNY+lwk+dwaKEaEeGBfM48Vk8fklsUW9u/PlenYEBg== - -xterm-addon-webgl@0.16.0-beta.2: - version "0.16.0-beta.2" - resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.16.0-beta.2.tgz#30489ef235405255ee54077002c90553531870d8" - integrity sha512-DAt4E/QI1w34ToBhcDj0vaZOAHOO+ffwMt2HGDAB7amPXRcMb0LBIjLpyZhB9sD4tbIgsE0vuqZi1R9vKxZwbg== - -xterm-headless@5.3.0-beta.7: - version "5.3.0-beta.7" - resolved "https://registry.yarnpkg.com/xterm-headless/-/xterm-headless-5.3.0-beta.7.tgz#92704cecf937a18f2223b16efcab8c4e9e8a9e62" - integrity sha512-8LDY/cId73q3w6jMmiGU6HtJlfIhtqu/oWlDj/9wUr8SQnCQJwPBzu6RizzQRz1lzMN+8WHdzrHjKcNtayZbdw== - -xterm@5.3.0-beta.7: - version "5.3.0-beta.7" - resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.3.0-beta.7.tgz#ee638fe60382e6b13f36dec2355c3530ff1c4c34" - integrity sha512-wd+QHHfCVSZMSH7ah8WSeCu7VAqZcAD5pEAOiQxCg4VfXu+L//QOycqlWecgr0SFui2X9LshfD+cI9J3FcHRNA== +xterm-addon-canvas@0.5.0-beta.22: + version "0.5.0-beta.22" + resolved "https://registry.yarnpkg.com/xterm-addon-canvas/-/xterm-addon-canvas-0.5.0-beta.22.tgz#513f0c2b7cf96073f47627b27e8965c1b1a22431" + integrity sha512-9F6ZI0DMRgffVfHkLkDwl5n8VscvCaV10tWI3skXOX7Y7Aws6OEeglkOPoU3IllofCU792kHKM4pPoToUxTltg== + +xterm-addon-image@0.6.0-beta.14: + version "0.6.0-beta.14" + resolved "https://registry.yarnpkg.com/xterm-addon-image/-/xterm-addon-image-0.6.0-beta.14.tgz#75fc3f824123183a4bbb5306e22f8b2c6966b0a6" + integrity sha512-D5Gh5JTKhHaPt1KwQNf6diF37KA4eToJw3XId1wy62tWmSqfq+QflhOGTfd+SnSQYCktU05ETzM+0tncIU62pQ== + +xterm-addon-search@0.13.0-beta.20: + version "0.13.0-beta.20" + resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.13.0-beta.20.tgz#8ddd0513e2a70fcefa325722100d2e1bfaf3b9cb" + integrity sha512-wrx6187cJ1UenGL6ZeYv3jFvRPhhENTfbC+Hv1Fnww8LmsKhcj+0+Pm6yInNjX/9hNVsNzdqKyqNeEMoykyoyA== + +xterm-addon-serialize@0.11.0-beta.20: + version "0.11.0-beta.20" + resolved "https://registry.yarnpkg.com/xterm-addon-serialize/-/xterm-addon-serialize-0.11.0-beta.20.tgz#e879b34d214761403f1081833f9221c6903bf0c3" + integrity sha512-OXnC1SATaz7kEFjFWhyv9MJaXi8yHdPjazpGLNi11h33CRTKtCQiqqPBHU87dztnXmpEX6Jw0/jr3zlyXuAmnw== + +xterm-addon-unicode11@0.6.0-beta.12: + version "0.6.0-beta.12" + resolved "https://registry.yarnpkg.com/xterm-addon-unicode11/-/xterm-addon-unicode11-0.6.0-beta.12.tgz#ac6df9d635325dc692e4c602e74a2fc27a09405c" + integrity sha512-9wWWf/5nFafYgq0pn9EgAWnXaXGleVxfjNOqavpLRYFv0nw42QbaYyGvnGcxyYHM5Aqx/8rYE/DDVWZBqQZdYA== + +xterm-addon-webgl@0.16.0-beta.30: + version "0.16.0-beta.30" + resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.16.0-beta.30.tgz#820d5c65f868b14ec4177bfb8a294931a53616bf" + integrity sha512-39qPHPFmNENxcHf8/CzGHS6wzKMMegoRkHB1+scqtBhSxFaD8tX5Ye33HZIEdQ9nXe9xtr4FWVp77T+n9hdrew== + +xterm-headless@5.3.0-beta.61: + version "5.3.0-beta.61" + resolved "https://registry.yarnpkg.com/xterm-headless/-/xterm-headless-5.3.0-beta.61.tgz#28654550cb572709b99ea3eb8672d4568ae141c9" + integrity sha512-yfkbPLUtKjE4K7DsZ204A1BuOKpu6Usqi6rIYWT4XRMi+LjnkTbBjGr2BSjyJ3Gmtm+cSgBD0SvRN+V3xNxbxA== + +xterm@5.3.0-beta.61: + version "5.3.0-beta.61" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.3.0-beta.61.tgz#a6c27d90a5314da51d80deeb32f3bd77f1e1c8f6" + integrity sha512-rJHpCc48GSpHnu0SSERynQ80D5ikvFVsqhv6JdmeONTrnAFRr134OglJRIpbi2YK8UPbV6F6Dfqm/AQh+9GZzA== yallist@^4.0.0: version "4.0.0" diff --git a/scripts/playground-server.ts b/scripts/playground-server.ts index 9468087409fdd..1c2074ee19134 100644 --- a/scripts/playground-server.ts +++ b/scripts/playground-server.ts @@ -280,7 +280,7 @@ function makeLoaderJsHotReloadable(loaderJsCode: string, fileChangesUrl: URL): s if (___globalModuleManager._modules2[moduleId]) { const srcUrl = ___globalModuleManager._config.moduleIdToPaths(data.moduleId); const newSrc = await (await fetch(srcUrl)).text(); - (new Function('define', newSrc))(function (deps, callback) { + (new Function('define', newSrc))(function (deps, callback) { // CodeQL [SM01632] This code is only executed during development (as part of the dev-only playground-server). It is required for the hot-reload functionality. const oldModule = ___globalModuleManager._modules2[moduleId]; delete ___globalModuleManager._modules2[moduleId]; diff --git a/src/bootstrap.js b/src/bootstrap.js index 0617532bd580d..bd0e92e672c10 100644 --- a/src/bootstrap.js +++ b/src/bootstrap.js @@ -23,6 +23,7 @@ const Module = typeof require === 'function' ? require('module') : undefined; const path = typeof require === 'function' ? require('path') : undefined; const fs = typeof require === 'function' ? require('fs') : undefined; + const util = typeof require === 'function' ? require('util') : undefined; //#region global bootstrapping @@ -222,8 +223,8 @@ return ipcRenderer.invoke('vscode:readNlsFile', ...pathSegments); } - if (fs && path) { - return (await fs.promises.readFile(path.join(...pathSegments))).toString(); + if (fs && path && util) { + return (await util.promisify(fs.readFile)(path.join(...pathSegments))).toString(); } throw new Error('Unsupported operation (read NLS files)'); @@ -240,8 +241,8 @@ return ipcRenderer.invoke('vscode:writeNlsFile', path, content); } - if (fs) { - return fs.promises.writeFile(path, content); + if (fs && util) { + return util.promisify(fs.writeFile)(path, content); } throw new Error('Unsupported operation (write NLS files)'); diff --git a/src/buildfile.js b/src/buildfile.js index 8917223094ad6..f03de33fb3db5 100644 --- a/src/buildfile.js +++ b/src/buildfile.js @@ -53,7 +53,7 @@ exports.workerProfileAnalysis = [createEditorWorkerModuleDescription('vs/platfor exports.workbenchDesktop = [ createEditorWorkerModuleDescription('vs/workbench/contrib/output/common/outputLinkComputer'), - createEditorWorkerModuleDescription('vs/workbench/services/textMate/browser/worker/textMate.worker'), + createEditorWorkerModuleDescription('vs/workbench/services/textMate/browser/backgroundTokenization/worker/textMateTokenizationWorker.worker'), createModuleDescription('vs/workbench/contrib/debug/node/telemetryApp'), createModuleDescription('vs/platform/files/node/watcher/watcherMain'), createModuleDescription('vs/platform/terminal/node/ptyHostMain'), @@ -62,7 +62,7 @@ exports.workbenchDesktop = [ exports.workbenchWeb = [ createEditorWorkerModuleDescription('vs/workbench/contrib/output/common/outputLinkComputer'), - createEditorWorkerModuleDescription('vs/workbench/services/textMate/browser/worker/textMate.worker'), + createEditorWorkerModuleDescription('vs/workbench/services/textMate/browser/backgroundTokenization/worker/textMateTokenizationWorker.worker'), createModuleDescription('vs/code/browser/workbench/workbench', ['vs/workbench/workbench.web.main']) ]; diff --git a/src/tsconfig.monaco.json b/src/tsconfig.monaco.json index 256f406fb6c2a..b7c5d7468b571 100644 --- a/src/tsconfig.monaco.json +++ b/src/tsconfig.monaco.json @@ -32,6 +32,8 @@ "vs/platform/files/browser/htmlFileSystemProvider.ts", "vs/platform/files/browser/webFileSystemAccess.ts", "vs/platform/telemetry/*", - "vs/platform/assignment/*" + "vs/platform/assignment/*", + "vs/platform/terminal/*", + "vs/platform/externalTerminal/*" ] } diff --git a/src/vs/base/browser/browser.ts b/src/vs/base/browser/browser.ts index 4194d976db257..2ac4671e49786 100644 --- a/src/vs/base/browser/browser.ts +++ b/src/vs/base/browser/browser.ts @@ -16,7 +16,7 @@ class WindowManager { public getZoomLevel(): number { return this._zoomLevel; } - public setZoomLevel(zoomLevel: number, isTrusted: boolean): void { + public setZoomLevel(zoomLevel: number): void { if (this._zoomLevel === zoomLevel) { return; } @@ -159,8 +159,8 @@ export function addMatchMediaChangeListener(query: string | MediaQueryList, call export const PixelRatio = new PixelRatioFacade(); /** A zoom index, e.g. 1, 2, 3 */ -export function setZoomLevel(zoomLevel: number, isTrusted: boolean): void { - WindowManager.INSTANCE.setZoomLevel(zoomLevel, isTrusted); +export function setZoomLevel(zoomLevel: number): void { + WindowManager.INSTANCE.setZoomLevel(zoomLevel); } export function getZoomLevel(): number { return WindowManager.INSTANCE.getZoomLevel(); diff --git a/src/vs/base/browser/contextmenu.ts b/src/vs/base/browser/contextmenu.ts index 8f67c23030664..3ab23f5bc9ff4 100644 --- a/src/vs/base/browser/contextmenu.ts +++ b/src/vs/base/browser/contextmenu.ts @@ -3,11 +3,13 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { StandardMouseEvent } from 'vs/base/browser/mouseEvent'; import { IActionViewItemOptions } from 'vs/base/browser/ui/actionbar/actionViewItems'; import { IActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar'; -import { AnchorAlignment, AnchorAxisAlignment } from 'vs/base/browser/ui/contextview/contextview'; +import { AnchorAlignment, AnchorAxisAlignment, IAnchor } from 'vs/base/browser/ui/contextview/contextview'; import { IAction, IActionRunner } from 'vs/base/common/actions'; import { ResolvedKeybinding } from 'vs/base/common/keybindings'; +import { OmitOptional } from 'vs/base/common/types'; export interface IContextMenuEvent { readonly shiftKey?: boolean; @@ -16,8 +18,21 @@ export interface IContextMenuEvent { readonly metaKey?: boolean; } +/** + * A specific context menu location to position the menu at. + * Uses some TypeScript type tricks to prevent allowing to + * pass in a `MouseEvent` and force people to use `StandardMouseEvent`. + */ +type ContextMenuLocation = OmitOptional & { getModifierState?: never }; + export interface IContextMenuDelegate { - getAnchor(): HTMLElement | { x: number; y: number; width?: number; height?: number }; + /** + * The anchor where to position the context view. + * Use a `HTMLElement` to position the view at the element, + * a `StandardMouseEvent` to position it at the mouse position + * or an `ContextMenuLocation` to position it at a specific location. + */ + getAnchor(): HTMLElement | StandardMouseEvent | ContextMenuLocation; getActions(): readonly IAction[]; getCheckedActionsRepresentation?(action: IAction): 'radio' | 'checkbox'; getActionViewItem?(action: IAction, options: IActionViewItemOptions): IActionViewItem | undefined; diff --git a/src/vs/base/browser/defaultWorkerFactory.ts b/src/vs/base/browser/defaultWorkerFactory.ts index 9cab36041966c..4f42810f0bd25 100644 --- a/src/vs/base/browser/defaultWorkerFactory.ts +++ b/src/vs/base/browser/defaultWorkerFactory.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { createTrustedTypesPolicy } from 'vs/base/browser/trustedTypes'; +import { onUnexpectedError } from 'vs/base/common/errors'; import { COI } from 'vs/base/common/network'; import { IWorker, IWorkerCallback, IWorkerFactory, logOnceWebWorkerWarning } from 'vs/base/common/worker/simpleWorker'; @@ -85,11 +86,13 @@ function isPromiseLike(obj: any): obj is PromiseLike { */ class WebWorker implements IWorker { - private id: number; + private readonly id: number; + private readonly label: string; private worker: Promise | null; constructor(moduleId: string, id: number, label: string, onMessageCallback: IWorkerCallback, onErrorCallback: (err: any) => void) { this.id = id; + this.label = label; const workerOrPromise = getWorker(label); if (isPromiseLike(workerOrPromise)) { this.worker = workerOrPromise; @@ -113,7 +116,14 @@ class WebWorker implements IWorker { } public postMessage(message: any, transfer: Transferable[]): void { - this.worker?.then(w => w.postMessage(message, transfer)); + this.worker?.then(w => { + try { + w.postMessage(message, transfer); + } catch (err) { + onUnexpectedError(err); + onUnexpectedError(new Error(`FAILED to post message to '${this.label}'-worker`, { cause: err })); + } + }); } public dispose(): void { diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index 249a479504b22..a72e8e0ea8533 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -15,7 +15,6 @@ import { KeyCode } from 'vs/base/common/keyCodes'; import { Disposable, DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; import { FileAccess, RemoteAuthorities, Schemas } from 'vs/base/common/network'; import * as platform from 'vs/base/common/platform'; -import { withNullAsUndefined } from 'vs/base/common/types'; import { URI } from 'vs/base/common/uri'; export function clearNode(node: HTMLElement): void { @@ -1284,7 +1283,7 @@ export function triggerUpload(): Promise { // Resolve once the input event has fired once event.Event.once(event.Event.fromDOMEventEmitter(input, 'input'))(() => { - resolve(withNullAsUndefined(input.files)); + resolve(input.files ?? undefined); }); input.click(); diff --git a/src/vs/base/browser/dompurify/cgmanifest.json b/src/vs/base/browser/dompurify/cgmanifest.json index eac506db4b671..67f049b86c82c 100644 --- a/src/vs/base/browser/dompurify/cgmanifest.json +++ b/src/vs/base/browser/dompurify/cgmanifest.json @@ -6,11 +6,11 @@ "git": { "name": "dompurify", "repositoryUrl": "https://github.com/cure53/DOMPurify", - "commitHash": "6cfcdf56269b892550af80baa7c1fa5b680e5db7" + "commitHash": "c96c9df61f1070146c0c13078e85b33d8fed3e51" } }, "license": "Apache 2.0", - "version": "2.3.1" + "version": "3.0.5" } ], "version": 1 diff --git a/src/vs/base/browser/dompurify/dompurify.d.ts b/src/vs/base/browser/dompurify/dompurify.d.ts index 14b0330711cdd..737515a3cbc2b 100644 --- a/src/vs/base/browser/dompurify/dompurify.d.ts +++ b/src/vs/base/browser/dompurify/dompurify.d.ts @@ -1,4 +1,4 @@ -// Type definitions for DOM Purify 2.2 +// Type definitions for DOM Purify 3.0 // Project: https://github.com/cure53/DOMPurify // Definitions by: Dave Taylor https://github.com/davetayls // Samira Bazuzi @@ -7,27 +7,49 @@ // Piotr Błażejewicz // Nicholas Ellul // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// Minimum TypeScript Version: 4.5 export as namespace DOMPurify; export = DOMPurify; declare const DOMPurify: createDOMPurifyI; +type WindowLike = Pick< + typeof globalThis, + | 'NodeFilter' + | 'Node' + | 'Element' + | 'HTMLTemplateElement' + | 'DocumentFragment' + | 'HTMLFormElement' + | 'DOMParser' + | 'NamedNodeMap' +>; + interface createDOMPurifyI extends DOMPurify.DOMPurifyI { - (window?: Window): DOMPurify.DOMPurifyI; + (window?: Window | WindowLike): DOMPurify.DOMPurifyI; } declare namespace DOMPurify { interface DOMPurifyI { sanitize(source: string | Node): string; sanitize(source: string | Node, config: Config & { RETURN_TRUSTED_TYPE: true }): TrustedHTML; - sanitize(source: string | Node, config: Config & { RETURN_DOM_FRAGMENT?: false | undefined; RETURN_DOM?: false | undefined }): string; + sanitize( + source: string | Node, + config: Config & { RETURN_DOM_FRAGMENT?: false | undefined; RETURN_DOM?: false | undefined }, + ): string; sanitize(source: string | Node, config: Config & { RETURN_DOM_FRAGMENT: true }): DocumentFragment; sanitize(source: string | Node, config: Config & { RETURN_DOM: true }): HTMLElement; sanitize(source: string | Node, config: Config): string | HTMLElement | DocumentFragment; - addHook(hook: 'uponSanitizeElement', cb: (currentNode: Element, data: SanitizeElementHookEvent, config: Config) => void): void; - addHook(hook: 'uponSanitizeAttribute', cb: (currentNode: Element, data: SanitizeAttributeHookEvent, config: Config) => void): void; + addHook( + hook: 'uponSanitizeElement', + cb: (currentNode: Element, data: SanitizeElementHookEvent, config: Config) => void, + ): void; + addHook( + hook: 'uponSanitizeAttribute', + cb: (currentNode: Element, data: SanitizeAttributeHookEvent, config: Config) => void, + ): void; addHook(hook: HookName, cb: (currentNode: Element, data: HookEvent, config: Config) => void): void; setConfig(cfg: Config): void; @@ -47,18 +69,26 @@ declare namespace DOMPurify { ADD_ATTR?: string[] | undefined; ADD_DATA_URI_TAGS?: string[] | undefined; ADD_TAGS?: string[] | undefined; + ADD_URI_SAFE_ATTR?: string[] | undefined; + ALLOW_ARIA_ATTR?: boolean | undefined; ALLOW_DATA_ATTR?: boolean | undefined; + ALLOW_UNKNOWN_PROTOCOLS?: boolean | undefined; + ALLOW_SELF_CLOSE_IN_ATTR?: boolean | undefined; ALLOWED_ATTR?: string[] | undefined; ALLOWED_TAGS?: string[] | undefined; + ALLOWED_NAMESPACES?: string[] | undefined; + ALLOWED_URI_REGEXP?: RegExp | undefined; FORBID_ATTR?: string[] | undefined; + FORBID_CONTENTS?: string[] | undefined; FORBID_TAGS?: string[] | undefined; FORCE_BODY?: boolean | undefined; + IN_PLACE?: boolean | undefined; KEEP_CONTENT?: boolean | undefined; /** * change the default namespace from HTML to something different */ NAMESPACE?: string | undefined; - RETURN_DOM?: boolean | undefined; + PARSER_MEDIA_TYPE?: string | undefined; RETURN_DOM_FRAGMENT?: boolean | undefined; /** * This defaults to `true` starting DOMPurify 2.2.0. Note that setting it to `false` @@ -66,14 +96,27 @@ declare namespace DOMPurify { * supports Declarative Shadow: DOM https://web.dev/declarative-shadow-dom/ */ RETURN_DOM_IMPORT?: boolean | undefined; + RETURN_DOM?: boolean | undefined; RETURN_TRUSTED_TYPE?: boolean | undefined; + SAFE_FOR_TEMPLATES?: boolean | undefined; SANITIZE_DOM?: boolean | undefined; + /** @default false */ + SANITIZE_NAMED_PROPS?: boolean | undefined; + USE_PROFILES?: + | false + | { + mathMl?: boolean | undefined; + svg?: boolean | undefined; + svgFilters?: boolean | undefined; + html?: boolean | undefined; + } + | undefined; WHOLE_DOCUMENT?: boolean | undefined; - ALLOWED_URI_REGEXP?: RegExp | undefined; - SAFE_FOR_TEMPLATES?: boolean | undefined; - ALLOW_UNKNOWN_PROTOCOLS?: boolean | undefined; - USE_PROFILES?: false | { mathMl?: boolean | undefined; svg?: boolean | undefined; svgFilters?: boolean | undefined; html?: boolean | undefined } | undefined; - IN_PLACE?: boolean | undefined; + CUSTOM_ELEMENT_HANDLING?: { + tagNameCheck?: RegExp | ((tagName: string) => boolean) | null | undefined; + attributeNameCheck?: RegExp | ((lcName: string) => boolean) | null | undefined; + allowCustomizedBuiltInElements?: boolean | undefined; + }; } type HookName = diff --git a/src/vs/base/browser/dompurify/dompurify.js b/src/vs/base/browser/dompurify/dompurify.js index 7563b15ba4489..d43b10a85d1cb 100644 --- a/src/vs/base/browser/dompurify/dompurify.js +++ b/src/vs/base/browser/dompurify/dompurify.js @@ -1,1366 +1,1622 @@ -/*! @license DOMPurify 2.3.1 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/2.3.1/LICENSE */ - -function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } - -var hasOwnProperty = Object.hasOwnProperty, - setPrototypeOf = Object.setPrototypeOf, - isFrozen = Object.isFrozen, - getPrototypeOf = Object.getPrototypeOf, - getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; -var freeze = Object.freeze, - seal = Object.seal, - create = Object.create; // eslint-disable-line import/no-mutable-exports - -var _ref = typeof Reflect !== 'undefined' && Reflect, - apply = _ref.apply, - construct = _ref.construct; +/*! @license DOMPurify 3.0.5 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.0.5/LICENSE */ + +const { + entries, + setPrototypeOf, + isFrozen, + getPrototypeOf, + getOwnPropertyDescriptor +} = Object; +let { + freeze, + seal, + create +} = Object; // eslint-disable-line import/no-mutable-exports + +let { + apply, + construct +} = typeof Reflect !== 'undefined' && Reflect; if (!apply) { - apply = function apply(fun, thisValue, args) { - return fun.apply(thisValue, args); - }; + apply = function apply(fun, thisValue, args) { + return fun.apply(thisValue, args); + }; } if (!freeze) { - freeze = function freeze(x) { - return x; - }; + freeze = function freeze(x) { + return x; + }; } if (!seal) { - seal = function seal(x) { - return x; - }; + seal = function seal(x) { + return x; + }; } if (!construct) { - construct = function construct(Func, args) { - return new (Function.prototype.bind.apply(Func, [null].concat(_toConsumableArray(args))))(); - }; + construct = function construct(Func, args) { + return new Func(...args); + }; } -var arrayForEach = unapply(Array.prototype.forEach); -var arrayPop = unapply(Array.prototype.pop); -var arrayPush = unapply(Array.prototype.push); +const arrayForEach = unapply(Array.prototype.forEach); +const arrayPop = unapply(Array.prototype.pop); +const arrayPush = unapply(Array.prototype.push); +const stringToLowerCase = unapply(String.prototype.toLowerCase); +const stringToString = unapply(String.prototype.toString); +const stringMatch = unapply(String.prototype.match); +const stringReplace = unapply(String.prototype.replace); +const stringIndexOf = unapply(String.prototype.indexOf); +const stringTrim = unapply(String.prototype.trim); +const regExpTest = unapply(RegExp.prototype.test); +const typeErrorCreate = unconstruct(TypeError); +function unapply(func) { + return function (thisArg) { + for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } -var stringToLowerCase = unapply(String.prototype.toLowerCase); -var stringMatch = unapply(String.prototype.match); -var stringReplace = unapply(String.prototype.replace); -var stringIndexOf = unapply(String.prototype.indexOf); -var stringTrim = unapply(String.prototype.trim); + return apply(func, thisArg, args); + }; +} +function unconstruct(func) { + return function () { + for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { + args[_key2] = arguments[_key2]; + } -var regExpTest = unapply(RegExp.prototype.test); + return construct(func, args); + }; +} +/* Add properties to a lookup table */ -var typeErrorCreate = unconstruct(TypeError); +function addToSet(set, array, transformCaseFunc) { + var _transformCaseFunc; -function unapply(func) { - return function (thisArg) { - for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { - args[_key - 1] = arguments[_key]; - } + transformCaseFunc = (_transformCaseFunc = transformCaseFunc) !== null && _transformCaseFunc !== void 0 ? _transformCaseFunc : stringToLowerCase; - return apply(func, thisArg, args); - }; -} + if (setPrototypeOf) { + // Make 'in' and truthy checks like Boolean(set.constructor) + // independent of any properties defined on Object.prototype. + // Prevent prototype setters from intercepting set as a this value. + setPrototypeOf(set, null); + } -function unconstruct(func) { - return function () { - for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { - args[_key2] = arguments[_key2]; - } + let l = array.length; - return construct(func, args); - }; -} + while (l--) { + let element = array[l]; -/* Add properties to a lookup table */ -function addToSet(set, array) { - if (setPrototypeOf) { - // Make 'in' and truthy checks like Boolean(set.constructor) - // independent of any properties defined on Object.prototype. - // Prevent prototype setters from intercepting set as a this value. - setPrototypeOf(set, null); - } - - var l = array.length; - while (l--) { - var element = array[l]; - if (typeof element === 'string') { - var lcElement = stringToLowerCase(element); - if (lcElement !== element) { - // Config presets (e.g. tags.js, attrs.js) are immutable. - if (!isFrozen(array)) { - array[l] = lcElement; - } - - element = lcElement; - } - } - - set[element] = true; - } - - return set; -} + if (typeof element === 'string') { + const lcElement = transformCaseFunc(element); + + if (lcElement !== element) { + // Config presets (e.g. tags.js, attrs.js) are immutable. + if (!isFrozen(array)) { + array[l] = lcElement; + } + + element = lcElement; + } + } + + set[element] = true; + } + return set; +} /* Shallow clone an object */ + function clone(object) { - var newObject = create(null); + const newObject = create(null); - var property = void 0; - for (property in object) { - if (apply(hasOwnProperty, object, [property])) { - newObject[property] = object[property]; - } - } + for (const [property, value] of entries(object)) { + newObject[property] = value; + } - return newObject; + return newObject; } +/* This method automatically checks if the prop is function + * or getter and behaves accordingly. */ -/* IE10 doesn't support __lookupGetter__ so lets' - * simulate it. It also automatically checks - * if the prop is function or getter and behaves - * accordingly. */ function lookupGetter(object, prop) { - while (object !== null) { - var desc = getOwnPropertyDescriptor(object, prop); - if (desc) { - if (desc.get) { - return unapply(desc.get); - } - - if (typeof desc.value === 'function') { - return unapply(desc.value); - } - } - - object = getPrototypeOf(object); - } - - function fallbackValue(element) { - console.warn('fallback value for', element); - return null; - } - - return fallbackValue; -} + while (object !== null) { + const desc = getOwnPropertyDescriptor(object, prop); -var html = freeze(['a', 'abbr', 'acronym', 'address', 'area', 'article', 'aside', 'audio', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'content', 'data', 'datalist', 'dd', 'decorator', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meter', 'nav', 'nobr', 'ol', 'optgroup', 'option', 'output', 'p', 'picture', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'section', 'select', 'shadow', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr']); + if (desc) { + if (desc.get) { + return unapply(desc.get); + } -// SVG -var svg = freeze(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'stop', 'style', 'switch', 'symbol', 'text', 'textpath', 'title', 'tref', 'tspan', 'view', 'vkern']); + if (typeof desc.value === 'function') { + return unapply(desc.value); + } + } -var svgFilters = freeze(['feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence']); + object = getPrototypeOf(object); + } -// List of SVG elements that are disallowed by default. + function fallbackValue(element) { + console.warn('fallback value for', element); + return null; + } + + return fallbackValue; +} + +const html$1 = freeze(['a', 'abbr', 'acronym', 'address', 'area', 'article', 'aside', 'audio', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'content', 'data', 'datalist', 'dd', 'decorator', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meter', 'nav', 'nobr', 'ol', 'optgroup', 'option', 'output', 'p', 'picture', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'section', 'select', 'shadow', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr']); // SVG + +const svg$1 = freeze(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'stop', 'style', 'switch', 'symbol', 'text', 'textpath', 'title', 'tref', 'tspan', 'view', 'vkern']); +const svgFilters = freeze(['feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feDropShadow', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence']); // List of SVG elements that are disallowed by default. // We still need to know them so that we can do namespace // checks properly in case one wants to add them to // allow-list. -var svgDisallowed = freeze(['animate', 'color-profile', 'cursor', 'discard', 'fedropshadow', 'feimage', 'font-face', 'font-face-format', 'font-face-name', 'font-face-src', 'font-face-uri', 'foreignobject', 'hatch', 'hatchpath', 'mesh', 'meshgradient', 'meshpatch', 'meshrow', 'missing-glyph', 'script', 'set', 'solidcolor', 'unknown', 'use']); -var mathMl = freeze(['math', 'menclose', 'merror', 'mfenced', 'mfrac', 'mglyph', 'mi', 'mlabeledtr', 'mmultiscripts', 'mn', 'mo', 'mover', 'mpadded', 'mphantom', 'mroot', 'mrow', 'ms', 'mspace', 'msqrt', 'mstyle', 'msub', 'msup', 'msubsup', 'mtable', 'mtd', 'mtext', 'mtr', 'munder', 'munderover']); - -// Similarly to SVG, we want to know all MathML elements, +const svgDisallowed = freeze(['animate', 'color-profile', 'cursor', 'discard', 'font-face', 'font-face-format', 'font-face-name', 'font-face-src', 'font-face-uri', 'foreignobject', 'hatch', 'hatchpath', 'mesh', 'meshgradient', 'meshpatch', 'meshrow', 'missing-glyph', 'script', 'set', 'solidcolor', 'unknown', 'use']); +const mathMl$1 = freeze(['math', 'menclose', 'merror', 'mfenced', 'mfrac', 'mglyph', 'mi', 'mlabeledtr', 'mmultiscripts', 'mn', 'mo', 'mover', 'mpadded', 'mphantom', 'mroot', 'mrow', 'ms', 'mspace', 'msqrt', 'mstyle', 'msub', 'msup', 'msubsup', 'mtable', 'mtd', 'mtext', 'mtr', 'munder', 'munderover', 'mprescripts']); // Similarly to SVG, we want to know all MathML elements, // even those that we disallow by default. -var mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']); -var text = freeze(['#text']); +const mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']); +const text = freeze(['#text']); -var html$1 = freeze(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'controlslist', 'coords', 'crossorigin', 'datetime', 'decoding', 'default', 'dir', 'disabled', 'disablepictureinpicture', 'disableremoteplayback', 'download', 'draggable', 'enctype', 'enterkeyhint', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'inputmode', 'integrity', 'ismap', 'kind', 'label', 'lang', 'list', 'loading', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'muted', 'name', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'pattern', 'placeholder', 'playsinline', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'xmlns', 'slot']); +const html = freeze(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'controlslist', 'coords', 'crossorigin', 'datetime', 'decoding', 'default', 'dir', 'disabled', 'disablepictureinpicture', 'disableremoteplayback', 'download', 'draggable', 'enctype', 'enterkeyhint', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'inputmode', 'integrity', 'ismap', 'kind', 'label', 'lang', 'list', 'loading', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'muted', 'name', 'nonce', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'pattern', 'placeholder', 'playsinline', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'xmlns', 'slot']); +const svg = freeze(['accent-height', 'accumulate', 'additive', 'alignment-baseline', 'ascent', 'attributename', 'attributetype', 'azimuth', 'basefrequency', 'baseline-shift', 'begin', 'bias', 'by', 'class', 'clip', 'clippathunits', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cx', 'cy', 'd', 'dx', 'dy', 'diffuseconstant', 'direction', 'display', 'divisor', 'dur', 'edgemode', 'elevation', 'end', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'filterunits', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'fx', 'fy', 'g1', 'g2', 'glyph-name', 'glyphref', 'gradientunits', 'gradienttransform', 'height', 'href', 'id', 'image-rendering', 'in', 'in2', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'keypoints', 'keysplines', 'keytimes', 'lang', 'lengthadjust', 'letter-spacing', 'kernelmatrix', 'kernelunitlength', 'lighting-color', 'local', 'marker-end', 'marker-mid', 'marker-start', 'markerheight', 'markerunits', 'markerwidth', 'maskcontentunits', 'maskunits', 'max', 'mask', 'media', 'method', 'mode', 'min', 'name', 'numoctaves', 'offset', 'operator', 'opacity', 'order', 'orient', 'orientation', 'origin', 'overflow', 'paint-order', 'path', 'pathlength', 'patterncontentunits', 'patterntransform', 'patternunits', 'points', 'preservealpha', 'preserveaspectratio', 'primitiveunits', 'r', 'rx', 'ry', 'radius', 'refx', 'refy', 'repeatcount', 'repeatdur', 'restart', 'result', 'rotate', 'scale', 'seed', 'shape-rendering', 'specularconstant', 'specularexponent', 'spreadmethod', 'startoffset', 'stddeviation', 'stitchtiles', 'stop-color', 'stop-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke', 'stroke-width', 'style', 'surfacescale', 'systemlanguage', 'tabindex', 'targetx', 'targety', 'transform', 'transform-origin', 'text-anchor', 'text-decoration', 'text-rendering', 'textlength', 'type', 'u1', 'u2', 'unicode', 'values', 'viewbox', 'visibility', 'version', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'width', 'word-spacing', 'wrap', 'writing-mode', 'xchannelselector', 'ychannelselector', 'x', 'x1', 'x2', 'xmlns', 'y', 'y1', 'y2', 'z', 'zoomandpan']); +const mathMl = freeze(['accent', 'accentunder', 'align', 'bevelled', 'close', 'columnsalign', 'columnlines', 'columnspan', 'denomalign', 'depth', 'dir', 'display', 'displaystyle', 'encoding', 'fence', 'frame', 'height', 'href', 'id', 'largeop', 'length', 'linethickness', 'lspace', 'lquote', 'mathbackground', 'mathcolor', 'mathsize', 'mathvariant', 'maxsize', 'minsize', 'movablelimits', 'notation', 'numalign', 'open', 'rowalign', 'rowlines', 'rowspacing', 'rowspan', 'rspace', 'rquote', 'scriptlevel', 'scriptminsize', 'scriptsizemultiplier', 'selection', 'separator', 'separators', 'stretchy', 'subscriptshift', 'supscriptshift', 'symmetric', 'voffset', 'width', 'xmlns']); +const xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']); -var svg$1 = freeze(['accent-height', 'accumulate', 'additive', 'alignment-baseline', 'ascent', 'attributename', 'attributetype', 'azimuth', 'basefrequency', 'baseline-shift', 'begin', 'bias', 'by', 'class', 'clip', 'clippathunits', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cx', 'cy', 'd', 'dx', 'dy', 'diffuseconstant', 'direction', 'display', 'divisor', 'dur', 'edgemode', 'elevation', 'end', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'filterunits', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'fx', 'fy', 'g1', 'g2', 'glyph-name', 'glyphref', 'gradientunits', 'gradienttransform', 'height', 'href', 'id', 'image-rendering', 'in', 'in2', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'keypoints', 'keysplines', 'keytimes', 'lang', 'lengthadjust', 'letter-spacing', 'kernelmatrix', 'kernelunitlength', 'lighting-color', 'local', 'marker-end', 'marker-mid', 'marker-start', 'markerheight', 'markerunits', 'markerwidth', 'maskcontentunits', 'maskunits', 'max', 'mask', 'media', 'method', 'mode', 'min', 'name', 'numoctaves', 'offset', 'operator', 'opacity', 'order', 'orient', 'orientation', 'origin', 'overflow', 'paint-order', 'path', 'pathlength', 'patterncontentunits', 'patterntransform', 'patternunits', 'points', 'preservealpha', 'preserveaspectratio', 'primitiveunits', 'r', 'rx', 'ry', 'radius', 'refx', 'refy', 'repeatcount', 'repeatdur', 'restart', 'result', 'rotate', 'scale', 'seed', 'shape-rendering', 'specularconstant', 'specularexponent', 'spreadmethod', 'startoffset', 'stddeviation', 'stitchtiles', 'stop-color', 'stop-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke', 'stroke-width', 'style', 'surfacescale', 'systemlanguage', 'tabindex', 'targetx', 'targety', 'transform', 'text-anchor', 'text-decoration', 'text-rendering', 'textlength', 'type', 'u1', 'u2', 'unicode', 'values', 'viewbox', 'visibility', 'version', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'width', 'word-spacing', 'wrap', 'writing-mode', 'xchannelselector', 'ychannelselector', 'x', 'x1', 'x2', 'xmlns', 'y', 'y1', 'y2', 'z', 'zoomandpan']); +const MUSTACHE_EXPR = seal(/\{\{[\w\W]*|[\w\W]*\}\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode -var mathMl$1 = freeze(['accent', 'accentunder', 'align', 'bevelled', 'close', 'columnsalign', 'columnlines', 'columnspan', 'denomalign', 'depth', 'dir', 'display', 'displaystyle', 'encoding', 'fence', 'frame', 'height', 'href', 'id', 'largeop', 'length', 'linethickness', 'lspace', 'lquote', 'mathbackground', 'mathcolor', 'mathsize', 'mathvariant', 'maxsize', 'minsize', 'movablelimits', 'notation', 'numalign', 'open', 'rowalign', 'rowlines', 'rowspacing', 'rowspan', 'rspace', 'rquote', 'scriptlevel', 'scriptminsize', 'scriptsizemultiplier', 'selection', 'separator', 'separators', 'stretchy', 'subscriptshift', 'supscriptshift', 'symmetric', 'voffset', 'width', 'xmlns']); +const ERB_EXPR = seal(/<%[\w\W]*|[\w\W]*%>/gm); +const TMPLIT_EXPR = seal(/\${[\w\W]*}/gm); +const DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]/); // eslint-disable-line no-useless-escape -var xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']); +const ARIA_ATTR = seal(/^aria-[\-\w]+$/); // eslint-disable-line no-useless-escape -// eslint-disable-next-line unicorn/better-regex -var MUSTACHE_EXPR = seal(/\{\{[\s\S]*|[\s\S]*\}\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode -var ERB_EXPR = seal(/<%[\s\S]*|[\s\S]*%>/gm); -var DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]/); // eslint-disable-line no-useless-escape -var ARIA_ATTR = seal(/^aria-[\-\w]+$/); // eslint-disable-line no-useless-escape -var IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i // eslint-disable-line no-useless-escape +const IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i // eslint-disable-line no-useless-escape ); -var IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i); -var ATTR_WHITESPACE = seal(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g // eslint-disable-line no-control-regex +const IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i); +const ATTR_WHITESPACE = seal(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g // eslint-disable-line no-control-regex ); - -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; - -function _toConsumableArray$1(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } - -var getGlobal = function getGlobal() { - return typeof window === 'undefined' ? null : window; -}; - +const DOCTYPE_NAME = seal(/^html$/i); + +var EXPRESSIONS = /*#__PURE__*/Object.freeze({ + __proto__: null, + MUSTACHE_EXPR: MUSTACHE_EXPR, + ERB_EXPR: ERB_EXPR, + TMPLIT_EXPR: TMPLIT_EXPR, + DATA_ATTR: DATA_ATTR, + ARIA_ATTR: ARIA_ATTR, + IS_ALLOWED_URI: IS_ALLOWED_URI, + IS_SCRIPT_OR_DATA: IS_SCRIPT_OR_DATA, + ATTR_WHITESPACE: ATTR_WHITESPACE, + DOCTYPE_NAME: DOCTYPE_NAME +}); + +const getGlobal = () => typeof window === 'undefined' ? null : window; /** * Creates a no-op policy for internal use only. * Don't export this function outside this module! * @param {?TrustedTypePolicyFactory} trustedTypes The policy factory. - * @param {Document} document The document object (to determine policy name suffix) + * @param {HTMLScriptElement} purifyHostElement The Script element used to load DOMPurify (to determine policy name suffix). * @return {?TrustedTypePolicy} The policy created (or null, if Trusted Types - * are not supported). + * are not supported or creating the policy failed). */ -var _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, document) { - if ((typeof trustedTypes === 'undefined' ? 'undefined' : _typeof(trustedTypes)) !== 'object' || typeof trustedTypes.createPolicy !== 'function') { - return null; - } - - // Allow the callers to control the unique policy name - // by adding a data-tt-policy-suffix to the script element with the DOMPurify. - // Policy creation with duplicate names throws in Trusted Types. - var suffix = null; - var ATTR_NAME = 'data-tt-policy-suffix'; - if (document.currentScript && document.currentScript.hasAttribute(ATTR_NAME)) { - suffix = document.currentScript.getAttribute(ATTR_NAME); - } - - var policyName = 'dompurify' + (suffix ? '#' + suffix : ''); - - try { - return trustedTypes.createPolicy(policyName, { - createHTML: function createHTML(html$$1) { - return html$$1; - } - }); - } catch (_) { - // Policy creation failed (most likely another DOMPurify script has - // already run). Skip creating the policy, as this will only cause errors - // if TT are enforced. - console.warn('TrustedTypes policy ' + policyName + ' could not be created.'); - return null; - } + + +const _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, purifyHostElement) { + if (typeof trustedTypes !== 'object' || typeof trustedTypes.createPolicy !== 'function') { + return null; + } // Allow the callers to control the unique policy name + // by adding a data-tt-policy-suffix to the script element with the DOMPurify. + // Policy creation with duplicate names throws in Trusted Types. + + + let suffix = null; + const ATTR_NAME = 'data-tt-policy-suffix'; + + if (purifyHostElement && purifyHostElement.hasAttribute(ATTR_NAME)) { + suffix = purifyHostElement.getAttribute(ATTR_NAME); + } + + const policyName = 'dompurify' + (suffix ? '#' + suffix : ''); + + try { + return trustedTypes.createPolicy(policyName, { + createHTML(html) { + return html; + }, + + createScriptURL(scriptUrl) { + return scriptUrl; + } + + }); + } catch (_) { + // Policy creation failed (most likely another DOMPurify script has + // already run). Skip creating the policy, as this will only cause errors + // if TT are enforced. + console.warn('TrustedTypes policy ' + policyName + ' could not be created.'); + return null; + } }; function createDOMPurify() { - var window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal(); - - var DOMPurify = function DOMPurify(root) { - return createDOMPurify(root); - }; - - /** - * Version label, exposed for easier checks - * if DOMPurify is up to date or not - */ - DOMPurify.version = '2.3.1'; - - /** - * Array of elements that DOMPurify removed during sanitation. - * Empty if nothing was removed. - */ - DOMPurify.removed = []; - - if (!window || !window.document || window.document.nodeType !== 9) { - // Not running in a browser, provide a factory function - // so that you can pass your own Window - DOMPurify.isSupported = false; - - return DOMPurify; - } - - var originalDocument = window.document; - - var document = window.document; - var DocumentFragment = window.DocumentFragment, - HTMLTemplateElement = window.HTMLTemplateElement, - Node = window.Node, - Element = window.Element, - NodeFilter = window.NodeFilter, - _window$NamedNodeMap = window.NamedNodeMap, - NamedNodeMap = _window$NamedNodeMap === undefined ? window.NamedNodeMap || window.MozNamedAttrMap : _window$NamedNodeMap, - Text = window.Text, - Comment = window.Comment, - DOMParser = window.DOMParser, - trustedTypes = window.trustedTypes; - - - var ElementPrototype = Element.prototype; - - var cloneNode = lookupGetter(ElementPrototype, 'cloneNode'); - var getNextSibling = lookupGetter(ElementPrototype, 'nextSibling'); - var getChildNodes = lookupGetter(ElementPrototype, 'childNodes'); - var getParentNode = lookupGetter(ElementPrototype, 'parentNode'); - - // As per issue #47, the web-components registry is inherited by a - // new document created via createHTMLDocument. As per the spec - // (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries) - // a new empty registry is used when creating a template contents owner - // document, so we use that as our parent document to ensure nothing - // is inherited. - if (typeof HTMLTemplateElement === 'function') { - var template = document.createElement('template'); - if (template.content && template.content.ownerDocument) { - document = template.content.ownerDocument; - } - } - - var trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, originalDocument); - var emptyHTML = trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML('') : ''; - - var _document = document, - implementation = _document.implementation, - createNodeIterator = _document.createNodeIterator, - createDocumentFragment = _document.createDocumentFragment, - getElementsByTagName = _document.getElementsByTagName; - var importNode = originalDocument.importNode; - - - var documentMode = {}; - try { - documentMode = clone(document).documentMode ? document.documentMode : {}; - } catch (_) {} - - var hooks = {}; - - /** - * Expose whether this browser supports running the full DOMPurify. - */ - DOMPurify.isSupported = typeof getParentNode === 'function' && implementation && typeof implementation.createHTMLDocument !== 'undefined' && documentMode !== 9; - - var MUSTACHE_EXPR$$1 = MUSTACHE_EXPR, - ERB_EXPR$$1 = ERB_EXPR, - DATA_ATTR$$1 = DATA_ATTR, - ARIA_ATTR$$1 = ARIA_ATTR, - IS_SCRIPT_OR_DATA$$1 = IS_SCRIPT_OR_DATA, - ATTR_WHITESPACE$$1 = ATTR_WHITESPACE; - var IS_ALLOWED_URI$$1 = IS_ALLOWED_URI; - - /** - * We consider the elements and attributes below to be safe. Ideally - * don't add any new ones but feel free to remove unwanted ones. - */ - - /* allowed element names */ - - var ALLOWED_TAGS = null; - var DEFAULT_ALLOWED_TAGS = addToSet({}, [].concat(_toConsumableArray$1(html), _toConsumableArray$1(svg), _toConsumableArray$1(svgFilters), _toConsumableArray$1(mathMl), _toConsumableArray$1(text))); - - /* Allowed attribute names */ - var ALLOWED_ATTR = null; - var DEFAULT_ALLOWED_ATTR = addToSet({}, [].concat(_toConsumableArray$1(html$1), _toConsumableArray$1(svg$1), _toConsumableArray$1(mathMl$1), _toConsumableArray$1(xml))); - - /* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */ - var FORBID_TAGS = null; - - /* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */ - var FORBID_ATTR = null; - - /* Decide if ARIA attributes are okay */ - var ALLOW_ARIA_ATTR = true; - - /* Decide if custom data attributes are okay */ - var ALLOW_DATA_ATTR = true; - - /* Decide if unknown protocols are okay */ - var ALLOW_UNKNOWN_PROTOCOLS = false; - - /* Output should be safe for common template engines. - * This means, DOMPurify removes data attributes, mustaches and ERB - */ - var SAFE_FOR_TEMPLATES = false; - - /* Decide if document with ... should be returned */ - var WHOLE_DOCUMENT = false; - - /* Track whether config is already set on this instance of DOMPurify. */ - var SET_CONFIG = false; - - /* Decide if all elements (e.g. style, script) must be children of - * document.body. By default, browsers might move them to document.head */ - var FORCE_BODY = false; - - /* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html - * string (or a TrustedHTML object if Trusted Types are supported). - * If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead - */ - var RETURN_DOM = false; - - /* Decide if a DOM `DocumentFragment` should be returned, instead of a html - * string (or a TrustedHTML object if Trusted Types are supported) */ - var RETURN_DOM_FRAGMENT = false; - - /* If `RETURN_DOM` or `RETURN_DOM_FRAGMENT` is enabled, decide if the returned DOM - * `Node` is imported into the current `Document`. If this flag is not enabled the - * `Node` will belong (its ownerDocument) to a fresh `HTMLDocument`, created by - * DOMPurify. - * - * This defaults to `true` starting DOMPurify 2.2.0. Note that setting it to `false` - * might cause XSS from attacks hidden in closed shadowroots in case the browser - * supports Declarative Shadow: DOM https://web.dev/declarative-shadow-dom/ - */ - var RETURN_DOM_IMPORT = true; - - /* Try to return a Trusted Type object instead of a string, return a string in - * case Trusted Types are not supported */ - var RETURN_TRUSTED_TYPE = false; - - /* Output should be free from DOM clobbering attacks? */ - var SANITIZE_DOM = true; - - /* Keep element content when removing element? */ - var KEEP_CONTENT = true; - - /* If a `Node` is passed to sanitize(), then performs sanitization in-place instead - * of importing it into a new Document and returning a sanitized copy */ - var IN_PLACE = false; - - /* Allow usage of profiles like html, svg and mathMl */ - var USE_PROFILES = {}; - - /* Tags to ignore content of when KEEP_CONTENT is true */ - var FORBID_CONTENTS = null; - var DEFAULT_FORBID_CONTENTS = addToSet({}, ['annotation-xml', 'audio', 'colgroup', 'desc', 'foreignobject', 'head', 'iframe', 'math', 'mi', 'mn', 'mo', 'ms', 'mtext', 'noembed', 'noframes', 'noscript', 'plaintext', 'script', 'style', 'svg', 'template', 'thead', 'title', 'video', 'xmp']); - - /* Tags that are safe for data: URIs */ - var DATA_URI_TAGS = null; - var DEFAULT_DATA_URI_TAGS = addToSet({}, ['audio', 'video', 'img', 'source', 'image', 'track']); - - /* Attributes safe for values like "javascript:" */ - var URI_SAFE_ATTRIBUTES = null; - var DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ['alt', 'class', 'for', 'id', 'label', 'name', 'pattern', 'placeholder', 'role', 'summary', 'title', 'value', 'style', 'xmlns']); - - var MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML'; - var SVG_NAMESPACE = 'http://www.w3.org/2000/svg'; - var HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml'; - /* Document namespace */ - var NAMESPACE = HTML_NAMESPACE; - var IS_EMPTY_INPUT = false; - - /* Keep a reference to config to pass to hooks */ - var CONFIG = null; - - /* Ideally, do not touch anything below this line */ - /* ______________________________________________ */ - - var formElement = document.createElement('form'); - - /** - * _parseConfig - * - * @param {Object} cfg optional config literal - */ - // eslint-disable-next-line complexity - var _parseConfig = function _parseConfig(cfg) { - if (CONFIG && CONFIG === cfg) { - return; - } - - /* Shield configuration object from tampering */ - if (!cfg || (typeof cfg === 'undefined' ? 'undefined' : _typeof(cfg)) !== 'object') { - cfg = {}; - } - - /* Shield configuration object from prototype pollution */ - cfg = clone(cfg); - - /* Set configuration parameters */ - ALLOWED_TAGS = 'ALLOWED_TAGS' in cfg ? addToSet({}, cfg.ALLOWED_TAGS) : DEFAULT_ALLOWED_TAGS; - ALLOWED_ATTR = 'ALLOWED_ATTR' in cfg ? addToSet({}, cfg.ALLOWED_ATTR) : DEFAULT_ALLOWED_ATTR; - URI_SAFE_ATTRIBUTES = 'ADD_URI_SAFE_ATTR' in cfg ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR) : DEFAULT_URI_SAFE_ATTRIBUTES; - DATA_URI_TAGS = 'ADD_DATA_URI_TAGS' in cfg ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS) : DEFAULT_DATA_URI_TAGS; - FORBID_CONTENTS = 'FORBID_CONTENTS' in cfg ? addToSet({}, cfg.FORBID_CONTENTS) : DEFAULT_FORBID_CONTENTS; - FORBID_TAGS = 'FORBID_TAGS' in cfg ? addToSet({}, cfg.FORBID_TAGS) : {}; - FORBID_ATTR = 'FORBID_ATTR' in cfg ? addToSet({}, cfg.FORBID_ATTR) : {}; - USE_PROFILES = 'USE_PROFILES' in cfg ? cfg.USE_PROFILES : false; - ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true - ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true - ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false - SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false - WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false - RETURN_DOM = cfg.RETURN_DOM || false; // Default false - RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false - RETURN_DOM_IMPORT = cfg.RETURN_DOM_IMPORT !== false; // Default true - RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false - FORCE_BODY = cfg.FORCE_BODY || false; // Default false - SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true - KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true - IN_PLACE = cfg.IN_PLACE || false; // Default false - IS_ALLOWED_URI$$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI$$1; - NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE; - if (SAFE_FOR_TEMPLATES) { - ALLOW_DATA_ATTR = false; - } - - if (RETURN_DOM_FRAGMENT) { - RETURN_DOM = true; - } - - /* Parse profile info */ - if (USE_PROFILES) { - ALLOWED_TAGS = addToSet({}, [].concat(_toConsumableArray$1(text))); - ALLOWED_ATTR = []; - if (USE_PROFILES.html === true) { - addToSet(ALLOWED_TAGS, html); - addToSet(ALLOWED_ATTR, html$1); - } - - if (USE_PROFILES.svg === true) { - addToSet(ALLOWED_TAGS, svg); - addToSet(ALLOWED_ATTR, svg$1); - addToSet(ALLOWED_ATTR, xml); - } - - if (USE_PROFILES.svgFilters === true) { - addToSet(ALLOWED_TAGS, svgFilters); - addToSet(ALLOWED_ATTR, svg$1); - addToSet(ALLOWED_ATTR, xml); - } - - if (USE_PROFILES.mathMl === true) { - addToSet(ALLOWED_TAGS, mathMl); - addToSet(ALLOWED_ATTR, mathMl$1); - addToSet(ALLOWED_ATTR, xml); - } - } - - /* Merge configuration parameters */ - if (cfg.ADD_TAGS) { - if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) { - ALLOWED_TAGS = clone(ALLOWED_TAGS); - } - - addToSet(ALLOWED_TAGS, cfg.ADD_TAGS); - } - - if (cfg.ADD_ATTR) { - if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) { - ALLOWED_ATTR = clone(ALLOWED_ATTR); - } - - addToSet(ALLOWED_ATTR, cfg.ADD_ATTR); - } - - if (cfg.ADD_URI_SAFE_ATTR) { - addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR); - } - - if (cfg.FORBID_CONTENTS) { - if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) { - FORBID_CONTENTS = clone(FORBID_CONTENTS); - } - - addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS); - } - - /* Add #text in case KEEP_CONTENT is set to true */ - if (KEEP_CONTENT) { - ALLOWED_TAGS['#text'] = true; - } - - /* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */ - if (WHOLE_DOCUMENT) { - addToSet(ALLOWED_TAGS, ['html', 'head', 'body']); - } - - /* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */ - if (ALLOWED_TAGS.table) { - addToSet(ALLOWED_TAGS, ['tbody']); - delete FORBID_TAGS.tbody; - } - - // Prevent further manipulation of configuration. - // Not available in IE8, Safari 5, etc. - if (freeze) { - freeze(cfg); - } - - CONFIG = cfg; - }; - - var MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ['mi', 'mo', 'mn', 'ms', 'mtext']); - - var HTML_INTEGRATION_POINTS = addToSet({}, ['foreignobject', 'desc', 'title', 'annotation-xml']); - - /* Keep track of all possible SVG and MathML tags - * so that we can perform the namespace checks - * correctly. */ - var ALL_SVG_TAGS = addToSet({}, svg); - addToSet(ALL_SVG_TAGS, svgFilters); - addToSet(ALL_SVG_TAGS, svgDisallowed); - - var ALL_MATHML_TAGS = addToSet({}, mathMl); - addToSet(ALL_MATHML_TAGS, mathMlDisallowed); - - /** - * - * - * @param {Element} element a DOM element whose namespace is being checked - * @returns {boolean} Return false if the element has a - * namespace that a spec-compliant parser would never - * return. Return true otherwise. - */ - var _checkValidNamespace = function _checkValidNamespace(element) { - var parent = getParentNode(element); - - // In JSDOM, if we're inside shadow DOM, then parentNode - // can be null. We just simulate parent in this case. - if (!parent || !parent.tagName) { - parent = { - namespaceURI: HTML_NAMESPACE, - tagName: 'template' - }; - } - - var tagName = stringToLowerCase(element.tagName); - var parentTagName = stringToLowerCase(parent.tagName); - - if (element.namespaceURI === SVG_NAMESPACE) { - // The only way to switch from HTML namespace to SVG - // is via . If it happens via any other tag, then - // it should be killed. - if (parent.namespaceURI === HTML_NAMESPACE) { - return tagName === 'svg'; - } - - // The only way to switch from MathML to SVG is via - // svg if parent is either or MathML - // text integration points. - if (parent.namespaceURI === MATHML_NAMESPACE) { - return tagName === 'svg' && (parentTagName === 'annotation-xml' || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]); - } - - // We only allow elements that are defined in SVG - // spec. All others are disallowed in SVG namespace. - return Boolean(ALL_SVG_TAGS[tagName]); - } - - if (element.namespaceURI === MATHML_NAMESPACE) { - // The only way to switch from HTML namespace to MathML - // is via . If it happens via any other tag, then - // it should be killed. - if (parent.namespaceURI === HTML_NAMESPACE) { - return tagName === 'math'; - } - - // The only way to switch from SVG to MathML is via - // and HTML integration points - if (parent.namespaceURI === SVG_NAMESPACE) { - return tagName === 'math' && HTML_INTEGRATION_POINTS[parentTagName]; - } - - // We only allow elements that are defined in MathML - // spec. All others are disallowed in MathML namespace. - return Boolean(ALL_MATHML_TAGS[tagName]); - } - - if (element.namespaceURI === HTML_NAMESPACE) { - // The only way to switch from SVG to HTML is via - // HTML integration points, and from MathML to HTML - // is via MathML text integration points - if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) { - return false; - } - - if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) { - return false; - } - - // Certain elements are allowed in both SVG and HTML - // namespace. We need to specify them explicitly - // so that they don't get erronously deleted from - // HTML namespace. - var commonSvgAndHTMLElements = addToSet({}, ['title', 'style', 'font', 'a', 'script']); - - // We disallow tags that are specific for MathML - // or SVG and should never appear in HTML namespace - return !ALL_MATHML_TAGS[tagName] && (commonSvgAndHTMLElements[tagName] || !ALL_SVG_TAGS[tagName]); - } - - // The code should never reach this place (this means - // that the element somehow got namespace that is not - // HTML, SVG or MathML). Return false just in case. - return false; - }; - - /** - * _forceRemove - * - * @param {Node} node a DOM node - */ - var _forceRemove = function _forceRemove(node) { - arrayPush(DOMPurify.removed, { element: node }); - try { - // eslint-disable-next-line unicorn/prefer-dom-node-remove - node.parentNode.removeChild(node); - } catch (_) { - try { - node.outerHTML = emptyHTML; - } catch (_) { - node.remove(); - } - } - }; - - /** - * _removeAttribute - * - * @param {String} name an Attribute name - * @param {Node} node a DOM node - */ - var _removeAttribute = function _removeAttribute(name, node) { - try { - arrayPush(DOMPurify.removed, { - attribute: node.getAttributeNode(name), - from: node - }); - } catch (_) { - arrayPush(DOMPurify.removed, { - attribute: null, - from: node - }); - } - - node.removeAttribute(name); - - // We void attribute values for unremovable "is"" attributes - if (name === 'is' && !ALLOWED_ATTR[name]) { - if (RETURN_DOM || RETURN_DOM_FRAGMENT) { - try { - _forceRemove(node); - } catch (_) {} - } else { - try { - node.setAttribute(name, ''); - } catch (_) {} - } - } - }; - - /** - * _initDocument - * - * @param {String} dirty a string of dirty markup - * @return {Document} a DOM, filled with the dirty markup - */ - var _initDocument = function _initDocument(dirty) { - /* Create a HTML document */ - var doc = void 0; - var leadingWhitespace = void 0; - - if (FORCE_BODY) { - dirty = '' + dirty; - } else { - /* If FORCE_BODY isn't used, leading whitespace needs to be preserved manually */ - var matches = stringMatch(dirty, /^[\r\n\t ]+/); - leadingWhitespace = matches && matches[0]; - } - - var dirtyPayload = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty; - /* - * Use the DOMParser API by default, fallback later if needs be - * DOMParser not work for svg when has multiple root element. - */ - if (NAMESPACE === HTML_NAMESPACE) { - try { - doc = new DOMParser().parseFromString(dirtyPayload, 'text/html'); - } catch (_) {} - } - - /* Use createHTMLDocument in case DOMParser is not available */ - if (!doc || !doc.documentElement) { - doc = implementation.createDocument(NAMESPACE, 'template', null); - try { - doc.documentElement.innerHTML = IS_EMPTY_INPUT ? '' : dirtyPayload; - } catch (_) { - // Syntax error if dirtyPayload is invalid xml - } - } - - var body = doc.body || doc.documentElement; - - if (dirty && leadingWhitespace) { - body.insertBefore(document.createTextNode(leadingWhitespace), body.childNodes[0] || null); - } - - /* Work on whole document or just its body */ - if (NAMESPACE === HTML_NAMESPACE) { - return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0]; - } - - return WHOLE_DOCUMENT ? doc.documentElement : body; - }; - - /** - * _createIterator - * - * @param {Document} root document/fragment to create iterator for - * @return {Iterator} iterator instance - */ - var _createIterator = function _createIterator(root) { - return createNodeIterator.call(root.ownerDocument || root, root, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT, null, false); - }; - - /** - * _isClobbered - * - * @param {Node} elm element to check for clobbering attacks - * @return {Boolean} true if clobbered, false if safe - */ - var _isClobbered = function _isClobbered(elm) { - if (elm instanceof Text || elm instanceof Comment) { - return false; - } - - if (typeof elm.nodeName !== 'string' || typeof elm.textContent !== 'string' || typeof elm.removeChild !== 'function' || !(elm.attributes instanceof NamedNodeMap) || typeof elm.removeAttribute !== 'function' || typeof elm.setAttribute !== 'function' || typeof elm.namespaceURI !== 'string' || typeof elm.insertBefore !== 'function') { - return true; - } - - return false; - }; - - /** - * _isNode - * - * @param {Node} obj object to check whether it's a DOM node - * @return {Boolean} true is object is a DOM node - */ - var _isNode = function _isNode(object) { - return (typeof Node === 'undefined' ? 'undefined' : _typeof(Node)) === 'object' ? object instanceof Node : object && (typeof object === 'undefined' ? 'undefined' : _typeof(object)) === 'object' && typeof object.nodeType === 'number' && typeof object.nodeName === 'string'; - }; - - /** - * _executeHook - * Execute user configurable hooks - * - * @param {String} entryPoint Name of the hook's entry point - * @param {Node} currentNode node to work on with the hook - * @param {Object} data additional hook parameters - */ - var _executeHook = function _executeHook(entryPoint, currentNode, data) { - if (!hooks[entryPoint]) { - return; - } - - arrayForEach(hooks[entryPoint], function (hook) { - hook.call(DOMPurify, currentNode, data, CONFIG); - }); - }; - - /** - * _sanitizeElements - * - * @protect nodeName - * @protect textContent - * @protect removeChild - * - * @param {Node} currentNode to check for permission to exist - * @return {Boolean} true if node was killed, false if left alive - */ - var _sanitizeElements = function _sanitizeElements(currentNode) { - var content = void 0; - - /* Execute a hook if present */ - _executeHook('beforeSanitizeElements', currentNode, null); - - /* Check if element is clobbered or can clobber */ - if (_isClobbered(currentNode)) { - _forceRemove(currentNode); - return true; - } - - /* Check if tagname contains Unicode */ - if (stringMatch(currentNode.nodeName, /[\u0080-\uFFFF]/)) { - _forceRemove(currentNode); - return true; - } - - /* Now let's check the element's type and name */ - var tagName = stringToLowerCase(currentNode.nodeName); - - /* Execute a hook if present */ - _executeHook('uponSanitizeElement', currentNode, { - tagName: tagName, - allowedTags: ALLOWED_TAGS - }); - - /* Detect mXSS attempts abusing namespace confusion */ - if (!_isNode(currentNode.firstElementChild) && (!_isNode(currentNode.content) || !_isNode(currentNode.content.firstElementChild)) && regExpTest(/<[/\w]/g, currentNode.innerHTML) && regExpTest(/<[/\w]/g, currentNode.textContent)) { - _forceRemove(currentNode); - return true; - } - - /* Mitigate a problem with templates inside select */ - if (tagName === 'select' && regExpTest(/' + dirty + ''; + } + + const dirtyPayload = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty; + /* + * Use the DOMParser API by default, fallback later if needs be + * DOMParser not work for svg when has multiple root element. + */ + + if (NAMESPACE === HTML_NAMESPACE) { + try { + doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE); + } catch (_) { } + } + /* Use createHTMLDocument in case DOMParser is not available */ + + + if (!doc || !doc.documentElement) { + doc = implementation.createDocument(NAMESPACE, 'template', null); + + try { + doc.documentElement.innerHTML = IS_EMPTY_INPUT ? emptyHTML : dirtyPayload; + } catch (_) {// Syntax error if dirtyPayload is invalid xml + } + } + + const body = doc.body || doc.documentElement; + + if (dirty && leadingWhitespace) { + body.insertBefore(document.createTextNode(leadingWhitespace), body.childNodes[0] || null); + } + /* Work on whole document or just its body */ + + + if (NAMESPACE === HTML_NAMESPACE) { + return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0]; + } + + return WHOLE_DOCUMENT ? doc.documentElement : body; + }; + /** + * _createIterator + * + * @param {Document} root document/fragment to create iterator for + * @return {Iterator} iterator instance + */ + + + const _createIterator = function _createIterator(root) { + return createNodeIterator.call(root.ownerDocument || root, root, // eslint-disable-next-line no-bitwise + NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT, null, false); + }; + /** + * _isClobbered + * + * @param {Node} elm element to check for clobbering attacks + * @return {Boolean} true if clobbered, false if safe + */ + + + const _isClobbered = function _isClobbered(elm) { + return elm instanceof HTMLFormElement && (typeof elm.nodeName !== 'string' || typeof elm.textContent !== 'string' || typeof elm.removeChild !== 'function' || !(elm.attributes instanceof NamedNodeMap) || typeof elm.removeAttribute !== 'function' || typeof elm.setAttribute !== 'function' || typeof elm.namespaceURI !== 'string' || typeof elm.insertBefore !== 'function' || typeof elm.hasChildNodes !== 'function'); + }; + /** + * _isNode + * + * @param {Node} obj object to check whether it's a DOM node + * @return {Boolean} true is object is a DOM node + */ + + + const _isNode = function _isNode(object) { + return typeof Node === 'object' ? object instanceof Node : object && typeof object === 'object' && typeof object.nodeType === 'number' && typeof object.nodeName === 'string'; + }; + /** + * _executeHook + * Execute user configurable hooks + * + * @param {String} entryPoint Name of the hook's entry point + * @param {Node} currentNode node to work on with the hook + * @param {Object} data additional hook parameters + */ + + + const _executeHook = function _executeHook(entryPoint, currentNode, data) { + if (!hooks[entryPoint]) { + return; + } + + arrayForEach(hooks[entryPoint], hook => { + hook.call(DOMPurify, currentNode, data, CONFIG); + }); + }; + /** + * _sanitizeElements + * + * @protect nodeName + * @protect textContent + * @protect removeChild + * + * @param {Node} currentNode to check for permission to exist + * @return {Boolean} true if node was killed, false if left alive + */ + + + const _sanitizeElements = function _sanitizeElements(currentNode) { + let content; + /* Execute a hook if present */ + + _executeHook('beforeSanitizeElements', currentNode, null); + /* Check if element is clobbered or can clobber */ + + + if (_isClobbered(currentNode)) { + _forceRemove(currentNode); + + return true; + } + /* Now let's check the element's type and name */ + + + const tagName = transformCaseFunc(currentNode.nodeName); + /* Execute a hook if present */ + + _executeHook('uponSanitizeElement', currentNode, { + tagName, + allowedTags: ALLOWED_TAGS + }); + /* Detect mXSS attempts abusing namespace confusion */ + + + if (currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && (!_isNode(currentNode.content) || !_isNode(currentNode.content.firstElementChild)) && regExpTest(/<[/\w]/g, currentNode.innerHTML) && regExpTest(/<[/\w]/g, currentNode.textContent)) { + _forceRemove(currentNode); + + return true; + } + /* Remove element if anything forbids its presence */ + + + if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) { + /* Check if we have a custom element to handle */ + if (!FORBID_TAGS[tagName] && _basicCustomElementTest(tagName)) { + if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) return false; + if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) return false; + } + /* Keep content except for bad-listed elements */ + + + if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) { + const parentNode = getParentNode(currentNode) || currentNode.parentNode; + const childNodes = getChildNodes(currentNode) || currentNode.childNodes; + + if (childNodes && parentNode) { + const childCount = childNodes.length; + + for (let i = childCount - 1; i >= 0; --i) { + parentNode.insertBefore(cloneNode(childNodes[i], true), getNextSibling(currentNode)); + } + } + } + + _forceRemove(currentNode); + + return true; + } + /* Check whether element has a valid namespace */ + + + if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) { + _forceRemove(currentNode); + + return true; + } + /* Make sure that older browsers don't get fallback-tag mXSS */ + + + if ((tagName === 'noscript' || tagName === 'noembed' || tagName === 'noframes') && regExpTest(/<\/no(script|embed|frames)/i, currentNode.innerHTML)) { + _forceRemove(currentNode); + + return true; + } + /* Sanitize element content to be template-safe */ + + + if (SAFE_FOR_TEMPLATES && currentNode.nodeType === 3) { + /* Get the element's text content */ + content = currentNode.textContent; + content = stringReplace(content, MUSTACHE_EXPR, ' '); + content = stringReplace(content, ERB_EXPR, ' '); + content = stringReplace(content, TMPLIT_EXPR, ' '); + + if (currentNode.textContent !== content) { + arrayPush(DOMPurify.removed, { + element: currentNode.cloneNode() + }); + currentNode.textContent = content; + } + } + /* Execute a hook if present */ + + + _executeHook('afterSanitizeElements', currentNode, null); + + return false; + }; + /** + * _isValidAttribute + * + * @param {string} lcTag Lowercase tag name of containing element. + * @param {string} lcName Lowercase attribute name. + * @param {string} value Attribute value. + * @return {Boolean} Returns true if `value` is valid, otherwise false. + */ + // eslint-disable-next-line complexity + + + const _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) { + /* Make sure attribute cannot clobber */ + if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) { + return false; + } + /* Allow valid data-* attributes: At least one character after "-" + (https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes) + XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804) + We don't need to check the value; it's always URI safe. */ + + + if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR, lcName)); else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR, lcName)); else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) { + if ( // First condition does a very basic check if a) it's basically a valid custom element tagname AND + // b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck + // and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck + _basicCustomElementTest(lcTag) && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag)) && (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName) || CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName)) || // Alternative, second condition checks if it's an `is`-attribute, AND + // the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck + lcName === 'is' && CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(value))); else { + return false; + } + /* Check value is safe. First, is attr inert? If so, is safe */ + + } else if (URI_SAFE_ATTRIBUTES[lcName]); else if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE, ''))); else if ((lcName === 'src' || lcName === 'xlink:href' || lcName === 'href') && lcTag !== 'script' && stringIndexOf(value, 'data:') === 0 && DATA_URI_TAGS[lcTag]); else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA, stringReplace(value, ATTR_WHITESPACE, ''))); else if (value) { + return false; + } else; + + return true; + }; + /** + * _basicCustomElementCheck + * checks if at least one dash is included in tagName, and it's not the first char + * for more sophisticated checking see https://github.com/sindresorhus/validate-element-name + * @param {string} tagName name of the tag of the node to sanitize + */ + + + const _basicCustomElementTest = function _basicCustomElementTest(tagName) { + return tagName.indexOf('-') > 0; + }; + /** + * _sanitizeAttributes + * + * @protect attributes + * @protect nodeName + * @protect removeAttribute + * @protect setAttribute + * + * @param {Node} currentNode to sanitize + */ + + + const _sanitizeAttributes = function _sanitizeAttributes(currentNode) { + let attr; + let value; + let lcName; + let l; + /* Execute a hook if present */ + + _executeHook('beforeSanitizeAttributes', currentNode, null); + + const { + attributes + } = currentNode; + /* Check if we have attributes; if not we might have a text node */ + + if (!attributes) { + return; + } + + const hookEvent = { + attrName: '', + attrValue: '', + keepAttr: true, + allowedAttributes: ALLOWED_ATTR + }; + l = attributes.length; + /* Go backwards over all attributes; safely remove bad ones */ + + while (l--) { + attr = attributes[l]; + const { + name, + namespaceURI + } = attr; + value = name === 'value' ? attr.value : stringTrim(attr.value); + lcName = transformCaseFunc(name); + /* Execute a hook if present */ + + hookEvent.attrName = lcName; + hookEvent.attrValue = value; + hookEvent.keepAttr = true; + hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set + + _executeHook('uponSanitizeAttribute', currentNode, hookEvent); + + value = hookEvent.attrValue; + /* Did the hooks approve of the attribute? */ + + if (hookEvent.forceKeepAttr) { + continue; + } + /* Remove attribute */ + + + _removeAttribute(name, currentNode); + /* Did the hooks approve of the attribute? */ + + + if (!hookEvent.keepAttr) { + continue; + } + /* Work around a security issue in jQuery 3.0 */ + + + if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(/\/>/i, value)) { + _removeAttribute(name, currentNode); + + continue; + } + /* Sanitize attribute content to be template-safe */ + + + if (SAFE_FOR_TEMPLATES) { + value = stringReplace(value, MUSTACHE_EXPR, ' '); + value = stringReplace(value, ERB_EXPR, ' '); + value = stringReplace(value, TMPLIT_EXPR, ' '); + } + /* Is `value` valid for this attribute? */ + + + const lcTag = transformCaseFunc(currentNode.nodeName); + + if (!_isValidAttribute(lcTag, lcName, value)) { + continue; + } + /* Full DOM Clobbering protection via namespace isolation, + * Prefix id and name attributes with `user-content-` + */ + + + if (SANITIZE_NAMED_PROPS && (lcName === 'id' || lcName === 'name')) { + // Remove the attribute with this value + _removeAttribute(name, currentNode); // Prefix the value and later re-create the attribute with the sanitized value + + + value = SANITIZE_NAMED_PROPS_PREFIX + value; + } + /* Handle attributes that require Trusted Types */ + + + if (trustedTypesPolicy && typeof trustedTypes === 'object' && typeof trustedTypes.getAttributeType === 'function') { + if (namespaceURI); else { + switch (trustedTypes.getAttributeType(lcTag, lcName)) { + case 'TrustedHTML': + { + value = trustedTypesPolicy.createHTML(value); + break; + } + + case 'TrustedScriptURL': + { + value = trustedTypesPolicy.createScriptURL(value); + break; + } + } + } + } + /* Handle invalid data-* attribute set by try-catching it */ + + + try { + if (namespaceURI) { + currentNode.setAttributeNS(namespaceURI, name, value); + } else { + /* Fallback to setAttribute() for browser-unrecognized namespaces e.g. "x-schema". */ + currentNode.setAttribute(name, value); + } + + arrayPop(DOMPurify.removed); + } catch (_) { } + } + /* Execute a hook if present */ + + + _executeHook('afterSanitizeAttributes', currentNode, null); + }; + /** + * _sanitizeShadowDOM + * + * @param {DocumentFragment} fragment to iterate over recursively + */ + + + const _sanitizeShadowDOM = function _sanitizeShadowDOM(fragment) { + let shadowNode; + + const shadowIterator = _createIterator(fragment); + /* Execute a hook if present */ + + + _executeHook('beforeSanitizeShadowDOM', fragment, null); + + while (shadowNode = shadowIterator.nextNode()) { + /* Execute a hook if present */ + _executeHook('uponSanitizeShadowNode', shadowNode, null); + /* Sanitize tags and elements */ + + + if (_sanitizeElements(shadowNode)) { + continue; + } + /* Deep shadow DOM detected */ + + + if (shadowNode.content instanceof DocumentFragment) { + _sanitizeShadowDOM(shadowNode.content); + } + /* Check attributes, sanitize if necessary */ + + + _sanitizeAttributes(shadowNode); + } + /* Execute a hook if present */ + + + _executeHook('afterSanitizeShadowDOM', fragment, null); + }; + /** + * Sanitize + * Public method providing core sanitation functionality + * + * @param {String|Node} dirty string or DOM node + * @param {Object} configuration object + */ + // eslint-disable-next-line complexity + + + DOMPurify.sanitize = function (dirty) { + let cfg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + let body; + let importedNode; + let currentNode; + let returnNode; + /* Make sure we have a string to sanitize. + DO NOT return early, as this will return the wrong type if + the user has requested a DOM object rather than a string */ + + IS_EMPTY_INPUT = !dirty; + + if (IS_EMPTY_INPUT) { + dirty = ''; + } + /* Stringify, in case dirty is an object */ + + + if (typeof dirty !== 'string' && !_isNode(dirty)) { + if (typeof dirty.toString === 'function') { + dirty = dirty.toString(); + + if (typeof dirty !== 'string') { + throw typeErrorCreate('dirty is not a string, aborting'); + } + } else { + throw typeErrorCreate('toString is not a function'); + } + } + /* Return dirty HTML if DOMPurify cannot run */ + + + if (!DOMPurify.isSupported) { + return dirty; + } + /* Assign config vars */ + + + if (!SET_CONFIG) { + _parseConfig(cfg); + } + /* Clean up removed elements */ + + + DOMPurify.removed = []; + /* Check if dirty is correctly typed for IN_PLACE */ + + if (typeof dirty === 'string') { + IN_PLACE = false; + } + + if (IN_PLACE) { + /* Do some early pre-sanitization to avoid unsafe root nodes */ + if (dirty.nodeName) { + const tagName = transformCaseFunc(dirty.nodeName); + + if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) { + throw typeErrorCreate('root node is forbidden and cannot be sanitized in-place'); + } + } + } else if (dirty instanceof Node) { + /* If dirty is a DOM element, append to an empty document to avoid + elements being stripped by the parser */ + body = _initDocument(''); + importedNode = body.ownerDocument.importNode(dirty, true); + + if (importedNode.nodeType === 1 && importedNode.nodeName === 'BODY') { + /* Node is already a body, use as is */ + body = importedNode; + } else if (importedNode.nodeName === 'HTML') { + body = importedNode; + } else { + // eslint-disable-next-line unicorn/prefer-dom-node-append + body.appendChild(importedNode); + } + } else { + /* Exit directly if we have nothing to do */ + if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT && // eslint-disable-next-line unicorn/prefer-includes + dirty.indexOf('<') === -1) { + return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(dirty) : dirty; + } + /* Initialize the document to work on */ + + + body = _initDocument(dirty); + /* Check we have a DOM node from the data */ + + if (!body) { + return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : ''; + } + } + /* Remove first element node (ours) if FORCE_BODY is set */ + + + if (body && FORCE_BODY) { + _forceRemove(body.firstChild); + } + /* Get node iterator */ + + + const nodeIterator = _createIterator(IN_PLACE ? dirty : body); + /* Now start iterating over the created document */ + + + while (currentNode = nodeIterator.nextNode()) { + /* Sanitize tags and elements */ + if (_sanitizeElements(currentNode)) { + continue; + } + /* Shadow DOM detected, sanitize it */ + + + if (currentNode.content instanceof DocumentFragment) { + _sanitizeShadowDOM(currentNode.content); + } + /* Check attributes, sanitize if necessary */ + + + _sanitizeAttributes(currentNode); + } + /* If we sanitized `dirty` in-place, return it. */ + + + if (IN_PLACE) { + return dirty; + } + /* Return sanitized string or DOM */ + + + if (RETURN_DOM) { + if (RETURN_DOM_FRAGMENT) { + returnNode = createDocumentFragment.call(body.ownerDocument); + + while (body.firstChild) { + // eslint-disable-next-line unicorn/prefer-dom-node-append + returnNode.appendChild(body.firstChild); + } + } else { + returnNode = body; + } + + if (ALLOWED_ATTR.shadowroot || ALLOWED_ATTR.shadowrootmode) { + /* + AdoptNode() is not used because internal state is not reset + (e.g. the past names map of a HTMLFormElement), this is safe + in theory but we would rather not risk another attack vector. + The state that is cloned by importNode() is explicitly defined + by the specs. + */ + returnNode = importNode.call(originalDocument, returnNode, true); + } + + return returnNode; + } + + let serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML; + /* Serialize doctype if allowed */ + + if (WHOLE_DOCUMENT && ALLOWED_TAGS['!doctype'] && body.ownerDocument && body.ownerDocument.doctype && body.ownerDocument.doctype.name && regExpTest(DOCTYPE_NAME, body.ownerDocument.doctype.name)) { + serializedHTML = '\n' + serializedHTML; + } + /* Sanitize final string template-safe */ + + + if (SAFE_FOR_TEMPLATES) { + serializedHTML = stringReplace(serializedHTML, MUSTACHE_EXPR, ' '); + serializedHTML = stringReplace(serializedHTML, ERB_EXPR, ' '); + serializedHTML = stringReplace(serializedHTML, TMPLIT_EXPR, ' '); + } + + return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(serializedHTML) : serializedHTML; + }; + /** + * Public method to set the configuration once + * setConfig + * + * @param {Object} cfg configuration object + */ + + + DOMPurify.setConfig = function (cfg) { + _parseConfig(cfg); + + SET_CONFIG = true; + }; + /** + * Public method to remove the configuration + * clearConfig + * + */ + + + DOMPurify.clearConfig = function () { + CONFIG = null; + SET_CONFIG = false; + }; + /** + * Public method to check if an attribute value is valid. + * Uses last set config, if any. Otherwise, uses config defaults. + * isValidAttribute + * + * @param {string} tag Tag name of containing element. + * @param {string} attr Attribute name. + * @param {string} value Attribute value. + * @return {Boolean} Returns true if `value` is valid. Otherwise, returns false. + */ + + + DOMPurify.isValidAttribute = function (tag, attr, value) { + /* Initialize shared config vars if necessary. */ + if (!CONFIG) { + _parseConfig({}); + } + + const lcTag = transformCaseFunc(tag); + const lcName = transformCaseFunc(attr); + return _isValidAttribute(lcTag, lcName, value); + }; + /** + * AddHook + * Public method to add DOMPurify hooks + * + * @param {String} entryPoint entry point for the hook to add + * @param {Function} hookFunction function to execute + */ + + + DOMPurify.addHook = function (entryPoint, hookFunction) { + if (typeof hookFunction !== 'function') { + return; + } + + hooks[entryPoint] = hooks[entryPoint] || []; + arrayPush(hooks[entryPoint], hookFunction); + }; + /** + * RemoveHook + * Public method to remove a DOMPurify hook at a given entryPoint + * (pops it from the stack of hooks if more are present) + * + * @param {String} entryPoint entry point for the hook to remove + * @return {Function} removed(popped) hook + */ + + + DOMPurify.removeHook = function (entryPoint) { + if (hooks[entryPoint]) { + return arrayPop(hooks[entryPoint]); + } + }; + /** + * RemoveHooks + * Public method to remove all DOMPurify hooks at a given entryPoint + * + * @param {String} entryPoint entry point for the hooks to remove + */ + + + DOMPurify.removeHooks = function (entryPoint) { + if (hooks[entryPoint]) { + hooks[entryPoint] = []; + } + }; + /** + * RemoveAllHooks + * Public method to remove all DOMPurify hooks + * + */ + + + DOMPurify.removeAllHooks = function () { + hooks = {}; + }; + + return DOMPurify; } var purify = createDOMPurify(); diff --git a/src/vs/base/browser/ui/actionbar/actionbar.ts b/src/vs/base/browser/ui/actionbar/actionbar.ts index c09670b422429..dd46e532100c1 100644 --- a/src/vs/base/browser/ui/actionbar/actionbar.ts +++ b/src/vs/base/browser/ui/actionbar/actionbar.ts @@ -51,6 +51,12 @@ export interface IActionBarOptions { readonly preventLoopNavigation?: boolean; readonly focusOnlyEnabledItems?: boolean; readonly hoverDelegate?: IHoverDelegate; + /** + * If true, toggled primary items are highlighted with a background color. + * Some action bars exclusively use icon states, we don't want to enable this for them. + * Thus, this is opt-in. + */ + readonly highlightToggledItems?: boolean; } export interface IActionOptions extends IActionViewItemOptions { @@ -203,8 +209,8 @@ export class ActionBar extends Disposable implements IActionRunner { this._register(this.focusTracker.onDidBlur(() => { if (DOM.getActiveElement() === this.domNode || !DOM.isAncestor(DOM.getActiveElement(), this.domNode)) { this._onDidBlur.fire(); + this.previouslyFocusedItem = this.focusedItem; this.focusedItem = undefined; - this.previouslyFocusedItem = undefined; this.triggerKeyDown = false; } })); @@ -213,6 +219,9 @@ export class ActionBar extends Disposable implements IActionRunner { this.actionsList = document.createElement('ul'); this.actionsList.className = 'actions-container'; + if (this.options.highlightToggledItems) { + this.actionsList.classList.add('highlight-toggled'); + } this.actionsList.setAttribute('role', this.options.ariaRole || 'toolbar'); if (this.options.ariaLabel) { diff --git a/src/vs/base/browser/ui/aria/aria.ts b/src/vs/base/browser/ui/aria/aria.ts index a4da8d7844560..d0b5b3aab2191 100644 --- a/src/vs/base/browser/ui/aria/aria.ts +++ b/src/vs/base/browser/ui/aria/aria.ts @@ -31,7 +31,6 @@ export function setARIAContainer(parent: HTMLElement) { const createStatusContainer = () => { const element = document.createElement('div'); element.className = 'monaco-status'; - element.setAttribute('role', 'complementary'); element.setAttribute('aria-live', 'polite'); element.setAttribute('aria-atomic', 'true'); ariaContainer.appendChild(element); diff --git a/src/vs/base/browser/ui/codicons/codicon/codicon.ttf b/src/vs/base/browser/ui/codicons/codicon/codicon.ttf index c4a33a4d5669d..b5623b0a55c72 100644 Binary files a/src/vs/base/browser/ui/codicons/codicon/codicon.ttf and b/src/vs/base/browser/ui/codicons/codicon/codicon.ttf differ diff --git a/src/vs/base/browser/ui/contextview/contextview.ts b/src/vs/base/browser/ui/contextview/contextview.ts index 04931cca3f09d..d2c9f9464ae5d 100644 --- a/src/vs/base/browser/ui/contextview/contextview.ts +++ b/src/vs/base/browser/ui/contextview/contextview.ts @@ -5,9 +5,11 @@ import { BrowserFeatures } from 'vs/base/browser/canIUse'; import * as DOM from 'vs/base/browser/dom'; +import { StandardMouseEvent } from 'vs/base/browser/mouseEvent'; import { Disposable, DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; import * as platform from 'vs/base/common/platform'; import { Range } from 'vs/base/common/range'; +import { OmitOptional } from 'vs/base/common/types'; import 'vs/css!./contextview'; export const enum ContextViewDOMPosition { @@ -23,6 +25,12 @@ export interface IAnchor { height?: number; } +export function isAnchor(obj: unknown): obj is IAnchor | OmitOptional { + const anchor = obj as IAnchor | OmitOptional | undefined; + + return !!anchor && typeof anchor.x === 'number' && typeof anchor.y === 'number'; +} + export const enum AnchorAlignment { LEFT, RIGHT } @@ -36,7 +44,13 @@ export const enum AnchorAxisAlignment { } export interface IDelegate { - getAnchor(): HTMLElement | IAnchor; + /** + * The anchor where to position the context view. + * Use a `HTMLElement` to position the view at the element, + * a `StandardMouseEvent` to position it at the mouse position + * or an `IAnchor` to position it at a specific location. + */ + getAnchor(): HTMLElement | StandardMouseEvent | IAnchor; render(container: HTMLElement): IDisposable | null; focus?(): void; layout?(): void; @@ -271,13 +285,24 @@ export class ContextView extends Disposable { width: elementPosition.width * zoom, height: elementPosition.height * zoom }; - } else { + } else if (isAnchor(anchor)) { around = { top: anchor.y, left: anchor.x, width: anchor.width || 1, height: anchor.height || 2 }; + } else { + around = { + top: anchor.posy, + left: anchor.posx, + // We are about to position the context view where the mouse + // cursor is. To prevent the view being exactly under the mouse + // when showing and thus potentially triggering an action within, + // we treat the mouse location like a small sized block element. + width: 2, + height: 2 + }; } const viewSizeWidth = DOM.getTotalWidth(this.view); diff --git a/src/vs/base/browser/ui/grid/grid.ts b/src/vs/base/browser/ui/grid/grid.ts index aee3cad23012e..2562b2fa153e4 100644 --- a/src/vs/base/browser/ui/grid/grid.ts +++ b/src/vs/base/browser/ui/grid/grid.ts @@ -455,7 +455,8 @@ export class Grid extends Disposable { if (sizing?.type === 'distribute') { gridViewSizing = GridViewSizing.Distribute; } else if (sizing?.type === 'auto') { - gridViewSizing = GridViewSizing.Auto(0); + const index = location[location.length - 1]; + gridViewSizing = GridViewSizing.Auto(index === 0 ? 1 : index - 1); } this.gridview.removeView(location, gridViewSizing); diff --git a/src/vs/base/browser/ui/grid/gridview.ts b/src/vs/base/browser/ui/grid/gridview.ts index c89c6a7a063f1..9445c64286a63 100644 --- a/src/vs/base/browser/ui/grid/gridview.ts +++ b/src/vs/base/browser/ui/grid/gridview.ts @@ -705,6 +705,7 @@ class BranchNode implements ISplitView, IDisposable { this.splitviewSashResetDisposable.dispose(); this.childrenSashResetDisposable.dispose(); this.childrenChangeDisposable.dispose(); + this.onDidScrollDisposable.dispose(); this.splitview.dispose(); } } diff --git a/src/vs/base/browser/ui/hover/hover.css b/src/vs/base/browser/ui/hover/hover.css index 0ce581993549b..ee294b766fba4 100644 --- a/src/vs/base/browser/ui/hover/hover.css +++ b/src/vs/base/browser/ui/hover/hover.css @@ -12,6 +12,7 @@ box-sizing: border-box; animation: fadein 100ms linear; line-height: 1.5em; + white-space: var(--vscode-hover-whiteSpace, normal); } .monaco-hover.hidden { @@ -27,7 +28,7 @@ } .monaco-hover .markdown-hover > .hover-contents:not(.code-hover-contents) { - max-width: 500px; + max-width: var(--vscode-hover-maxWidth, 500px); word-wrap: break-word; } @@ -105,7 +106,7 @@ } .monaco-hover .monaco-tokenized-source { - white-space: pre-wrap; + white-space: var(--vscode-hover-sourceWhiteSpace, pre-wrap); } .monaco-hover .hover-row.status-bar { diff --git a/src/vs/base/browser/ui/hover/hoverWidget.ts b/src/vs/base/browser/ui/hover/hoverWidget.ts index 96e99cbec4a2f..dc0af66ff5a13 100644 --- a/src/vs/base/browser/ui/hover/hoverWidget.ts +++ b/src/vs/base/browser/ui/hover/hoverWidget.ts @@ -9,6 +9,7 @@ import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableEle import { KeyCode } from 'vs/base/common/keyCodes'; import { Disposable } from 'vs/base/common/lifecycle'; import 'vs/css!./hover'; +import { localize } from 'vs/nls'; const $ = dom.$; @@ -94,3 +95,7 @@ export class HoverAction extends Disposable { } } } + +export function getHoverAccessibleViewHint(shouldHaveHint?: boolean, keybinding?: string | null): string | undefined { + return shouldHaveHint && keybinding ? localize('acessibleViewHint', "Inspect this in the accessible view with {0}.", keybinding) : shouldHaveHint ? localize('acessibleViewHintNoKbOpen', "Inspect this in the accessible view via the command Open Accessible View which is currently not triggerable via keybinding.") : ''; +} diff --git a/src/vs/base/browser/ui/iconLabel/iconLabel.ts b/src/vs/base/browser/ui/iconLabel/iconLabel.ts index 599abeaf6a177..980be904fa46c 100644 --- a/src/vs/base/browser/ui/iconLabel/iconLabel.ts +++ b/src/vs/base/browser/ui/iconLabel/iconLabel.ts @@ -120,6 +120,7 @@ export class IconLabel extends Disposable { setLabel(label: string | string[], description?: string, options?: IIconLabelValueOptions): void { const labelClasses = ['monaco-icon-label']; const containerClasses = ['monaco-icon-label-container']; + let ariaLabel: string = ''; if (options) { if (options.extraClasses) { labelClasses.push(...options.extraClasses); @@ -136,9 +137,13 @@ export class IconLabel extends Disposable { if (options.disabledCommand) { containerClasses.push('disabled'); } + if (options.title) { + ariaLabel += options.title; + } } this.domNode.className = labelClasses.join(' '); + this.domNode.element.setAttribute('aria-label', ariaLabel); this.labelContainer.className = containerClasses.join(' '); this.setupHover(options?.descriptionTitle ? this.labelContainer : this.element, options?.title); diff --git a/src/vs/base/browser/ui/list/list.ts b/src/vs/base/browser/ui/list/list.ts index f776ba7ecb2ea..2a77409cd830f 100644 --- a/src/vs/base/browser/ui/list/list.ts +++ b/src/vs/base/browser/ui/list/list.ts @@ -5,6 +5,7 @@ import { IDragAndDropData } from 'vs/base/browser/dnd'; import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent'; +import { IMouseEvent } from 'vs/base/browser/mouseEvent'; import { GestureEvent } from 'vs/base/browser/touch'; export interface IListVirtualDelegate { @@ -61,7 +62,7 @@ export interface IListContextMenuEvent { readonly browserEvent: UIEvent; readonly element: T | undefined; readonly index: number | undefined; - readonly anchor: HTMLElement | { readonly x: number; readonly y: number }; + readonly anchor: HTMLElement | IMouseEvent; } export interface IIdentityProvider { diff --git a/src/vs/base/browser/ui/list/listWidget.ts b/src/vs/base/browser/ui/list/listWidget.ts index e8ec5372e18f5..ee900068b4b2e 100644 --- a/src/vs/base/browser/ui/list/listWidget.ts +++ b/src/vs/base/browser/ui/list/listWidget.ts @@ -16,7 +16,7 @@ import { timeout } from 'vs/base/common/async'; import { Color } from 'vs/base/common/color'; import { memoize } from 'vs/base/common/decorators'; import { Emitter, Event, EventBufferer } from 'vs/base/common/event'; -import { matchesPrefix } from 'vs/base/common/filters'; +import { matchesFuzzy2, matchesPrefix } from 'vs/base/common/filters'; import { KeyCode } from 'vs/base/common/keyCodes'; import { DisposableStore, dispose, IDisposable } from 'vs/base/common/lifecycle'; import { clamp } from 'vs/base/common/numbers'; @@ -27,6 +27,7 @@ import { isNumber } from 'vs/base/common/types'; import 'vs/css!./list'; import { IIdentityProvider, IKeyboardNavigationDelegate, IKeyboardNavigationLabelProvider, IListContextMenuEvent, IListDragAndDrop, IListDragOverReaction, IListEvent, IListGestureEvent, IListMouseEvent, IListRenderer, IListTouchEvent, IListVirtualDelegate, ListError } from './list'; import { IListView, IListViewAccessibilityProvider, IListViewDragAndDrop, IListViewOptions, IListViewOptionsUpdate, ListView } from './listView'; +import { StandardMouseEvent } from 'vs/base/browser/mouseEvent'; interface ITraitChangeEvent { indexes: number[]; @@ -526,11 +527,27 @@ class TypeNavigationController implements IDisposable { const label = this.keyboardNavigationLabelProvider.getKeyboardNavigationLabel(this.view.element(index)); const labelStr = label && label.toString(); - if (typeof labelStr === 'undefined' || matchesPrefix(word, labelStr)) { - this.previouslyFocused = start; - this.list.setFocus([index]); - this.list.reveal(index); - return; + if (this.list.options.typeNavigationEnabled) { + if (typeof labelStr !== 'undefined') { + const prefix = matchesPrefix(word, labelStr); + const fuzzy = matchesFuzzy2(word, labelStr); + + // ensures that when fuzzy matching, it doesn't clash with prefix matching (1 input vs 1+ should be prefix and fuzzy respecitvely) + const fuzzyScore = fuzzy ? fuzzy[0].end - fuzzy[0].start : 0; + if (prefix || fuzzyScore > 1) { + this.previouslyFocused = start; + this.list.setFocus([index]); + this.list.reveal(index); + return; + } + } + } else { + if (typeof labelStr === 'undefined' || matchesPrefix(word, labelStr)) { + this.previouslyFocused = start; + this.list.setFocus([index]); + this.list.reveal(index); + return; + } } } } @@ -977,6 +994,7 @@ export interface IListOptions extends IListOptionsUpdate { readonly keyboardNavigationLabelProvider?: IKeyboardNavigationLabelProvider; readonly keyboardNavigationDelegate?: IKeyboardNavigationDelegate; readonly keyboardSupport?: boolean; + readonly keyboardNavigationEnabled?: boolean; readonly multipleSelectionController?: IMultipleSelectionController; readonly styleController?: (suffix: string) => IStyleController; readonly accessibilityProvider?: IListAccessibilityProvider; @@ -1354,7 +1372,7 @@ export class List implements ISpliceable, IDisposable { const fromMouse = this.disposables.add(Event.chain(this.view.onContextMenu)) .filter(_ => !didJustPressContextMenuKey) - .map(({ element, index, browserEvent }) => ({ element, index, anchor: { x: browserEvent.pageX + 1, y: browserEvent.pageY }, browserEvent })) + .map(({ element, index, browserEvent }) => ({ element, index, anchor: new StandardMouseEvent(browserEvent), browserEvent })) .event; return Event.any>(fromKeyDown, fromKeyUp, fromMouse); diff --git a/src/vs/base/browser/ui/menu/menu.ts b/src/vs/base/browser/ui/menu/menu.ts index 697a5102b7c57..9f09c7565e4c2 100644 --- a/src/vs/base/browser/ui/menu/menu.ts +++ b/src/vs/base/browser/ui/menu/menu.ts @@ -1288,7 +1288,7 @@ ${formatRule(Codicon.menuSubmenu)} padding: 0 1.8em; } -.linux .monaco-menu .monaco-action-bar.vertical .submenu-indicator { +.linux .monaco-menu .monaco-action-bar.vertical .submenu-indicator, :host-context(.linux) .monaco-menu .monaco-action-bar.vertical .submenu-indicator { height: 100%; mask-size: 10px 10px; diff --git a/src/vs/base/browser/ui/menu/menubar.ts b/src/vs/base/browser/ui/menu/menubar.ts index fe7586f0d563f..061003dbc9a43 100644 --- a/src/vs/base/browser/ui/menu/menubar.ts +++ b/src/vs/base/browser/ui/menu/menubar.ts @@ -20,7 +20,6 @@ import { ResolvedKeybinding } from 'vs/base/common/keybindings'; import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle'; import { isMacintosh } from 'vs/base/common/platform'; import * as strings from 'vs/base/common/strings'; -import { withNullAsUndefined } from 'vs/base/common/types'; import 'vs/css!./menubar'; import * as nls from 'vs/nls'; @@ -1020,7 +1019,7 @@ export class MenuBar extends Disposable { getKeyBinding: this.options.getKeybinding, actionRunner: this.actionRunner, enableMnemonics: this.options.alwaysOnMnemonics || (this.mnemonicsInUse && this.options.enableMnemonics), - ariaLabel: withNullAsUndefined(customMenu.buttonElement.getAttribute('aria-label')), + ariaLabel: customMenu.buttonElement.getAttribute('aria-label') ?? undefined, expandDirection: this.isCompact ? this.options.compactMode : Direction.Right, useEventAsContext: true }; diff --git a/src/vs/base/browser/ui/scrollbar/scrollableElement.ts b/src/vs/base/browser/ui/scrollbar/scrollableElement.ts index 5cf11ce785447..45a3b751e41c1 100644 --- a/src/vs/base/browser/ui/scrollbar/scrollableElement.ts +++ b/src/vs/base/browser/ui/scrollbar/scrollableElement.ts @@ -391,7 +391,13 @@ export abstract class AbstractScrollableElement extends Widget { let deltaX = e.deltaX * this._options.mouseWheelScrollSensitivity; if (this._options.scrollPredominantAxis) { - if (Math.abs(deltaY) >= Math.abs(deltaX)) { + if (this._options.scrollYToX && deltaX + deltaY === 0) { + // when configured to map Y to X and we both see + // no dominant axis and X and Y are competing with + // identical values into opposite directions, we + // ignore the delta as we cannot make a decision then + deltaX = deltaY = 0; + } else if (Math.abs(deltaY) >= Math.abs(deltaX)) { deltaX = 0; } else { deltaY = 0; diff --git a/src/vs/base/browser/ui/splitview/splitview.ts b/src/vs/base/browser/ui/splitview/splitview.ts index a4edaa6a3d900..28f18d4253713 100644 --- a/src/vs/base/browser/ui/splitview/splitview.ts +++ b/src/vs/base/browser/ui/splitview/splitview.ts @@ -259,7 +259,7 @@ abstract class ViewItem { constructor( protected container: HTMLElement, - private view: IView, + readonly view: IView, size: ViewItemSize, private disposable: IDisposable ) { @@ -280,9 +280,8 @@ abstract class ViewItem { abstract layoutContainer(offset: number): void; - dispose(): IView { + dispose(): void { this.disposable.dispose(); - return this.view; } } @@ -566,11 +565,11 @@ export class SplitView extends Disposable { this.sashContainer = append(this.el, $('.sash-container')); this.viewContainer = $('.split-view-container'); - this.scrollable = new Scrollable({ + this.scrollable = this._register(new Scrollable({ forceIntegerValues: true, smoothScrollDuration: 125, scheduleAtNextAnimationFrame - }); + })); this.scrollableElement = this._register(new SmoothScrollableElement(this.viewContainer, { vertical: this.orientation === Orientation.VERTICAL ? (options.scrollbarVisibility ?? ScrollbarVisibility.Auto) : ScrollbarVisibility.Hidden, horizontal: this.orientation === Orientation.HORIZONTAL ? (options.scrollbarVisibility ?? ScrollbarVisibility.Auto) : ScrollbarVisibility.Hidden @@ -662,13 +661,20 @@ export class SplitView extends Disposable { if (this.areViewsDistributed()) { sizing = { type: 'distribute' }; } else { - sizing = undefined; + sizing = { type: 'split', index: sizing.index }; } } + // Save referene view, in case of `split` sizing + const referenceViewItem = sizing?.type === 'split' ? this.viewItems[sizing.index] : undefined; + // Remove view - const viewItem = this.viewItems.splice(index, 1)[0]; - const view = viewItem.dispose(); + const viewItemToRemove = this.viewItems.splice(index, 1)[0]; + + // Resize reference view, in case of `split` sizing + if (referenceViewItem) { + referenceViewItem.size += viewItemToRemove.size; + } // Remove sash if (this.viewItems.length >= 1) { @@ -684,7 +690,9 @@ export class SplitView extends Disposable { this.distributeViewSizes(); } - return view; + const result = viewItemToRemove.view; + viewItemToRemove.dispose(); + return result; } /** diff --git a/src/vs/base/browser/ui/toolbar/toolbar.ts b/src/vs/base/browser/ui/toolbar/toolbar.ts index 85936d72ce613..bcb90361b41e8 100644 --- a/src/vs/base/browser/ui/toolbar/toolbar.ts +++ b/src/vs/base/browser/ui/toolbar/toolbar.ts @@ -13,7 +13,6 @@ import { ThemeIcon } from 'vs/base/common/themables'; import { EventMultiplexer } from 'vs/base/common/event'; import { ResolvedKeybinding } from 'vs/base/common/keybindings'; import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; -import { withNullAsUndefined } from 'vs/base/common/types'; import 'vs/css!./toolbar'; import * as nls from 'vs/nls'; @@ -31,6 +30,11 @@ export interface IToolBarOptions { moreIcon?: ThemeIcon; allowContextMenu?: boolean; skipTelemetry?: boolean; + + /** + * If true, toggled primary items are highlighted with a background color. + */ + highlightToggledItems?: boolean; } /** @@ -48,7 +52,7 @@ export class ToolBar extends Disposable { private _onDidChangeDropdownVisibility = this._register(new EventMultiplexer()); readonly onDidChangeDropdownVisibility = this._onDidChangeDropdownVisibility.event; - private disposables = new DisposableStore(); + private disposables = this._register(new DisposableStore()); constructor(container: HTMLElement, contextMenuProvider: IContextMenuProvider, options: IToolBarOptions = { orientation: ActionsOrientation.HORIZONTAL }) { super(); @@ -67,6 +71,7 @@ export class ToolBar extends Disposable { ariaLabel: options.ariaLabel, actionRunner: options.actionRunner, allowContextMenu: options.allowContextMenu, + highlightToggledItems: options.highlightToggledItems, actionViewItemProvider: (action, viewItemOptions) => { if (action.id === ToggleMenuAction.ID) { this.toggleMenuActionViewItem = new DropdownMenuActionViewItem( @@ -196,7 +201,7 @@ export class ToolBar extends Disposable { private getKeybindingLabel(action: IAction): string | undefined { const key = this.lookupKeybindings ? this.options.getKeyBinding?.(action) : undefined; - return withNullAsUndefined(key?.getLabel()); + return key?.getLabel() ?? undefined; } private clear(): void { diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index 3591193bab95a..70199a8164c80 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -1218,7 +1218,7 @@ export interface IAbstractTreeOptions extends IAbstractTr readonly collapseByDefault?: boolean; // defaults to false readonly filter?: ITreeFilter; readonly dnd?: ITreeDragAndDrop; - readonly additionalScrollHeight?: number; + readonly paddingBottom?: number; readonly findWidgetEnabled?: boolean; readonly findWidgetStyles?: IFindWidgetStyles; readonly defaultFindVisibility?: TreeVisibility | ((e: T) => TreeVisibility); diff --git a/src/vs/base/browser/ui/tree/tree.ts b/src/vs/base/browser/ui/tree/tree.ts index 94e8650f2defa..262badedf9fd2 100644 --- a/src/vs/base/browser/ui/tree/tree.ts +++ b/src/vs/base/browser/ui/tree/tree.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { IDragAndDropData } from 'vs/base/browser/dnd'; +import { IMouseEvent } from 'vs/base/browser/mouseEvent'; import { IListDragAndDrop, IListDragOverReaction, IListRenderer, ListDragOverEffect } from 'vs/base/browser/ui/list/list'; import { Event } from 'vs/base/common/event'; @@ -176,7 +177,7 @@ export interface ITreeMouseEvent { export interface ITreeContextMenuEvent { readonly browserEvent: UIEvent; readonly element: T | null; - readonly anchor: HTMLElement | { readonly x: number; readonly y: number }; + readonly anchor: HTMLElement | IMouseEvent; } export interface ITreeNavigator { diff --git a/src/vs/base/common/arrays.ts b/src/vs/base/common/arrays.ts index c22e14f3b7dea..22c2859f5e9e0 100644 --- a/src/vs/base/common/arrays.ts +++ b/src/vs/base/common/arrays.ts @@ -398,14 +398,14 @@ export function uniqueFilter(keyFn: (t: T) => R): (t: T) => boolean { } export function findLast(arr: readonly T[], predicate: (item: T) => boolean): T | undefined { - const idx = lastIndex(arr, predicate); + const idx = findLastIndex(arr, predicate); if (idx === -1) { return undefined; } return arr[idx]; } -export function lastIndex(array: ReadonlyArray, fn: (item: T) => boolean): number { +export function findLastIndex(array: ReadonlyArray, fn: (item: T) => boolean): number { for (let i = array.length - 1; i >= 0; i--) { const element = array[i]; @@ -707,6 +707,12 @@ export function tieBreakComparators(...comparators: Comparator[]): */ export const numberComparator: Comparator = (a, b) => a - b; +export const booleanComparator: Comparator = (a, b) => numberComparator(a ? 1 : 0, b ? 1 : 0); + +export function reverseOrder(comparator: Comparator): Comparator { + return (a, b) => -comparator(a, b); +} + /** * Returns the first item that is equal to or greater than every other item. */ @@ -750,6 +756,21 @@ export function findMinBy(items: readonly T[], comparator: Comparator): T return findMaxBy(items, (a, b) => -comparator(a, b)); } +export function findMaxIdxBy(items: readonly T[], comparator: Comparator): number { + if (items.length === 0) { + return -1; + } + + let maxIdx = 0; + for (let i = 1; i < items.length; i++) { + const item = items[i]; + if (comparator(item, items[maxIdx]) > 0) { + maxIdx = i; + } + } + return maxIdx; +} + export class ArrayQueue { private firstIdx = 0; private lastIdx = this.items.length - 1; diff --git a/src/vs/base/common/buffer.ts b/src/vs/base/common/buffer.ts index ff61eb5c9e253..08736ab8c0b71 100644 --- a/src/vs/base/common/buffer.ts +++ b/src/vs/base/common/buffer.ts @@ -172,51 +172,57 @@ export class VSBuffer { writeUInt8(this.buffer, value, offset); } - indexOf(subarray: VSBuffer | Uint8Array) { - const needle = subarray instanceof VSBuffer ? subarray.buffer : subarray; - const needleLen = needle.byteLength; - const haystack = this.buffer; - const haystackLen = haystack.byteLength; - - if (needleLen === 0) { - return 0; - } + indexOf(subarray: VSBuffer | Uint8Array, offset = 0) { + return binaryIndexOf(this.buffer, subarray instanceof VSBuffer ? subarray.buffer : subarray, offset); + } +} - if (needleLen === 1) { - return haystack.indexOf(needle[0]); - } +/** + * Like String.indexOf, but works on Uint8Arrays. + * Uses the boyer-moore-horspool algorithm to be reasonably speedy. + */ +export function binaryIndexOf(haystack: Uint8Array, needle: Uint8Array, offset = 0): number { + const needleLen = needle.byteLength; + const haystackLen = haystack.byteLength; - if (needleLen > haystackLen) { - return -1; - } + if (needleLen === 0) { + return 0; + } - // find index of the subarray using boyer-moore-horspool algorithm - const table = indexOfTable.value; - table.fill(needle.length); - for (let i = 0; i < needle.length; i++) { - table[needle[i]] = needle.length - i - 1; - } + if (needleLen === 1) { + return haystack.indexOf(needle[0]); + } + + if (needleLen > haystackLen - offset) { + return -1; + } + + // find index of the subarray using boyer-moore-horspool algorithm + const table = indexOfTable.value; + table.fill(needle.length); + for (let i = 0; i < needle.length; i++) { + table[needle[i]] = needle.length - i - 1; + } - let i = needle.length - 1; - let j = i; - let result = -1; - while (i < haystackLen) { - if (haystack[i] === needle[j]) { - if (j === 0) { - result = i; - break; - } - - i--; - j--; - } else { - i += Math.max(needle.length - j, table[haystack[i]]); - j = needle.length - 1; + let i = offset + needle.length - 1; + let j = i; + let result = -1; + while (i < haystackLen) { + if (haystack[i] === needle[j]) { + if (j === 0) { + result = i; + break; } - } - return result; + i--; + j--; + } else { + i += Math.max(needle.length - j, table[haystack[i]]); + j = needle.length - 1; + } } + + return result; } export function readUInt16LE(source: Uint8Array, offset: number): number { diff --git a/src/vs/base/common/codicons.ts b/src/vs/base/common/codicons.ts index f205af33b4cd5..48dd3abfb722c 100644 --- a/src/vs/base/common/codicons.ts +++ b/src/vs/base/common/codicons.ts @@ -60,6 +60,7 @@ export const Codicon = { tag: register('tag', 0xea66), tagAdd: register('tag-add', 0xea66), tagRemove: register('tag-remove', 0xea66), + gitPullRequestLabel: register('git-pull-request-label', 0xea66), person: register('person', 0xea67), personFollow: register('person-follow', 0xea67), personOutline: register('person-outline', 0xea67), @@ -314,6 +315,7 @@ export const Codicon = { megaphone: register('megaphone', 0xeb1e), mention: register('mention', 0xeb1f), milestone: register('milestone', 0xeb20), + gitPullRequestMilestone: register('git-pull-request-milestone', 0xeb20), mortarBoard: register('mortar-board', 0xeb21), move: register('move', 0xeb22), multipleWindows: register('multiple-windows', 0xeb23), @@ -438,9 +440,11 @@ export const Codicon = { menu: register('menu', 0xeb94), expandAll: register('expand-all', 0xeb95), feedback: register('feedback', 0xeb96), + gitPullRequestReviewer: register('git-pull-request-reviewer', 0xeb96), groupByRefType: register('group-by-ref-type', 0xeb97), ungroupByRefType: register('ungroup-by-ref-type', 0xeb98), account: register('account', 0xeb99), + gitPullRequestAssignee: register('git-pull-request-assignee', 0xeb99), bellDot: register('bell-dot', 0xeb9a), debugConsole: register('debug-console', 0xeb9b), library: register('library', 0xeb9c), diff --git a/src/vs/base/common/collections.ts b/src/vs/base/common/collections.ts index 95def40789d2f..8fdf74b05be7b 100644 --- a/src/vs/base/common/collections.ts +++ b/src/vs/base/common/collections.ts @@ -107,6 +107,6 @@ export class SetMap { if (!values) { return new Set(); } - return new Set(values); + return values; } } diff --git a/src/vs/base/common/event.ts b/src/vs/base/common/event.ts index c4f9b7282593d..872263f2e9e7c 100644 --- a/src/vs/base/common/event.ts +++ b/src/vs/base/common/event.ts @@ -682,6 +682,7 @@ export namespace Event { } }; observable.addObserver(observer); + observable.reportChanges(); return { dispose() { observable.removeObserver(observer); diff --git a/src/vs/base/common/htmlContent.ts b/src/vs/base/common/htmlContent.ts index 9cefc0e56a490..b62f09f07caa9 100644 --- a/src/vs/base/common/htmlContent.ts +++ b/src/vs/base/common/htmlContent.ts @@ -58,9 +58,9 @@ export class MarkdownString implements IMarkdownString { appendText(value: string, newlineStyle: MarkdownStringTextNewlineStyle = MarkdownStringTextNewlineStyle.Paragraph): MarkdownString { this.value += escapeMarkdownSyntaxTokens(this.supportThemeIcons ? escapeIcons(value) : value) - .replace(/([ \t]+)/g, (_match, g1) => ' '.repeat(g1.length)) - .replace(/\>/gm, '\\>') - .replace(/\n/g, newlineStyle === MarkdownStringTextNewlineStyle.Break ? '\\\n' : '\n\n'); + .replace(/([ \t]+)/g, (_match, g1) => ' '.repeat(g1.length)) // CodeQL [SM02383] The Markdown is fully sanitized after being rendered. + .replace(/\>/gm, '\\>') // CodeQL [SM02383] The Markdown is fully sanitized after being rendered. + .replace(/\n/g, newlineStyle === MarkdownStringTextNewlineStyle.Break ? '\\\n' : '\n\n'); // CodeQL [SM02383] The Markdown is fully sanitized after being rendered. return this; } diff --git a/src/vs/base/common/iterator.ts b/src/vs/base/common/iterator.ts index 308e03bfcd7c7..f06dcf7acbc99 100644 --- a/src/vs/base/common/iterator.ts +++ b/src/vs/base/common/iterator.ts @@ -47,7 +47,7 @@ export namespace Iterable { return false; } - export function find(iterable: Iterable, predicate: (t: T) => t is R): T | undefined; + export function find(iterable: Iterable, predicate: (t: T) => t is R): R | undefined; export function find(iterable: Iterable, predicate: (t: T) => boolean): T | undefined; export function find(iterable: Iterable, predicate: (t: T) => boolean): T | undefined { for (const element of iterable) { diff --git a/src/vs/base/common/marshalling.ts b/src/vs/base/common/marshalling.ts index 67a29703cdc4d..a51f009459179 100644 --- a/src/vs/base/common/marshalling.ts +++ b/src/vs/base/common/marshalling.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ import { VSBuffer } from 'vs/base/common/buffer'; -import { regExpFlags } from 'vs/base/common/strings'; import { URI, UriComponents } from 'vs/base/common/uri'; import { MarshalledId } from './marshallingIds'; @@ -28,7 +27,7 @@ function replacer(key: string, value: any): any { return { $mid: MarshalledId.Regexp, source: value.source, - flags: regExpFlags(value), + flags: value.flags, }; } return value; diff --git a/src/vs/base/common/marshallingIds.ts b/src/vs/base/common/marshallingIds.ts index abd7698ed92fd..ae02b8901fc27 100644 --- a/src/vs/base/common/marshallingIds.ts +++ b/src/vs/base/common/marshallingIds.ts @@ -20,5 +20,6 @@ export const enum MarshalledId { NotebookCellActionContext, NotebookActionContext, TestItemContext, - Date + Date, + TestMessageMenuArgs, } diff --git a/src/vs/base/common/objects.ts b/src/vs/base/common/objects.ts index 1633395798901..897a9fd824971 100644 --- a/src/vs/base/common/objects.ts +++ b/src/vs/base/common/objects.ts @@ -230,10 +230,9 @@ export function filter(obj: obj, predicate: (key: string, value: any) => boolean export function getAllPropertyNames(obj: object): string[] { let res: string[] = []; - let proto = Object.getPrototypeOf(obj); - while (Object.prototype !== proto) { - res = res.concat(Object.getOwnPropertyNames(proto)); - proto = Object.getPrototypeOf(proto); + while (Object.prototype !== obj) { + res = res.concat(Object.getOwnPropertyNames(obj)); + obj = Object.getPrototypeOf(obj); } return res; } diff --git a/src/vs/base/common/observable.ts b/src/vs/base/common/observable.ts index c588d68b9f626..895ba31352dbc 100644 --- a/src/vs/base/common/observable.ts +++ b/src/vs/base/common/observable.ts @@ -10,19 +10,43 @@ export { ISettable, ISettableObservable, ITransaction, + IChangeContext, + IChangeTracker, observableValue, + disposableObservableValue, transaction, -} from 'vs/base/common/observableImpl/base'; -export { derived } from 'vs/base/common/observableImpl/derived'; + subtransaction, +} from 'vs/base/common/observableInternal/base'; +export { + derived, + derivedOpts, + derivedHandleChanges, + derivedWithStore, +} from 'vs/base/common/observableInternal/derived'; export { autorun, autorunDelta, autorunHandleChanges, autorunWithStore, -} from 'vs/base/common/observableImpl/autorun'; -export * from 'vs/base/common/observableImpl/utils'; + autorunOpts, + autorunWithStoreHandleChanges, +} from 'vs/base/common/observableInternal/autorun'; +export { + IObservableSignal, + constObservable, + debouncedObservable, + derivedObservableWithCache, + derivedObservableWithWritableCache, + keepAlive, + observableFromEvent, + observableFromPromise, + observableSignal, + observableSignalFromEvent, + waitForState, + wasEventTriggeredRecently, +} from 'vs/base/common/observableInternal/utils'; -import { ConsoleObservableLogger, setLogger } from 'vs/base/common/observableImpl/logging'; +import { ConsoleObservableLogger, setLogger } from 'vs/base/common/observableInternal/logging'; const enableLogging = false; if (enableLogging) { diff --git a/src/vs/base/common/observableImpl/autorun.ts b/src/vs/base/common/observableInternal/autorun.ts similarity index 75% rename from src/vs/base/common/observableImpl/autorun.ts rename to src/vs/base/common/observableInternal/autorun.ts index aca09e3f08ead..482e592d88321 100644 --- a/src/vs/base/common/observableImpl/autorun.ts +++ b/src/vs/base/common/observableInternal/autorun.ts @@ -5,35 +5,31 @@ import { assertFn } from 'vs/base/common/assert'; import { DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; -import { IReader, IObservable, IObserver, IChangeContext } from 'vs/base/common/observableImpl/base'; -import { getLogger } from 'vs/base/common/observableImpl/logging'; +import { IReader, IObservable, IObserver, IChangeContext, getFunctionName } from 'vs/base/common/observableInternal/base'; +import { getLogger } from 'vs/base/common/observableInternal/logging'; -export function autorun(debugName: string, fn: (reader: IReader) => void): IDisposable { - return new AutorunObserver(debugName, fn, undefined, undefined); +export function autorunOpts(options: { debugName: string | (() => string | undefined) }, fn: (reader: IReader) => void): IDisposable { + return new AutorunObserver(options.debugName, fn, undefined, undefined); +} + +export function autorun(fn: (reader: IReader) => void): IDisposable { + return new AutorunObserver(undefined, fn, undefined, undefined); } export function autorunHandleChanges( - debugName: string, options: { + debugName?: string | (() => string | undefined); createEmptyChangeSummary?: () => TChangeSummary; handleChange: (context: IChangeContext, changeSummary: TChangeSummary) => boolean; }, fn: (reader: IReader, changeSummary: TChangeSummary) => void ): IDisposable { - return new AutorunObserver(debugName, fn, options.createEmptyChangeSummary, options.handleChange); -} - -// TODO@hediet rename to autorunWithStore -export function autorunWithStore2( - debugName: string, - fn: (reader: IReader, store: DisposableStore) => void, -): IDisposable { - return autorunWithStore(fn, debugName); + return new AutorunObserver(options.debugName, fn, options.createEmptyChangeSummary, options.handleChange); } export function autorunWithStoreHandleChanges( - debugName: string, options: { + debugName?: string | (() => string | undefined); createEmptyChangeSummary?: () => TChangeSummary; handleChange: (context: IChangeContext, changeSummary: TChangeSummary) => boolean; }, @@ -41,8 +37,8 @@ export function autorunWithStoreHandleChanges( ): IDisposable { const store = new DisposableStore(); const disposable = autorunHandleChanges( - debugName, { + debugName: options.debugName ?? (() => getFunctionName(fn)), createEmptyChangeSummary: options.createEmptyChangeSummary, handleChange: options.handleChange, }, @@ -57,14 +53,12 @@ export function autorunWithStoreHandleChanges( }); } -// TODO@hediet deprecate, rename to autorunWithStoreEx -export function autorunWithStore( - fn: (reader: IReader, store: DisposableStore) => void, - debugName: string -): IDisposable { +export function autorunWithStore(fn: (reader: IReader, store: DisposableStore) => void): IDisposable { const store = new DisposableStore(); - const disposable = autorun( - debugName, + const disposable = autorunOpts( + { + debugName: () => getFunctionName(fn) || '(anonymous)', + }, reader => { store.clear(); fn(reader, store); @@ -98,9 +92,23 @@ export class AutorunObserver implements IObserver, IReader private dependenciesToBeRemoved = new Set>(); private changeSummary: TChangeSummary | undefined; + public get debugName(): string { + if (typeof this._debugName === 'string') { + return this._debugName; + } + if (typeof this._debugName === 'function') { + const name = this._debugName(); + if (name !== undefined) { return name; } + } + const name = getFunctionName(this._runFn); + if (name !== undefined) { return name; } + + return '(anonymous)'; + } + constructor( - public readonly debugName: string, - private readonly runFn: (reader: IReader, changeSummary: TChangeSummary) => void, + private readonly _debugName: string | (() => string | undefined) | undefined, + public readonly _runFn: (reader: IReader, changeSummary: TChangeSummary) => void, private readonly createChangeSummary: (() => TChangeSummary) | undefined, private readonly _handleChange: ((context: IChangeContext, summary: TChangeSummary) => boolean) | undefined, ) { @@ -128,13 +136,15 @@ export class AutorunObserver implements IObserver, IReader this.state = AutorunState.upToDate; - getLogger()?.handleAutorunTriggered(this); - try { - const changeSummary = this.changeSummary!; - this.changeSummary = this.createChangeSummary?.(); - this.runFn(this, changeSummary); + if (!this.disposed) { + getLogger()?.handleAutorunTriggered(this); + const changeSummary = this.changeSummary!; + this.changeSummary = this.createChangeSummary?.(); + this._runFn(this, changeSummary); + } } finally { + getLogger()?.handleAutorunFinished(this); // We don't want our observed observables to think that they are (not even temporarily) not being observed. // Thus, we only unsubscribe from observables that are definitely not read anymore. for (const o of this.dependenciesToBeRemoved) { @@ -215,13 +225,13 @@ export class AutorunObserver implements IObserver, IReader export namespace autorun { export const Observer = AutorunObserver; } + export function autorunDelta( - name: string, observable: IObservable, handler: (args: { lastValue: T | undefined; newValue: T }) => void ): IDisposable { let _lastValue: T | undefined; - return autorun(name, (reader) => { + return autorunOpts({ debugName: () => getFunctionName(handler) }, (reader) => { const newValue = observable.read(reader); const lastValue = _lastValue; _lastValue = newValue; diff --git a/src/vs/base/common/observableImpl/base.ts b/src/vs/base/common/observableInternal/base.ts similarity index 92% rename from src/vs/base/common/observableImpl/base.ts rename to src/vs/base/common/observableInternal/base.ts index 61addad74113e..23ba8d4af19cd 100644 --- a/src/vs/base/common/observableImpl/base.ts +++ b/src/vs/base/common/observableInternal/base.ts @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ import { IDisposable } from 'vs/base/common/lifecycle'; -import type { derived } from 'vs/base/common/observableImpl/derived'; -import { getLogger } from 'vs/base/common/observableImpl/logging'; +import type { derived } from 'vs/base/common/observableInternal/derived'; +import { getLogger } from 'vs/base/common/observableInternal/logging'; /** * Represents an observable value. @@ -162,11 +162,21 @@ export abstract class ConvenientObservable implements IObservable(fn: (value: T, reader: IReader) => TNew): IObservable { return _derived( + (reader) => fn(this.read(reader), reader), () => { const name = getFunctionName(fn); - return name !== undefined ? name : `${this.debugName} (mapped)`; + if (name !== undefined) { + return name; + } + + // regexp to match `x => x.y` where x and y can be arbitrary identifiers (uses backref): + const regexp = /^\s*\(?\s*([a-zA-Z_$][a-zA-Z_$0-9]*)\s*\)?\s*=>\s*\1\.([a-zA-Z_$][a-zA-Z_$0-9]*)\s*$/; + const match = regexp.exec(fn.toString()); + if (match) { + return `${this.debugName}.${match[2]}`; + } + return `${this.debugName} (mapped)`; }, - (reader) => fn(this.read(reader), reader) ); } @@ -198,11 +208,9 @@ export abstract class BaseObservable extends ConvenientObserv export function transaction(fn: (tx: ITransaction) => void, getDebugName?: () => string): void { const tx = new TransactionImpl(fn, getDebugName); try { - getLogger()?.handleBeginTransaction(tx); fn(tx); } finally { tx.finish(); - getLogger()?.handleEndTransaction(); } } @@ -217,13 +225,15 @@ export function subtransaction(tx: ITransaction | undefined, fn: (tx: ITransacti export class TransactionImpl implements ITransaction { private updatingObservers: { observer: IObserver; observable: IObservable }[] | null = []; - constructor(private readonly fn: Function, private readonly _getDebugName?: () => string) { } + constructor(public readonly _fn: Function, private readonly _getDebugName?: () => string) { + getLogger()?.handleBeginTransaction(this); + } public getDebugName(): string | undefined { if (this._getDebugName) { return this._getDebugName(); } - return getFunctionName(this.fn); + return getFunctionName(this._fn); } public updateObserver(observer: IObserver, observable: IObservable): void { @@ -238,6 +248,7 @@ export class TransactionImpl implements ITransaction { for (const { observer, observable } of updatingObservers) { observer.endUpdate(observable); } + getLogger()?.handleEndTransaction(); } } @@ -287,7 +298,7 @@ export class ObservableValue try { const oldValue = this._value; this._setValue(value); - getLogger()?.handleObservableChanged(this, { oldValue, newValue: value, change, didChange: true }); + getLogger()?.handleObservableChanged(this, { oldValue, newValue: value, change, didChange: true, hadValue: true }); for (const observer of this.observers) { tx.updateObserver(observer, this); diff --git a/src/vs/base/common/observableImpl/derived.ts b/src/vs/base/common/observableInternal/derived.ts similarity index 81% rename from src/vs/base/common/observableImpl/derived.ts rename to src/vs/base/common/observableInternal/derived.ts index 0bfe5d7168198..2cb17f2f9daa7 100644 --- a/src/vs/base/common/observableImpl/derived.ts +++ b/src/vs/base/common/observableInternal/derived.ts @@ -5,11 +5,18 @@ import { BugIndicatingError } from 'vs/base/common/errors'; import { DisposableStore } from 'vs/base/common/lifecycle'; -import { IReader, IObservable, BaseObservable, IObserver, _setDerived, IChangeContext } from 'vs/base/common/observableImpl/base'; -import { getLogger } from 'vs/base/common/observableImpl/logging'; +import { IReader, IObservable, BaseObservable, IObserver, _setDerived, IChangeContext, getFunctionName } from 'vs/base/common/observableInternal/base'; +import { getLogger } from 'vs/base/common/observableInternal/logging'; -export function derived(debugName: string | (() => string), computeFn: (reader: IReader) => T): IObservable { - return new Derived(debugName, computeFn, undefined, undefined, undefined); +export type EqualityComparer = (a: T, b: T) => boolean; +const defaultEqualityComparer: EqualityComparer = (a, b) => a === b; + +export function derived(computeFn: (reader: IReader) => T, debugName?: string | (() => string)): IObservable { + return new Derived(debugName, computeFn, undefined, undefined, undefined, defaultEqualityComparer); +} + +export function derivedOpts(options: { debugName?: string | (() => string); equalityComparer?: EqualityComparer }, computeFn: (reader: IReader) => T): IObservable { + return new Derived(options.debugName, computeFn, undefined, undefined, undefined, options.equalityComparer ?? defaultEqualityComparer); } export function derivedHandleChanges( @@ -19,7 +26,7 @@ export function derivedHandleChanges( handleChange: (context: IChangeContext, changeSummary: TChangeSummary) => boolean; }, computeFn: (reader: IReader, changeSummary: TChangeSummary) => T): IObservable { - return new Derived(debugName, computeFn, options.createEmptyChangeSummary, options.handleChange, undefined); + return new Derived(debugName, computeFn, options.createEmptyChangeSummary, options.handleChange, undefined, defaultEqualityComparer); } export function derivedWithStore(name: string, computeFn: (reader: IReader, store: DisposableStore) => T): IObservable { @@ -27,7 +34,7 @@ export function derivedWithStore(name: string, computeFn: (reader: IReader, s return new Derived(name, r => { store.clear(); return computeFn(r, store); - }, undefined, undefined, () => store.dispose()); + }, undefined, undefined, () => store.dispose(), defaultEqualityComparer); } _setDerived(derived); @@ -63,15 +70,19 @@ export class Derived extends BaseObservable im private changeSummary: TChangeSummary | undefined = undefined; public override get debugName(): string { + if (!this._debugName) { + return getFunctionName(this._computeFn) || '(anonymous)'; + } return typeof this._debugName === 'function' ? this._debugName() : this._debugName; } constructor( - private readonly _debugName: string | (() => string), - private readonly computeFn: (reader: IReader, changeSummary: TChangeSummary) => T, + private readonly _debugName: string | (() => string) | undefined, + public readonly _computeFn: (reader: IReader, changeSummary: TChangeSummary) => T, private readonly createChangeSummary: (() => TChangeSummary) | undefined, private readonly _handleChange: ((context: IChangeContext, summary: TChangeSummary) => boolean) | undefined, - private readonly _handleLastObserverRemoved: (() => void) | undefined = undefined + private readonly _handleLastObserverRemoved: (() => void) | undefined = undefined, + private readonly _equalityComparator: EqualityComparer, ) { super(); this.changeSummary = this.createChangeSummary?.(); @@ -97,19 +108,17 @@ export class Derived extends BaseObservable im if (this.observers.size === 0) { // Without observers, we don't know when to clean up stuff. // Thus, we don't cache anything to prevent memory leaks. - const result = this.computeFn(this, this.createChangeSummary?.()!); + const result = this._computeFn(this, this.createChangeSummary?.()!); // Clear new dependencies this.onLastObserverRemoved(); return result; } else { do { + // We might not get a notification for a dependency that changed while it is updating, + // thus we also have to ask all our depedencies if they changed in this case. if (this.state === DerivedState.dependenciesMightHaveChanged) { - // We might not get a notification for a dependency that changed while it is updating, - // thus we also have to ask all our depedencies if they changed in this case. - this.state = DerivedState.upToDate; - for (const d of this.dependencies) { - /** might call {@link handleChange} indirectly, which could invalidate us */ + /** might call {@link handleChange} indirectly, which could make us stale */ d.reportChanges(); if (this.state as DerivedState === DerivedState.stale) { @@ -119,6 +128,12 @@ export class Derived extends BaseObservable im } } + // We called report changes of all dependencies. + // If we are still not stale, we can assume to be up to date again. + if (this.state === DerivedState.dependenciesMightHaveChanged) { + this.state = DerivedState.upToDate; + } + this._recomputeIfNeeded(); // In case recomputation changed one of our dependencies, we need to recompute again. } while (this.state !== DerivedState.upToDate); @@ -142,7 +157,7 @@ export class Derived extends BaseObservable im this.changeSummary = this.createChangeSummary?.(); try { /** might call {@link handleChange} indirectly, which could invalidate us */ - this.value = this.computeFn(this, changeSummary); + this.value = this._computeFn(this, changeSummary); } finally { // We don't want our observed observables to think that they are (not even temporarily) not being observed. // Thus, we only unsubscribe from observables that are definitely not read anymore. @@ -152,13 +167,14 @@ export class Derived extends BaseObservable im this.dependenciesToBeRemoved.clear(); } - const didChange = hadValue && oldValue !== this.value; + const didChange = hadValue && !(this._equalityComparator(oldValue!, this.value)); getLogger()?.handleDerivedRecomputed(this, { oldValue, newValue: this.value, change: undefined, - didChange + didChange, + hadValue, }); if (didChange) { diff --git a/src/vs/base/common/observableImpl/logging.ts b/src/vs/base/common/observableInternal/logging.ts similarity index 85% rename from src/vs/base/common/observableImpl/logging.ts rename to src/vs/base/common/observableInternal/logging.ts index 0c221d0c70083..01fcc3cdbbf48 100644 --- a/src/vs/base/common/observableImpl/logging.ts +++ b/src/vs/base/common/observableInternal/logging.ts @@ -3,10 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { AutorunObserver } from 'vs/base/common/observableImpl/autorun'; -import { IObservable, ObservableValue, TransactionImpl } from 'vs/base/common/observableImpl/base'; -import { Derived } from 'vs/base/common/observableImpl/derived'; -import { FromEventObservable } from 'vs/base/common/observableImpl/utils'; +import { AutorunObserver } from 'vs/base/common/observableInternal/autorun'; +import { IObservable, ObservableValue, TransactionImpl } from 'vs/base/common/observableInternal/base'; +import { Derived } from 'vs/base/common/observableInternal/derived'; +import { FromEventObservable } from 'vs/base/common/observableInternal/utils'; let globalObservableLogger: IObservableLogger | undefined; @@ -23,17 +23,19 @@ interface IChangeInformation { newValue: unknown; change: unknown; didChange: boolean; + hadValue: boolean; } export interface IObservableLogger { - handleObservableChanged(observable: ObservableValue, info: IChangeInformation): void; + handleObservableChanged(observable: ObservableValue, info: IChangeInformation): void; handleFromEventObservableTriggered(observable: FromEventObservable, info: IChangeInformation): void; handleAutorunCreated(autorun: AutorunObserver): void; handleAutorunTriggered(autorun: AutorunObserver): void; + handleAutorunFinished(autorun: AutorunObserver): void; - handleDerivedCreated(observable: Derived): void; - handleDerivedRecomputed(observable: Derived, info: IChangeInformation): void; + handleDerivedCreated(observable: Derived): void; + handleDerivedRecomputed(observable: Derived, info: IChangeInformation): void; handleBeginTransaction(transaction: TransactionImpl): void; handleEndTransaction(): void; @@ -50,6 +52,15 @@ export class ConsoleObservableLogger implements IObservableLogger { } private formatInfo(info: IChangeInformation): ConsoleText[] { + if (!info.hadValue) { + return [ + normalText(` `), + styled(formatValue(info.newValue, 60), { + color: 'green', + }), + normalText(` (initial)`), + ]; + } return info.didChange ? [ normalText(` `), @@ -102,7 +113,8 @@ export class ConsoleObservableLogger implements IObservableLogger { formatKind('derived recomputed'), styled(derived.debugName, { color: 'BlueViolet' }), ...this.formatInfo(info), - this.formatChanges(changedObservables) + this.formatChanges(changedObservables), + { data: [{ fn: derived._computeFn }] } ])); changedObservables.clear(); } @@ -112,6 +124,7 @@ export class ConsoleObservableLogger implements IObservableLogger { formatKind('observable from event triggered'), styled(observable.debugName, { color: 'BlueViolet' }), ...this.formatInfo(info), + { data: [{ fn: observable._getValue }] } ])); } @@ -129,9 +142,15 @@ export class ConsoleObservableLogger implements IObservableLogger { console.log(...this.textToConsoleArgs([ formatKind('autorun'), styled(autorun.debugName, { color: 'BlueViolet' }), - this.formatChanges(changedObservables) + this.formatChanges(changedObservables), + { data: [{ fn: autorun._runFn }] } ])); changedObservables.clear(); + this.indentation++; + } + + handleAutorunFinished(autorun: AutorunObserver): void { + this.indentation--; } handleBeginTransaction(transaction: TransactionImpl): void { @@ -142,6 +161,7 @@ export class ConsoleObservableLogger implements IObservableLogger { console.log(...this.textToConsoleArgs([ formatKind('transaction'), styled(transactionName, { color: 'BlueViolet' }), + { data: [{ fn: transaction._fn }] } ])); this.indentation++; } @@ -153,13 +173,12 @@ export class ConsoleObservableLogger implements IObservableLogger { type ConsoleText = | (ConsoleText | undefined)[] - | { text: string; style: string; data?: Record } - | { data: Record }; + | { text: string; style: string; data?: unknown[] } + | { data: unknown[] }; function consoleTextToArgs(text: ConsoleText): unknown[] { const styles = new Array(); - const initial = {}; - const data = initial; + const data: unknown[] = []; let firstArg = ''; function process(t: ConsoleText): void { @@ -173,20 +192,17 @@ function consoleTextToArgs(text: ConsoleText): unknown[] { firstArg += `%c${t.text}`; styles.push(t.style); if (t.data) { - Object.assign(data, t.data); + data.push(...t.data); } } else if ('data' in t) { - Object.assign(data, t.data); + data.push(...t.data); } } process(text); const result = [firstArg, ...styles]; - if (Object.keys(data).length > 0) { - result.push(data); - } - + result.push(...data); return result; } diff --git a/src/vs/base/common/observableImpl/utils.ts b/src/vs/base/common/observableInternal/utils.ts similarity index 89% rename from src/vs/base/common/observableImpl/utils.ts rename to src/vs/base/common/observableInternal/utils.ts index 5d9a2c568a812..c0e0adba01001 100644 --- a/src/vs/base/common/observableImpl/utils.ts +++ b/src/vs/base/common/observableInternal/utils.ts @@ -5,11 +5,14 @@ import { Event } from 'vs/base/common/event'; import { DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; -import { autorun } from 'vs/base/common/observableImpl/autorun'; -import { BaseObservable, ConvenientObservable, IObservable, IObserver, IReader, ITransaction, getFunctionName, observableValue, transaction } from 'vs/base/common/observableImpl/base'; -import { derived } from 'vs/base/common/observableImpl/derived'; -import { getLogger } from 'vs/base/common/observableImpl/logging'; +import { autorun } from 'vs/base/common/observableInternal/autorun'; +import { BaseObservable, ConvenientObservable, IObservable, IObserver, IReader, ITransaction, getFunctionName, observableValue, transaction } from 'vs/base/common/observableInternal/base'; +import { derived } from 'vs/base/common/observableInternal/derived'; +import { getLogger } from 'vs/base/common/observableInternal/logging'; +/** + * Represents an efficient observable whose value never changes. + */ export function constObservable(value: T): IObservable { return new ConstObservable(value); } @@ -53,7 +56,8 @@ export function waitForState(observable: IObservable, predicate: (state: T return new Promise(resolve => { let didRun = false; let shouldDispose = false; - const d = autorun('waitForState', reader => { + const d = autorun(reader => { + /** @description waitForState */ const currentState = observable.read(reader); if (predicate(currentState)) { if (!didRun) { @@ -85,13 +89,13 @@ export class FromEventObservable extends BaseObservable { constructor( private readonly event: Event, - private readonly getValue: (args: TArgs | undefined) => T + public readonly _getValue: (args: TArgs | undefined) => T ) { super(); } private getDebugName(): string | undefined { - return getFunctionName(this.getValue); + return getFunctionName(this._getValue); } public get debugName(): string { @@ -104,11 +108,11 @@ export class FromEventObservable extends BaseObservable { } private readonly handleEvent = (args: TArgs | undefined) => { - const newValue = this.getValue(args); + const newValue = this._getValue(args); const didChange = !this.hasValue || this.value !== newValue; - getLogger()?.handleFromEventObservableTriggered(this, { oldValue: this.value, newValue, change: undefined, didChange }); + getLogger()?.handleFromEventObservableTriggered(this, { oldValue: this.value, newValue, change: undefined, didChange, hadValue: this.hasValue }); if (didChange) { this.value = newValue; @@ -146,7 +150,7 @@ export class FromEventObservable extends BaseObservable { return this.value!; } else { // no cache, as there are no subscribers to keep it updated - return this.getValue(undefined); + return this._getValue(undefined); } } } @@ -200,6 +204,8 @@ class FromEventObservableSignal extends BaseObservable { /** * Creates a signal that can be triggered to invalidate observers. + * Signals don't have a value - when they are triggered they indicate a change. + * However, signals can carry a delta that is passed to observers. */ export function observableSignal( debugName: string @@ -242,7 +248,8 @@ export function debouncedObservable(observable: IObservable, debounceMs: n let timeout: any = undefined; - disposableStore.add(autorun('debounce', reader => { + disposableStore.add(autorun(reader => { + /** @description debounce */ const value = observable.read(reader); if (timeout) { @@ -278,6 +285,7 @@ export function wasEventTriggeredRecently(event: Event, timeoutMs: number, return observable; } +// TODO@hediet: Have `keepCacheAlive` and `recomputeOnChange` instead of forceRecompute /** * This ensures the observable is being observed. * Observed observables (such as {@link derived}s) can maintain a cache, as they receive invalidation events. @@ -326,21 +334,21 @@ class KeepAliveObserver implements IObserver { export function derivedObservableWithCache(name: string, computeFn: (reader: IReader, lastValue: T | undefined) => T): IObservable { let lastValue: T | undefined = undefined; - const observable = derived(name, reader => { + const observable = derived(reader => { lastValue = computeFn(reader, lastValue); return lastValue; - }); + }, name); return observable; } export function derivedObservableWithWritableCache(name: string, computeFn: (reader: IReader, lastValue: T | undefined) => T): IObservable & { clearCache(transaction: ITransaction): void } { let lastValue: T | undefined = undefined; const counter = observableValue('derivedObservableWithWritableCache.counter', 0); - const observable = derived(name, reader => { + const observable = derived(reader => { counter.read(reader); lastValue = computeFn(reader, lastValue); return lastValue; - }); + }, name); return Object.assign(observable, { clearCache: (transaction: ITransaction) => { lastValue = undefined; diff --git a/src/vs/base/common/prefixTree.ts b/src/vs/base/common/prefixTree.ts new file mode 100644 index 0000000000000..20ef79000e2fa --- /dev/null +++ b/src/vs/base/common/prefixTree.ts @@ -0,0 +1,168 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +const unset = Symbol('unset'); + +/** + * A simple prefix tree implementation where a value is stored based on + * well-defined prefix segments. + */ +export class WellDefinedPrefixTree { + private readonly root = new Node(); + private _size = 0; + + public get size() { + return this._size; + } + + /** Inserts a new value in the prefix tree. */ + insert(key: Iterable, value: V): void { + this.opNode(key, n => n.value = value); + } + + /** Mutates a value in the prefix tree. */ + mutate(key: Iterable, mutate: (value?: V) => V): void { + this.opNode(key, n => n.value = mutate(n.value === unset ? undefined : n.value)); + } + + /** Deletes a node from the prefix tree, returning the value it contained. */ + delete(key: Iterable): V | undefined { + const path = [{ part: '', node: this.root }]; + let i = 0; + for (const part of key) { + const node = path[i].node.children?.get(part); + if (!node) { + return undefined; // node not in tree + } + + path.push({ part, node }); + i++; + } + + const value = path[i].node.value; + if (value === unset) { + return; // not actually a real node + } + + this._size--; + for (; i > 0; i--) { + const parent = path[i - 1]; + parent.node.children!.delete(path[i].part); + if (parent.node.children!.size > 0 || parent.node.value !== unset) { + break; + } + } + + return value; + } + + /** Gets a value from the tree. */ + find(key: Iterable): V | undefined { + let node = this.root; + for (const segment of key) { + const next = node.children?.get(segment); + if (!next) { + return undefined; + } + + node = next; + } + + return node.value === unset ? undefined : node.value; + } + + /** Gets whether the tree has the key, or a parent of the key, already inserted. */ + hasKeyOrParent(key: Iterable): boolean { + let node = this.root; + for (const segment of key) { + const next = node.children?.get(segment); + if (!next) { + return false; + } + if (next.value !== unset) { + return true; + } + + node = next; + } + + return false; + } + + /** Gets whether the tree has the given key or any children. */ + hasKeyOrChildren(key: Iterable): boolean { + let node = this.root; + for (const segment of key) { + const next = node.children?.get(segment); + if (!next) { + return false; + } + + node = next; + } + + return true; + } + + /** Gets whether the tree has the given key. */ + hasKey(key: Iterable): boolean { + let node = this.root; + for (const segment of key) { + const next = node.children?.get(segment); + if (!next) { + return false; + } + + node = next; + } + + return node.value !== unset; + } + + private opNode(key: Iterable, fn: (node: Node) => void): void { + let node = this.root; + for (const part of key) { + if (!node.children) { + const next = new Node(); + node.children = new Map([[part, next]]); + node = next; + } else if (!node.children.has(part)) { + const next = new Node(); + node.children.set(part, next); + node = next; + } else { + node = node.children.get(part)!; + } + } + + if (node.value === unset) { + this._size++; + } + + fn(node); + } + + /** Returns an iterable of the tree values in no defined order. */ + *values() { + const stack = [this.root]; + while (stack.length > 0) { + const node = stack.pop()!; + if (node.value !== unset) { + yield node.value; + } + + if (node.children) { + for (const child of node.children.values()) { + stack.push(child); + } + } + } + } +} + +class Node { + public children?: Map>; + public value: T | typeof unset = unset; +} diff --git a/src/vs/base/common/product.ts b/src/vs/base/common/product.ts index 7cc06b49b3feb..47b2de558c488 100644 --- a/src/vs/base/common/product.ts +++ b/src/vs/base/common/product.ts @@ -130,11 +130,6 @@ export interface IProductConfiguration { readonly ariaKey: string; }; - readonly sendASmile?: { - readonly reportIssueUrl: string; - readonly requestFeatureUrl: string; - }; - readonly documentationUrl?: string; readonly serverDocumentationUrl?: string; readonly releaseNotesUrl?: string; @@ -144,7 +139,7 @@ export interface IProductConfiguration { readonly introductoryVideosUrl?: string; readonly tipsAndTricksUrl?: string; readonly newsletterSignupUrl?: string; - readonly twitterUrl?: string; + readonly youTubeUrl?: string; readonly requestFeatureUrl?: string; readonly reportIssueUrl?: string; readonly reportMarketplaceIssueUrl?: string; diff --git a/src/vs/base/common/stream.ts b/src/vs/base/common/stream.ts index 9f1039c0e522c..055558fc748e8 100644 --- a/src/vs/base/common/stream.ts +++ b/src/vs/base/common/stream.ts @@ -3,8 +3,9 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { CancellationToken } from 'vs/base/common/cancellation'; import { onUnexpectedError } from 'vs/base/common/errors'; -import { DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { DisposableStore, toDisposable } from 'vs/base/common/lifecycle'; /** * The payload that flows in readable stream events. @@ -567,17 +568,16 @@ export interface IStreamListener { /** * Helper to listen to all events of a T stream in proper order. */ -export function listenStream(stream: ReadableStreamEvents, listener: IStreamListener): IDisposable { - let destroyed = false; +export function listenStream(stream: ReadableStreamEvents, listener: IStreamListener, token?: CancellationToken): void { stream.on('error', error => { - if (!destroyed) { + if (!token?.isCancellationRequested) { listener.onError(error); } }); stream.on('end', () => { - if (!destroyed) { + if (!token?.isCancellationRequested) { listener.onEnd(); } }); @@ -586,12 +586,10 @@ export function listenStream(stream: ReadableStreamEvents, listener: IStre // into flowing mode. As such it is important to // add this listener last (DO NOT CHANGE!) stream.on('data', data => { - if (!destroyed) { + if (!token?.isCancellationRequested) { listener.onData(data); } }); - - return toDisposable(() => destroyed = true); } /** diff --git a/src/vs/base/common/strings.ts b/src/vs/base/common/strings.ts index 5837c2f4c4975..02d9179c7929a 100644 --- a/src/vs/base/common/strings.ts +++ b/src/vs/base/common/strings.ts @@ -217,17 +217,6 @@ export function regExpLeadsToEndlessLoop(regexp: RegExp): boolean { return !!(match && regexp.lastIndex === 0); } -export function regExpContainsBackreference(regexpValue: string): boolean { - return !!regexpValue.match(/([^\\]|^)(\\\\)*\\\d+/); -} - -export function regExpFlags(regexp: RegExp): string { - return (regexp.global ? 'g' : '') - + (regexp.ignoreCase ? 'i' : '') - + (regexp.multiline ? 'm' : '') - + ((regexp as any /* standalone editor compilation */).unicode ? 'u' : ''); -} - export function splitLines(str: string): string[] { return str.split(/\r\n|\r|\n/); } diff --git a/src/vs/base/common/types.ts b/src/vs/base/common/types.ts index c35da047d1f6f..d35246667bc41 100644 --- a/src/vs/base/common/types.ts +++ b/src/vs/base/common/types.ts @@ -190,20 +190,6 @@ export function validateConstraint(arg: unknown, constraint: TypeConstraint | un } } -/** - * Converts null to undefined, passes all other values through. - */ -export function withNullAsUndefined(x: T | null): T | undefined { - return x === null ? undefined : x; -} - -/** - * Converts undefined to null, passes all other values through. - */ -export function withUndefinedAsNull(x: T | undefined): T | null { - return typeof x === 'undefined' ? null : x; -} - type AddFirstParameterToFunction = T extends (...args: any[]) => TargetFunctionsReturnType ? // Function: add param to function (firstArg: FirstParameter, ...args: Parameters) => ReturnType : @@ -225,6 +211,10 @@ export type AddFirstParameterToFunctions }> = Partial & U[keyof U]; +/** + * Only picks the non-optional properties of a type. + */ +export type OmitOptional = { [K in keyof T as T[K] extends Required[K] ? K : never]: T[K] }; /** * A type that removed readonly-less from all properties of `T` diff --git a/src/vs/base/node/nodeStreams.ts b/src/vs/base/node/nodeStreams.ts new file mode 100644 index 0000000000000..0719bb4678735 --- /dev/null +++ b/src/vs/base/node/nodeStreams.ts @@ -0,0 +1,62 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import { Transform } from 'stream'; +import { binaryIndexOf } from 'vs/base/common/buffer'; + +/** + * A Transform stream that splits the input on the "splitter" substring. + * The resulting chunks will contain (and trail with) the splitter match. + * The last chunk when the stream ends will be emitted even if a splitter + * is not encountered. + */ +export class StreamSplitter extends Transform { + private buffer: Buffer | undefined; + private readonly splitter: Buffer | number; + private readonly spitterLen: number; + + constructor(splitter: string | number | Buffer) { + super(); + if (typeof splitter === 'number') { + this.splitter = splitter; + this.spitterLen = 1; + } else { + const buf = Buffer.isBuffer(splitter) ? splitter : Buffer.from(splitter); + this.splitter = buf.length === 1 ? buf[0] : buf; + this.spitterLen = buf.length; + } + } + + override _transform(chunk: Buffer, _encoding: string, callback: (error?: Error | null, data?: any) => void): void { + if (!this.buffer) { + this.buffer = chunk; + } else { + this.buffer = Buffer.concat([this.buffer, chunk]); + } + + let offset = 0; + while (offset < this.buffer.length) { + const index = typeof this.splitter === 'number' + ? this.buffer.indexOf(this.splitter, offset) + : binaryIndexOf(this.buffer, this.splitter, offset); + if (index === -1) { + break; + } + + this.push(this.buffer.slice(offset, index + this.spitterLen)); + offset = index + this.spitterLen; + } + + this.buffer = offset === this.buffer.length ? undefined : this.buffer.slice(offset); + callback(); + } + + override _flush(callback: (error?: Error | null, data?: any) => void): void { + if (this.buffer) { + this.push(this.buffer); + } + + callback(); + } +} diff --git a/src/vs/base/node/pfs.ts b/src/vs/base/node/pfs.ts index 0cdb1809b524f..9e409829caeb7 100644 --- a/src/vs/base/node/pfs.ts +++ b/src/vs/base/node/pfs.ts @@ -6,7 +6,7 @@ import * as fs from 'fs'; import { tmpdir } from 'os'; import { promisify } from 'util'; -import { ResourceQueue } from 'vs/base/common/async'; +import { ResourceQueue, timeout } from 'vs/base/common/async'; import { isEqualOrParent, isRootOrDriveLetter, randomPath } from 'vs/base/common/extpath'; import { normalizeNFC } from 'vs/base/common/normalization'; import { join } from 'vs/base/common/path'; @@ -491,16 +491,24 @@ function ensureWriteOptions(options?: IWriteFileOptions): IEnsuredWriteFileOptio /** * A drop-in replacement for `fs.rename` that: * - allows to move across multiple disks + * - attempts to retry the operation for certain error codes on Windows */ -async function move(source: string, target: string): Promise { +async function rename(source: string, target: string, windowsRetryTimeout: number | false = 60000 /* matches graceful-fs */): Promise { if (source === target) { return; // simulate node.js behaviour here and do a no-op if paths match } try { - await Promises.rename(source, target); + if (isWindows && typeof windowsRetryTimeout === 'number') { + // On Windows, a rename can fail when either source or target + // is locked by AV software. We do leverage graceful-fs to iron + // out these issues, however in case the target file exists, + // graceful-fs will immediately return without retry for fs.rename(). + await renameWithRetry(source, target, Date.now(), windowsRetryTimeout); + } else { + await promisify(fs.rename)(source, target); + } } catch (error) { - // In two cases we fallback to classic copy and delete: // // 1.) The EXDEV error indicates that source and target are on different devices @@ -518,6 +526,44 @@ async function move(source: string, target: string): Promise { } } +async function renameWithRetry(source: string, target: string, startTime: number, retryTimeout: number, attempt = 0): Promise { + try { + return await promisify(fs.rename)(source, target); + } catch (error) { + if (error.code !== 'EACCES' && error.code !== 'EPERM' && error.code !== 'EBUSY') { + throw error; // only for errors we think are temporary + } + + if (Date.now() - startTime >= retryTimeout) { + console.error(`[node.js fs] rename failed after ${attempt} retries with error: ${error}`); + + throw error; // give up after configurable timeout + } + + if (attempt === 0) { + let abortRetry = false; + try { + const { stat } = await SymlinkSupport.stat(target); + if (!stat.isFile()) { + abortRetry = true; // if target is not a file, EPERM error may be raised and we should not attempt to retry + } + } catch (error) { + // Ignore + } + + if (abortRetry) { + throw error; + } + } + + // Delay with incremental backoff up to 100ms + await timeout(Math.min(100, attempt * 10)); + + // Attempt again + return renameWithRetry(source, target, startTime, retryTimeout, attempt + 1); + } +} + interface ICopyPayload { readonly root: { source: string; target: string }; readonly options: { preserveSymlinks: boolean }; @@ -694,7 +740,6 @@ export const Promises = new class { get fdatasync() { return promisify(fs.fdatasync); } get truncate() { return promisify(fs.truncate); } - get rename() { return promisify(fs.rename); } get copyFile() { return promisify(fs.copyFile); } get open() { return promisify(fs.open); } @@ -733,7 +778,7 @@ export const Promises = new class { get rm() { return rimraf; } - get move() { return move; } + get rename() { return rename; } get copy() { return copy; } //#endregion diff --git a/src/vs/base/node/powershell.ts b/src/vs/base/node/powershell.ts index be6aeb7f4b82f..c24c14f7c942f 100644 --- a/src/vs/base/node/powershell.ts +++ b/src/vs/base/node/powershell.ts @@ -22,7 +22,6 @@ const enum Arch { let processArch: Arch; switch (process.arch) { case 'ia32': - case 'x32': processArch = Arch.x86; break; case 'arm': diff --git a/src/vs/base/parts/contextmenu/electron-main/contextmenu.ts b/src/vs/base/parts/contextmenu/electron-main/contextmenu.ts index 6b2eb1cb8202d..40b3d5c46d326 100644 --- a/src/vs/base/parts/contextmenu/electron-main/contextmenu.ts +++ b/src/vs/base/parts/contextmenu/electron-main/contextmenu.ts @@ -5,7 +5,6 @@ import { BrowserWindow, IpcMainEvent, Menu, MenuItem } from 'electron'; import { validatedIpcMain } from 'vs/base/parts/ipc/electron-main/ipcMain'; -import { withNullAsUndefined } from 'vs/base/common/types'; import { CONTEXT_MENU_CHANNEL, CONTEXT_MENU_CLOSE_CHANNEL, IPopupOptions, ISerializableContextMenuItem } from 'vs/base/parts/contextmenu/common/contextmenu'; export function registerContextMenuListener(): void { @@ -13,7 +12,7 @@ export function registerContextMenuListener(): void { const menu = createMenu(event, onClickChannel, items); menu.popup({ - window: withNullAsUndefined(BrowserWindow.fromWebContents(event.sender)), + window: BrowserWindow.fromWebContents(event.sender) ?? undefined, x: options ? options.x : undefined, y: options ? options.y : undefined, positioningItem: options ? options.positioningItem : undefined, diff --git a/src/vs/base/parts/ipc/common/ipc.ts b/src/vs/base/parts/ipc/common/ipc.ts index d71baaeeeb571..747e8513b1f01 100644 --- a/src/vs/base/parts/ipc/common/ipc.ts +++ b/src/vs/base/parts/ipc/common/ipc.ts @@ -8,7 +8,7 @@ import { CancelablePromise, createCancelablePromise, timeout } from 'vs/base/com import { VSBuffer } from 'vs/base/common/buffer'; import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; import { memoize } from 'vs/base/common/decorators'; -import { CancellationError } from 'vs/base/common/errors'; +import { CancellationError, ErrorNoTelemetry } from 'vs/base/common/errors'; import { Emitter, Event, EventMultiplexer, Relay } from 'vs/base/common/event'; import { combinedDisposable, DisposableStore, dispose, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; import { revive } from 'vs/base/common/marshalling'; @@ -1102,7 +1102,7 @@ export namespace ProxyChannel { } } - throw new Error(`Event not found: ${event}`); + throw new ErrorNoTelemetry(`Event not found: ${event}`); } call(_: unknown, command: string, args?: any[]): Promise { @@ -1119,7 +1119,7 @@ export namespace ProxyChannel { return target.apply(handler, args); } - throw new Error(`Method not found: ${command}`); + throw new ErrorNoTelemetry(`Method not found: ${command}`); } }; } @@ -1185,7 +1185,7 @@ export namespace ProxyChannel { }; } - throw new Error(`Property not found: ${String(propKey)}`); + throw new ErrorNoTelemetry(`Property not found: ${String(propKey)}`); } }) as T; } diff --git a/src/vs/base/parts/ipc/electron-main/ipcMain.ts b/src/vs/base/parts/ipc/electron-main/ipcMain.ts index 95e8e4e1c32e0..6fe43ab0b3a39 100644 --- a/src/vs/base/parts/ipc/electron-main/ipcMain.ts +++ b/src/vs/base/parts/ipc/electron-main/ipcMain.ts @@ -111,8 +111,12 @@ class ValidatedIpcMain implements Event.NodeEventEmitter { const sender = event.senderFrame; const url = sender.url; - if (!url) { - return true; // TODO@electron this only seems to happen from playwright runs (https://github.com/microsoft/vscode/issues/147301) + // `url` can be `undefined` when running tests from playwright https://github.com/microsoft/vscode/issues/147301 + // and `url` can be `about:blank` when reloading the window + // from performance tab of devtools https://github.com/electron/electron/issues/39427. + // It is fine to skip the checks in these cases. + if (!url || url === 'about:blank') { + return true; } let host = 'unknown'; diff --git a/src/vs/base/parts/sandbox/common/electronTypes.ts b/src/vs/base/parts/sandbox/common/electronTypes.ts index 814edae59b2fe..f8c7a35e077e0 100644 --- a/src/vs/base/parts/sandbox/common/electronTypes.ts +++ b/src/vs/base/parts/sandbox/common/electronTypes.ts @@ -17,12 +17,11 @@ export interface MessageBoxOptions { */ message: string; /** - * Can be `"none"`, `"info"`, `"error"`, `"question"` or `"warning"`. On Windows, - * `"question"` displays the same icon as `"info"`, unless you set an icon using - * the `"icon"` option. On macOS, both `"warning"` and `"error"` display the same - * warning icon. + * Can be `none`, `info`, `error`, `question` or `warning`. On Windows, `question` + * displays the same icon as `info`, unless you set an icon using the `icon` + * option. On macOS, both `warning` and `error` display the same warning icon. */ - type?: string; + type?: ('none' | 'info' | 'error' | 'question' | 'warning'); /** * Array of texts for buttons. On Windows, an empty array will result in one button * labeled "OK". diff --git a/src/vs/base/parts/storage/node/storage.ts b/src/vs/base/parts/storage/node/storage.ts index f4cf5ac78e19d..e629ab01f0e47 100644 --- a/src/vs/base/parts/storage/node/storage.ts +++ b/src/vs/base/parts/storage/node/storage.ts @@ -274,7 +274,7 @@ export class SQLiteStorageDatabase implements IStorageDatabase { try { await Promises.unlink(path); try { - await Promises.rename(this.toBackupPath(path), path); + await Promises.rename(this.toBackupPath(path), path, false /* no retry */); } catch (error) { // ignore } diff --git a/src/vs/base/test/common/observable.test.ts b/src/vs/base/test/common/observable.test.ts index 64d08a6c4d55a..4f507c7ece7fb 100644 --- a/src/vs/base/test/common/observable.test.ts +++ b/src/vs/base/test/common/observable.test.ts @@ -4,9 +4,9 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import { Emitter } from 'vs/base/common/event'; +import { Emitter, Event } from 'vs/base/common/event'; import { ISettableObservable, autorun, derived, ITransaction, observableFromEvent, observableValue, transaction, keepAlive } from 'vs/base/common/observable'; -import { BaseObservable, IObservable, IObserver } from 'vs/base/common/observableImpl/base'; +import { BaseObservable, IObservable, IObserver } from 'vs/base/common/observableInternal/base'; suite('observables', () => { /** @@ -17,7 +17,8 @@ suite('observables', () => { const log = new Log(); const myObservable = observableValue('myObservable', 0); - autorun('myAutorun', (reader) => { + autorun(reader => { + /** @description myAutorun */ log.log(`myAutorun.run(myObservable: ${myObservable.read(reader)})`); }); // The autorun runs immediately @@ -49,7 +50,8 @@ suite('observables', () => { const observable1 = observableValue('myObservable1', 0); const observable2 = observableValue('myObservable2', 0); - const myDerived = derived('myDerived', (reader) => { + const myDerived = derived(reader => { + /** @description myDerived */ const value1 = observable1.read(reader); const value2 = observable2.read(reader); const sum = value1 + value2; @@ -57,7 +59,8 @@ suite('observables', () => { return sum; }); - autorun('myAutorun', (reader) => { + autorun(reader => { + /** @description myAutorun */ log.log(`myAutorun(myDerived: ${myDerived.read(reader)})`); }); // autorun runs immediately @@ -110,7 +113,8 @@ suite('observables', () => { const observable1 = observableValue('myObservable1', 0); const observable2 = observableValue('myObservable2', 0); - const myDerived = derived('myDerived', (reader) => { + const myDerived = derived((reader) => { + /** @description myDerived */ const value1 = observable1.read(reader); const value2 = observable2.read(reader); const sum = value1 + value2; @@ -118,7 +122,8 @@ suite('observables', () => { return sum; }); - autorun('myAutorun', (reader) => { + autorun(reader => { + /** @description myAutorun */ log.log(`myAutorun(myDerived: ${myDerived.read(reader)})`); }); // autorun runs immediately @@ -147,25 +152,29 @@ suite('observables', () => { test('get without observers', () => { const log = new Log(); const observable1 = observableValue('myObservableValue1', 0); - const computed1 = derived('computed', (reader) => { + const computed1 = derived((reader) => { + /** @description computed */ const value1 = observable1.read(reader); const result = value1 % 3; log.log(`recompute1: ${value1} % 3 = ${result}`); return result; }); - const computed2 = derived('computed', (reader) => { + const computed2 = derived((reader) => { + /** @description computed */ const value1 = computed1.read(reader); const result = value1 * 2; log.log(`recompute2: ${value1} * 2 = ${result}`); return result; }); - const computed3 = derived('computed', (reader) => { + const computed3 = derived((reader) => { + /** @description computed */ const value1 = computed1.read(reader); const result = value1 * 3; log.log(`recompute3: ${value1} * 3 = ${result}`); return result; }); - const computedSum = derived('computed', (reader) => { + const computedSum = derived((reader) => { + /** @description computed */ const value1 = computed2.read(reader); const value2 = computed3.read(reader); const result = value1 + value2; @@ -256,7 +265,8 @@ suite('observables', () => { const myObservable1 = observableValue('myObservable1', 0); const myObservable2 = observableValue('myObservable2', 0); - const myComputed1 = derived('myComputed1', (reader) => { + const myComputed1 = derived(reader => { + /** @description myComputed1 */ const value1 = myObservable1.read(reader); const value2 = myObservable2.read(reader); const sum = value1 + value2; @@ -264,7 +274,8 @@ suite('observables', () => { return sum; }); - const myComputed2 = derived('myComputed2', (reader) => { + const myComputed2 = derived(reader => { + /** @description myComputed2 */ const value1 = myComputed1.read(reader); const value2 = myObservable1.read(reader); const value3 = myObservable2.read(reader); @@ -273,7 +284,8 @@ suite('observables', () => { return sum; }); - const myComputed3 = derived('myComputed3', (reader) => { + const myComputed3 = derived(reader => { + /** @description myComputed3 */ const value1 = myComputed2.read(reader); const value2 = myObservable1.read(reader); const value3 = myObservable2.read(reader); @@ -282,7 +294,8 @@ suite('observables', () => { return sum; }); - autorun('myAutorun', (reader) => { + autorun(reader => { + /** @description myAutorun */ log.log(`myAutorun.run(myComputed3: ${myComputed3.read(reader)})`); }); assert.deepStrictEqual(log.getAndClearEntries(), [ @@ -364,7 +377,8 @@ suite('observables', () => { setValue(undefined); - const autorunDisposable = autorun('MyAutorun', (reader) => { + const autorunDisposable = autorun(reader => { + /** @description MyAutorun */ observable.read(reader); log.log( `autorun, value: ${observable.read(reader)}` @@ -396,7 +410,8 @@ suite('observables', () => { const shouldReadObservable = observableValue('shouldReadObservable', true); - const autorunDisposable = autorun('MyAutorun', (reader) => { + const autorunDisposable = autorun(reader => { + /** @description MyAutorun */ if (shouldReadObservable.read(reader)) { observable.read(reader); log.log( @@ -468,14 +483,16 @@ suite('observables', () => { const shouldReadObservable = observableValue('shouldReadMyObs1', true); const myObs1 = new LoggingObservableValue('myObs1', 0, log); - const myComputed = derived('myComputed', reader => { + const myComputed = derived(reader => { + /** @description myComputed */ log.log('myComputed.recompute'); if (shouldReadObservable.read(reader)) { return myObs1.read(reader); } return 1; }); - autorun('myAutorun', reader => { + autorun(reader => { + /** @description myAutorun */ const value = myComputed.read(reader); log.log(`myAutorun: ${value}`); }); @@ -508,14 +525,16 @@ suite('observables', () => { const myObsShouldRead = new LoggingObservableValue('myObsShouldRead', true, log); const myObs1 = new LoggingObservableValue('myObs1', 0, log); - const myComputed1 = derived('myComputed1', reader => { + const myComputed1 = derived(reader => { + /** @description myComputed1 */ const myObs1Val = myObs1.read(reader); const result = myObs1Val % 10; log.log(`myComputed1(myObs1: ${myObs1Val}): Computed ${result}`); return myObs1Val; }); - autorun('myAutorun', reader => { + autorun(reader => { + /** @description myAutorun */ const shouldRead = myObsShouldRead.read(reader); if (shouldRead) { const v = myComputed1.read(reader); @@ -568,7 +587,8 @@ suite('observables', () => { const log = new Log(); const myObservable = observableValue('myObservable', 0); - autorun('myAutorun', (reader) => { + autorun(reader => { + /** @description myAutorun */ log.log(`myAutorun.run(myObservable: ${myObservable.read(reader)})`); }); assert.deepStrictEqual(log.getAndClearEntries(), ['myAutorun.run(myObservable: 0)']); @@ -587,13 +607,15 @@ suite('observables', () => { test('autorun does not rerun on indirect neutral observable double change', () => { const log = new Log(); const myObservable = observableValue('myObservable', 0); - const myDerived = derived('myDerived', (reader) => { + const myDerived = derived(reader => { + /** @description myDerived */ const val = myObservable.read(reader); log.log(`myDerived.read(myObservable: ${val})`); return val; }); - autorun('myAutorun', (reader) => { + autorun(reader => { + /** @description myAutorun */ log.log(`myAutorun.run(myDerived: ${myDerived.read(reader)})`); }); assert.deepStrictEqual(log.getAndClearEntries(), [ @@ -616,13 +638,15 @@ suite('observables', () => { test('autorun reruns on indirect neutral observable double change when changes propagate', () => { const log = new Log(); const myObservable = observableValue('myObservable', 0); - const myDerived = derived('myDerived', (reader) => { + const myDerived = derived(reader => { + /** @description myDerived */ const val = myObservable.read(reader); log.log(`myDerived.read(myObservable: ${val})`); return val; }); - autorun('myAutorun', (reader) => { + autorun(reader => { + /** @description myAutorun */ log.log(`myAutorun.run(myDerived: ${myDerived.read(reader)})`); }); assert.deepStrictEqual(log.getAndClearEntries(), [ @@ -656,7 +680,8 @@ suite('observables', () => { const myObservable2 = new LoggingObservableValue('myObservable2', 0, log); const myObservable3 = new LoggingObservableValue('myObservable3', 0, log); - const d = autorun('autorun', (reader) => { + const d = autorun(reader => { + /** @description autorun */ if (observable1.read(reader) >= 2) { assert.deepStrictEqual(log.getAndClearEntries(), [ "myObservable1.set (value 2)", @@ -706,13 +731,15 @@ suite('observables', () => { const myObservable1 = new LoggingObservableValue('myObservable1', 0, log); const myObservable2 = new LoggingObservableValue('myObservable2', 0, log); - const myDerived1 = derived('myDerived1', (reader) => { + const myDerived1 = derived(reader => { + /** @description myDerived1 */ const val = myObservable1.read(reader); log.log(`myDerived1.read(myObservable: ${val})`); return val; }); - const myDerived2 = derived('myDerived2', (reader) => { + const myDerived2 = derived(reader => { + /** @description myDerived2 */ const val = myObservable2.read(reader); if (val === 1) { myDerived1.read(reader); @@ -721,7 +748,8 @@ suite('observables', () => { return val; }); - autorun('myAutorun', (reader) => { + autorun(reader => { + /** @description myAutorun */ const myDerived1Val = myDerived1.read(reader); const myDerived2Val = myDerived2.read(reader); log.log(`myAutorun.run(myDerived1: ${myDerived1Val}, myDerived2: ${myDerived2Val})`); @@ -739,7 +767,8 @@ suite('observables', () => { const log = new Log(); const myObservable = new LoggingObservableValue('myObservable', 0, log); - const myComputed = derived('myComputed', reader => { + const myComputed = derived(reader => { + /** @description myComputed */ let value = myObservable.read(reader); const origValue = value; log.log(`myComputed(myObservable: ${origValue}): start computing`); @@ -751,7 +780,8 @@ suite('observables', () => { return value; }); - autorun('myAutorun', reader => { + autorun(reader => { + /** @description myAutorun */ const value = myComputed.read(reader); log.log(`myAutorun(myComputed: ${value})`); }); @@ -785,7 +815,8 @@ suite('observables', () => { const log = new Log(); const myObservable = new LoggingObservableValue('myObservable', 0, log); - autorun('myAutorun', reader => { + autorun(reader => { + /** @description myAutorun */ const value = myObservable.read(reader); log.log(`myAutorun(myObservable: ${value}): start`); if (value !== 0 && value < 4) { @@ -825,19 +856,22 @@ suite('observables', () => { const log = new Log(); const myObservable = new LoggingObservableValue('myObservable', 0, log); - const myDerived1 = derived('myDerived1', reader => { + const myDerived1 = derived(reader => { + /** @description myDerived1 */ const value = myObservable.read(reader); log.log(`myDerived1(myObservable: ${value}): start computing`); return value; }); - const myDerived2 = derived('myDerived2', reader => { + const myDerived2 = derived(reader => { + /** @description myDerived2 */ const value = myDerived1.read(reader); log.log(`myDerived2(myDerived1: ${value}): start computing`); return value; }); - autorun('myAutorun', reader => { + autorun(reader => { + /** @description myAutorun */ const value = myDerived2.read(reader); log.log(`myAutorun(myDerived2: ${value})`); }); @@ -880,20 +914,23 @@ suite('observables', () => { const myObservable1 = new LoggingObservableValue('myObservable1', 0, log); const myObservable2 = new LoggingObservableValue('myObservable2', 0, log); - const myDerived2 = derived('myDerived2', reader => { + const myDerived2 = derived(reader => { + /** @description myDerived2 */ const val = myObservable2.read(reader); log.log(`myDerived2.computed(myObservable2: ${val})`); return val % 10; }); - const myDerived3 = derived('myDerived3', reader => { + const myDerived3 = derived(reader => { + /** @description myDerived3 */ const val1 = myObservable1.read(reader); const val2 = myDerived2.read(reader); log.log(`myDerived3.computed(myDerived1: ${val1}, myDerived2: ${val2})`); return `${val1} + ${val2}`; }); - autorun('myAutorun', reader => { + autorun(reader => { + /** @description myAutorun */ const val = myDerived3.read(reader); log.log(`myAutorun(myDerived3: ${val})`); }); @@ -931,15 +968,17 @@ suite('observables', () => { const myObservable1 = observableValue('myObservable1', 0); const myObservable2 = observableValue('myObservable2', 0); - const myDerived1 = derived('myDerived1', reader => { + const myDerived1 = derived(reader => { + /** @description myDerived1 */ return myObservable1.read(reader); }); - const myDerived2 = derived('myDerived2', reader => { + const myDerived2 = derived(reader => { + /** @description myDerived2 */ return myObservable2.read(reader); }); - const myDerivedA1 = derived('myDerivedA1', reader => { + const myDerivedA1 = derived(reader => /** @description myDerivedA1 */ { const d1 = myDerived1.read(reader); if (d1 === 1) { // This adds an observer while myDerived is still in update mode. @@ -949,11 +988,13 @@ suite('observables', () => { } }); - autorun('myAutorun1', reader => { + autorun(reader => { + /** @description myAutorun1 */ myDerivedA1.read(reader); }); - autorun('myAutorun2', reader => { + autorun(reader => { + /** @description myAutorun2 */ myDerived2.read(reader); }); @@ -962,6 +1003,60 @@ suite('observables', () => { myObservable2.set(1, tx); }); }); + + test('bug: fromObservableLight doesnt subscribe', () => { + const log = new Log(); + const myObservable = new LoggingObservableValue('myObservable', 0, log); + + const myDerived = derived(reader => /** @description myDerived */ { + const val = myObservable.read(reader); + log.log(`myDerived.computed(myObservable2: ${val})`); + return val % 10; + }); + + const e = Event.fromObservableLight(myDerived); + log.log('event created'); + e(() => { + log.log('event fired'); + }); + + myObservable.set(1, undefined); + + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'event created', + 'myObservable.firstObserverAdded', + 'myObservable.get', + 'myDerived.computed(myObservable2: 0)', + 'myObservable.set (value 1)', + 'myObservable.get', + 'myDerived.computed(myObservable2: 1)', + 'event fired', + ]); + }); + + test('dont run autorun after dispose', () => { + const log = new Log(); + const myObservable = new LoggingObservableValue('myObservable', 0, log); + + const d = autorun(reader => { + /** @description update */ + const v = myObservable.read(reader); + log.log('autorun, myObservable:' + v); + }); + + transaction(tx => { + myObservable.set(1, tx); + d.dispose(); + }); + + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'myObservable.firstObserverAdded', + 'myObservable.get', + 'autorun, myObservable:0', + 'myObservable.set (value 1)', + 'myObservable.lastObserverRemoved', + ]); + }); }); export class LoggingObserver implements IObserver { diff --git a/src/vs/base/test/common/prefixTree.test.ts b/src/vs/base/test/common/prefixTree.test.ts new file mode 100644 index 0000000000000..b93921810d399 --- /dev/null +++ b/src/vs/base/test/common/prefixTree.test.ts @@ -0,0 +1,137 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { WellDefinedPrefixTree } from 'vs/base/common/prefixTree'; +import * as assert from 'assert'; + +suite('WellDefinedPrefixTree', () => { + let tree: WellDefinedPrefixTree; + + setup(() => { + tree = new WellDefinedPrefixTree(); + }); + + test('find', () => { + const key1 = ['foo', 'bar']; + const key2 = ['foo', 'baz']; + tree.insert(key1, 42); + tree.insert(key2, 43); + assert.strictEqual(tree.find(key1), 42); + assert.strictEqual(tree.find(key2), 43); + assert.strictEqual(tree.find(['foo', 'baz', 'bop']), undefined); + assert.strictEqual(tree.find(['foo']), undefined); + }); + + test('hasParentOfKey', () => { + const key = ['foo', 'bar']; + tree.insert(key, 42); + + assert.strictEqual(tree.hasKeyOrParent(['foo', 'bar', 'baz']), true); + assert.strictEqual(tree.hasKeyOrParent(['foo', 'bar']), true); + assert.strictEqual(tree.hasKeyOrParent(['foo']), false); + assert.strictEqual(tree.hasKeyOrParent(['baz']), false); + }); + + + test('hasKeyOrChildren', () => { + const key = ['foo', 'bar']; + tree.insert(key, 42); + + assert.strictEqual(tree.hasKeyOrChildren([]), true); + assert.strictEqual(tree.hasKeyOrChildren(['foo']), true); + assert.strictEqual(tree.hasKeyOrChildren(['foo', 'bar']), true); + assert.strictEqual(tree.hasKeyOrChildren(['foo', 'bar', 'baz']), false); + }); + + test('hasKey', () => { + const key = ['foo', 'bar']; + tree.insert(key, 42); + + assert.strictEqual(tree.hasKey(key), true); + assert.strictEqual(tree.hasKey(['foo']), false); + assert.strictEqual(tree.hasKey(['baz']), false); + assert.strictEqual(tree.hasKey(['foo', 'bar', 'baz']), false); + }); + + test('size', () => { + const key1 = ['foo', 'bar']; + const key2 = ['foo', 'baz']; + assert.strictEqual(tree.size, 0); + tree.insert(key1, 42); + assert.strictEqual(tree.size, 1); + tree.insert(key2, 43); + assert.strictEqual(tree.size, 2); + tree.insert(key2, 44); + assert.strictEqual(tree.size, 2); + }); + + test('mutate', () => { + const key1 = ['foo', 'bar']; + const key2 = ['foo', 'baz']; + tree.insert(key1, 42); + tree.insert(key2, 43); + tree.mutate(key1, (value) => { + assert.strictEqual(value, 42); + return 44; + }); + assert.strictEqual(tree.find(key1), 44); + assert.strictEqual(tree.find(key2), 43); + }); + + test('delete', () => { + const key1 = ['foo', 'bar']; + const key2 = ['foo', 'baz']; + tree.insert(key1, 42); + tree.insert(key2, 43); + assert.strictEqual(tree.size, 2); + + assert.strictEqual(tree.delete(key1), 42); + assert.strictEqual(tree.size, 1); + assert.strictEqual(tree.find(key1), undefined); + assert.strictEqual(tree.find(key2), 43); + + assert.strictEqual(tree.delete(key2), 43); + assert.strictEqual(tree.size, 0); + assert.strictEqual(tree.find(key1), undefined); + assert.strictEqual(tree.find(key2), undefined); + + tree.delete(key2); + assert.strictEqual(tree.size, 0); + }); + + test('delete child', () => { + const key1 = ['foo', 'bar']; + const key2 = ['foo', 'bar', 'baz']; + tree.insert(key1, 42); + tree.insert(key2, 43); + assert.strictEqual(tree.size, 2); + + assert.strictEqual(tree.delete(key2), 43); + assert.strictEqual(tree.size, 1); + assert.strictEqual(tree.find(key1), 42); + assert.strictEqual(tree.find(key2), undefined); + }); + + test('delete noops if deleting parent', () => { + const key1 = ['foo', 'bar']; + const key2 = ['foo', 'bar', 'baz']; + tree.insert(key2, 43); + assert.strictEqual(tree.size, 1); + + assert.strictEqual(tree.delete(key1), undefined); + assert.strictEqual(tree.size, 1); + assert.strictEqual(tree.find(key2), 43); + assert.strictEqual(tree.find(key1), undefined); + }); + + test('values', () => { + const key1 = ['foo', 'bar']; + const key2 = ['foo', 'baz']; + tree.insert(key1, 42); + tree.insert(key2, 43); + + assert.deepStrictEqual([...tree.values()], [43, 42]); + }); +}); diff --git a/src/vs/base/test/common/snapshot.ts b/src/vs/base/test/common/snapshot.ts new file mode 100644 index 0000000000000..72bbfb8b5935b --- /dev/null +++ b/src/vs/base/test/common/snapshot.ts @@ -0,0 +1,185 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Lazy } from 'vs/base/common/lazy'; +import { FileAccess } from 'vs/base/common/network'; +import { URI } from 'vs/base/common/uri'; + +declare const __readFileInTests: (path: string) => Promise; +declare const __writeFileInTests: (path: string, contents: string) => Promise; +declare const __readDirInTests: (path: string) => Promise; +declare const __unlinkInTests: (path: string) => Promise; +declare const __mkdirPInTests: (path: string) => Promise; + +// setup on import so assertSnapshot has the current context without explicit passing +let context: Lazy | undefined; +const sanitizeName = (name: string) => name.replace(/[^a-z0-9_-]/gi, '_'); +const normalizeCrlf = (str: string) => str.replace(/\r\n/g, '\n'); + +export interface ISnapshotOptions { + /** Name for snapshot file, rather than an incremented number */ + name?: string; + /** Extension name of the snapshot file, defaults to `.snap` */ + extension?: string; +} + +/** + * This is exported only for tests against the snapshotting itself! Use + * {@link assertSnapshot} as a consumer! + */ +export class SnapshotContext { + private nextIndex = 0; + protected snapshotsDir: URI; + private readonly namePrefix: string; + private readonly usedNames = new Set(); + + constructor(private readonly test: Mocha.Test | undefined) { + if (!test) { + throw new Error('assertSnapshot can only be used in a test'); + } + + if (!test.file) { + throw new Error('currentTest.file is not set, please open an issue with the test you\'re trying to run'); + } + + const src = FileAccess.asFileUri(''); + const parts = test.file.split(/[/\\]/g); + + this.namePrefix = sanitizeName(test.fullTitle()) + '_'; + this.snapshotsDir = URI.joinPath(src, ...[...parts.slice(0, -1), '__snapshots__']); + } + + public async assert(value: any, options?: ISnapshotOptions) { + const originalStack = new Error().stack!; // save to make the stack nicer on failure + const nameOrIndex = (options?.name ? sanitizeName(options.name) : this.nextIndex++); + const fileName = this.namePrefix + nameOrIndex + '.' + (options?.extension || 'snap'); + this.usedNames.add(fileName); + + const fpath = URI.joinPath(this.snapshotsDir, fileName).fsPath; + const actual = formatValue(value); + let expected: string; + try { + expected = await __readFileInTests(fpath); + } catch { + console.info(`Creating new snapshot in: ${fpath}`); + await __mkdirPInTests(this.snapshotsDir.fsPath); + await __writeFileInTests(fpath, actual); + return; + } + + if (normalizeCrlf(expected) !== normalizeCrlf(actual)) { + await __writeFileInTests(fpath + '.actual', actual); + const err: any = new Error(`Snapshot #${nameOrIndex} does not match expected output`); + err.expected = expected; + err.actual = actual; + err.snapshotPath = fpath; + err.stack = (err.stack as string) + .split('\n') + // remove all frames from the async stack and keep the original caller's frame + .slice(0, 1) + .concat(originalStack.split('\n').slice(3)) + .join('\n'); + throw err; + } + } + + public async removeOldSnapshots() { + const contents = await __readDirInTests(this.snapshotsDir.fsPath); + const toDelete = contents.filter(f => f.startsWith(this.namePrefix) && !this.usedNames.has(f)); + if (toDelete.length) { + console.info(`Deleting ${toDelete.length} old snapshots for ${this.test?.fullTitle()}`); + } + + await Promise.all(toDelete.map(f => __unlinkInTests(URI.joinPath(this.snapshotsDir, f).fsPath))); + } +} + +const debugDescriptionSymbol = Symbol.for('debug.description'); + +function formatValue(value: unknown, level = 0, seen: unknown[] = []): string { + switch (typeof value) { + case 'bigint': + case 'boolean': + case 'number': + case 'symbol': + case 'undefined': + return String(value); + case 'string': + return level === 0 ? value : JSON.stringify(value); + case 'function': + return `[Function ${value.name}]`; + case 'object': { + if (value === null) { + return 'null'; + } + if (value instanceof RegExp) { + return String(value); + } + if (seen.includes(value)) { + return '[Circular]'; + } + if (debugDescriptionSymbol in value && typeof (value as any)[debugDescriptionSymbol] === 'function') { + return (value as any)[debugDescriptionSymbol](); + } + const oi = ' '.repeat(level); + const ci = ' '.repeat(level + 1); + if (Array.isArray(value)) { + const children = value.map(v => formatValue(v, level + 1, [...seen, value])); + const multiline = children.some(c => c.includes('\n')) || children.join(', ').length > 80; + return multiline ? `[\n${ci}${children.join(`,\n${ci}`)}\n${oi}]` : `[ ${children.join(', ')} ]`; + } + + let entries; + let prefix = ''; + if (value instanceof Map) { + prefix = 'Map '; + entries = [...value.entries()]; + } else if (value instanceof Set) { + prefix = 'Set '; + entries = [...value.entries()]; + } else { + entries = Object.entries(value); + } + + const lines = entries.map(([k, v]) => `${k}: ${formatValue(v, level + 1, [...seen, value])}`); + return prefix + (lines.length > 1 + ? `{\n${ci}${lines.join(`,\n${ci}`)}\n${oi}}` + : `{ ${lines.join(',\n')} }`); + } + default: + throw new Error(`Unknown type ${value}`); + } +} + +setup(function () { + const currentTest = this.currentTest; + context = new Lazy(() => new SnapshotContext(currentTest)); +}); +teardown(async function () { + if (this.currentTest?.state === 'passed') { + await context?.rawValue?.removeOldSnapshots(); + } + context = undefined; +}); + +/** + * Implements a snapshot testing utility. āš ļø This is async! āš ļø + * + * The first time a snapshot test is run, it'll record the value it's called + * with as the expected value. Subsequent runs will fail if the value differs, + * but the snapshot can be regenerated by hand or using the Selfhost Test + * Provider Extension which'll offer to update it. + * + * The snapshot will be associated with the currently running test and stored + * in a `__snapshots__` directory next to the test file, which is expected to + * be the first `.test.js` file in the callstack. + */ +export function assertSnapshot(value: any, options?: ISnapshotOptions): Promise { + if (!context) { + throw new Error('assertSnapshot can only be used in a test'); + } + + return context.value.assert(value, options); +} diff --git a/src/vs/base/test/common/stream.test.ts b/src/vs/base/test/common/stream.test.ts index 78c38d691a4f8..63d30530a959e 100644 --- a/src/vs/base/test/common/stream.test.ts +++ b/src/vs/base/test/common/stream.test.ts @@ -6,6 +6,7 @@ import * as assert from 'assert'; import { timeout } from 'vs/base/common/async'; import { bufferToReadable, VSBuffer } from 'vs/base/common/buffer'; +import { CancellationTokenSource } from 'vs/base/common/cancellation'; import { consumeReadable, consumeStream, isReadable, isReadableBufferedStream, isReadableStream, listenStream, newWriteableStream, peekReadable, peekStream, prefixedReadable, prefixedStream, Readable, ReadableStream, toReadable, toStream, transform } from 'vs/base/common/stream'; suite('Stream', () => { @@ -351,14 +352,16 @@ suite('Stream', () => { assert.strictEqual(end, true); }); - test('listenStream - dispose', () => { + test('listenStream - cancellation', () => { const stream = newWriteableStream(strings => strings.join()); let error = false; let end = false; let data = ''; - const disposable = listenStream(stream, { + const cts = new CancellationTokenSource(); + + listenStream(stream, { onData: d => { data = d; }, @@ -368,9 +371,9 @@ suite('Stream', () => { onEnd: () => { end = true; } - }); + }, cts.token); - disposable.dispose(); + cts.cancel(); stream.write('Hello'); assert.strictEqual(data, ''); diff --git a/src/vs/base/test/common/strings.test.ts b/src/vs/base/test/common/strings.test.ts index f4bea3785b85e..18e53a2e5d0b6 100644 --- a/src/vs/base/test/common/strings.test.ts +++ b/src/vs/base/test/common/strings.test.ts @@ -265,22 +265,6 @@ suite('Strings', () => { assert(regExpWithFlags.multiline); }); - test('regExpContainsBackreference', () => { - assert(strings.regExpContainsBackreference('foo \\5 bar')); - assert(strings.regExpContainsBackreference('\\2')); - assert(strings.regExpContainsBackreference('(\\d)(\\n)(\\1)')); - assert(strings.regExpContainsBackreference('(A).*?\\1')); - assert(strings.regExpContainsBackreference('\\\\\\1')); - assert(strings.regExpContainsBackreference('foo \\\\\\1')); - - assert(!strings.regExpContainsBackreference('')); - assert(!strings.regExpContainsBackreference('\\\\1')); - assert(!strings.regExpContainsBackreference('foo \\\\1')); - assert(!strings.regExpContainsBackreference('(A).*?\\\\1')); - assert(!strings.regExpContainsBackreference('foo \\d1 bar')); - assert(!strings.regExpContainsBackreference('123')); - }); - test('getLeadingWhitespace', () => { assert.strictEqual(strings.getLeadingWhitespace(' foo'), ' '); assert.strictEqual(strings.getLeadingWhitespace(' foo', 2), ''); diff --git a/src/vs/base/test/node/__snapshots__/snapshot_cleans_up_old_snapshots_0.snap b/src/vs/base/test/node/__snapshots__/snapshot_cleans_up_old_snapshots_0.snap new file mode 100644 index 0000000000000..53d99c7989be1 --- /dev/null +++ b/src/vs/base/test/node/__snapshots__/snapshot_cleans_up_old_snapshots_0.snap @@ -0,0 +1,8 @@ +hello_world__0.snap: + { cool: true } +hello_world__1.snap: + { nifty: true } +hello_world__fourthTest.snap: + { customName: 2 } +hello_world__thirdTest.txt: + { customName: 1 } diff --git a/src/vs/base/test/node/__snapshots__/snapshot_cleans_up_old_snapshots_1.snap b/src/vs/base/test/node/__snapshots__/snapshot_cleans_up_old_snapshots_1.snap new file mode 100644 index 0000000000000..b7106c217c20a --- /dev/null +++ b/src/vs/base/test/node/__snapshots__/snapshot_cleans_up_old_snapshots_1.snap @@ -0,0 +1,4 @@ +hello_world__0.snap: + { cool: true } +hello_world__thirdTest.snap: + { customName: 1 } diff --git a/src/vs/base/test/node/__snapshots__/snapshot_creates_a_snapshot_0.snap b/src/vs/base/test/node/__snapshots__/snapshot_creates_a_snapshot_0.snap new file mode 100644 index 0000000000000..4c53158fc136b --- /dev/null +++ b/src/vs/base/test/node/__snapshots__/snapshot_creates_a_snapshot_0.snap @@ -0,0 +1,2 @@ +hello_world__0.snap: + { cool: true } diff --git a/src/vs/base/test/node/__snapshots__/snapshot_formats_object_nicely_0.snap b/src/vs/base/test/node/__snapshots__/snapshot_formats_object_nicely_0.snap new file mode 100644 index 0000000000000..d5e7745d23286 --- /dev/null +++ b/src/vs/base/test/node/__snapshots__/snapshot_formats_object_nicely_0.snap @@ -0,0 +1,35 @@ +[ + 1, + true, + undefined, + null, + 123, + Symbol(heyo), + "hello", + { hello: "world" }, + { a: [Circular] }, + Map { + hello: 1, + goodbye: 2 + }, + Set { + 1: 1, + 2: 2, + 3: 3 + }, + [Function helloWorld], + /hello/g, + [ + "long stringlong stringlong stringlong stringlong stringlong stringlong stringlong stringlong stringlong string", + "long stringlong stringlong stringlong stringlong stringlong stringlong stringlong stringlong stringlong string", + "long stringlong stringlong stringlong stringlong stringlong stringlong stringlong stringlong stringlong string", + "long stringlong stringlong stringlong stringlong stringlong stringlong stringlong stringlong stringlong string", + "long stringlong stringlong stringlong stringlong stringlong stringlong stringlong stringlong stringlong string", + "long stringlong stringlong stringlong stringlong stringlong stringlong stringlong stringlong stringlong string", + "long stringlong stringlong stringlong stringlong stringlong stringlong stringlong stringlong stringlong string", + "long stringlong stringlong stringlong stringlong stringlong stringlong stringlong stringlong stringlong string", + "long stringlong stringlong stringlong stringlong stringlong stringlong stringlong stringlong stringlong string", + "long stringlong stringlong stringlong stringlong stringlong stringlong stringlong stringlong stringlong string" + ], + Range [1 -> 5] +] \ No newline at end of file diff --git a/src/vs/base/test/node/nodeStreams.test.ts b/src/vs/base/test/node/nodeStreams.test.ts new file mode 100644 index 0000000000000..620f817dfc9ef --- /dev/null +++ b/src/vs/base/test/node/nodeStreams.test.ts @@ -0,0 +1,51 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + + +import { Writable } from 'stream'; +import * as assert from 'assert'; +import { StreamSplitter } from 'vs/base/node/nodeStreams'; + +suite('StreamSplitter', () => { + test('should split a stream on a single character splitter', (done) => { + const chunks: string[] = []; + const splitter = new StreamSplitter('\n'); + const writable = new Writable({ + write(chunk, _encoding, callback) { + chunks.push(chunk.toString()); + callback(); + }, + }); + + splitter.pipe(writable); + splitter.write('hello\nwor'); + splitter.write('ld\n'); + splitter.write('foo\nbar\nz'); + splitter.end(() => { + assert.deepStrictEqual(chunks, ['hello\n', 'world\n', 'foo\n', 'bar\n', 'z']); + done(); + }); + }); + + test('should split a stream on a multi-character splitter', (done) => { + const chunks: string[] = []; + const splitter = new StreamSplitter('---'); + const writable = new Writable({ + write(chunk, _encoding, callback) { + chunks.push(chunk.toString()); + callback(); + }, + }); + + splitter.pipe(writable); + splitter.write('hello---wor'); + splitter.write('ld---'); + splitter.write('foo---bar---z'); + splitter.end(() => { + assert.deepStrictEqual(chunks, ['hello---', 'world---', 'foo---', 'bar---', 'z']); + done(); + }); + }); +}); diff --git a/src/vs/base/test/node/pfs/pfs.test.ts b/src/vs/base/test/node/pfs/pfs.test.ts index cefdc23af5b2e..3a0fc605a71c5 100644 --- a/src/vs/base/test/node/pfs/pfs.test.ts +++ b/src/vs/base/test/node/pfs/pfs.test.ts @@ -173,7 +173,7 @@ flakySuite('PFS', function () { assert.ok(!fs.existsSync(testDir)); }); - test('copy, move and delete', async () => { + test('copy, rename and delete', async () => { const sourceDir = FileAccess.asFileUri('vs/base/test/node/pfs/fixtures').fsPath; const parentDir = join(tmpdir(), 'vsctests', 'pfs'); const targetDir = randomPath(parentDir); @@ -188,7 +188,7 @@ flakySuite('PFS', function () { assert.ok(fs.statSync(join(targetDir, 'examples')).isDirectory()); assert.ok(fs.existsSync(join(targetDir, 'examples', 'small.jxs'))); - await Promises.move(targetDir, targetDir2); + await Promises.rename(targetDir, targetDir2); assert.ok(!fs.existsSync(targetDir)); assert.ok(fs.existsSync(targetDir2)); @@ -198,7 +198,34 @@ flakySuite('PFS', function () { assert.ok(fs.statSync(join(targetDir2, 'examples')).isDirectory()); assert.ok(fs.existsSync(join(targetDir2, 'examples', 'small.jxs'))); - await Promises.move(join(targetDir2, 'index.html'), join(targetDir2, 'index_moved.html')); + await Promises.rename(join(targetDir2, 'index.html'), join(targetDir2, 'index_moved.html')); + + assert.ok(!fs.existsSync(join(targetDir2, 'index.html'))); + assert.ok(fs.existsSync(join(targetDir2, 'index_moved.html'))); + + await Promises.rm(parentDir); + + assert.ok(!fs.existsSync(parentDir)); + }); + + test('rename without retry', async () => { + const sourceDir = FileAccess.asFileUri('vs/base/test/node/pfs/fixtures').fsPath; + const parentDir = join(tmpdir(), 'vsctests', 'pfs'); + const targetDir = randomPath(parentDir); + const targetDir2 = randomPath(parentDir); + + await Promises.copy(sourceDir, targetDir, { preserveSymlinks: true }); + await Promises.rename(targetDir, targetDir2, false); + + assert.ok(!fs.existsSync(targetDir)); + assert.ok(fs.existsSync(targetDir2)); + assert.ok(fs.existsSync(join(targetDir2, 'index.html'))); + assert.ok(fs.existsSync(join(targetDir2, 'site.css'))); + assert.ok(fs.existsSync(join(targetDir2, 'examples'))); + assert.ok(fs.statSync(join(targetDir2, 'examples')).isDirectory()); + assert.ok(fs.existsSync(join(targetDir2, 'examples', 'small.jxs'))); + + await Promises.rename(join(targetDir2, 'index.html'), join(targetDir2, 'index_moved.html'), false); assert.ok(!fs.existsSync(join(targetDir2, 'index.html'))); assert.ok(fs.existsSync(join(targetDir2, 'index_moved.html'))); diff --git a/src/vs/base/test/node/snapshot.test.ts b/src/vs/base/test/node/snapshot.test.ts new file mode 100644 index 0000000000000..6c12ae70dd302 --- /dev/null +++ b/src/vs/base/test/node/snapshot.test.ts @@ -0,0 +1,146 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { tmpdir } from 'os'; +import { getRandomTestPath } from 'vs/base/test/node/testUtils'; +import { Promises } from 'vs/base/node/pfs'; +import { SnapshotContext, assertSnapshot } from 'vs/base/test/common/snapshot'; +import { URI } from 'vs/base/common/uri'; +import path = require('path'); +import { assertThrowsAsync } from 'vs/base/test/common/utils'; + +// tests for snapshot are in Node so that we can use native FS operations to +// set up and validate things. +// +// Uses snapshots for testing snapshots. It's snapception! + +suite('snapshot', () => { + let testDir: string; + + setup(function () { + testDir = getRandomTestPath(tmpdir(), 'vsctests', 'snapshot'); + return Promises.mkdir(testDir, { recursive: true }); + }); + + teardown(function () { + return Promises.rm(testDir); + }); + + const makeContext = (test: Partial | undefined) => { + return new class extends SnapshotContext { + constructor() { + super(test as Mocha.Test); + this.snapshotsDir = URI.file(testDir); + } + }; + }; + + const snapshotFileTree = async () => { + let str = ''; + + const printDir = async (dir: string, indent: number) => { + const children = await Promises.readdir(dir); + for (const child of children) { + const p = path.join(dir, child); + if ((await Promises.stat(p)).isFile()) { + const content = await Promises.readFile(p, 'utf-8'); + str += `${' '.repeat(indent)}${child}:\n`; + for (const line of content.split('\n')) { + str += `${' '.repeat(indent + 2)}${line}\n`; + } + } else { + str += `${' '.repeat(indent)}${child}/\n`; + await printDir(p, indent + 2); + } + } + }; + + await printDir(testDir, 0); + await assertSnapshot(str); + }; + + test('creates a snapshot', async () => { + const ctx = makeContext({ + file: 'foo/bar', + fullTitle: () => 'hello world!' + }); + + await ctx.assert({ cool: true }); + await snapshotFileTree(); + }); + + test('validates a snapshot', async () => { + const ctx1 = makeContext({ + file: 'foo/bar', + fullTitle: () => 'hello world!' + }); + + await ctx1.assert({ cool: true }); + + const ctx2 = makeContext({ + file: 'foo/bar', + fullTitle: () => 'hello world!' + }); + + // should pass: + await ctx2.assert({ cool: true }); + + const ctx3 = makeContext({ + file: 'foo/bar', + fullTitle: () => 'hello world!' + }); + + // should fail: + await assertThrowsAsync(() => ctx3.assert({ cool: false })); + }); + + test('cleans up old snapshots', async () => { + const ctx1 = makeContext({ + file: 'foo/bar', + fullTitle: () => 'hello world!' + }); + + await ctx1.assert({ cool: true }); + await ctx1.assert({ nifty: true }); + await ctx1.assert({ customName: 1 }, { name: 'thirdTest', extension: 'txt' }); + await ctx1.assert({ customName: 2 }, { name: 'fourthTest' }); + + await snapshotFileTree(); + + const ctx2 = makeContext({ + file: 'foo/bar', + fullTitle: () => 'hello world!' + }); + + await ctx2.assert({ cool: true }); + await ctx2.assert({ customName: 1 }, { name: 'thirdTest' }); + await ctx2.removeOldSnapshots(); + + await snapshotFileTree(); + }); + + test('formats object nicely', async () => { + const circular: any = {}; + circular.a = circular; + + await assertSnapshot([ + 1, + true, + undefined, + null, + 123n, + Symbol('heyo'), + 'hello', + { hello: 'world' }, + circular, + new Map([['hello', 1], ['goodbye', 2]]), + new Set([1, 2, 3]), + function helloWorld() { }, + /hello/g, + new Array(10).fill('long string'.repeat(10)), + { [Symbol.for('debug.description')]() { return `Range [1 -> 5]`; } }, + ]); + }); +}); diff --git a/src/vs/base/worker/workerMain.ts b/src/vs/base/worker/workerMain.ts index 65df427d79eb0..ec18c5ca0f468 100644 --- a/src/vs/base/worker/workerMain.ts +++ b/src/vs/base/worker/workerMain.ts @@ -54,7 +54,7 @@ try { const func = ( trustedTypesPolicy - ? globalThis.eval(trustedTypesPolicy.createScript('', 'true')) + ? globalThis.eval(trustedTypesPolicy.createScript('', 'true')) // CodeQL [SM01632] fetch + eval is used on the web worker instead of importScripts if possible because importScripts is synchronous and we observed deadlocks on Safari : new Function('true') // CodeQL [SM01632] fetch + eval is used on the web worker instead of importScripts if possible because importScripts is synchronous and we observed deadlocks on Safari ); func.call(globalThis); diff --git a/src/vs/code/browser/workbench/workbench.html b/src/vs/code/browser/workbench/workbench.html index a41b5dbf7bdc6..addc28f0c4d37 100644 --- a/src/vs/code/browser/workbench/workbench.html +++ b/src/vs/code/browser/workbench/workbench.html @@ -43,7 +43,9 @@ // Set up nls if the user is not using the default language (English) const nlsConfig = {}; - const locale = window.localStorage.getItem('vscode.nls.locale') || navigator.language; + // Normalize locale to lowercase because translationServiceUrl is case-sensitive. + // ref: https://github.com/microsoft/vscode/issues/187795 + const locale = window.localStorage.getItem('vscode.nls.locale') || navigator.language.toLowerCase(); if (!locale.startsWith('en')) { nlsConfig['vs/nls'] = { availableLanguages: { diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index 212689e3c33e4..bd6fb95a75d65 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -934,7 +934,7 @@ export class CodeApplication extends Disposable { services.set(IIssueMainService, new SyncDescriptor(IssueMainService, [this.userEnv])); // Encryption - services.set(IEncryptionMainService, new SyncDescriptor(EncryptionMainService, [machineId])); + services.set(IEncryptionMainService, new SyncDescriptor(EncryptionMainService)); // Keyboard Layout services.set(IKeyboardLayoutMainService, new SyncDescriptor(KeyboardLayoutMainService)); diff --git a/src/vs/code/electron-main/auth.ts b/src/vs/code/electron-main/auth.ts index 9e56bcfa902f0..9e6793fd489d5 100644 --- a/src/vs/code/electron-main/auth.ts +++ b/src/vs/code/electron-main/auth.ts @@ -13,6 +13,8 @@ import { ICredentialsMainService } from 'vs/platform/credentials/common/credenti import { IEncryptionMainService } from 'vs/platform/encryption/common/encryptionService'; import { ILogService } from 'vs/platform/log/common/log'; import { IProductService } from 'vs/platform/product/common/productService'; +import { StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; +import { IApplicationStorageMainService } from 'vs/platform/storage/electron-main/storageMainService'; import { IWindowsMainService } from 'vs/platform/windows/electron-main/windows'; interface ElectronAuthenticationResponseDetails extends AuthenticationResponseDetails { @@ -56,7 +58,8 @@ enum ProxyAuthState { export class ProxyAuthHandler extends Disposable { - private readonly PROXY_CREDENTIALS_SERVICE_KEY = `${this.productService.urlProtocol}.proxy-credentials`; + private readonly OLD_PROXY_CREDENTIALS_SERVICE_KEY = `${this.productService.urlProtocol}.proxy-credentials`; + private readonly PROXY_CREDENTIALS_SERVICE_KEY = 'proxy-credentials://'; private pendingProxyResolve: Promise | undefined = undefined; @@ -69,6 +72,7 @@ export class ProxyAuthHandler extends Disposable { @IWindowsMainService private readonly windowsMainService: IWindowsMainService, @ICredentialsMainService private readonly credentialsService: ICredentialsMainService, @IEncryptionMainService private readonly encryptionMainService: IEncryptionMainService, + @IApplicationStorageMainService private readonly applicationStorageMainService: IApplicationStorageMainService, @IProductService private readonly productService: IProductService ) { super(); @@ -141,29 +145,43 @@ export class ProxyAuthHandler extends Disposable { return undefined; } - private async doResolveProxyCredentials(authInfo: AuthInfo): Promise { - this.logService.trace('auth#doResolveProxyCredentials - enter', authInfo); - - // Compute a hash over the authentication info to be used - // with the credentials store to return the right credentials - // given the properties of the auth request - // (see https://github.com/microsoft/vscode/issues/109497) - const authInfoHash = String(hash({ scheme: authInfo.scheme, host: authInfo.host, port: authInfo.port })); - + // TODO: remove this migration in a release or two. + private async getAndMigrateProxyCredentials(authInfoHash: string): Promise<{ storedUsername: string | undefined; storedPassword: string | undefined }> { // Find any previously stored credentials - let storedUsername: string | undefined = undefined; - let storedPassword: string | undefined = undefined; try { - const encryptedSerializedProxyCredentials = await this.credentialsService.getPassword(this.PROXY_CREDENTIALS_SERVICE_KEY, authInfoHash); + let encryptedSerializedProxyCredentials = this.applicationStorageMainService.get(this.PROXY_CREDENTIALS_SERVICE_KEY + authInfoHash, StorageScope.APPLICATION); + let decryptedSerializedProxyCredentials: string | undefined; + if (!encryptedSerializedProxyCredentials) { + encryptedSerializedProxyCredentials = await this.credentialsService.getPassword(this.OLD_PROXY_CREDENTIALS_SERVICE_KEY, authInfoHash) ?? undefined; + if (encryptedSerializedProxyCredentials) { + // re-encrypt to force new encryption algorithm to apply + decryptedSerializedProxyCredentials = await this.encryptionMainService.decrypt(encryptedSerializedProxyCredentials); + encryptedSerializedProxyCredentials = await this.encryptionMainService.encrypt(decryptedSerializedProxyCredentials); + this.applicationStorageMainService.store(this.PROXY_CREDENTIALS_SERVICE_KEY + authInfoHash, encryptedSerializedProxyCredentials, StorageScope.APPLICATION, StorageTarget.MACHINE); + // Remove it from the old location since it's in the new location. + await this.credentialsService.deletePassword(this.OLD_PROXY_CREDENTIALS_SERVICE_KEY, authInfoHash); + } + } if (encryptedSerializedProxyCredentials) { - const credentials: Credentials = JSON.parse(await this.encryptionMainService.decrypt(encryptedSerializedProxyCredentials)); + const credentials: Credentials = JSON.parse(decryptedSerializedProxyCredentials ?? await this.encryptionMainService.decrypt(encryptedSerializedProxyCredentials)); - storedUsername = credentials.username; - storedPassword = credentials.password; + return { storedUsername: credentials.username, storedPassword: credentials.password }; } } catch (error) { this.logService.error(error); // handle errors by asking user for login via dialog } + return { storedUsername: undefined, storedPassword: undefined }; + } + + private async doResolveProxyCredentials(authInfo: AuthInfo): Promise { + this.logService.trace('auth#doResolveProxyCredentials - enter', authInfo); + + // Compute a hash over the authentication info to be used + // with the credentials store to return the right credentials + // given the properties of the auth request + // (see https://github.com/microsoft/vscode/issues/109497) + const authInfoHash = String(hash({ scheme: authInfo.scheme, host: authInfo.host, port: authInfo.port })); + const { storedUsername, storedPassword } = await this.getAndMigrateProxyCredentials(authInfoHash); // Reply with stored credentials unless we used them already. // In that case we need to show a login dialog again because @@ -212,9 +230,9 @@ export class ProxyAuthHandler extends Disposable { try { if (reply.remember) { const encryptedSerializedCredentials = await this.encryptionMainService.encrypt(JSON.stringify(credentials)); - await this.credentialsService.setPassword(this.PROXY_CREDENTIALS_SERVICE_KEY, authInfoHash, encryptedSerializedCredentials); + this.applicationStorageMainService.store(this.PROXY_CREDENTIALS_SERVICE_KEY + authInfoHash, encryptedSerializedCredentials, StorageScope.APPLICATION, StorageTarget.MACHINE); } else { - await this.credentialsService.deletePassword(this.PROXY_CREDENTIALS_SERVICE_KEY, authInfoHash); + this.applicationStorageMainService.remove(this.PROXY_CREDENTIALS_SERVICE_KEY + authInfoHash, StorageScope.APPLICATION); } } catch (error) { this.logService.error(error); // handle gracefully diff --git a/src/vs/code/node/cli.ts b/src/vs/code/node/cli.ts index 3b8233173033f..4770e9ef0bd9b 100644 --- a/src/vs/code/node/cli.ts +++ b/src/vs/code/node/cli.ts @@ -15,7 +15,7 @@ import { whenDeleted, writeFileSync } from 'vs/base/node/pfs'; import { findFreePort } from 'vs/base/node/ports'; import { watchFileContents } from 'vs/platform/files/node/watcher/nodejs/nodejsWatcherLib'; import { NativeParsedArgs } from 'vs/platform/environment/common/argv'; -import { buildHelpMessage, buildVersionMessage, OPTIONS } from 'vs/platform/environment/node/argv'; +import { buildHelpMessage, buildVersionMessage, NATIVE_CLI_COMMANDS, OPTIONS } from 'vs/platform/environment/node/argv'; import { addArg, parseCLIProcessArgv } from 'vs/platform/environment/node/argvHelper'; import { getStdinFilePath, hasStdinWithoutTty, readFromStdin, stdinDataListener } from 'vs/platform/environment/node/stdin'; import { createWaitMarkerFileSync } from 'vs/platform/environment/node/wait'; @@ -51,31 +51,33 @@ export async function main(argv: string[]): Promise { return; } - if (args.tunnel) { - if (!product.tunnelApplicationName) { - console.error(`'tunnel' command not supported in ${product.applicationName}`); - return; - } - const tunnelArgs = argv.slice(argv.indexOf('tunnel') + 1); // all arguments behind `tunnel` - return new Promise((resolve, reject) => { - let tunnelProcess: ChildProcess; - const stdio: StdioOptions = ['ignore', 'pipe', 'pipe']; - if (process.env['VSCODE_DEV']) { - tunnelProcess = spawn('cargo', ['run', '--', 'tunnel', ...tunnelArgs], { cwd: join(getAppRoot(), 'cli'), stdio }); - } else { - const appPath = process.platform === 'darwin' - // ./Contents/MacOS/Electron => ./Contents/Resources/app/bin/code-tunnel-insiders - ? join(dirname(dirname(process.execPath)), 'Resources', 'app') - : dirname(process.execPath); - const tunnelCommand = join(appPath, 'bin', `${product.tunnelApplicationName}${isWindows ? '.exe' : ''}`); - tunnelProcess = spawn(tunnelCommand, ['tunnel', ...tunnelArgs], { cwd: cwd(), stdio }); + for (const subcommand of NATIVE_CLI_COMMANDS) { + if (args[subcommand]) { + if (!product.tunnelApplicationName) { + console.error(`'${subcommand}' command not supported in ${product.applicationName}`); + return; } + const tunnelArgs = argv.slice(argv.indexOf(subcommand) + 1); // all arguments behind `tunnel` + return new Promise((resolve, reject) => { + let tunnelProcess: ChildProcess; + const stdio: StdioOptions = ['ignore', 'pipe', 'pipe']; + if (process.env['VSCODE_DEV']) { + tunnelProcess = spawn('cargo', ['run', '--', subcommand, ...tunnelArgs], { cwd: join(getAppRoot(), 'cli'), stdio }); + } else { + const appPath = process.platform === 'darwin' + // ./Contents/MacOS/Electron => ./Contents/Resources/app/bin/code-tunnel-insiders + ? join(dirname(dirname(process.execPath)), 'Resources', 'app') + : dirname(process.execPath); + const tunnelCommand = join(appPath, 'bin', `${product.tunnelApplicationName}${isWindows ? '.exe' : ''}`); + tunnelProcess = spawn(tunnelCommand, [subcommand, ...tunnelArgs], { cwd: cwd(), stdio }); + } - tunnelProcess.stdout!.pipe(process.stdout); - tunnelProcess.stderr!.pipe(process.stderr); - tunnelProcess.on('exit', resolve); - tunnelProcess.on('error', reject); - }); + tunnelProcess.stdout!.pipe(process.stdout); + tunnelProcess.stderr!.pipe(process.stderr); + tunnelProcess.on('exit', resolve); + tunnelProcess.on('error', reject); + }); + } } // Help diff --git a/src/vs/code/node/cliProcessMain.ts b/src/vs/code/node/cliProcessMain.ts index 0065a8da62e6f..a003267c0434a 100644 --- a/src/vs/code/node/cliProcessMain.ts +++ b/src/vs/code/node/cliProcessMain.ts @@ -192,7 +192,8 @@ class CliMain extends Disposable { services.set(IUriIdentityService, new UriIdentityService(fileService)); // Request - services.set(IRequestService, new SyncDescriptor(RequestService, undefined, true)); + const requestService = new RequestService(configurationService, environmentService, logService, loggerService); + services.set(IRequestService, requestService); // Download Service services.set(IDownloadService, new SyncDescriptor(DownloadService, undefined, true)); @@ -212,7 +213,7 @@ class CliMain extends Disposable { const isInternal = isInternalTelemetry(productService, configurationService); if (supportsTelemetry(productService, environmentService)) { if (productService.aiConfig && productService.aiConfig.ariaKey) { - appenders.push(new OneDataSystemAppender(isInternal, 'monacoworkbench', null, productService.aiConfig.ariaKey)); + appenders.push(new OneDataSystemAppender(requestService, isInternal, 'monacoworkbench', null, productService.aiConfig.ariaKey)); } const config: ITelemetryServiceConfig = { diff --git a/src/vs/code/node/sharedProcess/sharedProcessMain.ts b/src/vs/code/node/sharedProcess/sharedProcessMain.ts index d8b6d791e74b2..f911b0da431c2 100644 --- a/src/vs/code/node/sharedProcess/sharedProcessMain.ts +++ b/src/vs/code/node/sharedProcess/sharedProcessMain.ts @@ -251,7 +251,8 @@ class SharedProcessMain extends Disposable { services.set(IUriIdentityService, uriIdentityService); // Request - services.set(IRequestService, new RequestChannelClient(mainProcessService.getChannel('request'))); + const requestService = new RequestChannelClient(mainProcessService.getChannel('request')); + services.set(IRequestService, requestService); // Checksum services.set(IChecksumService, new SyncDescriptor(ChecksumService, undefined, false /* proxied to other processes */)); @@ -279,7 +280,7 @@ class SharedProcessMain extends Disposable { const logAppender = new TelemetryLogAppender(logService, loggerService, environmentService, productService); appenders.push(logAppender); if (productService.aiConfig?.ariaKey) { - const collectorAppender = new OneDataSystemAppender(internalTelemetry, 'monacoworkbench', null, productService.aiConfig.ariaKey); + const collectorAppender = new OneDataSystemAppender(requestService, internalTelemetry, 'monacoworkbench', null, productService.aiConfig.ariaKey); this._register(toDisposable(() => collectorAppender.flush())); // Ensure the 1DS appender is disposed so that it flushes remaining data appenders.push(collectorAppender); } diff --git a/src/vs/editor/browser/controller/mouseTarget.ts b/src/vs/editor/browser/controller/mouseTarget.ts index bbd250053d9fc..b39b8f95ba601 100644 --- a/src/vs/editor/browser/controller/mouseTarget.ts +++ b/src/vs/editor/browser/controller/mouseTarget.ts @@ -29,7 +29,7 @@ const enum HitTestResultType { class UnknownHitTestResult { readonly type = HitTestResultType.Unknown; constructor( - readonly hitTarget: Element | null = null + readonly hitTarget: HTMLElement | null = null ) { } } @@ -72,31 +72,31 @@ export class MouseTarget { } return range ?? null; } - public static createUnknown(element: Element | null, mouseColumn: number, position: Position | null): IMouseTargetUnknown { + public static createUnknown(element: HTMLElement | null, mouseColumn: number, position: Position | null): IMouseTargetUnknown { return { type: MouseTargetType.UNKNOWN, element, mouseColumn, position, range: this._deduceRage(position) }; } - public static createTextarea(element: Element | null, mouseColumn: number): IMouseTargetTextarea { + public static createTextarea(element: HTMLElement | null, mouseColumn: number): IMouseTargetTextarea { return { type: MouseTargetType.TEXTAREA, element, mouseColumn, position: null, range: null }; } - public static createMargin(type: MouseTargetType.GUTTER_GLYPH_MARGIN | MouseTargetType.GUTTER_LINE_NUMBERS | MouseTargetType.GUTTER_LINE_DECORATIONS, element: Element | null, mouseColumn: number, position: Position, range: EditorRange, detail: IMouseTargetMarginData): IMouseTargetMargin { + public static createMargin(type: MouseTargetType.GUTTER_GLYPH_MARGIN | MouseTargetType.GUTTER_LINE_NUMBERS | MouseTargetType.GUTTER_LINE_DECORATIONS, element: HTMLElement | null, mouseColumn: number, position: Position, range: EditorRange, detail: IMouseTargetMarginData): IMouseTargetMargin { return { type, element, mouseColumn, position, range, detail }; } - public static createViewZone(type: MouseTargetType.GUTTER_VIEW_ZONE | MouseTargetType.CONTENT_VIEW_ZONE, element: Element | null, mouseColumn: number, position: Position, detail: IMouseTargetViewZoneData): IMouseTargetViewZone { + public static createViewZone(type: MouseTargetType.GUTTER_VIEW_ZONE | MouseTargetType.CONTENT_VIEW_ZONE, element: HTMLElement | null, mouseColumn: number, position: Position, detail: IMouseTargetViewZoneData): IMouseTargetViewZone { return { type, element, mouseColumn, position, range: this._deduceRage(position), detail }; } - public static createContentText(element: Element | null, mouseColumn: number, position: Position, range: EditorRange | null, detail: IMouseTargetContentTextData): IMouseTargetContentText { + public static createContentText(element: HTMLElement | null, mouseColumn: number, position: Position, range: EditorRange | null, detail: IMouseTargetContentTextData): IMouseTargetContentText { return { type: MouseTargetType.CONTENT_TEXT, element, mouseColumn, position, range: this._deduceRage(position, range), detail }; } - public static createContentEmpty(element: Element | null, mouseColumn: number, position: Position, detail: IMouseTargetContentEmptyData): IMouseTargetContentEmpty { + public static createContentEmpty(element: HTMLElement | null, mouseColumn: number, position: Position, detail: IMouseTargetContentEmptyData): IMouseTargetContentEmpty { return { type: MouseTargetType.CONTENT_EMPTY, element, mouseColumn, position, range: this._deduceRage(position), detail }; } - public static createContentWidget(element: Element | null, mouseColumn: number, detail: string): IMouseTargetContentWidget { + public static createContentWidget(element: HTMLElement | null, mouseColumn: number, detail: string): IMouseTargetContentWidget { return { type: MouseTargetType.CONTENT_WIDGET, element, mouseColumn, position: null, range: null, detail }; } - public static createScrollbar(element: Element | null, mouseColumn: number, position: Position): IMouseTargetScrollbar { + public static createScrollbar(element: HTMLElement | null, mouseColumn: number, position: Position): IMouseTargetScrollbar { return { type: MouseTargetType.SCROLLBAR, element, mouseColumn, position, range: this._deduceRage(position) }; } - public static createOverlayWidget(element: Element | null, mouseColumn: number, detail: string): IMouseTargetOverlayWidget { + public static createOverlayWidget(element: HTMLElement | null, mouseColumn: number, detail: string): IMouseTargetOverlayWidget { return { type: MouseTargetType.OVERLAY_WIDGET, element, mouseColumn, position: null, range: null, detail }; } public static createOutsideEditor(mouseColumn: number, position: Position, outsidePosition: 'above' | 'below' | 'left' | 'right', outsideDistance: number): IMouseTargetOutsideEditor { @@ -198,6 +198,13 @@ class ElementPath { ); } + public static isChildOfOverflowGuard(path: Uint8Array): boolean { + return ( + path.length >= 1 + && path[0] === PartFingerprint.OverflowGuard + ); + } + public static isChildOfOverflowingContentWidgets(path: Uint8Array): boolean { return ( path.length >= 1 @@ -389,10 +396,10 @@ abstract class BareHitTestRequest { class HitTestRequest extends BareHitTestRequest { private readonly _ctx: HitTestContext; - public readonly target: Element | null; + public readonly target: HTMLElement | null; public readonly targetPath: Uint8Array; - constructor(ctx: HitTestContext, editorPos: EditorPagePosition, pos: PageCoordinates, relativePos: CoordinatesRelativeToEditor, target: Element | null) { + constructor(ctx: HitTestContext, editorPos: EditorPagePosition, pos: PageCoordinates, relativePos: CoordinatesRelativeToEditor, target: HTMLElement | null) { super(ctx, editorPos, pos, relativePos); this._ctx = ctx; @@ -445,13 +452,13 @@ class HitTestRequest extends BareHitTestRequest { return MouseTarget.createOverlayWidget(this.target, this._getMouseColumn(), detail); } - public withTarget(target: Element | null): HitTestRequest { + public withTarget(target: HTMLElement | null): HitTestRequest { return new HitTestRequest(this._ctx, this.editorPos, this.pos, this.relativePos, target); } } interface ResolvedHitTestRequest extends HitTestRequest { - readonly target: Element; + readonly target: HTMLElement; } const EMPTY_CONTENT_AFTER_LINES: IMouseTargetContentEmptyData = { isAfterLines: true }; @@ -538,6 +545,11 @@ export class MouseTargetFactory { let result: IMouseTarget | null = null; + if (!ElementPath.isChildOfOverflowGuard(request.targetPath) && !ElementPath.isChildOfOverflowingContentWidgets(request.targetPath)) { + // We only render dom nodes inside the overflow guard or in the overflowing content widgets + result = result || request.fulfillUnknown(); + } + result = result || MouseTargetFactory._hitTestContentWidget(ctx, resolvedRequest); result = result || MouseTargetFactory._hitTestOverlayWidget(ctx, resolvedRequest); result = result || MouseTargetFactory._hitTestMinimap(ctx, resolvedRequest); diff --git a/src/vs/editor/browser/controller/textAreaHandler.ts b/src/vs/editor/browser/controller/textAreaHandler.ts index bc95af4fe9e61..94fa1a8bdb173 100644 --- a/src/vs/editor/browser/controller/textAreaHandler.ts +++ b/src/vs/editor/browser/controller/textAreaHandler.ts @@ -35,6 +35,7 @@ import { TokenizationRegistry } from 'vs/editor/common/languages'; import { ColorId, ITokenPresentation } from 'vs/editor/common/encodedTokenAttributes'; import { Color } from 'vs/base/common/color'; import { IME } from 'vs/base/common/ime'; +import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; export interface IVisibleRangeProvider { visibleRangeForPosition(position: Position): HorizontalPosition | null; @@ -140,7 +141,12 @@ export class TextAreaHandler extends ViewPart { public readonly textAreaCover: FastDomNode; private readonly _textAreaInput: TextAreaInput; - constructor(context: ViewContext, viewController: ViewController, visibleRangeProvider: IVisibleRangeProvider) { + constructor( + context: ViewContext, + viewController: ViewController, + visibleRangeProvider: IVisibleRangeProvider, + @IKeybindingService private readonly _keybindingService: IKeybindingService + ) { super(context); this._viewController = viewController; @@ -553,7 +559,21 @@ export class TextAreaHandler extends ViewPart { private _getAriaLabel(options: IComputedEditorOptions): string { const accessibilitySupport = options.get(EditorOption.accessibilitySupport); if (accessibilitySupport === AccessibilitySupport.Disabled) { - return nls.localize('accessibilityOffAriaLabel', "The editor is not accessible at this time. Press {0} for options.", platform.isLinux ? 'Shift+Alt+F1' : 'Alt+F1'); + + const toggleKeybindingLabel = this._keybindingService.lookupKeybinding('editor.action.toggleScreenReaderAccessibilityMode')?.getAriaLabel(); + const runCommandKeybindingLabel = this._keybindingService.lookupKeybinding('workbench.action.showCommands')?.getAriaLabel(); + const keybindingEditorKeybindingLabel = this._keybindingService.lookupKeybinding('workbench.action.openGlobalKeybindings')?.getAriaLabel(); + const editorNotAccessibleMessage = nls.localize('accessibilityModeOff', "The editor is not accessible at this time."); + if (toggleKeybindingLabel) { + return nls.localize('accessibilityOffAriaLabel', "{0} To enable screen reader optimized mode, use {1}", editorNotAccessibleMessage, toggleKeybindingLabel); + } else if (runCommandKeybindingLabel) { + return nls.localize('accessibilityOffAriaLabelNoKb', "{0} To enable screen reader optimized mode, open the quick pick with {1} and run the command Toggle Screen Reader Accessibility Mode, which is currently not triggerable via keyboard.", editorNotAccessibleMessage, runCommandKeybindingLabel); + } else if (keybindingEditorKeybindingLabel) { + return nls.localize('accessibilityOffAriaLabelNoKbs', "{0} Please assign a keybinding for the command Toggle Screen Reader Accessibility Mode by accessing the keybindings editor with {1} and run it.", editorNotAccessibleMessage, keybindingEditorKeybindingLabel); + } else { + // SOS + return editorNotAccessibleMessage; + } } return options.get(EditorOption.ariaLabel); } diff --git a/src/vs/editor/browser/editorBrowser.ts b/src/vs/editor/browser/editorBrowser.ts index 4d6c57410be56..1ea2dff1bb61a 100644 --- a/src/vs/editor/browser/editorBrowser.ts +++ b/src/vs/editor/browser/editorBrowser.ts @@ -15,7 +15,7 @@ import { IRange, Range } from 'vs/editor/common/core/range'; import { Selection } from 'vs/editor/common/core/selection'; import { IWordAtPosition } from 'vs/editor/common/core/wordHelper'; import { ICursorPositionChangedEvent, ICursorSelectionChangedEvent } from 'vs/editor/common/cursorEvents'; -import { IDiffComputationResult, ILineChange } from 'vs/editor/common/diff/smartLinesDiffComputer'; +import { IDiffComputationResult, ILineChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; import * as editorCommon from 'vs/editor/common/editorCommon'; import { GlyphMarginLane, ICursorStateComputer, IIdentifiedSingleEditOperation, IModelDecoration, IModelDeltaDecoration, ITextModel, PositionAffinity } from 'vs/editor/common/model'; import { InjectedText } from 'vs/editor/common/modelLineProjectionData'; @@ -250,6 +250,10 @@ export interface IOverlayWidget { * If null is returned, the overlay widget is responsible to place itself. */ getPosition(): IOverlayWidgetPosition | null; + /** + * The editor will ensure that the scroll width is >= than this value. + */ + getMinContentWidthInPx?(): number; } /** @@ -354,7 +358,7 @@ export interface IBaseMouseTarget { /** * The target element */ - readonly element: Element | null; + readonly element: HTMLElement | null; /** * The 'approximate' editor position */ @@ -1263,9 +1267,9 @@ export interface IDiffEditor extends editorCommon.IEditor { */ revealFirstDiff(): unknown; - diffReviewNext(): void; + accessibleDiffViewerNext(): void; - diffReviewPrev(): void; + accessibleDiffViewerPrev(): void; } /** diff --git a/src/vs/editor/browser/editorExtensions.ts b/src/vs/editor/browser/editorExtensions.ts index 779468acc0abf..75562c538217c 100644 --- a/src/vs/editor/browser/editorExtensions.ts +++ b/src/vs/editor/browser/editorExtensions.ts @@ -19,7 +19,7 @@ import { ServicesAccessor as InstantiationServicesAccessor, BrandedService, IIns import { IKeybindings, KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { Registry } from 'vs/platform/registry/common/platform'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { withNullAsUndefined, assertType } from 'vs/base/common/types'; +import { assertType } from 'vs/base/common/types'; import { ThemeIcon } from 'vs/base/common/themables'; import { IDisposable } from 'vs/base/common/lifecycle'; import { KeyMod, KeyCode } from 'vs/base/common/keyCodes'; @@ -307,7 +307,7 @@ export abstract class EditorCommand extends Command { return editor.invokeWithinContext((editorAccessor) => { const kbService = editorAccessor.get(IContextKeyService); - if (!kbService.contextMatchesRules(withNullAsUndefined(precondition))) { + if (!kbService.contextMatchesRules(precondition ?? undefined)) { // precondition does not hold return; } @@ -460,7 +460,7 @@ export abstract class EditorAction2 extends Action2 { return editor.invokeWithinContext((editorAccessor) => { const kbService = editorAccessor.get(IContextKeyService); const logService = editorAccessor.get(ILogService); - const enabled = kbService.contextMatchesRules(withNullAsUndefined(this.desc.precondition)); + const enabled = kbService.contextMatchesRules(this.desc.precondition ?? undefined); if (!enabled) { logService.debug(`[EditorAction2] NOT running command because its precondition is FALSE`, this.desc.id, this.desc.precondition?.serialize()); return; diff --git a/src/vs/editor/browser/services/editorWorkerService.ts b/src/vs/editor/browser/services/editorWorkerService.ts index a4ffe3053b523..993fe8e813ca9 100644 --- a/src/vs/editor/browser/services/editorWorkerService.ts +++ b/src/vs/editor/browser/services/editorWorkerService.ts @@ -17,7 +17,6 @@ import { EditorSimpleWorker } from 'vs/editor/common/services/editorSimpleWorker import { DiffAlgorithmName, IDiffComputationResult, IEditorWorkerService, ILineChange, IUnicodeHighlightsResult } from 'vs/editor/common/services/editorWorker'; import { IModelService } from 'vs/editor/common/services/model'; import { ITextResourceConfigurationService } from 'vs/editor/common/services/textResourceConfiguration'; -import { regExpFlags } from 'vs/base/common/strings'; import { isNonEmptyArray } from 'vs/base/common/arrays'; import { ILogService } from 'vs/platform/log/common/log'; import { StopWatch } from 'vs/base/common/stopwatch'; @@ -25,7 +24,7 @@ import { canceled, onUnexpectedError } from 'vs/base/common/errors'; import { UnicodeHighlighterOptions } from 'vs/editor/common/services/unicodeTextModelHighlighter'; import { IEditorWorkerHost } from 'vs/editor/common/services/editorWorkerHost'; import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; -import { IChange } from 'vs/editor/common/diff/smartLinesDiffComputer'; +import { IChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; import { IDocumentDiff, IDocumentDiffProviderOptions } from 'vs/editor/common/diff/documentDiffProvider'; import { ILinesDiffComputerOptions, LineRangeMapping, MovedText, RangeMapping, SimpleLineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; import { LineRange } from 'vs/editor/common/core/lineRange'; @@ -582,7 +581,7 @@ export class EditorWorkerClient extends Disposable implements IEditorWorkerClien public async textualSuggest(resources: URI[], leadingWord: string | undefined, wordDefRegExp: RegExp): Promise<{ words: string[]; duration: number } | null> { const proxy = await this._withSyncedResources(resources); const wordDef = wordDefRegExp.source; - const wordDefFlags = regExpFlags(wordDefRegExp); + const wordDefFlags = wordDefRegExp.flags; return proxy.textualSuggest(resources.map(r => r.toString()), leadingWord, wordDef, wordDefFlags); } @@ -594,7 +593,7 @@ export class EditorWorkerClient extends Disposable implements IEditorWorkerClien } const wordDefRegExp = this.languageConfigurationService.getLanguageConfiguration(model.getLanguageId()).getWordDefinition(); const wordDef = wordDefRegExp.source; - const wordDefFlags = regExpFlags(wordDefRegExp); + const wordDefFlags = wordDefRegExp.flags; return proxy.computeWordRanges(resource.toString(), range, wordDef, wordDefFlags); }); } @@ -607,7 +606,7 @@ export class EditorWorkerClient extends Disposable implements IEditorWorkerClien } const wordDefRegExp = this.languageConfigurationService.getLanguageConfiguration(model.getLanguageId()).getWordDefinition(); const wordDef = wordDefRegExp.source; - const wordDefFlags = regExpFlags(wordDefRegExp); + const wordDefFlags = wordDefRegExp.flags; return proxy.navigateValueSet(resource.toString(), range, up, wordDef, wordDefFlags); }); } diff --git a/src/vs/editor/browser/view.ts b/src/vs/editor/browser/view.ts index 82d1fb7a26969..0e791b1430570 100644 --- a/src/vs/editor/browser/view.ts +++ b/src/vs/editor/browser/view.ts @@ -54,6 +54,7 @@ import { IMouseWheelEvent } from 'vs/base/browser/mouseEvent'; import { WhitespaceOverlay } from 'vs/editor/browser/viewParts/whitespace/whitespace'; import { GlyphMarginWidgets } from 'vs/editor/browser/viewParts/glyphMargin/glyphMargin'; import { GlyphMarginLane } from 'vs/editor/common/model'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; export interface IContentWidgetData { @@ -106,7 +107,8 @@ export class View extends ViewEventHandler { colorTheme: IColorTheme, model: IViewModel, userInputEvents: ViewUserInputEvents, - overflowWidgetsDomNode: HTMLElement | undefined + overflowWidgetsDomNode: HTMLElement | undefined, + @IInstantiationService private readonly _instantiationService: IInstantiationService ) { super(); this._selections = [new Selection(1, 1, 1, 1)]; @@ -123,7 +125,7 @@ export class View extends ViewEventHandler { this._viewParts = []; // Keyboard handler - this._textAreaHandler = new TextAreaHandler(this._context, viewController, this._createTextAreaHandlerHelper()); + this._textAreaHandler = this._instantiationService.createInstance(TextAreaHandler, this._context, viewController, this._createTextAreaHandlerHelper()); this._viewParts.push(this._textAreaHandler); // These two dom nodes must be constructed up front, since references are needed in the layout provider (scrolling & co.) diff --git a/src/vs/editor/browser/viewParts/lines/viewLine.ts b/src/vs/editor/browser/viewParts/lines/viewLine.ts index 6df2f278f54ce..e4174a2f2866a 100644 --- a/src/vs/editor/browser/viewParts/lines/viewLine.ts +++ b/src/vs/editor/browser/viewParts/lines/viewLine.ts @@ -332,11 +332,11 @@ export class ViewLine implements IVisibleLine { return null; } - public getColumnOfNodeOffset(lineNumber: number, spanNode: HTMLElement, offset: number): number { + public getColumnOfNodeOffset(spanNode: HTMLElement, offset: number): number { if (!this._renderedViewLine) { return 1; } - return this._renderedViewLine.getColumnOfNodeOffset(lineNumber, spanNode, offset); + return this._renderedViewLine.getColumnOfNodeOffset(spanNode, offset); } } @@ -346,7 +346,7 @@ interface IRenderedViewLine { getWidth(context: DomReadingContext | null): number; getWidthIsFast(): boolean; getVisibleRangesForRange(lineNumber: number, startColumn: number, endColumn: number, context: DomReadingContext): FloatHorizontalRange[] | null; - getColumnOfNodeOffset(lineNumber: number, spanNode: HTMLElement, offset: number): number; + getColumnOfNodeOffset(spanNode: HTMLElement, offset: number): number; } const enum Constants { @@ -476,16 +476,8 @@ class FastRenderedViewLine implements IRenderedViewLine { return r[0].left; } - public getColumnOfNodeOffset(lineNumber: number, spanNode: HTMLElement, offset: number): number { - const spanNodeTextContentLength = spanNode.textContent!.length; - - let spanIndex = -1; - while (spanNode) { - spanNode = spanNode.previousSibling; - spanIndex++; - } - - return this._characterMapping.getColumn(new DomPosition(spanIndex, offset), spanNodeTextContentLength); + public getColumnOfNodeOffset(spanNode: HTMLElement, offset: number): number { + return getColumnOfNodeOffset(this._characterMapping, spanNode, offset); } } @@ -679,16 +671,8 @@ class RenderedViewLine implements IRenderedViewLine { /** * Returns the column for the text found at a specific offset inside a rendered dom node */ - public getColumnOfNodeOffset(lineNumber: number, spanNode: HTMLElement, offset: number): number { - const spanNodeTextContentLength = spanNode.textContent!.length; - - let spanIndex = -1; - while (spanNode) { - spanNode = spanNode.previousSibling; - spanIndex++; - } - - return this._characterMapping.getColumn(new DomPosition(spanIndex, offset), spanNodeTextContentLength); + public getColumnOfNodeOffset(spanNode: HTMLElement, offset: number): number { + return getColumnOfNodeOffset(this._characterMapping, spanNode, offset); } } @@ -733,3 +717,15 @@ function createWebKitRenderedLine(domNode: FastDomNode | null, rend function createNormalRenderedLine(domNode: FastDomNode | null, renderLineInput: RenderLineInput, characterMapping: CharacterMapping, containsRTL: boolean, containsForeignElements: ForeignElementType): RenderedViewLine { return new RenderedViewLine(domNode, renderLineInput, characterMapping, containsRTL, containsForeignElements); } + +export function getColumnOfNodeOffset(characterMapping: CharacterMapping, spanNode: HTMLElement, offset: number): number { + const spanNodeTextContentLength = spanNode.textContent!.length; + + let spanIndex = -1; + while (spanNode) { + spanNode = spanNode.previousSibling; + spanIndex++; + } + + return characterMapping.getColumn(new DomPosition(spanIndex, offset), spanNodeTextContentLength); +} diff --git a/src/vs/editor/browser/viewParts/lines/viewLines.css b/src/vs/editor/browser/viewParts/lines/viewLines.css index 8fff7ae3155b1..fe686d3e441dc 100644 --- a/src/vs/editor/browser/viewParts/lines/viewLines.css +++ b/src/vs/editor/browser/viewParts/lines/viewLines.css @@ -20,8 +20,8 @@ } .mtkoverflow { - background-color: var(--vscode-button-background, --vscode-editor-background); - color: var(--vscode-button-foreground, --vscode-editor-foreground); + background-color: var(--vscode-button-background, var(--vscode-editor-background)); + color: var(--vscode-button-foreground, var(--vscode-editor-foreground)); border-width: 1px; border-style: solid; border-color: var(--vscode-contrastBorder); diff --git a/src/vs/editor/browser/viewParts/lines/viewLines.ts b/src/vs/editor/browser/viewParts/lines/viewLines.ts index 42f0eb34169b2..220ef98725529 100644 --- a/src/vs/editor/browser/viewParts/lines/viewLines.ts +++ b/src/vs/editor/browser/viewParts/lines/viewLines.ts @@ -364,7 +364,7 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost, return null; } - let column = this._visibleLines.getVisibleLine(lineNumber).getColumnOfNodeOffset(lineNumber, spanNode, offset); + let column = this._visibleLines.getVisibleLine(lineNumber).getColumnOfNodeOffset(spanNode, offset); const minColumn = this._context.viewModel.getLineMinColumn(lineNumber); if (column < minColumn) { column = minColumn; diff --git a/src/vs/editor/browser/viewParts/minimap/minimap.ts b/src/vs/editor/browser/viewParts/minimap/minimap.ts index 031f8a8f612e3..e5c416a9e4b90 100644 --- a/src/vs/editor/browser/viewParts/minimap/minimap.ts +++ b/src/vs/editor/browser/viewParts/minimap/minimap.ts @@ -377,7 +377,7 @@ class MinimapLayout { const partialLine = (scrollTop - viewportStartLineNumberVerticalOffset) / lineHeight; let sliderTopAligned: number; - if (scrollTop > options.paddingTop) { + if (scrollTop >= options.paddingTop) { sliderTopAligned = (viewportStartLineNumber - startLineNumber + topPaddingLineCount + partialLine) * minimapLineHeight / pixelRatio; } else { sliderTopAligned = (scrollTop / options.paddingTop) * (topPaddingLineCount + partialLine) * minimapLineHeight / pixelRatio; diff --git a/src/vs/editor/browser/viewParts/overlayWidgets/overlayWidgets.ts b/src/vs/editor/browser/viewParts/overlayWidgets/overlayWidgets.ts index 332bdb8372847..0165d4eb63ffb 100644 --- a/src/vs/editor/browser/viewParts/overlayWidgets/overlayWidgets.ts +++ b/src/vs/editor/browser/viewParts/overlayWidgets/overlayWidgets.ts @@ -92,16 +92,19 @@ export class ViewOverlayWidgets extends ViewPart { this._domNode.appendChild(domNode); this.setShouldRender(); + this._updateMaxMinWidth(); } public setWidgetPosition(widget: IOverlayWidget, preference: OverlayWidgetPositionPreference | null): boolean { const widgetData = this._widgets[widget.getId()]; if (widgetData.preference === preference) { + this._updateMaxMinWidth(); return false; } widgetData.preference = preference; this.setShouldRender(); + this._updateMaxMinWidth(); return true; } @@ -115,9 +118,24 @@ export class ViewOverlayWidgets extends ViewPart { domNode.parentNode!.removeChild(domNode); this.setShouldRender(); + this._updateMaxMinWidth(); } } + private _updateMaxMinWidth(): void { + let maxMinWidth = 0; + const keys = Object.keys(this._widgets); + for (let i = 0, len = keys.length; i < len; i++) { + const widgetId = keys[i]; + const widget = this._widgets[widgetId]; + const widgetMinWidthInPx = widget.widget.getMinContentWidthInPx?.(); + if (typeof widgetMinWidthInPx !== 'undefined') { + maxMinWidth = Math.max(maxMinWidth, widgetMinWidthInPx); + } + } + this._context.viewLayout.setOverlayWidgetsMinWidth(maxMinWidth); + } + private _renderWidget(widgetData: IWidgetData): void { const domNode = widgetData.domNode; diff --git a/src/vs/editor/browser/widget/codeEditorWidget.ts b/src/vs/editor/browser/widget/codeEditorWidget.ts index 0903e17470051..a6f59231e3908 100644 --- a/src/vs/editor/browser/widget/codeEditorWidget.ts +++ b/src/vs/editor/browser/widget/codeEditorWidget.ts @@ -48,7 +48,6 @@ import { ServiceCollection } from 'vs/platform/instantiation/common/serviceColle import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; import { IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; -import { withNullAsUndefined } from 'vs/base/common/types'; import { MonospaceLineBreaksComputerFactory } from 'vs/editor/common/viewModel/monospaceLineBreaksComputer'; import { DOMLineBreaksComputerFactory } from 'vs/editor/browser/view/domLineBreaksComputer'; import { WordOperations } from 'vs/editor/common/cursor/cursorWordOperations'; @@ -73,6 +72,8 @@ export interface ICodeEditorWidgetOptions { /** * Contributions to instantiate. + * When provided, only the contributions included will be instantiated. + * To include the defaults, those must be provided as well via [...EditorExtensionsRegistry.getEditorContributions()] * Defaults to EditorExtensionsRegistry.getEditorContributions(). */ contributions?: IEditorContributionDescription[]; @@ -343,7 +344,7 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE action.id, action.label, action.alias, - withNullAsUndefined(action.precondition), + action.precondition ?? undefined, (): Promise => { return this._instantiationService.invokeFunction((accessor) => { return Promise.resolve(action.runEditorCommand(accessor, this, null)); @@ -1851,7 +1852,8 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE this._themeService.getColorTheme(), viewModel, viewUserInputEvents, - this._overflowWidgetsDomNode + this._overflowWidgetsDomNode, + this._instantiationService ); return [view, true]; diff --git a/src/vs/editor/browser/widget/diffEditor.contribution.ts b/src/vs/editor/browser/widget/diffEditor.contribution.ts index 456dc90b2930a..9506f2bd5a7c3 100644 --- a/src/vs/editor/browser/widget/diffEditor.contribution.ts +++ b/src/vs/editor/browser/widget/diffEditor.contribution.ts @@ -4,60 +4,82 @@ *--------------------------------------------------------------------------------------------*/ import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; -import { ICodeEditor, IDiffEditor } from 'vs/editor/browser/editorBrowser'; -import { EditorAction, ServicesAccessor, registerEditorAction } from 'vs/editor/browser/editorExtensions'; +import { IDiffEditor } from 'vs/editor/browser/editorBrowser'; +import { ServicesAccessor } from 'vs/editor/browser/editorExtensions'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; +import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { localize } from 'vs/nls'; +import { ILocalizedString } from 'vs/platform/action/common/action'; +import { Action2, MenuId, MenuRegistry, registerAction2 } from 'vs/platform/actions/common/actions'; +import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; -export class DiffReviewNext extends EditorAction { - public static id = 'editor.action.diffReview.next'; +const accessibleDiffViewerCategory: ILocalizedString = { + value: localize('accessibleDiffViewer', 'Accessible Diff Viewer'), + original: 'Accessible Diff Viewer', +}; + +export class AccessibleDiffViewerNext extends Action2 { + public static id = 'editor.action.accessibleDiffViewer.next'; constructor() { super({ - id: DiffReviewNext.id, - label: localize('editor.action.diffReview.next', "Go to Next Difference"), - alias: 'Go to Next Difference', + id: AccessibleDiffViewerNext.id, + title: { value: localize('editor.action.accessibleDiffViewer.next', "Go to Next Difference"), original: 'Go to Next Difference' }, + category: accessibleDiffViewerCategory, precondition: ContextKeyExpr.has('isInDiffEditor'), - kbOpts: { - kbExpr: null, + keybinding: { primary: KeyCode.F7, weight: KeybindingWeight.EditorContrib - } + }, + f1: true, }); } - public run(accessor: ServicesAccessor, editor: ICodeEditor): void { + public override run(accessor: ServicesAccessor): void { const diffEditor = findFocusedDiffEditor(accessor); - diffEditor?.diffReviewNext(); + diffEditor?.accessibleDiffViewerNext(); } } -export class DiffReviewPrev extends EditorAction { - public static id = 'editor.action.diffReview.prev'; +MenuRegistry.appendMenuItem(MenuId.EditorTitle, { + command: { + id: AccessibleDiffViewerNext.id, + title: localize('Open Accessible Diff Viewer', "Open Accessible Diff Viewer"), + }, + order: 10, + group: '2_diff', + when: ContextKeyExpr.and( + EditorContextKeys.accessibleDiffViewerVisible.negate(), + ContextKeyExpr.has('isInDiffEditor'), + ), +}); + +export class AccessibleDiffViewerPrev extends Action2 { + public static id = 'editor.action.accessibleDiffViewer.prev'; constructor() { super({ - id: DiffReviewPrev.id, - label: localize('editor.action.diffReview.prev', "Go to Previous Difference"), - alias: 'Go to Previous Difference', + id: AccessibleDiffViewerPrev.id, + title: { value: localize('editor.action.accessibleDiffViewer.prev', "Go to Previous Difference"), original: 'Go to Previous Difference' }, + category: accessibleDiffViewerCategory, precondition: ContextKeyExpr.has('isInDiffEditor'), - kbOpts: { - kbExpr: null, + keybinding: { primary: KeyMod.Shift | KeyCode.F7, weight: KeybindingWeight.EditorContrib - } + }, + f1: true, }); } - public run(accessor: ServicesAccessor, editor: ICodeEditor): void { + public override run(accessor: ServicesAccessor): void { const diffEditor = findFocusedDiffEditor(accessor); - diffEditor?.diffReviewPrev(); + diffEditor?.accessibleDiffViewerPrev(); } } -function findFocusedDiffEditor(accessor: ServicesAccessor): IDiffEditor | null { +export function findFocusedDiffEditor(accessor: ServicesAccessor): IDiffEditor | null { const codeEditorService = accessor.get(ICodeEditorService); const diffEditors = codeEditorService.listDiffEditors(); const activeCodeEditor = codeEditorService.getFocusedCodeEditor() ?? codeEditorService.getActiveCodeEditor(); @@ -71,8 +93,32 @@ function findFocusedDiffEditor(accessor: ServicesAccessor): IDiffEditor | null { return diffEditor; } } + + if (document.activeElement) { + for (const d of diffEditors) { + const container = d.getContainerDomNode(); + if (isElementOrParentOf(container, document.activeElement)) { + return d; + } + } + } + return null; } -registerEditorAction(DiffReviewNext); -registerEditorAction(DiffReviewPrev); +function isElementOrParentOf(elementOrParent: Element, element: Element): boolean { + let e: Element | null = element; + while (e) { + if (e === elementOrParent) { + return true; + } + e = e.parentElement; + } + return false; +} + +CommandsRegistry.registerCommandAlias('editor.action.diffReview.next', AccessibleDiffViewerNext.id); +registerAction2(AccessibleDiffViewerNext); + +CommandsRegistry.registerCommandAlias('editor.action.diffReview.prev', AccessibleDiffViewerPrev.id); +registerAction2(AccessibleDiffViewerPrev); diff --git a/src/vs/editor/browser/widget/diffEditorWidget.ts b/src/vs/editor/browser/widget/diffEditorWidget.ts index e21c1e9f3beb2..5588ae6f5ec27 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget.ts @@ -11,6 +11,7 @@ import { MOUSE_CURSOR_TEXT_CSS_CLASS_NAME } from 'vs/base/browser/ui/mouseCursor import { IBoundarySashes, ISashEvent, IVerticalSashLayoutProvider, Orientation, Sash, SashState } from 'vs/base/browser/ui/sash/sash'; import * as assert from 'vs/base/common/assert'; import { RunOnceScheduler } from 'vs/base/common/async'; +import { CancellationToken } from 'vs/base/common/cancellation'; import { Codicon } from 'vs/base/common/codicons'; import { Color } from 'vs/base/common/color'; import { onUnexpectedError } from 'vs/base/common/errors'; @@ -40,7 +41,7 @@ import { IPosition, Position } from 'vs/editor/common/core/position'; import { IRange, Range } from 'vs/editor/common/core/range'; import { ISelection, Selection } from 'vs/editor/common/core/selection'; import { StringBuilder } from 'vs/editor/common/core/stringBuilder'; -import { IChange, ICharChange, IDiffComputationResult, ILineChange } from 'vs/editor/common/diff/smartLinesDiffComputer'; +import { IChange, ICharChange, IDiffComputationResult, ILineChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; import * as editorCommon from 'vs/editor/common/editorCommon'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { IModelDecorationsChangeAccessor, IModelDeltaDecoration, ITextModel } from 'vs/editor/common/model'; @@ -299,6 +300,9 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE collapseUnchangedRegions: false, }, isInEmbeddedEditor: false, + onlyShowAccessibleDiffViewer: false, + renderSideBySideInlineBreakpoint: 0, + useInlineViewWhenSpaceIsLimited: false, }); this.isEmbeddedDiffEditorKey = EditorContextKeys.isEmbeddedDiffEditor.bindTo(this._contextKeyService); @@ -444,11 +448,11 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE return dom.isAncestor(document.activeElement, this._domElement); } - public diffReviewNext(): void { + public accessibleDiffViewerNext(): void { this._reviewPane.next(); } - public diffReviewPrev(): void { + public accessibleDiffViewerPrev(): void { this._reviewPane.prev(); } @@ -1183,7 +1187,7 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE ignoreTrimWhitespace: this._options.ignoreTrimWhitespace, maxComputationTimeMs: this._options.maxComputationTime, computeMoves: false, - }).then(result => { + }, CancellationToken.None).then(result => { if (currentToken === this._diffComputationToken && currentOriginalModel === this._originalEditor.getModel() && currentModifiedModel === this._modifiedEditor.getModel() @@ -1368,7 +1372,7 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE this._originalDomNode.style.width = splitPoint + 'px'; this._originalDomNode.style.left = '0px'; - this._modifiedDomNode.style.width = (width - splitPoint) + 'px'; + this._modifiedDomNode.style.width = (width - splitPoint - DiffEditorWidget.ENTIRE_DIFF_OVERVIEW_WIDTH) + 'px'; this._modifiedDomNode.style.left = splitPoint + 'px'; this._overviewDomElement.style.top = '0px'; @@ -2743,6 +2747,9 @@ function validateDiffEditorOptions(options: Readonly, defaul collapseUnchangedRegions: false, }, isInEmbeddedEditor: validateBooleanOption(options.isInEmbeddedEditor, defaults.isInEmbeddedEditor), + onlyShowAccessibleDiffViewer: false, + renderSideBySideInlineBreakpoint: 0, + useInlineViewWhenSpaceIsLimited: false, }; } diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/accessibleDiffViewer.ts b/src/vs/editor/browser/widget/diffEditorWidget2/accessibleDiffViewer.ts new file mode 100644 index 0000000000000..32f45d8518655 --- /dev/null +++ b/src/vs/editor/browser/widget/diffEditorWidget2/accessibleDiffViewer.ts @@ -0,0 +1,689 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { addDisposableListener, addStandardDisposableListener, reset } from 'vs/base/browser/dom'; +import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; +import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement'; +import { Action } from 'vs/base/common/actions'; +import { Codicon } from 'vs/base/common/codicons'; +import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; +import { Disposable, DisposableStore, toDisposable } from 'vs/base/common/lifecycle'; +import { IObservable, ITransaction, autorun, autorunWithStore, derived, derivedWithStore, keepAlive, observableValue, subtransaction, transaction } from 'vs/base/common/observable'; +import { ThemeIcon } from 'vs/base/common/themables'; +import { applyFontInfo } from 'vs/editor/browser/config/domFontInfo'; +import { DiffEditorEditors } from 'vs/editor/browser/widget/diffEditorWidget2/diffEditorEditors'; +import { applyStyle } from 'vs/editor/browser/widget/diffEditorWidget2/utils'; +import { DiffReview } from 'vs/editor/browser/widget/diffReview'; +import { EditorFontLigatures, EditorOption, IComputedEditorOptions } from 'vs/editor/common/config/editorOptions'; +import { LineRange } from 'vs/editor/common/core/lineRange'; +import { OffsetRange } from 'vs/editor/common/core/offsetRange'; +import { Position } from 'vs/editor/common/core/position'; +import { Range } from 'vs/editor/common/core/range'; +import { LineRangeMapping, SimpleLineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; +import { ILanguageIdCodec } from 'vs/editor/common/languages'; +import { ILanguageService } from 'vs/editor/common/languages/language'; +import { ITextModel, TextModelResolvedOptions } from 'vs/editor/common/model'; +import { LineTokens } from 'vs/editor/common/tokens/lineTokens'; +import { RenderLineInput, renderViewLine2 } from 'vs/editor/common/viewLayout/viewLineRenderer'; +import { ViewLineRenderingData } from 'vs/editor/common/viewModel'; +import { localize } from 'vs/nls'; +import { AudioCue, IAudioCueService } from 'vs/platform/audioCues/browser/audioCueService'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { registerIcon } from 'vs/platform/theme/common/iconRegistry'; + +const accessibleDiffViewerInsertIcon = registerIcon('diff-review-insert', Codicon.add, localize('accessibleDiffViewerInsertIcon', 'Icon for \'Insert\' in accessible diff viewer.')); +const accessibleDiffViewerRemoveIcon = registerIcon('diff-review-remove', Codicon.remove, localize('accessibleDiffViewerRemoveIcon', 'Icon for \'Remove\' in accessible diff viewer.')); +const accessibleDiffViewerCloseIcon = registerIcon('diff-review-close', Codicon.close, localize('accessibleDiffViewerCloseIcon', 'Icon for \'Close\' in accessible diff viewer.')); + +export class AccessibleDiffViewer extends Disposable { + constructor( + private readonly _parentNode: HTMLElement, + private readonly _visible: IObservable, + private readonly _setVisible: (visible: boolean, tx: ITransaction | undefined) => void, + private readonly _canClose: IObservable, + private readonly _width: IObservable, + private readonly _height: IObservable, + private readonly _diffs: IObservable, + private readonly _editors: DiffEditorEditors, + @IInstantiationService private readonly _instantiationService: IInstantiationService, + ) { + super(); + this._register(keepAlive(this.model, true)); + } + + private readonly model = derivedWithStore('model', (reader, store) => { + const visible = this._visible.read(reader); + this._parentNode.style.visibility = visible ? 'visible' : 'hidden'; + if (!visible) { + return null; + } + const model = store.add(this._instantiationService.createInstance(ViewModel, this._diffs, this._editors, this._setVisible, this._canClose)); + const view = store.add(this._instantiationService.createInstance(View, this._parentNode, model, this._width, this._height, this._editors)); + return { + model, + view + }; + }); + + next(): void { + transaction(tx => { + const isVisible = this._visible.get(); + this._setVisible(true, tx); + if (isVisible) { + this.model.get()!.model.nextGroup(tx); + } + }); + } + + prev(): void { + transaction(tx => { + this._setVisible(true, tx); + this.model.get()!.model.previousGroup(tx); + }); + } + + close(): void { + transaction(tx => { + this._setVisible(false, tx); + }); + } +} + +class ViewModel extends Disposable { + private readonly _groups = observableValue('groups', []); + private readonly _currentGroupIdx = observableValue('currentGroupIdx', 0); + private readonly _currentElementIdx = observableValue('currentElementIdx', 0); + + public readonly groups: IObservable = this._groups; + public readonly currentGroup: IObservable + = this._currentGroupIdx.map((idx, r) => this._groups.read(r)[idx]); + public readonly currentGroupIndex: IObservable = this._currentGroupIdx; + + public readonly currentElement: IObservable + = this._currentElementIdx.map((idx, r) => this.currentGroup.read(r)?.lines[idx]); + + constructor( + private readonly _diffs: IObservable, + private readonly _editors: DiffEditorEditors, + private readonly _setVisible: (visible: boolean, tx: ITransaction | undefined) => void, + public readonly canClose: IObservable, + @IAudioCueService private readonly _audioCueService: IAudioCueService, + ) { + super(); + + this._register(autorun(reader => { + /** @description update groups */ + const diffs = this._diffs.read(reader); + if (!diffs) { + this._groups.set([], undefined); + return; + } + + const groups = computeViewElementGroups( + diffs, + this._editors.original.getModel()!.getLineCount(), + this._editors.modified.getModel()!.getLineCount() + ); + + transaction(tx => { + const p = this._editors.modified.getPosition(); + if (p) { + const nextGroup = groups.findIndex(g => p?.lineNumber < g.range.modified.endLineNumberExclusive); + if (nextGroup !== -1) { + this._currentGroupIdx.set(nextGroup, tx); + } + } + this._groups.set(groups, tx); + }); + })); + + this._register(autorun(reader => { + /** @description play audio-cue for diff */ + const currentViewItem = this.currentElement.read(reader); + if (currentViewItem?.type === LineType.Deleted) { + this._audioCueService.playAudioCue(AudioCue.diffLineDeleted, { source: 'accessibleDiffViewer.currentElementChanged' }); + } else if (currentViewItem?.type === LineType.Added) { + this._audioCueService.playAudioCue(AudioCue.diffLineInserted, { source: 'accessibleDiffViewer.currentElementChanged' }); + } + })); + + this._register(autorun(reader => { + /** @description select lines in editor */ + // This ensures editor commands (like revert/stage) work + const currentViewItem = this.currentElement.read(reader); + if (currentViewItem && currentViewItem.type !== LineType.Header) { + const lineNumber = currentViewItem.modifiedLineNumber ?? currentViewItem.diff.modifiedRange.startLineNumber; + this._editors.modified.setSelection(Range.fromPositions(new Position(lineNumber, 1))); + } + })); + } + + private _goToGroupDelta(delta: number, tx?: ITransaction): void { + const groups = this.groups.get(); + if (!groups || groups.length <= 1) { return; } + subtransaction(tx, tx => { + this._currentGroupIdx.set(OffsetRange.ofLength(groups.length).clipCyclic(this._currentGroupIdx.get() + delta), tx); + this._currentElementIdx.set(0, tx); + }); + } + + nextGroup(tx?: ITransaction): void { this._goToGroupDelta(1, tx); } + previousGroup(tx?: ITransaction): void { this._goToGroupDelta(-1, tx); } + + private _goToLineDelta(delta: number): void { + const group = this.currentGroup.get(); + if (!group || group.lines.length <= 1) { return; } + transaction(tx => { + this._currentElementIdx.set(OffsetRange.ofLength(group.lines.length).clip(this._currentElementIdx.get() + delta), tx); + }); + } + + goToNextLine(): void { this._goToLineDelta(1); } + goToPreviousLine(): void { this._goToLineDelta(-1); } + + goToLine(line: ViewElement): void { + const group = this.currentGroup.get(); + if (!group) { return; } + const idx = group.lines.indexOf(line); + if (idx === -1) { return; } + transaction(tx => { + this._currentElementIdx.set(idx, tx); + }); + } + + revealCurrentElementInEditor(): void { + this._setVisible(false, undefined); + + const curElem = this.currentElement.get(); + if (curElem) { + if (curElem.type === LineType.Deleted) { + this._editors.original.setSelection(Range.fromPositions(new Position(curElem.originalLineNumber, 1))); + this._editors.original.revealLine(curElem.originalLineNumber); + this._editors.original.focus(); + } else { + if (curElem.type !== LineType.Header) { + this._editors.modified.setSelection(Range.fromPositions(new Position(curElem.modifiedLineNumber, 1))); + this._editors.modified.revealLine(curElem.modifiedLineNumber); + } + this._editors.modified.focus(); + } + } + } + + close(): void { + this._setVisible(false, undefined); + this._editors.modified.focus(); + } +} + + +const viewElementGroupLineMargin = 3; + +function computeViewElementGroups(diffs: LineRangeMapping[], originalLineCount: number, modifiedLineCount: number): ViewElementGroup[] { + const result: ViewElementGroup[] = []; + + for (const g of group(diffs, (a, b) => (b.modifiedRange.startLineNumber - a.modifiedRange.endLineNumberExclusive < 2 * viewElementGroupLineMargin))) { + const viewElements: ViewElement[] = []; + viewElements.push(new HeaderViewElement()); + + const origFullRange = new LineRange( + Math.max(1, g[0].originalRange.startLineNumber - viewElementGroupLineMargin), + Math.min(g[g.length - 1].originalRange.endLineNumberExclusive + viewElementGroupLineMargin, originalLineCount + 1) + ); + const modifiedFullRange = new LineRange( + Math.max(1, g[0].modifiedRange.startLineNumber - viewElementGroupLineMargin), + Math.min(g[g.length - 1].modifiedRange.endLineNumberExclusive + viewElementGroupLineMargin, modifiedLineCount + 1) + ); + + forEachAdjacentItems(g, (a, b) => { + const origRange = new LineRange(a ? a.originalRange.endLineNumberExclusive : origFullRange.startLineNumber, b ? b.originalRange.startLineNumber : origFullRange.endLineNumberExclusive); + const modifiedRange = new LineRange(a ? a.modifiedRange.endLineNumberExclusive : modifiedFullRange.startLineNumber, b ? b.modifiedRange.startLineNumber : modifiedFullRange.endLineNumberExclusive); + + origRange.forEach(origLineNumber => { + viewElements.push(new UnchangedLineViewElement(origLineNumber, modifiedRange.startLineNumber + (origLineNumber - origRange.startLineNumber))); + }); + + if (b) { + b.originalRange.forEach(origLineNumber => { + viewElements.push(new DeletedLineViewElement(b, origLineNumber)); + }); + b.modifiedRange.forEach(modifiedLineNumber => { + viewElements.push(new AddedLineViewElement(b, modifiedLineNumber)); + }); + } + }); + + const modifiedRange = g[0].modifiedRange.join(g[g.length - 1].modifiedRange); + const originalRange = g[0].originalRange.join(g[g.length - 1].originalRange); + + result.push(new ViewElementGroup(new SimpleLineRangeMapping(modifiedRange, originalRange), viewElements)); + } + return result; +} + +enum LineType { + Header, + Unchanged, + Deleted, + Added, +} + +class ViewElementGroup { + constructor( + public readonly range: SimpleLineRangeMapping, + public readonly lines: readonly ViewElement[], + ) { } +} + +type ViewElement = HeaderViewElement | UnchangedLineViewElement | DeletedLineViewElement | AddedLineViewElement; + +class HeaderViewElement { + public readonly type = LineType.Header; +} + +class DeletedLineViewElement { + public readonly type = LineType.Deleted; + + public readonly modifiedLineNumber = undefined; + + constructor( + public readonly diff: LineRangeMapping, + public readonly originalLineNumber: number, + ) { + } +} + +class AddedLineViewElement { + public readonly type = LineType.Added; + + public readonly originalLineNumber = undefined; + + constructor( + public readonly diff: LineRangeMapping, + public readonly modifiedLineNumber: number, + ) { + } +} + +class UnchangedLineViewElement { + public readonly type = LineType.Unchanged; + constructor( + public readonly originalLineNumber: number, + public readonly modifiedLineNumber: number, + ) { + } +} + +class View extends Disposable { + public readonly domNode: HTMLElement; + private readonly _content: HTMLElement; + private readonly _scrollbar: DomScrollableElement; + private readonly _actionBar: ActionBar; + + constructor( + private readonly _element: HTMLElement, + private readonly _model: ViewModel, + private readonly _width: IObservable, + private readonly _height: IObservable, + private readonly _editors: DiffEditorEditors, + @ILanguageService private readonly _languageService: ILanguageService, + ) { + super(); + + this.domNode = this._element; + this.domNode.className = 'diff-review monaco-editor-background'; + + const actionBarContainer = document.createElement('div'); + actionBarContainer.className = 'diff-review-actions'; + this._actionBar = this._register(new ActionBar( + actionBarContainer + )); + this._register(autorun(reader => { + /** @description update actions */ + this._actionBar.clear(); + if (this._model.canClose.read(reader)) { + this._actionBar.push(new Action( + 'diffreview.close', + localize('label.close', "Close"), + 'close-diff-review ' + ThemeIcon.asClassName(accessibleDiffViewerCloseIcon), + true, + async () => _model.close() + ), { label: false, icon: true }); + } + })); + + this._content = document.createElement('div'); + this._content.className = 'diff-review-content'; + this._content.setAttribute('role', 'code'); + this._scrollbar = this._register(new DomScrollableElement(this._content, {})); + reset(this.domNode, this._scrollbar.getDomNode(), actionBarContainer); + + this._register(toDisposable(() => { reset(this.domNode); })); + + this._register(applyStyle(this.domNode, { width: this._width, height: this._height })); + this._register(applyStyle(this._content, { width: this._width, height: this._height })); + + this._register(autorunWithStore((reader, store) => { + /** @description render */ + this._model.currentGroup.read(reader); + this._render(store); + })); + + // TODO@hediet use commands + this._register(addStandardDisposableListener(this.domNode, 'keydown', (e) => { + if ( + e.equals(KeyCode.DownArrow) + || e.equals(KeyMod.CtrlCmd | KeyCode.DownArrow) + || e.equals(KeyMod.Alt | KeyCode.DownArrow) + ) { + e.preventDefault(); + this._model.goToNextLine(); + } + + if ( + e.equals(KeyCode.UpArrow) + || e.equals(KeyMod.CtrlCmd | KeyCode.UpArrow) + || e.equals(KeyMod.Alt | KeyCode.UpArrow) + ) { + e.preventDefault(); + this._model.goToPreviousLine(); + } + + if ( + e.equals(KeyCode.Escape) + || e.equals(KeyMod.CtrlCmd | KeyCode.Escape) + || e.equals(KeyMod.Alt | KeyCode.Escape) + || e.equals(KeyMod.Shift | KeyCode.Escape) + ) { + e.preventDefault(); + this._model.close(); + } + + if ( + e.equals(KeyCode.Space) + || e.equals(KeyCode.Enter) + ) { + e.preventDefault(); + this._model.revealCurrentElementInEditor(); + } + })); + } + + private _render(store: DisposableStore): void { + const originalOptions = this._editors.original.getOptions(); + const modifiedOptions = this._editors.modified.getOptions(); + + const container = document.createElement('div'); + container.className = 'diff-review-table'; + container.setAttribute('role', 'list'); + container.setAttribute('aria-label', localize('ariaLabel', 'Accessible Diff Viewer. Use arrow up and down to navigate.')); + applyFontInfo(container, modifiedOptions.get(EditorOption.fontInfo)); + + reset(this._content, container); + + const originalModel = this._editors.original.getModel(); + const modifiedModel = this._editors.modified.getModel(); + if (!originalModel || !modifiedModel) { + return; + } + + const originalModelOpts = originalModel.getOptions(); + const modifiedModelOpts = modifiedModel.getOptions(); + + const lineHeight = modifiedOptions.get(EditorOption.lineHeight); + const group = this._model.currentGroup.get(); + for (const viewItem of group?.lines || []) { + if (!group) { + break; + } + let row: HTMLDivElement; + + if (viewItem.type === LineType.Header) { + + const header = document.createElement('div'); + header.className = 'diff-review-row'; + header.setAttribute('role', 'listitem'); + + const r = group.range; + const diffIndex = this._model.currentGroupIndex.get(); + const diffsLength = this._model.groups.get().length; + const getAriaLines = (lines: number) => + lines === 0 ? localize('no_lines_changed', "no lines changed") + : lines === 1 ? localize('one_line_changed', "1 line changed") + : localize('more_lines_changed', "{0} lines changed", lines); + + const originalChangedLinesCntAria = getAriaLines(r.original.length); + const modifiedChangedLinesCntAria = getAriaLines(r.modified.length); + header.setAttribute('aria-label', localize({ + key: 'header', + comment: [ + 'This is the ARIA label for a git diff header.', + 'A git diff header looks like this: @@ -154,12 +159,39 @@.', + 'That encodes that at original line 154 (which is now line 159), 12 lines were removed/changed with 39 lines.', + 'Variables 0 and 1 refer to the diff index out of total number of diffs.', + 'Variables 2 and 4 will be numbers (a line number).', + 'Variables 3 and 5 will be "no lines changed", "1 line changed" or "X lines changed", localized separately.' + ] + }, "Difference {0} of {1}: original line {2}, {3}, modified line {4}, {5}", + (diffIndex + 1), + diffsLength, + r.original.startLineNumber, + originalChangedLinesCntAria, + r.modified.startLineNumber, + modifiedChangedLinesCntAria + )); + + const cell = document.createElement('div'); + cell.className = 'diff-review-cell diff-review-summary'; + // e.g.: `1/10: @@ -504,7 +517,7 @@` + cell.appendChild(document.createTextNode(`${diffIndex + 1}/${diffsLength}: @@ -${r.original.startLineNumber},${r.original.length} +${r.modified.startLineNumber},${r.modified.length} @@`)); + header.appendChild(cell); + + row = header; + } else { + row = this._createRow(viewItem, lineHeight, + this._width.get(), originalOptions, originalModel, originalModelOpts, modifiedOptions, modifiedModel, modifiedModelOpts, + ); + } + + container.appendChild(row); + + const isSelectedObs = derived(reader => /** @description isSelected */ this._model.currentElement.read(reader) === viewItem); + + store.add(autorun(reader => { + /** @description update tab index */ + const isSelected = isSelectedObs.read(reader); + row.tabIndex = isSelected ? 0 : -1; + if (isSelected) { + row.focus(); + } + })); + + store.add(addDisposableListener(row, 'focus', () => { + this._model.goToLine(viewItem); + })); + } + + this._scrollbar.scanDomNode(); + } + + private _createRow( + item: DeletedLineViewElement | AddedLineViewElement | UnchangedLineViewElement, + lineHeight: number, + width: number, + originalOptions: IComputedEditorOptions, originalModel: ITextModel, originalModelOpts: TextModelResolvedOptions, + modifiedOptions: IComputedEditorOptions, modifiedModel: ITextModel, modifiedModelOpts: TextModelResolvedOptions, + ): HTMLDivElement { + const originalLayoutInfo = originalOptions.get(EditorOption.layoutInfo); + const originalLineNumbersWidth = originalLayoutInfo.glyphMarginWidth + originalLayoutInfo.lineNumbersWidth; + + const modifiedLayoutInfo = modifiedOptions.get(EditorOption.layoutInfo); + const modifiedLineNumbersWidth = 10 + modifiedLayoutInfo.glyphMarginWidth + modifiedLayoutInfo.lineNumbersWidth; + + let rowClassName: string = 'diff-review-row'; + let lineNumbersExtraClassName: string = ''; + const spacerClassName: string = 'diff-review-spacer'; + let spacerIcon: ThemeIcon | null = null; + switch (item.type) { + case LineType.Added: + rowClassName = 'diff-review-row line-insert'; + lineNumbersExtraClassName = ' char-insert'; + spacerIcon = accessibleDiffViewerInsertIcon; + break; + case LineType.Deleted: + rowClassName = 'diff-review-row line-delete'; + lineNumbersExtraClassName = ' char-delete'; + spacerIcon = accessibleDiffViewerRemoveIcon; + break; + } + + const row = document.createElement('div'); + row.style.minWidth = width + 'px'; + row.className = rowClassName; + row.setAttribute('role', 'listitem'); + row.ariaLevel = ''; + + const cell = document.createElement('div'); + cell.className = 'diff-review-cell'; + cell.style.height = `${lineHeight}px`; + row.appendChild(cell); + + const originalLineNumber = document.createElement('span'); + originalLineNumber.style.width = (originalLineNumbersWidth + 'px'); + originalLineNumber.style.minWidth = (originalLineNumbersWidth + 'px'); + originalLineNumber.className = 'diff-review-line-number' + lineNumbersExtraClassName; + if (item.originalLineNumber !== undefined) { + originalLineNumber.appendChild(document.createTextNode(String(item.originalLineNumber))); + } else { + originalLineNumber.innerText = '\u00a0'; + } + cell.appendChild(originalLineNumber); + + const modifiedLineNumber = document.createElement('span'); + modifiedLineNumber.style.width = (modifiedLineNumbersWidth + 'px'); + modifiedLineNumber.style.minWidth = (modifiedLineNumbersWidth + 'px'); + modifiedLineNumber.style.paddingRight = '10px'; + modifiedLineNumber.className = 'diff-review-line-number' + lineNumbersExtraClassName; + if (item.modifiedLineNumber !== undefined) { + modifiedLineNumber.appendChild(document.createTextNode(String(item.modifiedLineNumber))); + } else { + modifiedLineNumber.innerText = '\u00a0'; + } + cell.appendChild(modifiedLineNumber); + + const spacer = document.createElement('span'); + spacer.className = spacerClassName; + + if (spacerIcon) { + const spacerCodicon = document.createElement('span'); + spacerCodicon.className = ThemeIcon.asClassName(spacerIcon); + spacerCodicon.innerText = '\u00a0\u00a0'; + spacer.appendChild(spacerCodicon); + } else { + spacer.innerText = '\u00a0\u00a0'; + } + cell.appendChild(spacer); + + let lineContent: string; + if (item.modifiedLineNumber !== undefined) { + let html: string | TrustedHTML = this._getLineHtml(modifiedModel, modifiedOptions, modifiedModelOpts.tabSize, item.modifiedLineNumber, this._languageService.languageIdCodec); + if (DiffReview._ttPolicy) { + html = DiffReview._ttPolicy.createHTML(html as string); + } + cell.insertAdjacentHTML('beforeend', html as string); + lineContent = modifiedModel.getLineContent(item.modifiedLineNumber); + } else { + let html: string | TrustedHTML = this._getLineHtml(originalModel, originalOptions, originalModelOpts.tabSize, item.originalLineNumber, this._languageService.languageIdCodec); + if (DiffReview._ttPolicy) { + html = DiffReview._ttPolicy.createHTML(html as string); + } + cell.insertAdjacentHTML('beforeend', html as string); + lineContent = originalModel.getLineContent(item.originalLineNumber); + } + + if (lineContent.length === 0) { + lineContent = localize('blankLine', "blank"); + } + + let ariaLabel: string = ''; + switch (item.type) { + case LineType.Unchanged: + if (item.originalLineNumber === item.modifiedLineNumber) { + ariaLabel = localize({ key: 'unchangedLine', comment: ['The placeholders are contents of the line and should not be translated.'] }, "{0} unchanged line {1}", lineContent, item.originalLineNumber); + } else { + ariaLabel = localize('equalLine', "{0} original line {1} modified line {2}", lineContent, item.originalLineNumber, item.modifiedLineNumber); + } + break; + case LineType.Added: + ariaLabel = localize('insertLine', "+ {0} modified line {1}", lineContent, item.modifiedLineNumber); + break; + case LineType.Deleted: + ariaLabel = localize('deleteLine', "- {0} original line {1}", lineContent, item.originalLineNumber); + break; + } + row.setAttribute('aria-label', ariaLabel); + + return row; + } + + private _getLineHtml(model: ITextModel, options: IComputedEditorOptions, tabSize: number, lineNumber: number, languageIdCodec: ILanguageIdCodec): string { + const lineContent = model.getLineContent(lineNumber); + const fontInfo = options.get(EditorOption.fontInfo); + const lineTokens = LineTokens.createEmpty(lineContent, languageIdCodec); + const isBasicASCII = ViewLineRenderingData.isBasicASCII(lineContent, model.mightContainNonBasicASCII()); + const containsRTL = ViewLineRenderingData.containsRTL(lineContent, isBasicASCII, model.mightContainRTL()); + const r = renderViewLine2(new RenderLineInput( + (fontInfo.isMonospace && !options.get(EditorOption.disableMonospaceOptimizations)), + fontInfo.canUseHalfwidthRightwardsArrow, + lineContent, + false, + isBasicASCII, + containsRTL, + 0, + lineTokens, + [], + tabSize, + 0, + fontInfo.spaceWidth, + fontInfo.middotWidth, + fontInfo.wsmiddotWidth, + options.get(EditorOption.stopRenderingLineAfter), + options.get(EditorOption.renderWhitespace), + options.get(EditorOption.renderControlCharacters), + options.get(EditorOption.fontLigatures) !== EditorFontLigatures.OFF, + null + )); + + return r.html; + } +} + +function forEachAdjacentItems(items: T[], callback: (item1: T | undefined, item2: T | undefined) => void) { + let last: T | undefined; + for (const item of items) { + callback(last, item); + last = item; + } + callback(last, undefined); +} + +function* group(items: Iterable, shouldBeGrouped: (item1: T, item2: T) => boolean): Iterable { + let currentGroup: T[] | undefined; + let last: T | undefined; + for (const item of items) { + if (last !== undefined && shouldBeGrouped(last, item)) { + currentGroup!.push(item); + } else { + if (currentGroup) { + yield currentGroup; + } + currentGroup = [item]; + } + last = item; + } + if (currentGroup) { + yield currentGroup; + } +} diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/colors.ts b/src/vs/editor/browser/widget/diffEditorWidget2/colors.ts index 8c78445d74bbd..449e67f06f8dd 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/colors.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/colors.ts @@ -11,3 +11,9 @@ export const diffMoveBorder = registerColor( { dark: '#8b8b8b9c', light: '#8b8b8b9c', hcDark: '#8b8b8b9c', hcLight: '#8b8b8b9c', }, localize('diffEditor.move.border', 'The border color for text that got moved in the diff editor.') ); + +export const diffMoveBorderActive = registerColor( + 'diffEditor.moveActive.border', + { dark: '#FFA500', light: '#FFA500', hcDark: '#FFA500', hcLight: '#FFA500', }, + localize('diffEditor.moveActive.border', 'The active border color for text that got moved in the diff editor.') +); diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorDecorations.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorDecorations.ts index 8a821c0b135cf..9a4b5bcf09493 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorDecorations.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorDecorations.ts @@ -5,14 +5,12 @@ import { Disposable } from 'vs/base/common/lifecycle'; import { IObservable, derived } from 'vs/base/common/observable'; -import { isDefined } from 'vs/base/common/types'; import { arrowRevertChange, diffAddDecoration, diffAddDecorationEmpty, diffDeleteDecoration, diffDeleteDecorationEmpty, diffLineAddDecorationBackground, diffLineAddDecorationBackgroundWithIndicator, diffLineDeleteDecorationBackground, diffLineDeleteDecorationBackgroundWithIndicator, diffWholeLineAddDecoration, diffWholeLineDeleteDecoration } from 'vs/editor/browser/widget/diffEditorWidget2/decorations'; import { DiffEditorEditors } from 'vs/editor/browser/widget/diffEditorWidget2/diffEditorEditors'; import { DiffEditorOptions } from 'vs/editor/browser/widget/diffEditorWidget2/diffEditorOptions'; import { DiffEditorViewModel } from 'vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel'; import { MovedBlocksLinesPart } from 'vs/editor/browser/widget/diffEditorWidget2/movedBlocksLines'; import { applyObservableDecorations } from 'vs/editor/browser/widget/diffEditorWidget2/utils'; -import { LineRange } from 'vs/editor/common/core/lineRange'; import { Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; import { IModelDeltaDecoration } from 'vs/editor/common/model'; @@ -29,63 +27,55 @@ export class DiffEditorDecorations extends Disposable { this._register(applyObservableDecorations(this._editors.modified, this._decorations.map(d => d?.modifiedDecorations || []))); } - private readonly _decorations = derived('decorations', (reader) => { + private readonly _decorations = derived((reader) => { + /** @description _decorations */ const diff = this._diffModel.read(reader)?.diff.read(reader); if (!diff) { return null; } - const currentMove = this._diffModel.read(reader)!.syncedMovedTexts.read(reader); + const movedTextToCompare = this._diffModel.read(reader)!.movedTextToCompare.read(reader); const renderIndicators = this._options.renderIndicators.read(reader); const showEmptyDecorations = this._options.showEmptyDecorations.read(reader); const originalDecorations: IModelDeltaDecoration[] = []; const modifiedDecorations: IModelDeltaDecoration[] = []; - for (const m of diff.mappings) { - const fullRangeOriginal = LineRange.subtract(m.lineRangeMapping.originalRange, currentMove?.lineRangeMapping.originalRange) - .map(i => i.toInclusiveRange()).filter(isDefined); - for (const range of fullRangeOriginal) { - originalDecorations.push({ range, options: renderIndicators ? diffLineDeleteDecorationBackgroundWithIndicator : diffLineDeleteDecorationBackground }); - } - - const fullRangeModified = LineRange.subtract(m.lineRangeMapping.modifiedRange, currentMove?.lineRangeMapping.modifiedRange) - .map(i => i.toInclusiveRange()).filter(isDefined); - for (const range of fullRangeModified) { - modifiedDecorations.push({ range, options: renderIndicators ? diffLineAddDecorationBackgroundWithIndicator : diffLineAddDecorationBackground }); - } - - if (m.lineRangeMapping.modifiedRange.isEmpty || m.lineRangeMapping.originalRange.isEmpty) { - for (const range of fullRangeOriginal) { - originalDecorations.push({ range, options: diffWholeLineDeleteDecoration }); + if (!movedTextToCompare) { + for (const m of diff.mappings) { + if (!m.lineRangeMapping.originalRange.isEmpty) { + originalDecorations.push({ range: m.lineRangeMapping.originalRange.toInclusiveRange()!, options: renderIndicators ? diffLineDeleteDecorationBackgroundWithIndicator : diffLineDeleteDecorationBackground }); } - for (const range of fullRangeModified) { - modifiedDecorations.push({ range, options: diffWholeLineAddDecoration }); + if (!m.lineRangeMapping.modifiedRange.isEmpty) { + modifiedDecorations.push({ range: m.lineRangeMapping.modifiedRange.toInclusiveRange()!, options: renderIndicators ? diffLineAddDecorationBackgroundWithIndicator : diffLineAddDecorationBackground }); } - } else { - for (const i of m.lineRangeMapping.innerChanges || []) { - if (currentMove - && (currentMove.lineRangeMapping.originalRange.intersect(new LineRange(i.originalRange.startLineNumber, i.originalRange.endLineNumber)) - || currentMove.lineRangeMapping.modifiedRange.intersect(new LineRange(i.modifiedRange.startLineNumber, i.modifiedRange.endLineNumber)))) { - continue; - } - // Don't show empty markers outside the line range - if (m.lineRangeMapping.originalRange.contains(i.originalRange.startLineNumber)) { - originalDecorations.push({ range: i.originalRange, options: (i.originalRange.isEmpty() && showEmptyDecorations) ? diffDeleteDecorationEmpty : diffDeleteDecoration }); + if (m.lineRangeMapping.modifiedRange.isEmpty || m.lineRangeMapping.originalRange.isEmpty) { + if (!m.lineRangeMapping.originalRange.isEmpty) { + originalDecorations.push({ range: m.lineRangeMapping.originalRange.toInclusiveRange()!, options: diffWholeLineDeleteDecoration }); + } + if (!m.lineRangeMapping.modifiedRange.isEmpty) { + modifiedDecorations.push({ range: m.lineRangeMapping.modifiedRange.toInclusiveRange()!, options: diffWholeLineAddDecoration }); } - if (m.lineRangeMapping.modifiedRange.contains(i.modifiedRange.startLineNumber)) { - modifiedDecorations.push({ range: i.modifiedRange, options: (i.modifiedRange.isEmpty() && showEmptyDecorations) ? diffAddDecorationEmpty : diffAddDecoration }); + } else { + for (const i of m.lineRangeMapping.innerChanges || []) { + // Don't show empty markers outside the line range + if (m.lineRangeMapping.originalRange.contains(i.originalRange.startLineNumber)) { + originalDecorations.push({ range: i.originalRange, options: (i.originalRange.isEmpty() && showEmptyDecorations) ? diffDeleteDecorationEmpty : diffDeleteDecoration }); + } + if (m.lineRangeMapping.modifiedRange.contains(i.modifiedRange.startLineNumber)) { + modifiedDecorations.push({ range: i.modifiedRange, options: (i.modifiedRange.isEmpty() && showEmptyDecorations) ? diffAddDecorationEmpty : diffAddDecoration }); + } } } - } - if (!m.lineRangeMapping.modifiedRange.isEmpty && this._options.shouldRenderRevertArrows.read(reader) && !currentMove) { - modifiedDecorations.push({ range: Range.fromPositions(new Position(m.lineRangeMapping.modifiedRange.startLineNumber, 1)), options: arrowRevertChange }); + if (!m.lineRangeMapping.modifiedRange.isEmpty && this._options.shouldRenderRevertArrows.read(reader) && !movedTextToCompare) { + modifiedDecorations.push({ range: Range.fromPositions(new Position(m.lineRangeMapping.modifiedRange.startLineNumber, 1)), options: arrowRevertChange }); + } } } - if (currentMove) { - for (const m of currentMove.changes) { + if (movedTextToCompare) { + for (const m of movedTextToCompare.changes) { const fullRangeOriginal = m.originalRange.toInclusiveRange(); if (fullRangeOriginal) { originalDecorations.push({ range: fullRangeOriginal, options: renderIndicators ? diffLineDeleteDecorationBackgroundWithIndicator : diffLineDeleteDecorationBackground }); @@ -101,20 +91,21 @@ export class DiffEditorDecorations extends Disposable { } } } + const activeMovedText = this._diffModel.read(reader)!.activeMovedText.read(reader); for (const m of diff.movedTexts) { originalDecorations.push({ - range: m.lineRangeMapping.originalRange.toInclusiveRange()!, options: { + range: m.lineRangeMapping.original.toInclusiveRange()!, options: { description: 'moved', - blockClassName: 'movedOriginal', + blockClassName: 'movedOriginal' + (m === activeMovedText ? ' currentMove' : ''), blockPadding: [MovedBlocksLinesPart.movedCodeBlockPadding, 0, MovedBlocksLinesPart.movedCodeBlockPadding, MovedBlocksLinesPart.movedCodeBlockPadding], } }); modifiedDecorations.push({ - range: m.lineRangeMapping.modifiedRange.toInclusiveRange()!, options: { + range: m.lineRangeMapping.modified.toInclusiveRange()!, options: { description: 'moved', - blockClassName: 'movedModified', + blockClassName: 'movedModified' + (m === activeMovedText ? ' currentMove' : ''), blockPadding: [4, 0, 4, 4], } }); diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorEditors.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorEditors.ts index a77d3c1727b34..877f79ce430d4 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorEditors.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorEditors.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { Emitter } from 'vs/base/common/event'; import { Disposable } from 'vs/base/common/lifecycle'; -import { autorunHandleChanges } from 'vs/base/common/observableImpl/autorun'; +import { IReader, autorunHandleChanges } from 'vs/base/common/observable'; import { IEditorConstructionOptions } from 'vs/editor/browser/config/editorConfiguration'; import { IDiffEditorConstructionOptions } from 'vs/editor/browser/editorBrowser'; import { CodeEditorWidget, ICodeEditorWidgetOptions } from 'vs/editor/browser/widget/codeEditorWidget'; @@ -14,9 +14,8 @@ import { EditorOptions, IEditorOptions } from 'vs/editor/common/config/editorOpt import { IContentSizeChangedEvent } from 'vs/editor/common/editorCommon'; import { localize } from 'vs/nls'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { DiffEditorOptions } from './diffEditorOptions'; -import { IObservable, IReader } from 'vs/base/common/observable'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; +import { DiffEditorOptions } from './diffEditorOptions'; export class DiffEditorEditors extends Disposable { public readonly modified: CodeEditorWidget; @@ -31,16 +30,15 @@ export class DiffEditorEditors extends Disposable { private readonly _options: DiffEditorOptions, codeEditorWidgetOptions: IDiffCodeEditorWidgetOptions, private readonly _createInnerEditor: (instantiationService: IInstantiationService, container: HTMLElement, options: Readonly, editorWidgetOptions: ICodeEditorWidgetOptions) => CodeEditorWidget, - private readonly _modifiedReadOnlyOverride: IObservable, @IInstantiationService private readonly _instantiationService: IInstantiationService, @IKeybindingService private readonly _keybindingService: IKeybindingService, ) { super(); - this.original = this._createLeftHandSideEditor(_options.editorOptions.get(), codeEditorWidgetOptions.originalEditor || {}); - this.modified = this._createRightHandSideEditor(_options.editorOptions.get(), codeEditorWidgetOptions.modifiedEditor || {}); + this.original = this._register(this._createLeftHandSideEditor(_options.editorOptions.get(), codeEditorWidgetOptions.originalEditor || {})); + this.modified = this._register(this._createRightHandSideEditor(_options.editorOptions.get(), codeEditorWidgetOptions.modifiedEditor || {})); - this._register(autorunHandleChanges('update editor options', { + this._register(autorunHandleChanges({ createEmptyChangeSummary: () => ({} as IDiffEditorConstructionOptions), handleChange: (ctx, changeSummary) => { if (ctx.didChange(_options.editorOptions)) { @@ -49,8 +47,11 @@ export class DiffEditorEditors extends Disposable { return true; } }, (reader, changeSummary) => { + /** @description update editor options */ _options.editorOptions.read(reader); + this._options.renderSideBySide.read(reader); + this.modified.updateOptions(this._adjustOptionsForRightHandSide(reader, changeSummary)); this.original.updateOptions(this._adjustOptionsForLeftHandSide(reader, changeSummary)); })); @@ -94,7 +95,11 @@ export class DiffEditorEditors extends Disposable { result.wordWrapOverride1 = 'off'; result.wordWrapOverride2 = 'off'; result.stickyScroll = { enabled: false }; + + // Disable unicode highlighting for the original side in inline mode, as they are not shown anyway. + result.unicodeHighlight = { nonBasicASCII: false, ambiguousCharacters: false, invisibleCharacters: false }; } else { + result.unicodeHighlight = this._options.editorOptions.get().unicodeHighlight; result.wordWrapOverride1 = this._options.diffWordWrap.get(); } if (changedOptions.originalAriaLabel) { @@ -117,7 +122,6 @@ export class DiffEditorEditors extends Disposable { result.revealHorizontalRightPadding = EditorOptions.revealHorizontalRightPadding.defaultValue + OverviewRulerPart.ENTIRE_DIFF_OVERVIEW_WIDTH; result.scrollbar!.verticalHasArrows = false; result.extraEditorClassName = 'modified-in-monaco-diff-editor'; - result.readOnly = this._modifiedReadOnlyOverride.read(reader) || this._options.editorOptions.get().readOnly; return result; } @@ -161,6 +165,6 @@ export class DiffEditorEditors extends Disposable { } else if (ariaLabel) { return ariaLabel.replaceAll(ariaNavigationTip, ''); } - return undefined; + return ''; } } diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorOptions.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorOptions.ts index fcec4e86f0926..ee8aa4e9ca0d1 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorOptions.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorOptions.ts @@ -14,38 +14,46 @@ export class DiffEditorOptions { public get editorOptions(): IObservable { return this._options; } - constructor(options: Readonly) { + constructor(options: Readonly, private readonly diffEditorWidth: IObservable) { const optionsCopy = { ...options, ...validateDiffEditorOptions(options, diffEditorDefaultOptions) }; this._options = observableValue('options', optionsCopy); } - public readonly renderOverviewRuler = derived('renderOverviewRuler', reader => this._options.read(reader).renderOverviewRuler); - public readonly renderSideBySide = derived('renderSideBySide', reader => this._options.read(reader).renderSideBySide); - public readonly readOnly = derived('readOnly', reader => this._options.read(reader).readOnly); + public readonly couldShowInlineViewBecauseOfSize = derived(reader => /** @description couldShowInlineViewBecauseOfSize */ this._options.read(reader).renderSideBySide && this.diffEditorWidth.read(reader) <= this._options.read(reader).renderSideBySideInlineBreakpoint + ); - public readonly shouldRenderRevertArrows = derived('shouldRenderRevertArrows', (reader) => { + public readonly renderOverviewRuler = derived(reader => /** @description renderOverviewRuler */ this._options.read(reader).renderOverviewRuler); + public readonly renderSideBySide = derived(reader => /** @description renderSideBySide */ this._options.read(reader).renderSideBySide + && !(this._options.read(reader).useInlineViewWhenSpaceIsLimited && this.couldShowInlineViewBecauseOfSize.read(reader)) + ); + public readonly readOnly = derived(reader => /** @description readOnly */ this._options.read(reader).readOnly); + + public readonly shouldRenderRevertArrows = derived(reader => { + /** @description shouldRenderRevertArrows */ if (!this._options.read(reader).renderMarginRevertIcon) { return false; } if (!this.renderSideBySide.read(reader)) { return false; } if (this.readOnly.read(reader)) { return false; } return true; }); - public readonly renderIndicators = derived('renderIndicators', reader => this._options.read(reader).renderIndicators); - public readonly enableSplitViewResizing = derived('enableSplitViewResizing', reader => this._options.read(reader).enableSplitViewResizing); - public readonly collapseUnchangedRegions = derived('hideUnchangedRegions', reader => this._options.read(reader).experimental.collapseUnchangedRegions!); - public readonly splitViewDefaultRatio = derived('splitViewDefaultRatio', reader => this._options.read(reader).splitViewDefaultRatio); - public readonly ignoreTrimWhitespace = derived('ignoreTrimWhitespace', reader => this._options.read(reader).ignoreTrimWhitespace); - public readonly maxComputationTimeMs = derived('maxComputationTime', reader => this._options.read(reader).maxComputationTime); - public readonly showMoves = derived('showMoves', reader => { + public readonly renderIndicators = derived(reader => /** @description renderIndicators */ this._options.read(reader).renderIndicators); + public readonly enableSplitViewResizing = derived(reader => /** @description enableSplitViewResizing */ this._options.read(reader).enableSplitViewResizing); + public readonly collapseUnchangedRegions = derived(reader => /** @description hideUnchangedRegions */ this._options.read(reader).experimental.collapseUnchangedRegions!); + public readonly splitViewDefaultRatio = derived(reader => /** @description splitViewDefaultRatio */ this._options.read(reader).splitViewDefaultRatio); + public readonly ignoreTrimWhitespace = derived(reader => /** @description ignoreTrimWhitespace */ this._options.read(reader).ignoreTrimWhitespace); + public readonly maxComputationTimeMs = derived(reader => /** @description maxComputationTime */ this._options.read(reader).maxComputationTime); + public readonly showMoves = derived(reader => { + /** @description showMoves */ const o = this._options.read(reader); return o.experimental.showMoves! && o.renderSideBySide; }); - public readonly isInEmbeddedEditor = derived('isInEmbeddedEditor', reader => this._options.read(reader).isInEmbeddedEditor); - public readonly diffWordWrap = derived('diffWordWrap', reader => this._options.read(reader).diffWordWrap); - public readonly originalEditable = derived('originalEditable', reader => this._options.read(reader).originalEditable); - public readonly diffCodeLens = derived('diffCodeLens', reader => this._options.read(reader).diffCodeLens); - public readonly accessibilityVerbose = derived('accessibilityVerbose', reader => this._options.read(reader).accessibilityVerbose); - public readonly diffAlgorithm = derived('diffAlgorithm', reader => this._options.read(reader).diffAlgorithm); - public readonly showEmptyDecorations = derived('showEmptyDecorations', reader => this._options.read(reader).experimental.showEmptyDecorations!); + public readonly isInEmbeddedEditor = derived(reader => /** @description isInEmbeddedEditor */ this._options.read(reader).isInEmbeddedEditor); + public readonly diffWordWrap = derived(reader => /** @description diffWordWrap */ this._options.read(reader).diffWordWrap); + public readonly originalEditable = derived(reader => /** @description originalEditable */ this._options.read(reader).originalEditable); + public readonly diffCodeLens = derived(reader => /** @description diffCodeLens */ this._options.read(reader).diffCodeLens); + public readonly accessibilityVerbose = derived(reader => /** @description accessibilityVerbose */ this._options.read(reader).accessibilityVerbose); + public readonly diffAlgorithm = derived(reader => /** @description diffAlgorithm */ this._options.read(reader).diffAlgorithm); + public readonly showEmptyDecorations = derived(reader => /** @description showEmptyDecorations */ this._options.read(reader).experimental.showEmptyDecorations!); + public readonly onlyShowAccessibleDiffViewer = derived(reader => /** @description onlyShowAccessibleDiffViewer */ this._options.read(reader).onlyShowAccessibleDiffViewer); public updateOptions(changedOptions: IDiffEditorOptions): void { const newDiffEditorOptions = validateDiffEditorOptions(changedOptions, this._options.get()); @@ -75,6 +83,9 @@ const diffEditorDefaultOptions: ValidDiffEditorBaseOptions = { showEmptyDecorations: true, }, isInEmbeddedEditor: false, + onlyShowAccessibleDiffViewer: false, + renderSideBySideInlineBreakpoint: 900, + useInlineViewWhenSpaceIsLimited: true, }; function validateDiffEditorOptions(options: Readonly, defaults: ValidDiffEditorBaseOptions): ValidDiffEditorBaseOptions { @@ -99,5 +110,8 @@ function validateDiffEditorOptions(options: Readonly, defaul showEmptyDecorations: validateBooleanOption(options.experimental?.showEmptyDecorations, defaults.experimental.showEmptyDecorations!), }, isInEmbeddedEditor: validateBooleanOption(options.isInEmbeddedEditor, defaults.isInEmbeddedEditor), + onlyShowAccessibleDiffViewer: validateBooleanOption(options.onlyShowAccessibleDiffViewer, defaults.onlyShowAccessibleDiffViewer), + renderSideBySideInlineBreakpoint: clampedInt(options.renderSideBySideInlineBreakpoint, defaults.renderSideBySideInlineBreakpoint, 0, Constants.MAX_SAFE_SMALL_INTEGER), + useInlineViewWhenSpaceIsLimited: validateBooleanOption(options.useInlineViewWhenSpaceIsLimited, defaults.useInlineViewWhenSpaceIsLimited), }; } diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorSash.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorSash.ts index 953a41f5a0c7d..aa25a92dacf7d 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorSash.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorSash.ts @@ -11,7 +11,8 @@ import { DiffEditorOptions } from './diffEditorOptions'; export class DiffEditorSash extends Disposable { private readonly _sashRatio = observableValue('sashRatio', undefined); - public readonly sashLeft = derived('sashLeft', reader => { + public readonly sashLeft = derived(reader => { + /** @description sashLeft */ const ratio = this._sashRatio.read(reader) ?? this._options.splitViewDefaultRatio.read(reader); return this._computeSashLeft(ratio, reader); }); @@ -42,7 +43,8 @@ export class DiffEditorSash extends Disposable { this._register(this._sash.onDidEnd(() => this._sash.layout())); this._register(this._sash.onDidReset(() => this._sashRatio.set(undefined, undefined))); - this._register(autorun('update sash layout', (reader) => { + this._register(autorun(reader => { + /** @description update sash layout */ const enabled = this._options.enableSplitViewResizing.read(reader); this._sash.state = enabled ? SashState.Enabled : SashState.Disabled; this.sashLeft.read(reader); diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts index f9d77296cea2f..a41ba6a99094f 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts @@ -4,21 +4,22 @@ *--------------------------------------------------------------------------------------------*/ import { RunOnceScheduler } from 'vs/base/common/async'; -import { Disposable } from 'vs/base/common/lifecycle'; -import { IObservable, IReader, ISettableObservable, ITransaction, derived, observableSignal, observableSignalFromEvent, observableValue, transaction, waitForState } from 'vs/base/common/observable'; -import { autorunWithStore2 } from 'vs/base/common/observableImpl/autorun'; +import { Disposable, toDisposable } from 'vs/base/common/lifecycle'; +import { IObservable, IReader, ISettableObservable, ITransaction, autorunWithStore, derived, observableSignal, observableSignalFromEvent, observableValue, transaction, waitForState } from 'vs/base/common/observable'; import { isDefined } from 'vs/base/common/types'; import { ISerializedLineRange, LineRange } from 'vs/editor/common/core/lineRange'; import { Range } from 'vs/editor/common/core/range'; import { IDocumentDiff, IDocumentDiffProvider } from 'vs/editor/common/diff/documentDiffProvider'; import { LineRangeMapping, MovedText, RangeMapping, SimpleLineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; -import { lineRangeMappingFromRangeMappings } from 'vs/editor/common/diff/standardLinesDiffComputer'; +import { AdvancedLinesDiffComputer, lineRangeMappingFromRangeMappings } from 'vs/editor/common/diff/advancedLinesDiffComputer'; import { IDiffEditorModel, IDiffEditorViewModel } from 'vs/editor/common/editorCommon'; import { ITextModel } from 'vs/editor/common/model'; import { TextEditInfo } from 'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/beforeEditPositionMapper'; import { combineTextEditInfos } from 'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/combineTextEditInfos'; import { lengthAdd, lengthDiffNonNegative, lengthGetLineCount, lengthOfRange, lengthToPosition, lengthZero, positionToLength } from 'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/length'; import { DiffEditorOptions } from './diffEditorOptions'; +import { readHotReloadableExport } from 'vs/editor/browser/widget/diffEditorWidget2/utils'; +import { CancellationTokenSource } from 'vs/base/common/cancellation'; export class DiffEditorViewModel extends Disposable implements IDiffEditorViewModel { private readonly _isDiffUpToDate = observableValue('isDiffUpToDate', false); @@ -32,7 +33,8 @@ export class DiffEditorViewModel extends Disposable implements IDiffEditorViewMo 'unchangedRegion', { regions: [], originalDecorationIds: [], modifiedDecorationIds: [] } ); - public readonly unchangedRegions: IObservable = derived('unchangedRegions', r => { + public readonly unchangedRegions: IObservable = derived(r => { + /** @description unchangedRegions */ if (this._options.collapseUnchangedRegions.read(r)) { return this._unchangedRegions.read(r).regions; } else { @@ -47,7 +49,23 @@ export class DiffEditorViewModel extends Disposable implements IDiffEditorViewMo } ); - public readonly syncedMovedTexts = observableValue('syncedMovedText', undefined); + public readonly movedTextToCompare = observableValue('movedTextToCompare', undefined); + + private readonly _activeMovedText = observableValue('activeMovedText', undefined); + private readonly _hoveredMovedText = observableValue('hoveredMovedText', undefined); + + + public readonly activeMovedText = derived(r => this.movedTextToCompare.read(r) ?? this._hoveredMovedText.read(r) ?? this._activeMovedText.read(r)); + + public setActiveMovedText(movedText: MovedText | undefined): void { + this._activeMovedText.set(movedText, undefined); + } + + public setHoveredMovedText(movedText: MovedText | undefined): void { + this._hoveredMovedText.set(movedText, undefined); + } + + private readonly _cancellationTokenSource = new CancellationTokenSource(); constructor( public readonly model: IDiffEditorModel, @@ -56,6 +74,8 @@ export class DiffEditorViewModel extends Disposable implements IDiffEditorViewMo ) { super(); + this._register(toDisposable(() => this._cancellationTokenSource.cancel())); + const contentChangedSignal = observableSignal('contentChangedSignal'); const debouncer = this._register(new RunOnceScheduler(() => contentChangedSignal.trigger(undefined), 200)); @@ -105,40 +125,36 @@ export class DiffEditorViewModel extends Disposable implements IDiffEditorViewMo this._register(model.modified.onDidChangeContent((e) => { const diff = this._diff.get(); - if (!diff) { - return; - } - - const textEdits = TextEditInfo.fromModelContentChanges(e.changes); - const result = applyModifiedEdits(this._lastDiff!, textEdits, model.original, model.modified); - if (result) { - this._lastDiff = result; - transaction(tx => { - this._diff.set(DiffState.fromDiffResult(this._lastDiff!), tx); - updateUnchangedRegions(result, tx); - const currentSyncedMovedText = this.syncedMovedTexts.get(); - this.syncedMovedTexts.set(currentSyncedMovedText ? this._lastDiff!.moves.find(m => m.lineRangeMapping.modifiedRange.intersect(currentSyncedMovedText.lineRangeMapping.modifiedRange)) : undefined, tx); - }); + if (diff) { + const textEdits = TextEditInfo.fromModelContentChanges(e.changes); + const result = applyModifiedEdits(this._lastDiff!, textEdits, model.original, model.modified); + if (result) { + this._lastDiff = result; + transaction(tx => { + this._diff.set(DiffState.fromDiffResult(this._lastDiff!), tx); + updateUnchangedRegions(result, tx); + const currentSyncedMovedText = this.movedTextToCompare.get(); + this.movedTextToCompare.set(currentSyncedMovedText ? this._lastDiff!.moves.find(m => m.lineRangeMapping.modified.intersect(currentSyncedMovedText.lineRangeMapping.modified)) : undefined, tx); + }); + } } debouncer.schedule(); })); this._register(model.original.onDidChangeContent((e) => { const diff = this._diff.get(); - if (!diff) { - return; - } - - const textEdits = TextEditInfo.fromModelContentChanges(e.changes); - const result = applyOriginalEdits(this._lastDiff!, textEdits, model.original, model.modified); - if (result) { - this._lastDiff = result; - transaction(tx => { - this._diff.set(DiffState.fromDiffResult(this._lastDiff!), tx); - updateUnchangedRegions(result, tx); - const currentSyncedMovedText = this.syncedMovedTexts.get(); - this.syncedMovedTexts.set(currentSyncedMovedText ? this._lastDiff!.moves.find(m => m.lineRangeMapping.modifiedRange.intersect(currentSyncedMovedText.lineRangeMapping.modifiedRange)) : undefined, tx); - }); + if (diff) { + const textEdits = TextEditInfo.fromModelContentChanges(e.changes); + const result = applyOriginalEdits(this._lastDiff!, textEdits, model.original, model.modified); + if (result) { + this._lastDiff = result; + transaction(tx => { + this._diff.set(DiffState.fromDiffResult(this._lastDiff!), tx); + updateUnchangedRegions(result, tx); + const currentSyncedMovedText = this.movedTextToCompare.get(); + this.movedTextToCompare.set(currentSyncedMovedText ? this._lastDiff!.moves.find(m => m.lineRangeMapping.modified.intersect(currentSyncedMovedText.lineRangeMapping.modified)) : undefined, tx); + }); + } } debouncer.schedule(); @@ -146,10 +162,12 @@ export class DiffEditorViewModel extends Disposable implements IDiffEditorViewMo const documentDiffProviderOptionChanged = observableSignalFromEvent('documentDiffProviderOptionChanged', documentDiffProvider.onDidChange); - this._register(autorunWithStore2('compute diff', async (reader, store) => { + this._register(autorunWithStore(async (reader, store) => { + /** @description compute diff */ debouncer.cancel(); contentChangedSignal.read(reader); documentDiffProviderOptionChanged.read(reader); + readHotReloadableExport(AdvancedLinesDiffComputer, reader); this._isDiffUpToDate.set(false, undefined); @@ -169,12 +187,15 @@ export class DiffEditorViewModel extends Disposable implements IDiffEditorViewMo ignoreTrimWhitespace: this._options.ignoreTrimWhitespace.read(reader), maxComputationTimeMs: this._options.maxComputationTimeMs.read(reader), computeMoves: this._options.showMoves.read(reader), - }); + }, this._cancellationTokenSource.token); + + if (this._cancellationTokenSource.token.isCancellationRequested) { + return; + } result = applyOriginalEdits(result, originalTextEditInfos, model.original, model.modified) ?? result; result = applyModifiedEdits(result, modifiedTextEditInfos, model.original, model.modified) ?? result; - transaction(tx => { updateUnchangedRegions(result, tx); @@ -182,8 +203,8 @@ export class DiffEditorViewModel extends Disposable implements IDiffEditorViewMo const state = DiffState.fromDiffResult(result); this._diff.set(state, tx); this._isDiffUpToDate.set(true, tx); - const currentSyncedMovedText = this.syncedMovedTexts.get(); - this.syncedMovedTexts.set(currentSyncedMovedText ? this._lastDiff.moves.find(m => m.lineRangeMapping.modifiedRange.intersect(currentSyncedMovedText.lineRangeMapping.modifiedRange)) : undefined, tx); + const currentSyncedMovedText = this.movedTextToCompare.get(); + this.movedTextToCompare.set(currentSyncedMovedText ? this._lastDiff.moves.find(m => m.lineRangeMapping.modified.intersect(currentSyncedMovedText.lineRangeMapping.modified)) : undefined, tx); }); })); } @@ -339,7 +360,7 @@ export class UnchangedRegion { private readonly _visibleLineCountBottom = observableValue('visibleLineCountBottom', 0); public readonly visibleLineCountBottom: ISettableObservable = this._visibleLineCountBottom; - private readonly _shouldHideControls = derived('isVisible', reader => this.visibleLineCountTop.read(reader) + this.visibleLineCountBottom.read(reader) === this.lineCount && !this.isDragged.read(reader)); + private readonly _shouldHideControls = derived(reader => /** @description isVisible */ this.visibleLineCountTop.read(reader) + this.visibleLineCountBottom.read(reader) === this.lineCount && !this.isDragged.read(reader)); public readonly isDragged = observableValue('isDragged', false); @@ -443,9 +464,9 @@ function applyModifiedEdits(diff: IDocumentDiff, textEdits: TextEditInfo[], orig const changes = applyModifiedEditsToLineRangeMappings(diff.changes, textEdits, originalTextModel, modifiedTextModel); const moves = diff.moves.map(m => { - const newModifiedRange = applyEditToLineRange(m.lineRangeMapping.modifiedRange, textEdits); + const newModifiedRange = applyEditToLineRange(m.lineRangeMapping.modified, textEdits); return newModifiedRange ? new MovedText( - new SimpleLineRangeMapping(m.lineRangeMapping.originalRange, newModifiedRange), + new SimpleLineRangeMapping(m.lineRangeMapping.original, newModifiedRange), applyModifiedEditsToLineRangeMappings(m.changes, textEdits, originalTextModel, modifiedTextModel), ) : undefined; }).filter(isDefined); diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.contribution.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.contribution.ts index 11543c2c18db2..7421abcd3862c 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.contribution.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.contribution.ts @@ -4,13 +4,17 @@ *--------------------------------------------------------------------------------------------*/ import { Codicon } from 'vs/base/common/codicons'; -import { ThemeIcon } from 'vs/base/common/themables'; -import { ServicesAccessor } from 'vs/editor/browser/editorExtensions'; +import { KeyCode } from 'vs/base/common/keyCodes'; +import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; +import { EditorAction2, ServicesAccessor } from 'vs/editor/browser/editorExtensions'; +import { findFocusedDiffEditor } from 'vs/editor/browser/widget/diffEditor.contribution'; +import { DiffEditorWidget2 } from 'vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2'; +import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { localize } from 'vs/nls'; +import { ILocalizedString } from 'vs/platform/action/common/action'; import { Action2, MenuId, MenuRegistry, registerAction2 } from 'vs/platform/actions/common/actions'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ContextKeyEqualsExpr, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; -import './colors'; export class ToggleCollapseUnchangedRegions extends Action2 { constructor() { @@ -19,6 +23,13 @@ export class ToggleCollapseUnchangedRegions extends Action2 { title: { value: localize('toggleCollapseUnchangedRegions', "Toggle Collapse Unchanged Regions"), original: 'Toggle Collapse Unchanged Regions' }, icon: Codicon.map, precondition: ContextKeyEqualsExpr.create('diffEditorVersion', 2), + toggled: ContextKeyExpr.has('config.diffEditor.experimental.collapseUnchangedRegions'), + menu: { + id: MenuId.EditorTitle, + order: 22, + group: 'navigation', + when: ContextKeyEqualsExpr.create('diffEditorVersion', 2), + }, }); } @@ -31,34 +42,6 @@ export class ToggleCollapseUnchangedRegions extends Action2 { registerAction2(ToggleCollapseUnchangedRegions); -MenuRegistry.appendMenuItem(MenuId.EditorTitle, { - command: { - id: new ToggleCollapseUnchangedRegions().desc.id, - title: localize('collapseUnchangedRegions', "Show Unchanged Regions"), - icon: Codicon.map - }, - order: 22, - group: 'navigation', - when: ContextKeyExpr.and( - ContextKeyExpr.has('config.diffEditor.experimental.collapseUnchangedRegions'), - ContextKeyEqualsExpr.create('diffEditorVersion', 2) - ) -}); - -MenuRegistry.appendMenuItem(MenuId.EditorTitle, { - command: { - id: new ToggleCollapseUnchangedRegions().desc.id, - title: localize('showUnchangedRegions', "Collapse Unchanged Regions"), - icon: ThemeIcon.modify(Codicon.map, 'disabled'), - }, - order: 22, - group: 'navigation', - when: ContextKeyExpr.and( - ContextKeyExpr.has('config.diffEditor.experimental.collapseUnchangedRegions').negate(), - ContextKeyEqualsExpr.create('diffEditorVersion', 2) - ) -}); - export class ToggleShowMovedCodeBlocks extends Action2 { constructor() { super({ @@ -77,10 +60,42 @@ export class ToggleShowMovedCodeBlocks extends Action2 { registerAction2(ToggleShowMovedCodeBlocks); +export class ToggleUseInlineViewWhenSpaceIsLimited extends Action2 { + constructor() { + super({ + id: 'diffEditor.toggleUseInlineViewWhenSpaceIsLimited', + title: { value: localize('toggleUseInlineViewWhenSpaceIsLimited', "Toggle Use Inline View When Space Is Limited"), original: 'Toggle Use Inline View When Space Is Limited' }, + precondition: ContextKeyEqualsExpr.create('diffEditorVersion', 2), + }); + } + + run(accessor: ServicesAccessor, ...args: unknown[]): void { + const configurationService = accessor.get(IConfigurationService); + const newValue = !configurationService.getValue('diffEditor.useInlineViewWhenSpaceIsLimited'); + configurationService.updateValue('diffEditor.useInlineViewWhenSpaceIsLimited', newValue); + } +} + +registerAction2(ToggleUseInlineViewWhenSpaceIsLimited); + +MenuRegistry.appendMenuItem(MenuId.EditorTitle, { + command: { + id: new ToggleUseInlineViewWhenSpaceIsLimited().desc.id, + title: localize('useInlineViewWhenSpaceIsLimited', "Use Inline View When Space Is Limited"), + toggled: ContextKeyExpr.has('config.diffEditor.useInlineViewWhenSpaceIsLimited'), + }, + order: 11, + group: '1_diff', + when: ContextKeyExpr.and( + EditorContextKeys.diffEditorRenderSideBySideInlineBreakpointReached, + ContextKeyEqualsExpr.create('diffEditorVersion', 2) + ) +}); + MenuRegistry.appendMenuItem(MenuId.EditorTitle, { command: { id: new ToggleShowMovedCodeBlocks().desc.id, - title: localize('showMoves', "Show Moves"), + title: localize('showMoves', "Show Moved Code Blocks"), icon: Codicon.move, toggled: ContextKeyEqualsExpr.create('config.diffEditor.experimental.showMoves', true), }, @@ -88,3 +103,55 @@ MenuRegistry.appendMenuItem(MenuId.EditorTitle, { group: '1_diff', when: ContextKeyEqualsExpr.create('diffEditorVersion', 2) }); + +const diffEditorCategory: ILocalizedString = { + value: localize('diffEditor', 'Diff Editor'), + original: 'Diff Editor', +}; +export class SwitchSide extends EditorAction2 { + constructor() { + super({ + id: 'diffEditor.switchSide', + title: { value: localize('switchSide', "Switch Side"), original: 'Switch Side' }, + icon: Codicon.arrowSwap, + precondition: ContextKeyExpr.and(ContextKeyEqualsExpr.create('diffEditorVersion', 2), ContextKeyExpr.has('isInDiffEditor')), + f1: true, + category: diffEditorCategory, + }); + } + + runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, ...args: unknown[]): void { + const diffEditor = findFocusedDiffEditor(accessor); + if (diffEditor instanceof DiffEditorWidget2) { + diffEditor.switchSide(); + } + } +} + +registerAction2(SwitchSide); + +export class ExitCompareMove extends EditorAction2 { + constructor() { + super({ + id: 'diffEditor.exitCompareMove', + title: { value: localize('exitCompareMove', "Exit Compare Move"), original: 'Exit Compare Move' }, + icon: Codicon.close, + precondition: EditorContextKeys.comparingMovedCode, + f1: false, + category: diffEditorCategory, + keybinding: { + weight: 10000, + primary: KeyCode.Escape, + } + }); + } + + runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, ...args: unknown[]): void { + const diffEditor = findFocusedDiffEditor(accessor); + if (diffEditor instanceof DiffEditorWidget2) { + diffEditor.exitCompareMove(); + } + } +} + +registerAction2(ExitCompareMove); diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts index 91f99d55c6b15..b8c42ae717f70 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts @@ -7,10 +7,7 @@ import { IBoundarySashes } from 'vs/base/browser/ui/sash/sash'; import { findLast } from 'vs/base/common/arrays'; import { onUnexpectedError } from 'vs/base/common/errors'; import { Event } from 'vs/base/common/event'; -import { IObservable, autorun, derived, keepAlive, observableValue } from 'vs/base/common/observable'; -import { autorunWithStore2 } from 'vs/base/common/observableImpl/autorun'; -import { disposableObservableValue, transaction } from 'vs/base/common/observableImpl/base'; -import { derivedWithStore } from 'vs/base/common/observableImpl/derived'; +import { IObservable, autorun, autorunWithStore, derived, derivedWithStore, disposableObservableValue, keepAlive, observableValue, transaction } from 'vs/base/common/observable'; import 'vs/css!./style'; import { IEditorConstructionOptions } from 'vs/editor/browser/config/editorConfiguration'; import { ICodeEditor, IDiffEditor, IDiffEditorConstructionOptions, IMouseTargetViewZone } from 'vs/editor/browser/editorBrowser'; @@ -18,36 +15,43 @@ import { EditorExtensionsRegistry, IDiffEditorContributionDescription } from 'vs import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; import { CodeEditorWidget, ICodeEditorWidgetOptions } from 'vs/editor/browser/widget/codeEditorWidget'; import { IDiffCodeEditorWidgetOptions } from 'vs/editor/browser/widget/diffEditorWidget'; +import { AccessibleDiffViewer } from 'vs/editor/browser/widget/diffEditorWidget2/accessibleDiffViewer'; import { DiffEditorDecorations } from 'vs/editor/browser/widget/diffEditorWidget2/diffEditorDecorations'; import { DiffEditorSash } from 'vs/editor/browser/widget/diffEditorWidget2/diffEditorSash'; -import { DiffReview2 } from 'vs/editor/browser/widget/diffEditorWidget2/diffReview'; import { ViewZoneManager } from 'vs/editor/browser/widget/diffEditorWidget2/lineAlignment'; import { MovedBlocksLinesPart } from 'vs/editor/browser/widget/diffEditorWidget2/movedBlocksLines'; import { OverviewRulerPart } from 'vs/editor/browser/widget/diffEditorWidget2/overviewRulerPart'; import { UnchangedRangesFeature } from 'vs/editor/browser/widget/diffEditorWidget2/unchangedRanges'; -import { ObservableElementSizeObserver, applyStyle, readHotReloadableExport } from 'vs/editor/browser/widget/diffEditorWidget2/utils'; +import { CSSStyle, ObservableElementSizeObserver, applyStyle, readHotReloadableExport } from 'vs/editor/browser/widget/diffEditorWidget2/utils'; import { WorkerBasedDocumentDiffProvider } from 'vs/editor/browser/widget/workerBasedDocumentDiffProvider'; import { IDiffEditorOptions } from 'vs/editor/common/config/editorOptions'; import { IDimension } from 'vs/editor/common/core/dimension'; import { Position } from 'vs/editor/common/core/position'; +import { Range } from 'vs/editor/common/core/range'; +import { CursorChangeReason } from 'vs/editor/common/cursorEvents'; import { LineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; -import { IDiffComputationResult, ILineChange } from 'vs/editor/common/diff/smartLinesDiffComputer'; +import { IDiffComputationResult, ILineChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; import { EditorType, IDiffEditorModel, IDiffEditorViewModel, IDiffEditorViewState } from 'vs/editor/common/editorCommon'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { IIdentifiedSingleEditOperation } from 'vs/editor/common/model'; +import { LengthObj } from 'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/length'; +import { AudioCue, IAudioCueService } from 'vs/platform/audioCues/browser/audioCueService'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; +import './colors'; import { DelegatingEditor } from './delegatingEditorImpl'; import { DiffEditorEditors } from './diffEditorEditors'; import { DiffEditorOptions } from './diffEditorOptions'; import { DiffEditorViewModel, DiffMapping, DiffState } from './diffEditorViewModel'; +import { toDisposable } from 'vs/base/common/lifecycle'; export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { private readonly elements = h('div.monaco-diff-editor.side-by-side', { style: { position: 'relative', height: '100%' } }, [ h('div.noModificationsOverlay@overlay', { style: { position: 'absolute', height: '100%', visibility: 'hidden', } }, [$('span', {}, 'No Changes')]), h('div.editor.original@original', { style: { position: 'absolute', height: '100%' } }), h('div.editor.modified@modified', { style: { position: 'absolute', height: '100%' } }), + h('div.accessibleDiffViewer@accessibleDiffViewer', { style: { position: 'absolute', height: '100%' } }), ]); private readonly _diffModel = this._register(disposableObservableValue('diffModel', undefined)); public readonly onDidChangeModel = Event.fromObservableLight(this._diffModel); @@ -65,10 +69,18 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { private unchangedRangesFeature!: UnchangedRangesFeature; - private readonly _reviewPane: DiffReview2; + private _accessibleDiffViewerShouldBeVisible = observableValue('accessibleDiffViewerShouldBeVisible', false); + private _accessibleDiffViewerVisible = derived(reader => + /** @description accessibleDiffViewerVisible */ this._options.onlyShowAccessibleDiffViewer.read(reader) + ? true + : this._accessibleDiffViewerShouldBeVisible.read(reader) + ); + private _accessibleDiffViewer!: AccessibleDiffViewer; private readonly _options: DiffEditorOptions; private readonly _editors: DiffEditorEditors; + private readonly movedBlocksLinesPart = observableValue('MovedBlocksLinesPart', undefined); + constructor( private readonly _domElement: HTMLElement, options: Readonly, @@ -76,6 +88,7 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { @IContextKeyService private readonly _parentContextKeyService: IContextKeyService, @IInstantiationService private readonly _parentInstantiationService: IInstantiationService, @ICodeEditorService codeEditorService: ICodeEditorService, + @IAudioCueService private readonly _audioCueService: IAudioCueService, ) { super(); codeEditorService.willCreateDiffEditor(); @@ -83,28 +96,40 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { this._contextKeyService.createKey('isInDiffEditor', true); this._contextKeyService.createKey('diffEditorVersion', 2); - this._options = new DiffEditorOptions(options); + this._domElement.appendChild(this.elements.root); + this._register(toDisposable(() => this._domElement.removeChild(this.elements.root))); + + this._rootSizeObserver = this._register(new ObservableElementSizeObserver(this.elements.root, options.dimension)); + this._rootSizeObserver.setAutomaticLayout(options.automaticLayout ?? false); + + this._options = new DiffEditorOptions(options, this._rootSizeObserver.width); this._contextKeyService.createKey(EditorContextKeys.isEmbeddedDiffEditor.key, false); const isEmbeddedDiffEditorKey = EditorContextKeys.isEmbeddedDiffEditor.bindTo(this._contextKeyService); - this._register(autorun('update isEmbeddedDiffEditorKey', reader => { + this._register(autorun(reader => { + /** @description update isEmbeddedDiffEditorKey */ isEmbeddedDiffEditorKey.set(this._options.isInEmbeddedEditor.read(reader)); })); - this._domElement.appendChild(this.elements.root); + const comparingMovedCodeKey = EditorContextKeys.comparingMovedCode.bindTo(this._contextKeyService); + this._register(autorun(reader => { + /** @description update comparingMovedCodeKey */ + comparingMovedCodeKey.set(!!this._diffModel.read(reader)?.movedTextToCompare.read(reader)); + })); - this._rootSizeObserver = this._register(new ObservableElementSizeObserver(this.elements.root, options.dimension)); - this._rootSizeObserver.setAutomaticLayout(options.automaticLayout ?? false); + const diffEditorRenderSideBySideInlineBreakpointReachedContextKeyValue = EditorContextKeys.diffEditorRenderSideBySideInlineBreakpointReached.bindTo(this._contextKeyService); + this._register(autorun(reader => { + /** @description update accessibleDiffViewerVisible context key */ + diffEditorRenderSideBySideInlineBreakpointReachedContextKeyValue.set(this._options.couldShowInlineViewBecauseOfSize.read(reader)); + })); - const reviewPaneObservable = observableValue('reviewPane', undefined); this._editors = this._register(this._instantiationService.createInstance( DiffEditorEditors, this.elements.original, this.elements.modified, this._options, codeEditorWidgetOptions, - (i, c, o, o2) => this._createInnerEditor(i, c, o, o2), - reviewPaneObservable.map((r, reader) => r?.isVisible.read(reader) ?? false), + (i, c, o, o2) => this._createInnerEditor(i, c, o, o2) )); this._sash = derivedWithStore('sash', (reader, store) => { @@ -119,7 +144,8 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { width: this._rootSizeObserver.width.map((w, reader) => w - (this._options.renderOverviewRuler.read(reader) ? OverviewRulerPart.ENTIRE_DIFF_OVERVIEW_WIDTH : 0)), } )); - store.add(autorun('setBoundarySashes', reader => { + store.add(autorun(reader => { + /** @description setBoundarySashes */ const boundarySashes = this._boundarySashes.read(reader); if (boundarySashes) { result.setBoundarySashes(boundarySashes); @@ -129,25 +155,34 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { }); this._register(keepAlive(this._sash, true)); - this._register(autorunWithStore2('UnchangedRangesFeature', (reader, store) => { - this.unchangedRangesFeature = store.add(new (readHotReloadableExport(UnchangedRangesFeature, reader))(this._editors, this._diffModel, this._options)); + this._register(autorunWithStore((reader, store) => { + /** @description UnchangedRangesFeature */ + this.unchangedRangesFeature = store.add( + this._instantiationService.createInstance(readHotReloadableExport(UnchangedRangesFeature, reader), this._editors, this._diffModel, this._options) + ); })); - this._register(autorunWithStore2('DiffEditorDecorations', (reader, store) => { + this._register(autorunWithStore((reader, store) => { + /** @description DiffEditorDecorations */ store.add(new (readHotReloadableExport(DiffEditorDecorations, reader))(this._editors, this._diffModel, this._options)); })); + this._register(autorunWithStore((reader, store) => { + /** @description ViewZoneManager */ + store.add(this._instantiationService.createInstance( + readHotReloadableExport(ViewZoneManager, reader), + this._editors, + this._diffModel, + this._options, + this, + () => this.unchangedRangesFeature.isUpdatingViewZones, + )); + })); - this._register(this._instantiationService.createInstance( - ViewZoneManager, - this._editors, - this._diffModel, - this._options, - this, - () => this.unchangedRangesFeature.isUpdatingViewZones, - )); - - this._register(autorunWithStore2('OverviewRulerPart', (reader, store) => { - store.add(this._instantiationService.createInstance(readHotReloadableExport(OverviewRulerPart, reader), this._editors, + this._register(autorunWithStore((reader, store) => { + /** @description OverviewRulerPart */ + store.add(this._instantiationService.createInstance( + readHotReloadableExport(OverviewRulerPart, reader), + this._editors, this.elements.root, this._diffModel, this._rootSizeObserver.width, @@ -157,10 +192,23 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { )); })); - this._reviewPane = this._register(this._instantiationService.createInstance(DiffReview2, this)); - this.elements.root.appendChild(this._reviewPane.domNode.domNode); - this.elements.root.appendChild(this._reviewPane.actionBarContainer.domNode); - reviewPaneObservable.set(this._reviewPane, undefined); + this._register(autorunWithStore((reader, store) => { + /** @description _accessibleDiffViewer */ + this._accessibleDiffViewer = store.add(this._register(this._instantiationService.createInstance( + readHotReloadableExport(AccessibleDiffViewer, reader), + this.elements.accessibleDiffViewer, + this._accessibleDiffViewerVisible, + (visible, tx) => this._accessibleDiffViewerShouldBeVisible.set(visible, tx), + this._options.onlyShowAccessibleDiffViewer.map(v => !v), + this._rootSizeObserver.width, + this._rootSizeObserver.height, + this._diffModel.map((m, r) => m?.diff.read(r)?.mappings.map(m => m.lineRangeMapping)), + this._editors, + ))); + })); + const visibility = this._accessibleDiffViewerVisible.map(v => v ? 'hidden' : 'visible'); + this._register(applyStyle(this.elements.modified, { visibility })); + this._register(applyStyle(this.elements.original, { visibility })); this._createDiffEditorContributions(); @@ -168,35 +216,23 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { this._register(keepAlive(this._layoutInfo, true)); - this._register(new MovedBlocksLinesPart( - this.elements.root, - this._diffModel, - this._layoutInfo.map(i => i.originalEditor), - this._layoutInfo.map(i => i.modifiedEditor), - this._editors, - )); + this._register(autorunWithStore((reader, store) => { + this.movedBlocksLinesPart.set(store.add(new (readHotReloadableExport(MovedBlocksLinesPart, reader))( + this.elements.root, + this._diffModel, + this._layoutInfo.map(i => i.originalEditor), + this._layoutInfo.map(i => i.modifiedEditor), + this._editors, + )), undefined); + })); this._register(applyStyle(this.elements.overlay, { width: this._layoutInfo.map((i, r) => i.originalEditor.width + (this._options.renderSideBySide.read(r) ? 0 : i.modifiedEditor.width)), - visibility: derived('visibility', reader => - (this._options.collapseUnchangedRegions.read(reader) && this._diffModel.read(reader)?.diff.read(reader)?.mappings.length === 0) - ? 'visible' : 'hidden' + visibility: derived(reader => /** @description visibility */(this._options.collapseUnchangedRegions.read(reader) && this._diffModel.read(reader)?.diff.read(reader)?.mappings.length === 0) + ? 'visible' : 'hidden' ), })); - this._register(this._editors.original.onDidChangeCursorPosition(e => { - const m = this._diffModel.get(); - if (!m) { return; } - const movedText = m.diff.get()!.movedTexts.find(m => m.lineRangeMapping.originalRange.contains(e.position.lineNumber)); - m.syncedMovedTexts.set(movedText, undefined); - })); - this._register(this._editors.modified.onDidChangeCursorPosition(e => { - const m = this._diffModel.get(); - if (!m) { return; } - const movedText = m.diff.get()!.movedTexts.find(m => m.lineRangeMapping.modifiedRange.contains(e.position.lineNumber)); - m.syncedMovedTexts.set(movedText, undefined); - })); - // Revert change when an arrow is clicked. this._register(this._editors.modified.onMouseDown(event => { if (!event.event.rightButton && event.target.position && event.target.element?.className.includes('arrow-revert-change')) { @@ -217,6 +253,23 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { event.event.stopPropagation(); } })); + + this._register(Event.runAndSubscribe(this._editors.modified.onDidChangeCursorPosition, (e) => { + if (e?.reason === CursorChangeReason.Explicit) { + const diff = this._diffModel.get()?.diff.get()?.mappings.find(m => m.lineRangeMapping.modifiedRange.contains(e.position.lineNumber)); + if (diff?.lineRangeMapping.modifiedRange.isEmpty) { + this._audioCueService.playAudioCue(AudioCue.diffLineDeleted, { source: 'diffEditor.cursorPositionChanged' }); + } else if (diff?.lineRangeMapping.originalRange.isEmpty) { + this._audioCueService.playAudioCue(AudioCue.diffLineInserted, { source: 'diffEditor.cursorPositionChanged' }); + } else if (diff) { + this._audioCueService.playAudioCue(AudioCue.diffLineModified, { source: 'diffEditor.cursorPositionChanged' }); + } + } + })); + } + + public getContentHeight() { + return this._editors.modified.getContentHeight(); } protected _createInnerEditor(instantiationService: IInstantiationService, container: HTMLElement, options: Readonly, editorWidgetOptions: ICodeEditorWidgetOptions): CodeEditorWidget { @@ -224,26 +277,25 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { return editor; } - private readonly _layoutInfo = derived('modifiedEditorLayoutInfo', (reader) => { + private readonly _layoutInfo = derived(reader => { + /** @description modifiedEditorLayoutInfo */ const width = this._rootSizeObserver.width.read(reader); const height = this._rootSizeObserver.height.read(reader); const sashLeft = this._sash.read(reader)?.sashLeft.read(reader); const originalWidth = sashLeft ?? Math.max(5, this._editors.original.getLayoutInfo().decorationsLeft); + const modifiedWidth = width - originalWidth - (this._options.renderOverviewRuler.read(reader) ? OverviewRulerPart.ENTIRE_DIFF_OVERVIEW_WIDTH : 0); - this.elements.original.style.width = originalWidth + 'px'; + const movedBlocksLinesWidth = this.movedBlocksLinesPart.read(reader)?.width.read(reader) ?? 0; + const originalWidthWithoutMovedBlockLines = originalWidth - movedBlocksLinesWidth; + this.elements.original.style.width = originalWidthWithoutMovedBlockLines + 'px'; this.elements.original.style.left = '0px'; - this.elements.modified.style.width = (width - originalWidth) + 'px'; + this.elements.modified.style.width = modifiedWidth + 'px'; this.elements.modified.style.left = originalWidth + 'px'; - this._editors.original.layout({ width: originalWidth, height: height }); - this._editors.modified.layout({ - width: width - originalWidth - - (this._options.renderOverviewRuler.read(reader) ? OverviewRulerPart.ENTIRE_DIFF_OVERVIEW_WIDTH : 0), - height - }); - this._reviewPane.layout(0, width, height); + this._editors.original.layout({ width: originalWidthWithoutMovedBlockLines, height }); + this._editors.modified.layout({ width: modifiedWidth, height }); return { modifiedEditor: this._editors.modified.getLayoutInfo(), @@ -316,7 +368,7 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { override setModel(model: IDiffEditorModel | null | IDiffEditorViewModel): void { if (!model && this._diffModel.get()) { // Transitioning from a model to no-model - this._reviewPane.hide(); + this._accessibleDiffViewer.close(); } const vm = model ? ('model' in model) ? model : this.createViewModel(model) : undefined; @@ -411,6 +463,14 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { diff = findLast(diffs, d => d.lineRangeMapping.modifiedRange.startLineNumber < curLineNumber) ?? diffs[diffs.length - 1]; } this._goTo(diff); + + if (diff.lineRangeMapping.modifiedRange.isEmpty) { + this._audioCueService.playAudioCue(AudioCue.diffLineDeleted, { source: 'diffEditor.goToDiff' }); + } else if (diff.lineRangeMapping.originalRange.isEmpty) { + this._audioCueService.playAudioCue(AudioCue.diffLineInserted, { source: 'diffEditor.goToDiff' }); + } else if (diff) { + this._audioCueService.playAudioCue(AudioCue.diffLineModified, { source: 'diffEditor.goToDiff' }); + } } revealFirstDiff(): void { @@ -428,15 +488,86 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { }); } - diffReviewNext(): void { this._reviewPane.next(); } + accessibleDiffViewerNext(): void { this._accessibleDiffViewer.next(); } - diffReviewPrev(): void { this._reviewPane.prev(); } + accessibleDiffViewerPrev(): void { this._accessibleDiffViewer.prev(); } async waitForDiff(): Promise { const diffModel = this._diffModel.get(); if (!diffModel) { return; } await diffModel.waitForDiff(); } + + switchSide(): void { + const isModifiedFocus = this._editors.modified.hasWidgetFocus(); + const source = isModifiedFocus ? this._editors.modified : this._editors.original; + const destination = isModifiedFocus ? this._editors.original : this._editors.modified; + + const sourceSelection = source.getSelection(); + if (sourceSelection) { + const mappings = this._diffModel.get()?.diff.get()?.mappings.map(m => isModifiedFocus ? m.lineRangeMapping.flip() : m.lineRangeMapping); + if (mappings) { + const newRange1 = translatePosition(sourceSelection.getStartPosition(), mappings); + const newRange2 = translatePosition(sourceSelection.getEndPosition(), mappings); + const range = Range.plusRange(newRange1, newRange2); + destination.setSelection(range); + } + } + destination.focus(); + } + + exitCompareMove(): void { + const model = this._diffModel.get(); + if (!model) { return; } + model.movedTextToCompare.set(undefined, undefined); + } +} + +function translatePosition(posInOriginal: Position, mappings: LineRangeMapping[]): Range { + const mapping = findLast(mappings, m => m.originalRange.startLineNumber <= posInOriginal.lineNumber); + if (!mapping) { + // No changes before the position + return Range.fromPositions(posInOriginal); + } + + if (mapping.originalRange.endLineNumberExclusive <= posInOriginal.lineNumber) { + const newLineNumber = posInOriginal.lineNumber - mapping.originalRange.endLineNumberExclusive + mapping.modifiedRange.endLineNumberExclusive; + return Range.fromPositions(new Position(newLineNumber, posInOriginal.column)); + } + + if (!mapping.innerChanges) { + // Only for legacy algorithm + return Range.fromPositions(new Position(mapping.modifiedRange.startLineNumber, 1)); + } + + const innerMapping = findLast(mapping.innerChanges, m => m.originalRange.getStartPosition().isBeforeOrEqual(posInOriginal)); + if (!innerMapping) { + const newLineNumber = posInOriginal.lineNumber - mapping.originalRange.startLineNumber + mapping.modifiedRange.startLineNumber; + return Range.fromPositions(new Position(newLineNumber, posInOriginal.column)); + } + + if (innerMapping.originalRange.containsPosition(posInOriginal)) { + return innerMapping.modifiedRange; + } else { + const l = lengthBetweenPositions(innerMapping.originalRange.getEndPosition(), posInOriginal); + return Range.fromPositions(addLength(innerMapping.modifiedRange.getEndPosition(), l)); + } +} + +function lengthBetweenPositions(position1: Position, position2: Position): LengthObj { + if (position1.lineNumber === position2.lineNumber) { + return new LengthObj(0, position2.column - position1.column); + } else { + return new LengthObj(position2.lineNumber - position1.lineNumber, position2.column - 1); + } +} + +function addLength(position: Position, length: LengthObj): Position { + if (length.lineCount === 0) { + return new Position(position.lineNumber, position.column + length.columnCount); + } else { + return new Position(position.lineNumber + length.lineCount, length.columnCount + 1); + } } function toLineChanges(state: DiffState): ILineChange[] { diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffReview.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffReview.ts deleted file mode 100644 index 82359ffaef04e..0000000000000 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffReview.ts +++ /dev/null @@ -1,821 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as dom from 'vs/base/browser/dom'; -import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode'; -import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; -import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement'; -import { Action } from 'vs/base/common/actions'; -import { Codicon } from 'vs/base/common/codicons'; -import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; -import { Disposable } from 'vs/base/common/lifecycle'; -import { IObservable, observableValue } from 'vs/base/common/observable'; -import { ThemeIcon } from 'vs/base/common/themables'; -import { Constants } from 'vs/base/common/uint'; -import { applyFontInfo } from 'vs/editor/browser/config/domFontInfo'; -import { DiffEditorWidget2 } from 'vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2'; -import { DiffReview } from 'vs/editor/browser/widget/diffReview'; -import { EditorFontLigatures, EditorOption, IComputedEditorOptions } from 'vs/editor/common/config/editorOptions'; -import { Position } from 'vs/editor/common/core/position'; -import { ILineChange } from 'vs/editor/common/diff/smartLinesDiffComputer'; -import { ScrollType } from 'vs/editor/common/editorCommon'; -import { ILanguageIdCodec } from 'vs/editor/common/languages'; -import { ILanguageService } from 'vs/editor/common/languages/language'; -import { ITextModel, TextModelResolvedOptions } from 'vs/editor/common/model'; -import { LineTokens } from 'vs/editor/common/tokens/lineTokens'; -import { RenderLineInput, renderViewLine2 as renderViewLine } from 'vs/editor/common/viewLayout/viewLineRenderer'; -import { ViewLineRenderingData } from 'vs/editor/common/viewModel'; -import * as nls from 'vs/nls'; -import { AudioCue, IAudioCueService } from 'vs/platform/audioCues/browser/audioCueService'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { registerIcon } from 'vs/platform/theme/common/iconRegistry'; - -const DIFF_LINES_PADDING = 3; - -const enum DiffEntryType { - Equal = 0, - Insert = 1, - Delete = 2 -} - -class DiffEntry { - readonly originalLineStart: number; - readonly originalLineEnd: number; - readonly modifiedLineStart: number; - readonly modifiedLineEnd: number; - - constructor(originalLineStart: number, originalLineEnd: number, modifiedLineStart: number, modifiedLineEnd: number) { - this.originalLineStart = originalLineStart; - this.originalLineEnd = originalLineEnd; - this.modifiedLineStart = modifiedLineStart; - this.modifiedLineEnd = modifiedLineEnd; - } - - public getType(): DiffEntryType { - if (this.originalLineStart === 0) { - return DiffEntryType.Insert; - } - if (this.modifiedLineStart === 0) { - return DiffEntryType.Delete; - } - return DiffEntryType.Equal; - } -} - -const enum DiffEditorLineClasses { - Insert = 'line-insert', - Delete = 'line-delete' -} - -class Diff { - readonly entries: DiffEntry[]; - - constructor(entries: DiffEntry[]) { - this.entries = entries; - } -} - -const diffReviewInsertIcon = registerIcon('diff-review-insert', Codicon.add, nls.localize('diffReviewInsertIcon', 'Icon for \'Insert\' in diff review.')); -const diffReviewRemoveIcon = registerIcon('diff-review-remove', Codicon.remove, nls.localize('diffReviewRemoveIcon', 'Icon for \'Remove\' in diff review.')); -const diffReviewCloseIcon = registerIcon('diff-review-close', Codicon.close, nls.localize('diffReviewCloseIcon', 'Icon for \'Close\' in diff review.')); - -export class DiffReview2 extends Disposable { - - private static _ttPolicy = DiffReview._ttPolicy; // TODO inline once DiffReview is deprecated. - - private readonly _diffEditor: DiffEditorWidget2; - private get _isVisible() { return this._isVisibleObs.get(); } - private readonly _actionBar: ActionBar; - public readonly actionBarContainer: FastDomNode; - public readonly domNode: FastDomNode; - private readonly _content: FastDomNode; - private readonly scrollbar: DomScrollableElement; - private _diffs: Diff[]; - private _currentDiff: Diff | null; - - private readonly _isVisibleObs = observableValue('isVisible', false); - - public readonly isVisible: IObservable = this._isVisibleObs; - - constructor( - diffEditor: DiffEditorWidget2, - @ILanguageService private readonly _languageService: ILanguageService, - @IAudioCueService private readonly _audioCueService: IAudioCueService, - @IConfigurationService private readonly _configurationService: IConfigurationService - ) { - super(); - this._diffEditor = diffEditor; - - this.actionBarContainer = createFastDomNode(document.createElement('div')); - this.actionBarContainer.setClassName('diff-review-actions'); - this._actionBar = this._register(new ActionBar( - this.actionBarContainer.domNode - )); - - this._actionBar.push(new Action('diffreview.close', nls.localize('label.close', "Close"), 'close-diff-review ' + ThemeIcon.asClassName(diffReviewCloseIcon), true, async () => this.hide()), { label: false, icon: true }); - - this.domNode = createFastDomNode(document.createElement('div')); - this.domNode.setClassName('diff-review monaco-editor-background'); - - this._content = createFastDomNode(document.createElement('div')); - this._content.setClassName('diff-review-content'); - this._content.setAttribute('role', 'code'); - this.scrollbar = this._register(new DomScrollableElement(this._content.domNode, {})); - this.domNode.domNode.appendChild(this.scrollbar.getDomNode()); - - this._register(diffEditor.onDidUpdateDiff(() => { - if (!this._isVisible) { - return; - } - this._diffs = this._compute(); - this._render(); - })); - this._register(diffEditor.getModifiedEditor().onDidChangeCursorPosition(() => { - if (!this._isVisible) { - return; - } - this._render(); - })); - this._register(dom.addStandardDisposableListener(this.domNode.domNode, 'click', (e) => { - e.preventDefault(); - - const row = dom.findParentWithClass(e.target, 'diff-review-row'); - if (row) { - this._goToRow(row); - } - })); - this._register(dom.addStandardDisposableListener(this.domNode.domNode, 'keydown', (e) => { - if ( - e.equals(KeyCode.DownArrow) - || e.equals(KeyMod.CtrlCmd | KeyCode.DownArrow) - || e.equals(KeyMod.Alt | KeyCode.DownArrow) - ) { - e.preventDefault(); - this._goToRow(this._getNextRow(), 'next'); - } - - if ( - e.equals(KeyCode.UpArrow) - || e.equals(KeyMod.CtrlCmd | KeyCode.UpArrow) - || e.equals(KeyMod.Alt | KeyCode.UpArrow) - ) { - e.preventDefault(); - this._goToRow(this._getPrevRow(), 'previous'); - } - - if ( - e.equals(KeyCode.Escape) - || e.equals(KeyMod.CtrlCmd | KeyCode.Escape) - || e.equals(KeyMod.Alt | KeyCode.Escape) - || e.equals(KeyMod.Shift | KeyCode.Escape) - || e.equals(KeyCode.Space) - || e.equals(KeyCode.Enter) - ) { - e.preventDefault(); - this.accept(); - } - })); - this._register(this._configurationService.onDidChangeConfiguration(e => { - if (e.affectsConfiguration('accessibility.verbosity.diffEditor')) { - this._diffEditor.updateOptions({ accessibilityVerbose: this._configurationService.getValue('accessibility.verbosity.diffEditor') }); - } - })); - this._diffs = []; - this._currentDiff = null; - } - - public prev(): void { - let index = 0; - - if (!this._isVisible) { - this._diffs = this._compute(); - } - - if (this._isVisible) { - let currentIndex = -1; - for (let i = 0, len = this._diffs.length; i < len; i++) { - if (this._diffs[i] === this._currentDiff) { - currentIndex = i; - break; - } - } - index = (this._diffs.length + currentIndex - 1); - } else { - index = this._findDiffIndex(this._diffEditor.getPosition()!); - } - - if (this._diffs.length === 0) { - // Nothing to do - return; - } - - index = index % this._diffs.length; - const entries = this._diffs[index].entries; - this._diffEditor.setPosition(new Position(entries[0].modifiedLineStart, 1)); - this._diffEditor.setSelection({ startColumn: 1, startLineNumber: entries[0].modifiedLineStart, endColumn: Constants.MAX_SAFE_SMALL_INTEGER, endLineNumber: entries[entries.length - 1].modifiedLineEnd }); - this._isVisibleObs.set(true, undefined); - this.layout(); - this._render(); - this._goToRow(this._getPrevRow(), 'previous'); - } - - public next(): void { - let index = 0; - - if (!this._isVisible) { - this._diffs = this._compute(); - } - - if (this._isVisible) { - let currentIndex = -1; - for (let i = 0, len = this._diffs.length; i < len; i++) { - if (this._diffs[i] === this._currentDiff) { - currentIndex = i; - break; - } - } - index = (currentIndex + 1); - } else { - index = this._findDiffIndex(this._diffEditor.getPosition()!); - } - - if (this._diffs.length === 0) { - // Nothing to do - return; - } - - index = index % this._diffs.length; - const entries = this._diffs[index].entries; - this._diffEditor.setPosition(new Position(entries[0].modifiedLineStart, 1)); - this._diffEditor.setSelection({ startColumn: 1, startLineNumber: entries[0].modifiedLineStart, endColumn: Constants.MAX_SAFE_SMALL_INTEGER, endLineNumber: entries[entries.length - 1].modifiedLineEnd }); - this._isVisibleObs.set(true, undefined); - this.layout(); - this._render(); - this._goToRow(this._getNextRow(), 'next'); - } - - private accept(): void { - let jumpToLineNumber = -1; - const current = this._getCurrentFocusedRow(); - if (current) { - const lineNumber = parseInt(current.getAttribute('data-line')!, 10); - if (!isNaN(lineNumber)) { - jumpToLineNumber = lineNumber; - } - } - this.hide(); - - if (jumpToLineNumber !== -1) { - this._diffEditor.setPosition(new Position(jumpToLineNumber, 1)); - this._diffEditor.revealPosition(new Position(jumpToLineNumber, 1), ScrollType.Immediate); - } - } - - public hide(): void { - this._isVisibleObs.set(false, undefined); - this._diffEditor.focus(); - this.layout(); - this._render(); - } - - private _getPrevRow(): HTMLElement { - const current = this._getCurrentFocusedRow(); - if (!current) { - return this._getFirstRow(); - } - if (current.previousElementSibling) { - return current.previousElementSibling; - } - return current; - } - - private _getNextRow(): HTMLElement { - const current = this._getCurrentFocusedRow(); - if (!current) { - return this._getFirstRow(); - } - if (current.nextElementSibling) { - return current.nextElementSibling; - } - return current; - } - - private _getFirstRow(): HTMLElement { - return this.domNode.domNode.querySelector('.diff-review-row'); - } - - private _getCurrentFocusedRow(): HTMLElement | null { - const result = document.activeElement; - if (result && /diff-review-row/.test(result.className)) { - return result; - } - return null; - } - - private _goToRow(row: HTMLElement, type?: 'next' | 'previous'): void { - const current = this._getCurrentFocusedRow(); - row.tabIndex = 0; - row.focus(); - if (current && current !== row) { - current.tabIndex = -1; - } - const element = !type ? current : type === 'next' ? current?.nextElementSibling : current?.previousElementSibling; - if (element?.classList.contains(DiffEditorLineClasses.Insert)) { - this._audioCueService.playAudioCue(AudioCue.diffLineInserted, true); - } else if (element?.classList.contains(DiffEditorLineClasses.Delete)) { - this._audioCueService.playAudioCue(AudioCue.diffLineDeleted, true); - } - this.scrollbar.scanDomNode(); - } - - private _width: number = 0; - private _top: number = 0; - private _height: number = 0; - - public layout(top: number = this._top, width: number = this._width, height: number = this._height): void { - this._width = width; - this._top = top; - this._height = height; - - this.domNode.setTop(top); - this.domNode.setWidth(width); - this.domNode.setHeight(height); - this._content.setHeight(height); - this._content.setWidth(width); - - if (this._isVisible) { - this.domNode.setDisplay('block'); - this.actionBarContainer.setAttribute('aria-hidden', 'false'); - this.actionBarContainer.setDisplay('block'); - } else { - this.domNode.setDisplay('none'); - this.actionBarContainer.setAttribute('aria-hidden', 'true'); - this.actionBarContainer.setDisplay('none'); - } - } - - private _compute(): Diff[] { - const lineChanges = this._diffEditor.getLineChanges(); - if (!lineChanges || lineChanges.length === 0) { - return []; - } - const originalModel = this._diffEditor.getOriginalEditor().getModel(); - const modifiedModel = this._diffEditor.getModifiedEditor().getModel(); - - if (!originalModel || !modifiedModel) { - return []; - } - - return DiffReview2._mergeAdjacent(lineChanges, originalModel.getLineCount(), modifiedModel.getLineCount()); - } - - private static _mergeAdjacent(lineChanges: ILineChange[], originalLineCount: number, modifiedLineCount: number): Diff[] { - if (!lineChanges || lineChanges.length === 0) { - return []; - } - - const diffs: Diff[] = []; - let diffsLength = 0; - - for (let i = 0, len = lineChanges.length; i < len; i++) { - const lineChange = lineChanges[i]; - - const originalStart = lineChange.originalStartLineNumber; - const originalEnd = lineChange.originalEndLineNumber; - const modifiedStart = lineChange.modifiedStartLineNumber; - const modifiedEnd = lineChange.modifiedEndLineNumber; - - const r: DiffEntry[] = []; - let rLength = 0; - - // Emit before anchors - { - const originalEqualAbove = (originalEnd === 0 ? originalStart : originalStart - 1); - const modifiedEqualAbove = (modifiedEnd === 0 ? modifiedStart : modifiedStart - 1); - - // Make sure we don't step into the previous diff - let minOriginal = 1; - let minModified = 1; - if (i > 0) { - const prevLineChange = lineChanges[i - 1]; - - if (prevLineChange.originalEndLineNumber === 0) { - minOriginal = prevLineChange.originalStartLineNumber + 1; - } else { - minOriginal = prevLineChange.originalEndLineNumber + 1; - } - - if (prevLineChange.modifiedEndLineNumber === 0) { - minModified = prevLineChange.modifiedStartLineNumber + 1; - } else { - minModified = prevLineChange.modifiedEndLineNumber + 1; - } - } - - let fromOriginal = originalEqualAbove - DIFF_LINES_PADDING + 1; - let fromModified = modifiedEqualAbove - DIFF_LINES_PADDING + 1; - if (fromOriginal < minOriginal) { - const delta = minOriginal - fromOriginal; - fromOriginal = fromOriginal + delta; - fromModified = fromModified + delta; - } - if (fromModified < minModified) { - const delta = minModified - fromModified; - fromOriginal = fromOriginal + delta; - fromModified = fromModified + delta; - } - - r[rLength++] = new DiffEntry( - fromOriginal, originalEqualAbove, - fromModified, modifiedEqualAbove - ); - } - - // Emit deleted lines - { - if (originalEnd !== 0) { - r[rLength++] = new DiffEntry(originalStart, originalEnd, 0, 0); - } - } - - // Emit inserted lines - { - if (modifiedEnd !== 0) { - r[rLength++] = new DiffEntry(0, 0, modifiedStart, modifiedEnd); - } - } - - // Emit after anchors - { - const originalEqualBelow = (originalEnd === 0 ? originalStart + 1 : originalEnd + 1); - const modifiedEqualBelow = (modifiedEnd === 0 ? modifiedStart + 1 : modifiedEnd + 1); - - // Make sure we don't step into the next diff - let maxOriginal = originalLineCount; - let maxModified = modifiedLineCount; - if (i + 1 < len) { - const nextLineChange = lineChanges[i + 1]; - - if (nextLineChange.originalEndLineNumber === 0) { - maxOriginal = nextLineChange.originalStartLineNumber; - } else { - maxOriginal = nextLineChange.originalStartLineNumber - 1; - } - - if (nextLineChange.modifiedEndLineNumber === 0) { - maxModified = nextLineChange.modifiedStartLineNumber; - } else { - maxModified = nextLineChange.modifiedStartLineNumber - 1; - } - } - - let toOriginal = originalEqualBelow + DIFF_LINES_PADDING - 1; - let toModified = modifiedEqualBelow + DIFF_LINES_PADDING - 1; - - if (toOriginal > maxOriginal) { - const delta = maxOriginal - toOriginal; - toOriginal = toOriginal + delta; - toModified = toModified + delta; - } - if (toModified > maxModified) { - const delta = maxModified - toModified; - toOriginal = toOriginal + delta; - toModified = toModified + delta; - } - - r[rLength++] = new DiffEntry( - originalEqualBelow, toOriginal, - modifiedEqualBelow, toModified, - ); - } - - diffs[diffsLength++] = new Diff(r); - } - - // Merge adjacent diffs - let curr: DiffEntry[] = diffs[0].entries; - const r: Diff[] = []; - let rLength = 0; - for (let i = 1, len = diffs.length; i < len; i++) { - const thisDiff = diffs[i].entries; - - const currLast = curr[curr.length - 1]; - const thisFirst = thisDiff[0]; - - if ( - currLast.getType() === DiffEntryType.Equal - && thisFirst.getType() === DiffEntryType.Equal - && thisFirst.originalLineStart <= currLast.originalLineEnd - ) { - // We are dealing with equal lines that overlap - - curr[curr.length - 1] = new DiffEntry( - currLast.originalLineStart, thisFirst.originalLineEnd, - currLast.modifiedLineStart, thisFirst.modifiedLineEnd - ); - curr = curr.concat(thisDiff.slice(1)); - continue; - } - - r[rLength++] = new Diff(curr); - curr = thisDiff; - } - r[rLength++] = new Diff(curr); - return r; - } - - private _findDiffIndex(pos: Position): number { - const lineNumber = pos.lineNumber; - for (let i = 0, len = this._diffs.length; i < len; i++) { - const diff = this._diffs[i].entries; - const lastModifiedLine = diff[diff.length - 1].modifiedLineEnd; - if (lineNumber <= lastModifiedLine) { - return i; - } - } - return 0; - } - - private _render(): void { - - const originalOptions = this._diffEditor.getOriginalEditor().getOptions(); - const modifiedOptions = this._diffEditor.getModifiedEditor().getOptions(); - - const originalModel = this._diffEditor.getOriginalEditor().getModel(); - const modifiedModel = this._diffEditor.getModifiedEditor().getModel(); - - const originalModelOpts = originalModel!.getOptions(); - const modifiedModelOpts = modifiedModel!.getOptions(); - - if (!this._isVisible || !originalModel || !modifiedModel) { - dom.clearNode(this._content.domNode); - this._currentDiff = null; - this.scrollbar.scanDomNode(); - return; - } - - const diffIndex = this._findDiffIndex(this._diffEditor.getPosition()!); - - if (this._diffs[diffIndex] === this._currentDiff) { - return; - } - this._currentDiff = this._diffs[diffIndex]; - - const diffs = this._diffs[diffIndex].entries; - const container = document.createElement('div'); - container.className = 'diff-review-table'; - container.setAttribute('role', 'list'); - container.setAttribute('aria-label', 'Difference review. Use "Stage | Unstage | Revert Selected Ranges" commands'); - applyFontInfo(container, modifiedOptions.get(EditorOption.fontInfo)); - - let minOriginalLine = 0; - let maxOriginalLine = 0; - let minModifiedLine = 0; - let maxModifiedLine = 0; - for (let i = 0, len = diffs.length; i < len; i++) { - const diffEntry = diffs[i]; - const originalLineStart = diffEntry.originalLineStart; - const originalLineEnd = diffEntry.originalLineEnd; - const modifiedLineStart = diffEntry.modifiedLineStart; - const modifiedLineEnd = diffEntry.modifiedLineEnd; - - if (originalLineStart !== 0 && ((minOriginalLine === 0 || originalLineStart < minOriginalLine))) { - minOriginalLine = originalLineStart; - } - if (originalLineEnd !== 0 && ((maxOriginalLine === 0 || originalLineEnd > maxOriginalLine))) { - maxOriginalLine = originalLineEnd; - } - if (modifiedLineStart !== 0 && ((minModifiedLine === 0 || modifiedLineStart < minModifiedLine))) { - minModifiedLine = modifiedLineStart; - } - if (modifiedLineEnd !== 0 && ((maxModifiedLine === 0 || modifiedLineEnd > maxModifiedLine))) { - maxModifiedLine = modifiedLineEnd; - } - } - - const header = document.createElement('div'); - header.className = 'diff-review-row'; - - const cell = document.createElement('div'); - cell.className = 'diff-review-cell diff-review-summary'; - const originalChangedLinesCnt = maxOriginalLine - minOriginalLine + 1; - const modifiedChangedLinesCnt = maxModifiedLine - minModifiedLine + 1; - cell.appendChild(document.createTextNode(`${diffIndex + 1}/${this._diffs.length}: @@ -${minOriginalLine},${originalChangedLinesCnt} +${minModifiedLine},${modifiedChangedLinesCnt} @@`)); - header.setAttribute('data-line', String(minModifiedLine)); - - const getAriaLines = (lines: number) => { - if (lines === 0) { - return nls.localize('no_lines_changed', "no lines changed"); - } else if (lines === 1) { - return nls.localize('one_line_changed', "1 line changed"); - } else { - return nls.localize('more_lines_changed', "{0} lines changed", lines); - } - }; - - const originalChangedLinesCntAria = getAriaLines(originalChangedLinesCnt); - const modifiedChangedLinesCntAria = getAriaLines(modifiedChangedLinesCnt); - header.setAttribute('aria-label', nls.localize({ - key: 'header', - comment: [ - 'This is the ARIA label for a git diff header.', - 'A git diff header looks like this: @@ -154,12 +159,39 @@.', - 'That encodes that at original line 154 (which is now line 159), 12 lines were removed/changed with 39 lines.', - 'Variables 0 and 1 refer to the diff index out of total number of diffs.', - 'Variables 2 and 4 will be numbers (a line number).', - 'Variables 3 and 5 will be "no lines changed", "1 line changed" or "X lines changed", localized separately.' - ] - }, "Difference {0} of {1}: original line {2}, {3}, modified line {4}, {5}", (diffIndex + 1), this._diffs.length, minOriginalLine, originalChangedLinesCntAria, minModifiedLine, modifiedChangedLinesCntAria)); - header.appendChild(cell); - - // @@ -504,7 +517,7 @@ - header.setAttribute('role', 'listitem'); - container.appendChild(header); - - const lineHeight = modifiedOptions.get(EditorOption.lineHeight); - let modLine = minModifiedLine; - for (let i = 0, len = diffs.length; i < len; i++) { - const diffEntry = diffs[i]; - DiffReview2._renderSection(container, diffEntry, modLine, lineHeight, this._width, originalOptions, originalModel, originalModelOpts, modifiedOptions, modifiedModel, modifiedModelOpts, this._languageService.languageIdCodec); - if (diffEntry.modifiedLineStart !== 0) { - modLine = diffEntry.modifiedLineEnd; - } - } - - dom.clearNode(this._content.domNode); - this._content.domNode.appendChild(container); - this.scrollbar.scanDomNode(); - } - - private static _renderSection( - dest: HTMLElement, diffEntry: DiffEntry, modLine: number, lineHeight: number, width: number, - originalOptions: IComputedEditorOptions, originalModel: ITextModel, originalModelOpts: TextModelResolvedOptions, - modifiedOptions: IComputedEditorOptions, modifiedModel: ITextModel, modifiedModelOpts: TextModelResolvedOptions, - languageIdCodec: ILanguageIdCodec - ): void { - - const type = diffEntry.getType(); - - let rowClassName: string = 'diff-review-row'; - let lineNumbersExtraClassName: string = ''; - const spacerClassName: string = 'diff-review-spacer'; - let spacerIcon: ThemeIcon | null = null; - switch (type) { - case DiffEntryType.Insert: - rowClassName = 'diff-review-row line-insert'; - lineNumbersExtraClassName = ' char-insert'; - spacerIcon = diffReviewInsertIcon; - break; - case DiffEntryType.Delete: - rowClassName = 'diff-review-row line-delete'; - lineNumbersExtraClassName = ' char-delete'; - spacerIcon = diffReviewRemoveIcon; - break; - } - - const originalLineStart = diffEntry.originalLineStart; - const originalLineEnd = diffEntry.originalLineEnd; - const modifiedLineStart = diffEntry.modifiedLineStart; - const modifiedLineEnd = diffEntry.modifiedLineEnd; - - const cnt = Math.max( - modifiedLineEnd - modifiedLineStart, - originalLineEnd - originalLineStart - ); - - const originalLayoutInfo = originalOptions.get(EditorOption.layoutInfo); - const originalLineNumbersWidth = originalLayoutInfo.glyphMarginWidth + originalLayoutInfo.lineNumbersWidth; - - const modifiedLayoutInfo = modifiedOptions.get(EditorOption.layoutInfo); - const modifiedLineNumbersWidth = 10 + modifiedLayoutInfo.glyphMarginWidth + modifiedLayoutInfo.lineNumbersWidth; - - for (let i = 0; i <= cnt; i++) { - const originalLine = (originalLineStart === 0 ? 0 : originalLineStart + i); - const modifiedLine = (modifiedLineStart === 0 ? 0 : modifiedLineStart + i); - - const row = document.createElement('div'); - row.style.minWidth = width + 'px'; - row.className = rowClassName; - row.setAttribute('role', 'listitem'); - if (modifiedLine !== 0) { - modLine = modifiedLine; - } - row.setAttribute('data-line', String(modLine)); - - const cell = document.createElement('div'); - cell.className = 'diff-review-cell'; - cell.style.height = `${lineHeight}px`; - row.appendChild(cell); - - const originalLineNumber = document.createElement('span'); - originalLineNumber.style.width = (originalLineNumbersWidth + 'px'); - originalLineNumber.style.minWidth = (originalLineNumbersWidth + 'px'); - originalLineNumber.className = 'diff-review-line-number' + lineNumbersExtraClassName; - if (originalLine !== 0) { - originalLineNumber.appendChild(document.createTextNode(String(originalLine))); - } else { - originalLineNumber.innerText = '\u00a0'; - } - cell.appendChild(originalLineNumber); - - const modifiedLineNumber = document.createElement('span'); - modifiedLineNumber.style.width = (modifiedLineNumbersWidth + 'px'); - modifiedLineNumber.style.minWidth = (modifiedLineNumbersWidth + 'px'); - modifiedLineNumber.style.paddingRight = '10px'; - modifiedLineNumber.className = 'diff-review-line-number' + lineNumbersExtraClassName; - if (modifiedLine !== 0) { - modifiedLineNumber.appendChild(document.createTextNode(String(modifiedLine))); - } else { - modifiedLineNumber.innerText = '\u00a0'; - } - cell.appendChild(modifiedLineNumber); - - const spacer = document.createElement('span'); - spacer.className = spacerClassName; - - if (spacerIcon) { - const spacerCodicon = document.createElement('span'); - spacerCodicon.className = ThemeIcon.asClassName(spacerIcon); - spacerCodicon.innerText = '\u00a0\u00a0'; - spacer.appendChild(spacerCodicon); - } else { - spacer.innerText = '\u00a0\u00a0'; - } - cell.appendChild(spacer); - - let lineContent: string; - if (modifiedLine !== 0) { - let html: string | TrustedHTML = this._renderLine(modifiedModel, modifiedOptions, modifiedModelOpts.tabSize, modifiedLine, languageIdCodec); - if (DiffReview2._ttPolicy) { - html = DiffReview2._ttPolicy.createHTML(html as string); - } - cell.insertAdjacentHTML('beforeend', html as string); - lineContent = modifiedModel.getLineContent(modifiedLine); - } else { - let html: string | TrustedHTML = this._renderLine(originalModel, originalOptions, originalModelOpts.tabSize, originalLine, languageIdCodec); - if (DiffReview2._ttPolicy) { - html = DiffReview2._ttPolicy.createHTML(html as string); - } - cell.insertAdjacentHTML('beforeend', html as string); - lineContent = originalModel.getLineContent(originalLine); - } - - if (lineContent.length === 0) { - lineContent = nls.localize('blankLine', "blank"); - } - - let ariaLabel: string = ''; - switch (type) { - case DiffEntryType.Equal: - if (originalLine === modifiedLine) { - ariaLabel = nls.localize({ key: 'unchangedLine', comment: ['The placeholders are contents of the line and should not be translated.'] }, "{0} unchanged line {1}", lineContent, originalLine); - } else { - ariaLabel = nls.localize('equalLine', "{0} original line {1} modified line {2}", lineContent, originalLine, modifiedLine); - } - break; - case DiffEntryType.Insert: - ariaLabel = nls.localize('insertLine', "+ {0} modified line {1}", lineContent, modifiedLine); - break; - case DiffEntryType.Delete: - ariaLabel = nls.localize('deleteLine', "- {0} original line {1}", lineContent, originalLine); - break; - } - row.setAttribute('aria-label', ariaLabel); - - dest.appendChild(row); - } - } - - private static _renderLine(model: ITextModel, options: IComputedEditorOptions, tabSize: number, lineNumber: number, languageIdCodec: ILanguageIdCodec): string { - const lineContent = model.getLineContent(lineNumber); - const fontInfo = options.get(EditorOption.fontInfo); - const lineTokens = LineTokens.createEmpty(lineContent, languageIdCodec); - const isBasicASCII = ViewLineRenderingData.isBasicASCII(lineContent, model.mightContainNonBasicASCII()); - const containsRTL = ViewLineRenderingData.containsRTL(lineContent, isBasicASCII, model.mightContainRTL()); - const r = renderViewLine(new RenderLineInput( - (fontInfo.isMonospace && !options.get(EditorOption.disableMonospaceOptimizations)), - fontInfo.canUseHalfwidthRightwardsArrow, - lineContent, - false, - isBasicASCII, - containsRTL, - 0, - lineTokens, - [], - tabSize, - 0, - fontInfo.spaceWidth, - fontInfo.middotWidth, - fontInfo.wsmiddotWidth, - options.get(EditorOption.stopRenderingLineAfter), - options.get(EditorOption.renderWhitespace), - options.get(EditorOption.renderControlCharacters), - options.get(EditorOption.fontLigatures) !== EditorFontLigatures.OFF, - null - )); - - return r.html; - } -} diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/lineAlignment.ts b/src/vs/editor/browser/widget/diffEditorWidget2/lineAlignment.ts index 12f0c9bafed67..56357753f6251 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/lineAlignment.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/lineAlignment.ts @@ -7,9 +7,8 @@ import { $ } from 'vs/base/browser/dom'; import { ArrayQueue } from 'vs/base/common/arrays'; import { RunOnceScheduler } from 'vs/base/common/async'; import { Codicon } from 'vs/base/common/codicons'; -import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; -import { IObservable, derived, observableFromEvent, observableValue } from 'vs/base/common/observable'; -import { autorun, autorunWithStore2 } from 'vs/base/common/observableImpl/autorun'; +import { Disposable, DisposableStore, toDisposable } from 'vs/base/common/lifecycle'; +import { IObservable, autorun, autorunWithStore, derived, observableFromEvent, observableValue } from 'vs/base/common/observable'; import { ThemeIcon } from 'vs/base/common/themables'; import { assertIsDefined } from 'vs/base/common/types'; import { applyFontInfo } from 'vs/editor/browser/config/domFontInfo'; @@ -70,8 +69,12 @@ export class ViewZoneManager extends Disposable { this._register(this._editors.original.onDidChangeViewZones((_args) => { if (!isChangingViewZones && !this._canIgnoreViewZoneUpdateEvent()) { updateImmediately.schedule(); } })); this._register(this._editors.modified.onDidChangeViewZones((_args) => { if (!isChangingViewZones && !this._canIgnoreViewZoneUpdateEvent()) { updateImmediately.schedule(); } })); - this._register(this._editors.original.onDidChangeConfiguration((args) => { if (args.hasChanged(EditorOption.wrappingInfo)) { updateImmediately.schedule(); } })); - this._register(this._editors.modified.onDidChangeConfiguration((args) => { if (args.hasChanged(EditorOption.wrappingInfo)) { updateImmediately.schedule(); } })); + this._register(this._editors.original.onDidChangeConfiguration((args) => { + if (args.hasChanged(EditorOption.wrappingInfo) || args.hasChanged(EditorOption.lineHeight)) { updateImmediately.schedule(); } + })); + this._register(this._editors.modified.onDidChangeConfiguration((args) => { + if (args.hasChanged(EditorOption.wrappingInfo) || args.hasChanged(EditorOption.lineHeight)) { updateImmediately.schedule(); } + })); const originalModelTokenizationCompleted = this._diffModel.map(m => m ? observableFromEvent(m.model.original.onDidChangeTokens, () => m.model.original.tokenization.backgroundTokenizationState === BackgroundTokenizationState.Completed) : undefined @@ -80,21 +83,39 @@ export class ViewZoneManager extends Disposable { const alignmentViewZoneIdsOrig = new Set(); const alignmentViewZoneIdsMod = new Set(); - const alignments = derived('alignments', (reader) => { + const alignments = derived((reader) => { + /** @description alignments */ const diffModel = this._diffModel.read(reader); const diff = diffModel?.diff.read(reader); if (!diffModel || !diff) { return null; } state.read(reader); - return computeRangeAlignment(this._editors.original, this._editors.modified, diff.mappings, alignmentViewZoneIdsOrig, alignmentViewZoneIdsMod); + const renderSideBySide = this._options.renderSideBySide.read(reader); + const innerHunkAlignment = renderSideBySide; + return computeRangeAlignment( + this._editors.original, + this._editors.modified, + diff.mappings, + alignmentViewZoneIdsOrig, + alignmentViewZoneIdsMod, + innerHunkAlignment + ); }); - const alignmentsSyncedMovedText = derived('alignments', (reader) => { - const syncedMovedText = this._diffModel.read(reader)?.syncedMovedTexts.read(reader); + const alignmentsSyncedMovedText = derived((reader) => { + /** @description alignments */ + const syncedMovedText = this._diffModel.read(reader)?.movedTextToCompare.read(reader); if (!syncedMovedText) { return null; } state.read(reader); const mappings = syncedMovedText.changes.map(c => new DiffMapping(c)); // TODO dont include alignments outside syncedMovedText - return computeRangeAlignment(this._editors.original, this._editors.modified, mappings, alignmentViewZoneIdsOrig, alignmentViewZoneIdsMod); + return computeRangeAlignment( + this._editors.original, + this._editors.modified, + mappings, + alignmentViewZoneIdsOrig, + alignmentViewZoneIdsMod, + true + ); }); function createFakeLinesDiv(): HTMLElement { @@ -104,7 +125,8 @@ export class ViewZoneManager extends Disposable { } const alignmentViewZonesDisposables = this._register(new DisposableStore()); - const alignmentViewZones = derived<{ orig: IViewZoneWithZoneId[]; mod: IViewZoneWithZoneId[] }>('alignment viewzones', (reader) => { + const alignmentViewZones = derived<{ orig: IViewZoneWithZoneId[]; mod: IViewZoneWithZoneId[] }>((reader) => { + /** @description alignment viewzones */ alignmentViewZonesDisposables.clear(); const alignmentsVal = alignments.read(reader) || []; @@ -149,7 +171,7 @@ export class ViewZoneManager extends Disposable { const modLineHeight = this._editors.modified.getOption(EditorOption.lineHeight); - const syncedMovedText = this._diffModel.read(reader)?.syncedMovedTexts.read(reader); + const syncedMovedText = this._diffModel.read(reader)?.movedTextToCompare.read(reader); const mightContainNonBasicASCII = this._editors.original.getModel()?.mightContainNonBasicASCII() ?? false; const mightContainRTL = this._editors.original.getModel()?.mightContainRTL() ?? false; @@ -243,7 +265,7 @@ export class ViewZoneManager extends Disposable { } else { const delta = a.modifiedHeightInPx - a.originalHeightInPx; if (delta > 0) { - if (syncedMovedText?.lineRangeMapping.originalRange.contains(a.originalRange.endLineNumberExclusive - 1)) { + if (syncedMovedText?.lineRangeMapping.original.delta(-1).deltaLength(2).contains(a.originalRange.endLineNumberExclusive - 1)) { continue; } @@ -254,7 +276,7 @@ export class ViewZoneManager extends Disposable { showInHiddenAreas: true, }); } else { - if (syncedMovedText?.lineRangeMapping.modifiedRange.contains(a.modifiedRange.endLineNumberExclusive - 1)) { + if (syncedMovedText?.lineRangeMapping.modified.delta(-1).deltaLength(2).contains(a.modifiedRange.endLineNumberExclusive - 1)) { continue; } @@ -281,8 +303,8 @@ export class ViewZoneManager extends Disposable { } for (const a of alignmentsSyncedMovedText.read(reader) ?? []) { - if (!syncedMovedText?.lineRangeMapping.originalRange.intersect(a.originalRange) - && !syncedMovedText?.lineRangeMapping.modifiedRange.intersect(a.modifiedRange)) { + if (!syncedMovedText?.lineRangeMapping.original.intersect(a.originalRange) + || !syncedMovedText?.lineRangeMapping.modified.intersect(a.modifiedRange)) { // ignore unrelated alignments outside the synced moved text continue; } @@ -308,7 +330,8 @@ export class ViewZoneManager extends Disposable { return { orig: origViewZones, mod: modViewZones }; }); - this._register(autorunWithStore2('alignment viewzones', (reader) => { + this._register(autorunWithStore((reader) => { + /** @description alignment viewzones */ const scrollState = StableEditorScrollState.capture(this._editors.modified); const alignmentViewZones_ = alignmentViewZones.read(reader); @@ -340,6 +363,17 @@ export class ViewZoneManager extends Disposable { scrollState.restore(this._editors.modified); })); + this._register(toDisposable(() => { + this._editors.original.changeViewZones((a) => { + for (const id of alignmentViewZoneIdsOrig) { a.removeZone(id); } + alignmentViewZoneIdsOrig.clear(); + }); + this._editors.modified.changeViewZones((a) => { + for (const id of alignmentViewZoneIdsMod) { a.removeZone(id); } + alignmentViewZoneIdsMod.clear(); + }); + })); + let ignoreChange = false; this._register(this._editors.original.onDidScrollChange(e => { if (e.scrollLeftChanged && !ignoreChange) { @@ -367,7 +401,8 @@ export class ViewZoneManager extends Disposable { // origOffset - modOffset = heightOfLines(1..Y) - heightOfLines(1..X) // origScrollTop >= 0, modScrollTop >= 0 - this._register(autorun('update scroll modified', (reader) => { + this._register(autorun(reader => { + /** @description update scroll modified */ const newScrollTopModified = this._originalScrollTop.read(reader) - (this._originalScrollOffsetAnimated.get() - this._modifiedScrollOffsetAnimated.read(reader)) - (this._originalTopPadding.get() - this._modifiedTopPadding.read(reader)); @@ -376,7 +411,8 @@ export class ViewZoneManager extends Disposable { } })); - this._register(autorun('update scroll original', (reader) => { + this._register(autorun(reader => { + /** @description update scroll original */ const newScrollTopOriginal = this._modifiedScrollTop.read(reader) - (this._modifiedScrollOffsetAnimated.get() - this._originalScrollOffsetAnimated.read(reader)) - (this._modifiedTopPadding.get() - this._originalTopPadding.read(reader)); @@ -386,13 +422,14 @@ export class ViewZoneManager extends Disposable { })); - this._register(autorun('update', reader => { - const m = this._diffModel.read(reader)?.syncedMovedTexts.read(reader); + this._register(autorun(reader => { + /** @description update editor top offsets */ + const m = this._diffModel.read(reader)?.movedTextToCompare.read(reader); let deltaOrigToMod = 0; if (m) { - const trueTopOriginal = this._editors.original.getTopForLineNumber(m.lineRangeMapping.originalRange.startLineNumber, true) - this._originalTopPadding.get(); - const trueTopModified = this._editors.modified.getTopForLineNumber(m.lineRangeMapping.modifiedRange.startLineNumber, true) - this._modifiedTopPadding.get(); + const trueTopOriginal = this._editors.original.getTopForLineNumber(m.lineRangeMapping.original.startLineNumber, true) - this._originalTopPadding.get(); + const trueTopModified = this._editors.modified.getTopForLineNumber(m.lineRangeMapping.modified.startLineNumber, true) - this._modifiedTopPadding.get(); deltaOrigToMod = trueTopModified - trueTopOriginal; } @@ -444,6 +481,7 @@ function computeRangeAlignment( diffs: readonly DiffMapping[], originalEditorAlignmentViewZones: ReadonlySet, modifiedEditorAlignmentViewZones: ReadonlySet, + innerHunkAlignment: boolean, ): ILineRangeAlignment[] { const originalLineHeightOverrides = new ArrayQueue(getAdditionalLineHeights(originalEditor, originalEditorAlignmentViewZones)); const modifiedLineHeightOverrides = new ArrayQueue(getAdditionalLineHeights(modifiedEditor, modifiedEditorAlignmentViewZones)); @@ -504,20 +542,58 @@ function computeRangeAlignment( const c = m.lineRangeMapping; handleAlignmentsOutsideOfDiffs(c.originalRange.startLineNumber, c.modifiedRange.startLineNumber); - const originalAdditionalHeight = originalLineHeightOverrides - .takeWhile(v => v.lineNumber < c.originalRange.endLineNumberExclusive) - ?.reduce((p, c) => p + c.heightInPx, 0) ?? 0; - const modifiedAdditionalHeight = modifiedLineHeightOverrides - .takeWhile(v => v.lineNumber < c.modifiedRange.endLineNumberExclusive) - ?.reduce((p, c) => p + c.heightInPx, 0) ?? 0; - - result.push({ - originalRange: c.originalRange, - modifiedRange: c.modifiedRange, - originalHeightInPx: c.originalRange.length * origLineHeight + originalAdditionalHeight, - modifiedHeightInPx: c.modifiedRange.length * modLineHeight + modifiedAdditionalHeight, - diff: m.lineRangeMapping, - }); + let first = true; + let lastModLineNumber = c.modifiedRange.startLineNumber; + let lastOrigLineNumber = c.originalRange.startLineNumber; + + function emitAlignment(origLineNumberExclusive: number, modLineNumberExclusive: number) { + if (origLineNumberExclusive < lastOrigLineNumber || modLineNumberExclusive < lastModLineNumber) { + return; + } + if (first) { + first = false; + } else if (origLineNumberExclusive === lastOrigLineNumber || modLineNumberExclusive === lastModLineNumber) { + return; + } + const originalRange = new LineRange(lastOrigLineNumber, origLineNumberExclusive); + const modifiedRange = new LineRange(lastModLineNumber, modLineNumberExclusive); + if (originalRange.isEmpty && modifiedRange.isEmpty) { + return; + } + + const originalAdditionalHeight = originalLineHeightOverrides + .takeWhile(v => v.lineNumber < origLineNumberExclusive) + ?.reduce((p, c) => p + c.heightInPx, 0) ?? 0; + const modifiedAdditionalHeight = modifiedLineHeightOverrides + .takeWhile(v => v.lineNumber < modLineNumberExclusive) + ?.reduce((p, c) => p + c.heightInPx, 0) ?? 0; + + result.push({ + originalRange, + modifiedRange, + originalHeightInPx: originalRange.length * origLineHeight + originalAdditionalHeight, + modifiedHeightInPx: modifiedRange.length * modLineHeight + modifiedAdditionalHeight, + diff: m.lineRangeMapping, + }); + + lastOrigLineNumber = origLineNumberExclusive; + lastModLineNumber = modLineNumberExclusive; + } + + if (innerHunkAlignment) { + for (const i of c.innerChanges || []) { + if (i.originalRange.startColumn > 1 && i.modifiedRange.startColumn > 1) { + // There is some unmodified text on this line before the diff + emitAlignment(i.originalRange.startLineNumber, i.modifiedRange.startLineNumber); + } + if (i.originalRange.endColumn < originalEditor.getModel()!.getLineMaxColumn(i.originalRange.endLineNumber)) { + // // There is some unmodified text on this line after the diff + emitAlignment(i.originalRange.endLineNumber, i.modifiedRange.endLineNumber); + } + } + } + + emitAlignment(c.originalRange.endLineNumberExclusive, c.modifiedRange.endLineNumberExclusive); lastOriginalLineNumber = c.originalRange.endLineNumberExclusive; lastModifiedLineNumber = c.modifiedRange.endLineNumberExclusive; diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/movedBlocksLines.ts b/src/vs/editor/browser/widget/diffEditorWidget2/movedBlocksLines.ts index 4c85fd8afa699..c4144924bcede 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/movedBlocksLines.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/movedBlocksLines.ts @@ -3,17 +3,34 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Disposable } from 'vs/base/common/lifecycle'; -import { IObservable, autorun, observableFromEvent, observableSignalFromEvent } from 'vs/base/common/observable'; +import { h } from 'vs/base/browser/dom'; +import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; +import { Action } from 'vs/base/common/actions'; +import { booleanComparator, compareBy, findMaxIdxBy, numberComparator, tieBreakComparators } from 'vs/base/common/arrays'; +import { Codicon } from 'vs/base/common/codicons'; +import { Disposable, toDisposable } from 'vs/base/common/lifecycle'; +import { IObservable, autorun, autorunWithStore, constObservable, derived, derivedWithStore, keepAlive, observableFromEvent, observableSignalFromEvent, observableValue } from 'vs/base/common/observable'; +import { ThemeIcon } from 'vs/base/common/themables'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { DiffEditorEditors } from 'vs/editor/browser/widget/diffEditorWidget2/diffEditorEditors'; import { DiffEditorViewModel } from 'vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel'; +import { PlaceholderViewZone, ViewZoneOverlayWidget, applyStyle, applyViewZones } from 'vs/editor/browser/widget/diffEditorWidget2/utils'; import { EditorLayoutInfo } from 'vs/editor/common/config/editorOptions'; import { LineRange } from 'vs/editor/common/core/lineRange'; +import { OffsetRange, OffsetRangeSet } from 'vs/editor/common/core/offsetRange'; +import { MovedText } from 'vs/editor/common/diff/linesDiffComputer'; +import { localize } from 'vs/nls'; export class MovedBlocksLinesPart extends Disposable { public static readonly movedCodeBlockPadding = 4; + private readonly _element: SVGElement; + private readonly _originalScrollTop = observableFromEvent(this._editors.original.onDidScrollChange, () => this._editors.original.getScrollTop()); + private readonly _modifiedScrollTop = observableFromEvent(this._editors.modified.onDidScrollChange, () => this._editors.modified.getScrollTop()); + private readonly _viewZonesChanged = observableSignalFromEvent('onDidChangeViewZones', this._editors.modified.onDidChangeViewZones); + + public readonly width = observableValue('width', 0); + constructor( private readonly _rootElement: HTMLElement, private readonly _diffModel: IObservable, @@ -23,67 +40,292 @@ export class MovedBlocksLinesPart extends Disposable { ) { super(); - const element = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); - element.setAttribute('class', 'moved-blocks-lines'); - this._rootElement.appendChild(element); + this._element = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); + this._element.setAttribute('class', 'moved-blocks-lines'); + this._rootElement.appendChild(this._element); + this._register(toDisposable(() => this._element.remove())); - this._register(autorun('update', (reader) => { + this._register(autorun(reader => { + /** @description update moved blocks lines positioning */ const info = this._originalEditorLayoutInfo.read(reader); const info2 = this._modifiedEditorLayoutInfo.read(reader); if (!info || !info2) { return; } - element.style.left = `${info.width - info.verticalScrollbarWidth}px`; - element.style.height = `${info.height}px`; - element.style.width = `${info.verticalScrollbarWidth + info.contentLeft - MovedBlocksLinesPart.movedCodeBlockPadding}px`; + this._element.style.left = `${info.width - info.verticalScrollbarWidth}px`; + this._element.style.height = `${info.height}px`; + this._element.style.width = `${info.verticalScrollbarWidth + info.contentLeft - MovedBlocksLinesPart.movedCodeBlockPadding + this.width.read(reader)}px`; })); - const originalScrollTop = observableFromEvent(this._editors.original.onDidScrollChange, () => this._editors.original.getScrollTop()); - const modifiedScrollTop = observableFromEvent(this._editors.modified.onDidScrollChange, () => this._editors.modified.getScrollTop()); - const viewZonesChanged = observableSignalFromEvent('onDidChangeViewZones', this._editors.modified.onDidChangeViewZones); + this._register(keepAlive(this._state, true)); - this._register(autorun('update', (reader) => { - element.replaceChildren(); - viewZonesChanged.read(reader); + const movedBlockViewZones = derived(reader => { + const model = this._diffModel.read(reader); + const d = model?.diff.read(reader); + if (!d) { return []; } + return d.movedTexts.map(move => ({ + move, + original: new PlaceholderViewZone(constObservable(move.lineRangeMapping.original.startLineNumber - 1), 18), + modified: new PlaceholderViewZone(constObservable(move.lineRangeMapping.modified.startLineNumber - 1), 18), + })); + }); - const info = this._originalEditorLayoutInfo.read(reader); - const info2 = this._modifiedEditorLayoutInfo.read(reader); - if (!info || !info2) { - return; + this._register(applyViewZones(this._editors.original, movedBlockViewZones.map(zones => zones.map(z => z.original)))); + this._register(applyViewZones(this._editors.modified, movedBlockViewZones.map(zones => zones.map(z => z.modified)))); + + this._register(autorunWithStore((reader, store) => { + const blocks = movedBlockViewZones.read(reader); + for (const b of blocks) { + store.add(new MovedBlockOverlayWidget(this._editors.original, b.original, b.move, 'original', this._diffModel.get()!)); + store.add(new MovedBlockOverlayWidget(this._editors.modified, b.modified, b.move, 'modified', this._diffModel.get()!)); } - const width = info.verticalScrollbarWidth + info.contentLeft - MovedBlocksLinesPart.movedCodeBlockPadding; + })); - const moves = this._diffModel.read(reader)?.diff.read(reader)?.movedTexts; - if (!moves) { - return; + this._register(this._editors.original.onDidChangeCursorPosition(e => { + const m = this._diffModel.get(); + if (!m) { return; } + const movedText = m.diff.get()!.movedTexts.find(m => m.lineRangeMapping.original.contains(e.position.lineNumber)); + if (movedText !== m.movedTextToCompare.get()) { + m.movedTextToCompare.set(undefined, undefined); + } + m.setActiveMovedText(movedText); + })); + this._register(this._editors.modified.onDidChangeCursorPosition(e => { + const m = this._diffModel.get(); + if (!m) { return; } + const movedText = m.diff.get()!.movedTexts.find(m => m.lineRangeMapping.modified.contains(e.position.lineNumber)); + if (movedText !== m.movedTextToCompare.get()) { + m.movedTextToCompare.set(undefined, undefined); } + m.setActiveMovedText(movedText); + })); + } - let idx = 0; - for (const m of moves) { - function computeLineStart(range: LineRange, editor: ICodeEditor) { - const t1 = editor.getTopForLineNumber(range.startLineNumber); - const t2 = editor.getTopForLineNumber(range.endLineNumberExclusive); - return (t1 + t2) / 2; - } + private readonly _state = derivedWithStore('state', (reader, store) => { + /** @description update moved blocks lines */ + + this._element.replaceChildren(); + const model = this._diffModel.read(reader); + const moves = model?.diff.read(reader)?.movedTexts; + if (!moves || moves.length === 0) { + this.width.set(0, undefined); + return; + } + + this._viewZonesChanged.read(reader); + + const infoOrig = this._originalEditorLayoutInfo.read(reader); + const infoMod = this._modifiedEditorLayoutInfo.read(reader); + if (!infoOrig || !infoMod) { + this.width.set(0, undefined); + return; + } + + const lines = moves.map((move) => { + function computeLineStart(range: LineRange, editor: ICodeEditor) { + const t1 = editor.getTopForLineNumber(range.startLineNumber); + const t2 = editor.getTopForLineNumber(range.endLineNumberExclusive); + return (t1 + t2) / 2; + } + + const start = computeLineStart(move.lineRangeMapping.original, this._editors.original); + const startOffset = this._originalScrollTop.read(reader); + const end = computeLineStart(move.lineRangeMapping.modified, this._editors.modified); + const endOffset = this._modifiedScrollTop.read(reader); + + const from = start - startOffset; + const to = end - endOffset; + + const top = Math.min(start, end); + const bottom = Math.max(start, end); + + return { range: new OffsetRange(top, bottom), from, to, fromWithoutScroll: start, toWithoutScroll: end, move }; + }); + + lines.sort(tieBreakComparators( + compareBy(l => l.fromWithoutScroll > l.toWithoutScroll, booleanComparator), + compareBy(l => l.fromWithoutScroll > l.toWithoutScroll ? l.fromWithoutScroll : -l.toWithoutScroll, numberComparator) + )); + + const layout = LinesLayout.compute(lines.map(l => l.range)); + + const padding = 10; + const lineAreaLeft = infoOrig.verticalScrollbarWidth; + const lineAreaWidth = (layout.getTrackCount() - 1) * 10 + padding * 2; + const width = lineAreaLeft + lineAreaWidth + (infoMod.contentLeft - MovedBlocksLinesPart.movedCodeBlockPadding); + + let idx = 0; + for (const line of lines) { + const track = layout.getTrack(idx); + const verticalY = lineAreaLeft + padding + track * 10; + + const arrowHeight = 15; + const arrowWidth = 15; + const right = width; + + const rectWidth = infoMod.glyphMarginWidth + infoMod.lineNumbersWidth; + const rectHeight = 18; + const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect'); + rect.classList.add('arrow-rectangle'); + rect.setAttribute('x', `${right - rectWidth}`); + rect.setAttribute('y', `${line.to - rectHeight / 2}`); + rect.setAttribute('width', `${rectWidth}`); + rect.setAttribute('height', `${rectHeight}`); + this._element.appendChild(rect); + + const g = document.createElementNS('http://www.w3.org/2000/svg', 'g'); - const start = computeLineStart(m.lineRangeMapping.originalRange, this._editors.original); - const startOffset = originalScrollTop.read(reader); - const end = computeLineStart(m.lineRangeMapping.modifiedRange, this._editors.modified); - const endOffset = modifiedScrollTop.read(reader); + const path = document.createElementNS('http://www.w3.org/2000/svg', 'path'); - const top = start - startOffset; - const bottom = end - endOffset; + path.setAttribute('d', `M ${0} ${line.from} L ${verticalY} ${line.from} L ${verticalY} ${line.to} L ${right - arrowWidth} ${line.to}`); + path.setAttribute('fill', 'none'); + g.appendChild(path); - const center = (width / 2) - moves.length * 5 + idx * 10; - idx++; + const arrowRight = document.createElementNS('http://www.w3.org/2000/svg', 'polygon'); + arrowRight.classList.add('arrow'); - const path = document.createElementNS('http://www.w3.org/2000/svg', 'path'); - path.setAttribute('d', `M ${0} ${top} L ${center} ${top} L ${center} ${bottom} L ${width} ${bottom}`); + store.add(autorun(reader => { + path.classList.toggle('currentMove', line.move === model.activeMovedText.read(reader)); + arrowRight.classList.toggle('currentMove', line.move === model.activeMovedText.read(reader)); + })); - path.setAttribute('fill', 'none'); - element.appendChild(path); + arrowRight.setAttribute('points', `${right - arrowWidth},${line.to - arrowHeight / 2} ${right},${line.to} ${right - arrowWidth},${line.to + arrowHeight / 2}`); + g.appendChild(arrowRight); + + this._element.appendChild(g); + + /* + TODO@hediet + path.addEventListener('mouseenter', () => { + model.setHoveredMovedText(line.move); + }); + path.addEventListener('mouseleave', () => { + model.setHoveredMovedText(undefined); + });*/ + + idx++; + } + + this.width.set(lineAreaWidth, undefined); + }); +} + +class LinesLayout { + public static compute(lines: OffsetRange[]): LinesLayout { + const setsPerTrack: OffsetRangeSet[] = []; + const trackPerLineIdx: number[] = []; + + for (const line of lines) { + let trackIdx = setsPerTrack.findIndex(set => !set.intersectsStrict(line)); + if (trackIdx === -1) { + const maxTrackCount = 6; + if (setsPerTrack.length >= maxTrackCount) { + trackIdx = findMaxIdxBy(setsPerTrack, compareBy(set => set.intersectWithRangeLength(line), numberComparator)); + } else { + trackIdx = setsPerTrack.length; + setsPerTrack.push(new OffsetRangeSet()); + } } + setsPerTrack[trackIdx].addRange(line); + trackPerLineIdx.push(trackIdx); + } + + return new LinesLayout(setsPerTrack.length, trackPerLineIdx); + } + + private constructor( + private readonly _trackCount: number, + private readonly trackPerLineIdx: number[] + ) { } + + getTrack(lineIdx: number): number { + return this.trackPerLineIdx[lineIdx]; + } + + getTrackCount(): number { + return this._trackCount; + } +} + +class MovedBlockOverlayWidget extends ViewZoneOverlayWidget { + private readonly _nodes = h('div.diff-moved-code-block', { style: { marginRight: '4px' } }, [ + h('div.text-content@textContent'), + h('div.action-bar@actionBar'), + ]); + + constructor( + private readonly _editor: ICodeEditor, + _viewZone: PlaceholderViewZone, + private readonly _move: MovedText, + private readonly _kind: 'original' | 'modified', + private readonly _diffModel: DiffEditorViewModel, + ) { + const root = h('div.diff-hidden-lines-widget'); + super(_editor, _viewZone, root.root); + root.root.appendChild(this._nodes.root); + + const editorLayout = observableFromEvent(this._editor.onDidLayoutChange, () => this._editor.getLayoutInfo()); + + this._register(applyStyle(this._nodes.root, { + paddingRight: editorLayout.map(l => l.verticalScrollbarWidth) })); + + let text: string; + + if (_move.changes.length > 0) { + text = this._kind === 'original' ? localize( + 'codeMovedToWithChanges', + 'Code moved with changes to line {0}-{1}', + this._move.lineRangeMapping.modified.startLineNumber, + this._move.lineRangeMapping.modified.endLineNumberExclusive + ) : localize( + 'codeMovedFromWithChanges', + 'Code moved with changes from line {0}-{1}', + this._move.lineRangeMapping.original.startLineNumber, + this._move.lineRangeMapping.original.endLineNumberExclusive + ); + } else { + text = this._kind === 'original' ? localize( + 'codeMovedTo', + 'Code moved to line {0}-{1}', + this._move.lineRangeMapping.modified.startLineNumber, + this._move.lineRangeMapping.modified.endLineNumberExclusive + ) : localize( + 'codeMovedFrom', + 'Code moved from line {0}-{1}', + this._move.lineRangeMapping.original.startLineNumber, + this._move.lineRangeMapping.original.endLineNumberExclusive + ); + } + + const actionBar = this._register(new ActionBar(this._nodes.actionBar, { + highlightToggledItems: true, + })); + + const caption = new Action( + '', + text, + '', + false, + ); + actionBar.push(caption, { icon: false, label: true }); + + const actionCompare = new Action( + '', + 'Compare', + ThemeIcon.asClassName(Codicon.compareChanges), + true, + () => { + this._editor.focus(); + this._diffModel.movedTextToCompare.set(this._diffModel.movedTextToCompare.get() ? undefined : this._move, undefined); + }, + ); + this._register(autorun(reader => { + const isActive = this._diffModel.movedTextToCompare.read(reader) === _move; + actionCompare.checked = isActive; + })); + + actionBar.push(actionCompare, { icon: false, label: true }); } } diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/outlineModel.ts b/src/vs/editor/browser/widget/diffEditorWidget2/outlineModel.ts new file mode 100644 index 0000000000000..cd12277b82cf9 --- /dev/null +++ b/src/vs/editor/browser/widget/diffEditorWidget2/outlineModel.ts @@ -0,0 +1,384 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { binarySearch, coalesceInPlace, equals } from 'vs/base/common/arrays'; +import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; +import { onUnexpectedExternalError } from 'vs/base/common/errors'; +import { Iterable } from 'vs/base/common/iterator'; +import { commonPrefixLength } from 'vs/base/common/strings'; +import { URI } from 'vs/base/common/uri'; +import { IPosition, Position } from 'vs/editor/common/core/position'; +import { IRange, Range } from 'vs/editor/common/core/range'; +import { LanguageFeatureRegistry } from 'vs/editor/common/languageFeatureRegistry'; +import { DocumentSymbol, DocumentSymbolProvider } from 'vs/editor/common/languages'; +import { ITextModel } from 'vs/editor/common/model'; +import { MarkerSeverity } from 'vs/platform/markers/common/markers'; + +// TODO@hediet: These classes are copied from outlineModel.ts because of layering issues. +// Because these classes just depend on the DocumentSymbolProvider (which is in the core editor), +// they should be moved to the core editor as well. + +export abstract class TreeElement { + + abstract id: string; + abstract children: Map; + abstract parent: TreeElement | undefined; + + remove(): void { + this.parent?.children.delete(this.id); + } + + static findId(candidate: DocumentSymbol | string, container: TreeElement): string { + // complex id-computation which contains the origin/extension, + // the parent path, and some dedupe logic when names collide + let candidateId: string; + if (typeof candidate === 'string') { + candidateId = `${container.id}/${candidate}`; + } else { + candidateId = `${container.id}/${candidate.name}`; + if (container.children.get(candidateId) !== undefined) { + candidateId = `${container.id}/${candidate.name}_${candidate.range.startLineNumber}_${candidate.range.startColumn}`; + } + } + + let id = candidateId; + for (let i = 0; container.children.get(id) !== undefined; i++) { + id = `${candidateId}_${i}`; + } + + return id; + } + + static getElementById(id: string, element: TreeElement): TreeElement | undefined { + if (!id) { + return undefined; + } + const len = commonPrefixLength(id, element.id); + if (len === id.length) { + return element; + } + if (len < element.id.length) { + return undefined; + } + for (const [, child] of element.children) { + const candidate = TreeElement.getElementById(id, child); + if (candidate) { + return candidate; + } + } + return undefined; + } + + static size(element: TreeElement): number { + let res = 1; + for (const [, child] of element.children) { + res += TreeElement.size(child); + } + return res; + } + + static empty(element: TreeElement): boolean { + return element.children.size === 0; + } +} + +export interface IOutlineMarker { + startLineNumber: number; + startColumn: number; + endLineNumber: number; + endColumn: number; + severity: MarkerSeverity; +} + +export class OutlineElement extends TreeElement { + + children = new Map(); + marker: { count: number; topSev: MarkerSeverity } | undefined; + + constructor( + readonly id: string, + public parent: TreeElement | undefined, + readonly symbol: DocumentSymbol + ) { + super(); + } +} + +export class OutlineGroup extends TreeElement { + + children = new Map(); + + constructor( + readonly id: string, + public parent: TreeElement | undefined, + readonly label: string, + readonly order: number, + ) { + super(); + } + + getItemEnclosingPosition(position: IPosition): OutlineElement | undefined { + return position ? this._getItemEnclosingPosition(position, this.children) : undefined; + } + + private _getItemEnclosingPosition(position: IPosition, children: Map): OutlineElement | undefined { + for (const [, item] of children) { + if (!item.symbol.range || !Range.containsPosition(item.symbol.range, position)) { + continue; + } + return this._getItemEnclosingPosition(position, item.children) || item; + } + return undefined; + } + + updateMarker(marker: IOutlineMarker[]): void { + for (const [, child] of this.children) { + this._updateMarker(marker, child); + } + } + + private _updateMarker(markers: IOutlineMarker[], item: OutlineElement): void { + item.marker = undefined; + + // find the proper start index to check for item/marker overlap. + const idx = binarySearch(markers, item.symbol.range, Range.compareRangesUsingStarts); + let start: number; + if (idx < 0) { + start = ~idx; + if (start > 0 && Range.areIntersecting(markers[start - 1], item.symbol.range)) { + start -= 1; + } + } else { + start = idx; + } + + const myMarkers: IOutlineMarker[] = []; + let myTopSev: MarkerSeverity | undefined; + + for (; start < markers.length && Range.areIntersecting(item.symbol.range, markers[start]); start++) { + // remove markers intersecting with this outline element + // and store them in a 'private' array. + const marker = markers[start]; + myMarkers.push(marker); + (markers as Array)[start] = undefined; + if (!myTopSev || marker.severity > myTopSev) { + myTopSev = marker.severity; + } + } + + // Recurse into children and let them match markers that have matched + // this outline element. This might remove markers from this element and + // therefore we remember that we have had markers. That allows us to render + // the dot, saying 'this element has children with markers' + for (const [, child] of item.children) { + this._updateMarker(myMarkers, child); + } + + if (myTopSev) { + item.marker = { + count: myMarkers.length, + topSev: myTopSev + }; + } + + coalesceInPlace(markers); + } +} + +export class OutlineModel extends TreeElement { + + static create(registry: LanguageFeatureRegistry, textModel: ITextModel, token: CancellationToken): Promise { + + const cts = new CancellationTokenSource(token); + const result = new OutlineModel(textModel.uri); + const provider = registry.ordered(textModel); + const promises = provider.map((provider, index) => { + + const id = TreeElement.findId(`provider_${index}`, result); + const group = new OutlineGroup(id, result, provider.displayName ?? 'Unknown Outline Provider', index); + + + return Promise.resolve(provider.provideDocumentSymbols(textModel, cts.token)).then(result => { + for (const info of result || []) { + OutlineModel._makeOutlineElement(info, group); + } + return group; + }, err => { + onUnexpectedExternalError(err); + return group; + }).then(group => { + if (!TreeElement.empty(group)) { + result._groups.set(id, group); + } else { + group.remove(); + } + }); + }); + + const listener = registry.onDidChange(() => { + const newProvider = registry.ordered(textModel); + if (!equals(newProvider, provider)) { + cts.cancel(); + } + }); + + return Promise.all(promises).then(() => { + if (cts.token.isCancellationRequested && !token.isCancellationRequested) { + return OutlineModel.create(registry, textModel, token); + } else { + return result._compact(); + } + }).finally(() => { + listener.dispose(); + }); + } + + private static _makeOutlineElement(info: DocumentSymbol, container: OutlineGroup | OutlineElement): void { + const id = TreeElement.findId(info, container); + const res = new OutlineElement(id, container, info); + if (info.children) { + for (const childInfo of info.children) { + OutlineModel._makeOutlineElement(childInfo, res); + } + } + container.children.set(res.id, res); + } + + static get(element: TreeElement | undefined): OutlineModel | undefined { + while (element) { + if (element instanceof OutlineModel) { + return element; + } + element = element.parent; + } + return undefined; + } + + readonly id = 'root'; + readonly parent = undefined; + + protected _groups = new Map(); + children = new Map(); + + protected constructor(readonly uri: URI) { + super(); + + this.id = 'root'; + this.parent = undefined; + } + + private _compact(): this { + let count = 0; + for (const [key, group] of this._groups) { + if (group.children.size === 0) { // empty + this._groups.delete(key); + } else { + count += 1; + } + } + if (count !== 1) { + // + this.children = this._groups; + } else { + // adopt all elements of the first group + const group = Iterable.first(this._groups.values())!; + for (const [, child] of group.children) { + child.parent = this; + this.children.set(child.id, child); + } + } + return this; + } + + merge(other: OutlineModel): boolean { + if (this.uri.toString() !== other.uri.toString()) { + return false; + } + if (this._groups.size !== other._groups.size) { + return false; + } + this._groups = other._groups; + this.children = other.children; + return true; + } + + getItemEnclosingPosition(position: IPosition, context?: OutlineElement): OutlineElement | undefined { + + let preferredGroup: OutlineGroup | undefined; + if (context) { + let candidate = context.parent; + while (candidate && !preferredGroup) { + if (candidate instanceof OutlineGroup) { + preferredGroup = candidate; + } + candidate = candidate.parent; + } + } + + let result: OutlineElement | undefined = undefined; + for (const [, group] of this._groups) { + result = group.getItemEnclosingPosition(position); + if (result && (!preferredGroup || preferredGroup === group)) { + break; + } + } + return result; + } + + getItemById(id: string): TreeElement | undefined { + return TreeElement.getElementById(id, this); + } + + updateMarker(marker: IOutlineMarker[]): void { + // sort markers by start range so that we can use + // outline element starts for quicker look up + marker.sort(Range.compareRangesUsingStarts); + + for (const [, group] of this._groups) { + group.updateMarker(marker.slice(0)); + } + } + + getTopLevelSymbols(): DocumentSymbol[] { + const roots: DocumentSymbol[] = []; + for (const child of this.children.values()) { + if (child instanceof OutlineElement) { + roots.push(child.symbol); + } else { + roots.push(...Iterable.map(child.children.values(), child => child.symbol)); + } + } + return roots.sort((a, b) => Range.compareRangesUsingStarts(a.range, b.range)); + } + + asListOfDocumentSymbols(): DocumentSymbol[] { + const roots = this.getTopLevelSymbols(); + const bucket: DocumentSymbol[] = []; + OutlineModel._flattenDocumentSymbols(bucket, roots, ''); + return bucket.sort((a, b) => + Position.compare(Range.getStartPosition(a.range), Range.getStartPosition(b.range)) || Position.compare(Range.getEndPosition(b.range), Range.getEndPosition(a.range)) + ); + } + + private static _flattenDocumentSymbols(bucket: DocumentSymbol[], entries: DocumentSymbol[], overrideContainerLabel: string): void { + for (const entry of entries) { + bucket.push({ + kind: entry.kind, + tags: entry.tags, + name: entry.name, + detail: entry.detail, + containerName: entry.containerName || overrideContainerLabel, + range: entry.range, + selectionRange: entry.selectionRange, + children: undefined, // we flatten it... + }); + + // Recurse over children + if (entry.children) { + OutlineModel._flattenDocumentSymbols(bucket, entry.children, entry.name); + } + } + } +} diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/overviewRulerPart.ts b/src/vs/editor/browser/widget/diffEditorWidget2/overviewRulerPart.ts index cc6b948140527..8996560b36a4b 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/overviewRulerPart.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/overviewRulerPart.ts @@ -9,8 +9,7 @@ import { IMouseWheelEvent } from 'vs/base/browser/mouseEvent'; import { ScrollbarState } from 'vs/base/browser/ui/scrollbar/scrollbarState'; import { Color } from 'vs/base/common/color'; import { Disposable } from 'vs/base/common/lifecycle'; -import { IObservable, autorun, derived, observableFromEvent, observableSignalFromEvent } from 'vs/base/common/observable'; -import { autorunWithStore2 } from 'vs/base/common/observableImpl/autorun'; +import { IObservable, autorun, autorunWithStore, derived, observableFromEvent, observableSignalFromEvent } from 'vs/base/common/observable'; import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget'; import { DiffEditorEditors } from 'vs/editor/browser/widget/diffEditorWidget2/diffEditorEditors'; import { DiffEditorViewModel } from 'vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel'; @@ -41,7 +40,8 @@ export class OverviewRulerPart extends Disposable { const currentColorTheme = observableFromEvent(this._themeService.onDidColorThemeChange, () => this._themeService.getColorTheme()); - const currentColors = derived('colors', reader => { + const currentColors = derived(reader => { + /** @description colors */ const theme = currentColorTheme.read(reader); const insertColor = theme.getColor(diffOverviewRulerInserted) || (theme.getColor(diffInserted) || defaultInsertColor).transparent(2); const removeColor = theme.getColor(diffOverviewRulerRemoved) || (theme.getColor(diffRemoved) || defaultRemoveColor).transparent(2); @@ -51,7 +51,8 @@ export class OverviewRulerPart extends Disposable { const scrollTopObservable = observableFromEvent(this._editors.modified.onDidScrollChange, () => this._editors.modified.getScrollTop()); const scrollHeightObservable = observableFromEvent(this._editors.modified.onDidScrollChange, () => this._editors.modified.getScrollHeight()); - this._register(autorunWithStore2('create diff editor overview ruler if enabled', (reader, store) => { + this._register(autorunWithStore((reader, store) => { + /** @description create diff editor overview ruler if enabled */ if (!this._options.renderOverviewRuler.read(reader)) { return; } @@ -72,7 +73,8 @@ export class OverviewRulerPart extends Disposable { }, { passive: false })); store.add(appendRemoveOnDispose(this._rootElement, diffOverviewRoot)); - store.add(autorunWithStore2('recreate overview rules when model changes', (reader, store) => { + store.add(autorunWithStore((reader, store) => { + /** @description recreate overview rules when model changes */ const m = this._diffModel.read(reader); const originalOverviewRuler = this._editors.original.createOverviewRuler('original diffOverviewRuler'); @@ -97,7 +99,8 @@ export class OverviewRulerPart extends Disposable { const origHiddenRangesChanged = observableSignalFromEvent('hiddenRangesChanged', this._editors.original.onDidChangeHiddenAreas); const modHiddenRangesChanged = observableSignalFromEvent('hiddenRangesChanged', this._editors.modified.onDidChangeHiddenAreas); - store.add(autorun('set overview ruler zones', (reader) => { + store.add(autorun(reader => { + /** @description set overview ruler zones */ origViewZonesChanged.read(reader); modViewZonesChanged.read(reader); origHiddenRangesChanged.read(reader); @@ -116,16 +119,22 @@ export class OverviewRulerPart extends Disposable { .map(r => { const start = vm.coordinatesConverter.convertModelPositionToViewPosition(new Position(r.startLineNumber, 1)); const end = vm.coordinatesConverter.convertModelPositionToViewPosition(new Position(r.endLineNumberExclusive, 1)); - - return new OverviewRulerZone(start.lineNumber, end.lineNumber, 0, color.toString()); + // By computing the lineCount, we won't ask the view model later for the bottom vertical position. + // (The view model will take into account the alignment viewzones, which will give + // modifications and deletetions always the same height.) + const lineCount = end.lineNumber - start.lineNumber; + return new OverviewRulerZone(start.lineNumber, end.lineNumber, lineCount, color.toString()); }); } - originalOverviewRuler?.setZones(createZones((diff || []).map(d => d.lineRangeMapping.originalRange), colors.removeColor, this._editors.original)); - modifiedOverviewRuler?.setZones(createZones((diff || []).map(d => d.lineRangeMapping.modifiedRange), colors.insertColor, this._editors.modified)); + const originalZones = createZones((diff || []).map(d => d.lineRangeMapping.originalRange), colors.removeColor, this._editors.original); + const modifiedZones = createZones((diff || []).map(d => d.lineRangeMapping.modifiedRange), colors.insertColor, this._editors.modified); + originalOverviewRuler?.setZones(originalZones); + modifiedOverviewRuler?.setZones(modifiedZones); })); - store.add(autorun('layout overview ruler', (reader) => { + store.add(autorun(reader => { + /** @description layout overview ruler */ const height = this._rootHeight.read(reader); const width = this._rootWidth.read(reader); const layoutInfo = this._modifiedEditorLayoutInfo.read(reader); diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/style.css b/src/vs/editor/browser/widget/diffEditorWidget2/style.css index f8243853b7024..aa681f8f61766 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/style.css +++ b/src/vs/editor/browser/widget/diffEditorWidget2/style.css @@ -78,6 +78,30 @@ border: 2px solid var(--vscode-diffEditor-move-border); } +.monaco-editor .movedOriginal.currentMove, .monaco-editor .movedModified.currentMove { + border: 2px solid var(--vscode-diffEditor-moveActive-border); +} + +.monaco-diff-editor .moved-blocks-lines path.currentMove { + stroke: var(--vscode-diffEditor-moveActive-border); +} + +.monaco-diff-editor .moved-blocks-lines path { + pointer-events: visiblestroke; +} + +.monaco-diff-editor .moved-blocks-lines .arrow { + fill: var(--vscode-diffEditor-move-border); +} + +.monaco-diff-editor .moved-blocks-lines .arrow.currentMove { + fill: var(--vscode-diffEditor-moveActive-border); +} + +.monaco-diff-editor .moved-blocks-lines .arrow-rectangle { + fill: var(--vscode-editor-background); +} + .monaco-diff-editor .moved-blocks-lines { position: absolute; pointer-events: none; @@ -101,3 +125,15 @@ .monaco-editor .fold-unchanged { cursor: pointer; } + +.monaco-diff-editor .diff-moved-code-block { + display: flex; + justify-content: flex-end; + margin-top: -4px; +} + +.monaco-diff-editor .diff-moved-code-block .action-bar .action-label.codicon { + width: 12px; + height: 12px; + font-size: 12px; +} diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/unchangedRanges.ts b/src/vs/editor/browser/widget/diffEditorWidget2/unchangedRanges.ts index 844dcc30f2ed2..b3ac905331d52 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/unchangedRanges.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/unchangedRanges.ts @@ -4,36 +4,49 @@ *--------------------------------------------------------------------------------------------*/ import { $, addDisposableListener, h, reset } from 'vs/base/browser/dom'; -import { renderLabelWithIcons } from 'vs/base/browser/ui/iconLabel/iconLabels'; +import { renderIcon, renderLabelWithIcons } from 'vs/base/browser/ui/iconLabel/iconLabels'; +import { compareBy, numberComparator, reverseOrder } from 'vs/base/common/arrays'; +import { CancellationTokenSource } from 'vs/base/common/cancellation'; import { Codicon } from 'vs/base/common/codicons'; +import { Event } from 'vs/base/common/event'; import { MarkdownString } from 'vs/base/common/htmlContent'; import { Disposable } from 'vs/base/common/lifecycle'; -import { IObservable, observableFromEvent, transaction } from 'vs/base/common/observable'; -import { autorun, autorunWithStore2 } from 'vs/base/common/observableImpl/autorun'; -import { derived, derivedWithStore } from 'vs/base/common/observableImpl/derived'; +import { IObservable, IReader, autorun, autorunWithStore, derived, derivedWithStore, observableFromEvent, observableSignalFromEvent, observableValue, transaction } from 'vs/base/common/observable'; import { ThemeIcon } from 'vs/base/common/themables'; import { isDefined } from 'vs/base/common/types'; import { ICodeEditor, IViewZone } from 'vs/editor/browser/editorBrowser'; import { DiffEditorEditors } from 'vs/editor/browser/widget/diffEditorWidget2/diffEditorEditors'; import { DiffEditorOptions } from 'vs/editor/browser/widget/diffEditorWidget2/diffEditorOptions'; import { DiffEditorViewModel, UnchangedRegion } from 'vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel'; +import { OutlineModel } from 'vs/editor/browser/widget/diffEditorWidget2/outlineModel'; import { PlaceholderViewZone, ViewZoneOverlayWidget, applyObservableDecorations, applyStyle, applyViewZones } from 'vs/editor/browser/widget/diffEditorWidget2/utils'; import { EditorOption } from 'vs/editor/common/config/editorOptions'; import { LineRange } from 'vs/editor/common/core/lineRange'; import { Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; import { CursorChangeReason } from 'vs/editor/common/cursorEvents'; -import { IModelDecorationOptions, IModelDeltaDecoration } from 'vs/editor/common/model'; +import { SymbolKind, SymbolKinds } from 'vs/editor/common/languages'; +import { IModelDecorationOptions, IModelDeltaDecoration, ITextModel } from 'vs/editor/common/model'; +import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; import { localize } from 'vs/nls'; export class UnchangedRangesFeature extends Disposable { private _isUpdatingViewZones = false; public get isUpdatingViewZones(): boolean { return this._isUpdatingViewZones; } + private readonly _modifiedModel = observableFromEvent(this._editors.modified.onDidChangeModel, () => this._editors.modified.getModel()); + + private readonly _modifiedOutlineSource = derivedWithStore('modified outline source', (reader, store) => { + const m = this._modifiedModel.read(reader); + if (!m) { return undefined; } + return store.add(new OutlineSource(this._languageFeaturesService, m)); + }); + constructor( private readonly _editors: DiffEditorEditors, private readonly _diffModel: IObservable, private readonly _options: DiffEditorOptions, + @ILanguageFeaturesService private readonly _languageFeaturesService: ILanguageFeaturesService, ) { super(); @@ -68,6 +81,9 @@ export class UnchangedRangesFeature extends Disposable { const modViewZones: IViewZone[] = []; const sideBySide = this._options.renderSideBySide.read(reader); + const modifiedOutlineSource = this._modifiedOutlineSource.read(reader); + if (!modifiedOutlineSource) { return { origViewZones, modViewZones }; } + const curUnchangedRegions = unchangedRegions.read(reader); for (const r of curUnchangedRegions) { if (r.shouldHideControls(reader)) { @@ -75,16 +91,16 @@ export class UnchangedRangesFeature extends Disposable { } { - const d = derived('hiddenOriginalRangeStart', reader => r.getHiddenOriginalRange(reader).startLineNumber - 1); + const d = derived(reader => /** @description hiddenOriginalRangeStart */ r.getHiddenOriginalRange(reader).startLineNumber - 1); const origVz = new PlaceholderViewZone(d, 24); origViewZones.push(origVz); - store.add(new CollapsedCodeOverlayWidget(this._editors.original, origVz, r, !sideBySide)); + store.add(new CollapsedCodeOverlayWidget(this._editors.original, origVz, r, !sideBySide, modifiedOutlineSource)); } { - const d = derived('hiddenModifiedRangeStart', reader => r.getHiddenModifiedRange(reader).startLineNumber - 1); + const d = derived(reader => /** @description hiddenModifiedRangeStart */ r.getHiddenModifiedRange(reader).startLineNumber - 1); const modViewZone = new PlaceholderViewZone(d, 24); modViewZones.push(modViewZone); - store.add(new CollapsedCodeOverlayWidget(this._editors.modified, modViewZone, r, false)); + store.add(new CollapsedCodeOverlayWidget(this._editors.modified, modViewZone, r, false, modifiedOutlineSource)); } } @@ -99,12 +115,14 @@ export class UnchangedRangesFeature extends Disposable { }; const unchangedLinesDecorationShow: IModelDecorationOptions = { description: 'Fold Unchanged', - glyphMarginHoverMessage: new MarkdownString(undefined, { isTrusted: true, supportThemeIcons: true }).appendMarkdown(localize('foldUnchanged', 'Fold Unchanged Region')), + glyphMarginHoverMessage: new MarkdownString(undefined, { isTrusted: true, supportThemeIcons: true }) + .appendMarkdown(localize('foldUnchanged', 'Fold Unchanged Region')), glyphMarginClassName: 'fold-unchanged ' + ThemeIcon.asClassName(Codicon.fold), zIndex: 10001, }; - this._register(applyObservableDecorations(this._editors.original, derived('decorations', (reader) => { + this._register(applyObservableDecorations(this._editors.original, derived(reader => { + /** @description decorations */ const curUnchangedRegions = unchangedRegions.read(reader); const result = curUnchangedRegions.map(r => ({ range: r.originalRange.toInclusiveRange()!, @@ -121,7 +139,8 @@ export class UnchangedRangesFeature extends Disposable { return result; }))); - this._register(applyObservableDecorations(this._editors.modified, derived('decorations', (reader) => { + this._register(applyObservableDecorations(this._editors.modified, derived(reader => { + /** @description decorations */ const curUnchangedRegions = unchangedRegions.read(reader); const result = curUnchangedRegions.map(r => ({ range: r.modifiedRange.toInclusiveRange()!, @@ -141,7 +160,8 @@ export class UnchangedRangesFeature extends Disposable { this._register(applyViewZones(this._editors.original, viewZones.map(v => v.origViewZones), v => this._isUpdatingViewZones = v)); this._register(applyViewZones(this._editors.modified, viewZones.map(v => v.modViewZones), v => this._isUpdatingViewZones = v)); - this._register(autorunWithStore2('update folded unchanged regions', (reader, store) => { + this._register(autorun((reader) => { + /** @description update folded unchanged regions */ const curUnchangedRegions = unchangedRegions.read(reader); this._editors.original.setHiddenAreas(curUnchangedRegions.map(r => r.getHiddenOriginalRange(reader).toInclusiveRange()).filter(isDefined)); this._editors.modified.setHiddenAreas(curUnchangedRegions.map(r => r.getHiddenModifiedRange(reader).toInclusiveRange()).filter(isDefined)); @@ -175,16 +195,67 @@ export class UnchangedRangesFeature extends Disposable { } } +class DisposableCancellationTokenSource extends CancellationTokenSource { + public override dispose() { + super.dispose(true); + } +} + +class OutlineSource extends Disposable { + private readonly _currentModel = observableValue('current model', undefined); + + constructor( + @ILanguageFeaturesService private readonly _languageFeaturesService: ILanguageFeaturesService, + private readonly _textModel: ITextModel, + ) { + super(); + + const documentSymbolProviderChanged = observableSignalFromEvent( + 'documentSymbolProvider.onDidChange', + this._languageFeaturesService.documentSymbolProvider.onDidChange + ); + + const textModelChanged = observableSignalFromEvent( + '_textModel.onDidChangeContent', + Event.debounce(e => this._textModel.onDidChangeContent(e), () => undefined, 100) + ); + + this._register(autorunWithStore(async (reader, store) => { + documentSymbolProviderChanged.read(reader); + textModelChanged.read(reader); + + const src = store.add(new DisposableCancellationTokenSource()); + const model = await OutlineModel.create( + this._languageFeaturesService.documentSymbolProvider, + this._textModel, + src.token, + ); + if (store.isDisposed) { return; } + + this._currentModel.set(model, undefined); + })); + } + + public getBreadcrumbItems(startRange: LineRange, reader: IReader): { name: string; kind: SymbolKind }[] { + const m = this._currentModel.read(reader); + if (!m) { return []; } + const symbols = m.asListOfDocumentSymbols() + .filter(s => startRange.contains(s.range.startLineNumber) && !startRange.contains(s.range.endLineNumber)); + symbols.sort(reverseOrder(compareBy(s => s.range.endLineNumber - s.range.startLineNumber, numberComparator))); + return symbols.map(s => ({ name: s.name, kind: s.kind })); + } +} + class CollapsedCodeOverlayWidget extends ViewZoneOverlayWidget { private readonly _nodes = h('div.diff-hidden-lines', [ - h('div.top@top', { title: 'Click or drag to show more above' }), + h('div.top@top', { title: localize('diff.hiddenLines.top', 'Click or drag to show more above') }), h('div.center@content', { style: { display: 'flex' } }, [ h('div@first', { style: { display: 'flex', justifyContent: 'center', alignItems: 'center' } }, - [$('a', { title: 'Show all', role: 'button', onclick: () => { this._unchangedRegion.showAll(undefined); } }, ...renderLabelWithIcons('$(unfold)'))] + [$('a', { title: localize('showAll', 'Show all'), role: 'button', onclick: () => { this._unchangedRegion.showAll(undefined); } }, ...renderLabelWithIcons('$(unfold)'))] ), h('div@others', { style: { display: 'flex', justifyContent: 'center', alignItems: 'center' } }), ]), - h('div.bottom@bottom', { title: 'Click or drag to show more below', role: 'button' }), + h('div.bottom@bottom', { title: localize('diff.bottom', 'Click or drag to show more below'), role: 'button' }), ]); constructor( @@ -192,6 +263,7 @@ class CollapsedCodeOverlayWidget extends ViewZoneOverlayWidget { _viewZone: PlaceholderViewZone, private readonly _unchangedRegion: UnchangedRegion, private readonly hide: boolean, + private readonly _modifiedOutlineSource: OutlineSource, ) { const root = h('div.diff-hidden-lines-widget'); super(_editor, _viewZone, root.root); @@ -284,28 +356,35 @@ class CollapsedCodeOverlayWidget extends ViewZoneOverlayWidget { }); })); - this._register(autorun('update labels', (reader) => { + this._register(autorun(reader => { + /** @description update labels */ const children: HTMLElement[] = []; if (!this.hide && true) { const lineCount = _unchangedRegion.getHiddenModifiedRange(reader).length; - const linesHiddenText = `${lineCount} Hidden Lines`; + const linesHiddenText = localize('hiddenLines', '{0} Hidden Lines', lineCount); children.push($('span', { title: linesHiddenText }, linesHiddenText)); } - // TODO@hediet implement breadcrumbs for collapsed regions - /* - if (_unchangedRegion.originalLineNumber === 48) { - children.push($('span', undefined, '\u00a0|\u00a0')); - children.push($('span', { title: 'test' }, ...renderLabelWithIcons('$(symbol-class) DiffEditorWidget2'))); - } else if (_unchangedRegion.originalLineNumber === 88) { + const range = this._unchangedRegion.getHiddenModifiedRange(reader); + const items = this._modifiedOutlineSource.getBreadcrumbItems(range, reader); + + if (items.length > 0) { children.push($('span', undefined, '\u00a0|\u00a0')); - children.push($('span', { title: 'test' }, ...renderLabelWithIcons('$(symbol-constructor) constructor'))); + + let isFirst = true; + for (const item of items) { + if (!isFirst) { + children.push($('span', {}, ' ', renderIcon(Codicon.chevronRight), ' ')); + } + + const icon = SymbolKinds.toIcon(item.kind); + children.push($('span', {}, renderIcon(icon), ' ', item.name)); + isFirst = false; + } } - */ reset(this._nodes.others, ...children); - })); } } diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/utils.ts b/src/vs/editor/browser/widget/diffEditorWidget2/utils.ts index 7d497d5562893..8460b24326eb5 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/utils.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/utils.ts @@ -5,7 +5,7 @@ import { IDimension } from 'vs/base/browser/dom'; import { Disposable, DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; -import { IObservable, IReader, ISettableObservable, autorun, autorunHandleChanges, observableFromEvent, observableSignalFromEvent, observableValue, transaction } from 'vs/base/common/observable'; +import { IObservable, IReader, ISettableObservable, autorun, autorunHandleChanges, autorunOpts, observableFromEvent, observableSignalFromEvent, observableValue, transaction } from 'vs/base/common/observable'; import { ElementSizeObserver } from 'vs/editor/browser/config/elementSizeObserver'; import { ICodeEditor, IOverlayWidget, IViewZone } from 'vs/editor/browser/editorBrowser'; import { IModelDeltaDecoration } from 'vs/editor/common/model'; @@ -55,7 +55,7 @@ export function joinCombine(arr1: readonly T[], arr2: readonly T[], keySelect export function applyObservableDecorations(editor: ICodeEditor, decorations: IObservable): IDisposable { const d = new DisposableStore(); const decorationsCollection = editor.createDecorationsCollection(); - d.add(autorun(`Apply decorations from ${decorations.debugName}`, reader => { + d.add(autorunOpts({ debugName: `Apply decorations from ${decorations.debugName}` }, reader => { const d = decorations.read(reader); decorationsCollection.set(d); })); @@ -102,6 +102,7 @@ export class ObservableElementSizeObserver extends Disposable { this._height = observableValue('height', this.elementSizeObserver.getHeight()); this._register(this.elementSizeObserver.onDidChange(e => transaction(tx => { + /** @description Set width/height from elementSizeObserver */ this._width.set(this.elementSizeObserver.getWidth(), tx); this._height.set(this.elementSizeObserver.getHeight(), tx); }))); @@ -130,7 +131,7 @@ export function animatedObservable(base: IObservable, store: Di const durationMs = 300; let animationFrame: number | undefined = undefined; - store.add(autorunHandleChanges('update value', { + store.add(autorunHandleChanges({ createEmptyChangeSummary: () => ({ animate: false }), handleChange: (ctx, s) => { if (ctx.didChange(base)) { @@ -139,6 +140,7 @@ export function animatedObservable(base: IObservable, store: Di return true; } }, (reader, s) => { + /** @description update value */ if (animationFrame !== undefined) { cancelAnimationFrame(animationFrame); animationFrame = undefined; @@ -266,10 +268,13 @@ export interface CSSStyle { top: number | string; visibility: 'visible' | 'hidden' | 'collapse'; display: 'block' | 'inline' | 'inline-block' | 'flex' | 'none'; + paddingLeft: number | string; + paddingRight: number | string; } export function applyStyle(domNode: HTMLElement, style: Partial<{ [TKey in keyof CSSStyle]: CSSStyle[TKey] | IObservable | undefined }>) { - return autorun('applyStyle', (reader) => { + return autorun(reader => { + /** @description applyStyle */ for (let [key, val] of Object.entries(style)) { if (val && typeof val === 'object' && 'read' in val) { val = val.read(reader) as any; @@ -277,6 +282,7 @@ export function applyStyle(domNode: HTMLElement, style: Partial<{ [TKey in keyof if (typeof val === 'number') { val = `${val}px`; } + key = key.replace(/[A-Z]/g, m => '-' + m.toLowerCase()); domNode.style[key as any] = val as any; } }); @@ -316,7 +322,8 @@ export function applyViewZones(editor: ICodeEditor, viewZones: IObservable { + store.add(autorun(reader => { + /** @description applyViewZones */ const curViewZones = viewZones.read(reader); const viewZonIdsPerViewZone = new Map(); @@ -335,7 +342,7 @@ export function applyViewZones(editor: ICodeEditor, viewZones: IObservable { + /** @description layoutZone on change */ for (const vz of curViewZones) { if (vz.onChange) { viewZoneIdPerOnChangeObservable.set(vz.onChange, viewZonIdsPerViewZone.get(vz)!); diff --git a/src/vs/editor/browser/widget/diffNavigator.ts b/src/vs/editor/browser/widget/diffNavigator.ts index 0b221d7c7a406..1edce99edf63c 100644 --- a/src/vs/editor/browser/widget/diffNavigator.ts +++ b/src/vs/editor/browser/widget/diffNavigator.ts @@ -10,7 +10,7 @@ import * as objects from 'vs/base/common/objects'; import { IDiffEditor } from 'vs/editor/browser/editorBrowser'; import { ICursorPositionChangedEvent } from 'vs/editor/common/cursorEvents'; import { Range } from 'vs/editor/common/core/range'; -import { ILineChange } from 'vs/editor/common/diff/smartLinesDiffComputer'; +import { ILineChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; import { ScrollType } from 'vs/editor/common/editorCommon'; import { AudioCue, IAudioCueService } from 'vs/platform/audioCues/browser/audioCueService'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; @@ -224,11 +224,11 @@ export class DiffNavigator extends Disposable implements IDiffNavigator { } const insertedOrModified = modifiedEditor.getLineDecorations(lineNumber).find(l => l.options.className === 'line-insert'); if (insertedOrModified) { - this._audioCueService.playAudioCue(AudioCue.diffLineModified, true); + this._audioCueService.playAudioCue(AudioCue.diffLineModified, { allowManyInParallel: true }); } else if (jumpToChange) { // The modified editor does not include deleted lines, but when // we are moved to the area where lines were deleted, play this cue - this._audioCueService.playAudioCue(AudioCue.diffLineDeleted, true); + this._audioCueService.playAudioCue(AudioCue.diffLineDeleted, { allowManyInParallel: true }); } else { return; } diff --git a/src/vs/editor/browser/widget/diffReview.ts b/src/vs/editor/browser/widget/diffReview.ts index 66ec0c678e128..268d41d2f3b11 100644 --- a/src/vs/editor/browser/widget/diffReview.ts +++ b/src/vs/editor/browser/widget/diffReview.ts @@ -19,7 +19,7 @@ import { applyFontInfo } from 'vs/editor/browser/config/domFontInfo'; import { DiffEditorWidget } from 'vs/editor/browser/widget/diffEditorWidget'; import { EditorFontLigatures, EditorOption, IComputedEditorOptions } from 'vs/editor/common/config/editorOptions'; import { Position } from 'vs/editor/common/core/position'; -import { ILineChange } from 'vs/editor/common/diff/smartLinesDiffComputer'; +import { ILineChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; import { ScrollType } from 'vs/editor/common/editorCommon'; import { ILanguageIdCodec } from 'vs/editor/common/languages'; import { ILanguageService } from 'vs/editor/common/languages/language'; @@ -325,9 +325,9 @@ export class DiffReview extends Disposable { } const element = !type ? current : type === 'next' ? current?.nextElementSibling : current?.previousElementSibling; if (element?.classList.contains(DiffEditorLineClasses.Insert)) { - this._audioCueService.playAudioCue(AudioCue.diffLineInserted, true); + this._audioCueService.playAudioCue(AudioCue.diffLineInserted, { allowManyInParallel: true }); } else if (element?.classList.contains(DiffEditorLineClasses.Delete)) { - this._audioCueService.playAudioCue(AudioCue.diffLineDeleted, true); + this._audioCueService.playAudioCue(AudioCue.diffLineDeleted, { allowManyInParallel: true }); } this.scrollbar.scanDomNode(); } diff --git a/src/vs/editor/browser/widget/embeddedCodeEditorWidget.ts b/src/vs/editor/browser/widget/embeddedCodeEditorWidget.ts index 553470a8494bc..dc5dd6c299cce 100644 --- a/src/vs/editor/browser/widget/embeddedCodeEditorWidget.ts +++ b/src/vs/editor/browser/widget/embeddedCodeEditorWidget.ts @@ -20,6 +20,8 @@ import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService import { IEditorProgressService } from 'vs/platform/progress/common/progress'; import { ILanguageConfigurationService } from 'vs/editor/common/languages/languageConfigurationRegistry'; import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; +import { DiffEditorWidget2 } from 'vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2'; +import { IAudioCueService } from 'vs/platform/audioCues/browser/audioCueService'; export class EmbeddedCodeEditorWidget extends CodeEditorWidget { @@ -67,6 +69,9 @@ export class EmbeddedCodeEditorWidget extends CodeEditorWidget { } } +/** + * @deprecated Use EmbeddedDiffEditorWidget2 instead. + */ export class EmbeddedDiffEditorWidget extends DiffEditorWidget { private readonly _parentEditor: ICodeEditor; @@ -111,3 +116,47 @@ export class EmbeddedDiffEditorWidget extends DiffEditorWidget { super.updateOptions(this._overwriteOptions); } } + +/** + * TODO: Rename to EmbeddedDiffEditorWidget once EmbeddedDiffEditorWidget is removed. + */ +export class EmbeddedDiffEditorWidget2 extends DiffEditorWidget2 { + + private readonly _parentEditor: ICodeEditor; + private readonly _overwriteOptions: IDiffEditorOptions; + + constructor( + domElement: HTMLElement, + options: Readonly, + codeEditorWidgetOptions: IDiffCodeEditorWidgetOptions, + parentEditor: ICodeEditor, + @IContextKeyService contextKeyService: IContextKeyService, + @IInstantiationService instantiationService: IInstantiationService, + @ICodeEditorService codeEditorService: ICodeEditorService, + @IAudioCueService audioCueService: IAudioCueService, + ) { + super(domElement, parentEditor.getRawOptions(), codeEditorWidgetOptions, contextKeyService, instantiationService, codeEditorService, audioCueService); + + this._parentEditor = parentEditor; + this._overwriteOptions = options; + + // Overwrite parent's options + super.updateOptions(this._overwriteOptions); + + this._register(parentEditor.onDidChangeConfiguration(e => this._onParentConfigurationChanged(e))); + } + + getParentEditor(): ICodeEditor { + return this._parentEditor; + } + + private _onParentConfigurationChanged(e: ConfigurationChangedEvent): void { + super.updateOptions(this._parentEditor.getRawOptions()); + super.updateOptions(this._overwriteOptions); + } + + override updateOptions(newOptions: IEditorOptions): void { + objects.mixin(this._overwriteOptions, newOptions, true); + super.updateOptions(this._overwriteOptions); + } +} diff --git a/src/vs/editor/browser/widget/media/diffEditor.css b/src/vs/editor/browser/widget/media/diffEditor.css index 66fa2b5ab83a1..6d086fe1031c0 100644 --- a/src/vs/editor/browser/widget/media/diffEditor.css +++ b/src/vs/editor/browser/widget/media/diffEditor.css @@ -81,7 +81,7 @@ } .monaco-editor .line-insert, .monaco-diff-editor .line-insert { - background-color: var(--vscode-diffEditor-insertedLineBackground, --vscode-diffEditor-insertedTextBackground); + background-color: var(--vscode-diffEditor-insertedLineBackground, var(--vscode-diffEditor-insertedTextBackground)); } .monaco-editor .line-insert, @@ -106,7 +106,7 @@ .monaco-editor .inline-added-margin-view-zone, .monaco-editor .gutter-insert, .monaco-diff-editor .gutter-insert { - background-color: var(--vscode-diffEditorGutter-insertedLineBackground, --vscode-diffEditor-insertedLineBackground, --vscode-diffEditor-insertedTextBackground); + background-color: var(--vscode-diffEditorGutter-insertedLineBackground, var(--vscode-diffEditor-insertedLineBackground), var(--vscode-diffEditor-insertedTextBackground)); } .monaco-editor .char-delete, .monaco-diff-editor .char-delete { @@ -114,12 +114,12 @@ } .monaco-editor .line-delete, .monaco-diff-editor .line-delete { - background-color: var(--vscode-diffEditor-removedLineBackground, --vscode-diffEditor-removedTextBackground); + background-color: var(--vscode-diffEditor-removedLineBackground, var(--vscode-diffEditor-removedTextBackground)); } .monaco-editor .inline-deleted-margin-view-zone, .monaco-editor .gutter-delete, .monaco-diff-editor .gutter-delete { - background-color: var(--vscode-diffEditorGutter-removedLineBackground, --vscode-diffEditor-removedLineBackground, --vscode-diffEditor-removedTextBackground); + background-color: var(--vscode-diffEditorGutter-removedLineBackground, var(--vscode-diffEditor-removedLineBackground), var(--vscode-diffEditor-removedTextBackground)); } .monaco-diff-editor.side-by-side .editor.modified { diff --git a/src/vs/editor/browser/widget/workerBasedDocumentDiffProvider.ts b/src/vs/editor/browser/widget/workerBasedDocumentDiffProvider.ts index 8994275abc16a..648ba44763c21 100644 --- a/src/vs/editor/browser/widget/workerBasedDocumentDiffProvider.ts +++ b/src/vs/editor/browser/widget/workerBasedDocumentDiffProvider.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { CancellationToken } from 'vs/base/common/cancellation'; import { Emitter, Event } from 'vs/base/common/event'; import { IDisposable } from 'vs/base/common/lifecycle'; import { StopWatch } from 'vs/base/common/stopwatch'; @@ -34,13 +35,22 @@ export class WorkerBasedDocumentDiffProvider implements IDocumentDiffProvider, I this.diffAlgorithmOnDidChangeSubscription?.dispose(); } - async computeDiff(original: ITextModel, modified: ITextModel, options: IDocumentDiffProviderOptions): Promise { + async computeDiff(original: ITextModel, modified: ITextModel, options: IDocumentDiffProviderOptions, cancellationToken: CancellationToken): Promise { if (typeof this.diffAlgorithm !== 'string') { - return this.diffAlgorithm.computeDiff(original, modified, options); + return this.diffAlgorithm.computeDiff(original, modified, options, cancellationToken); } // This significantly speeds up the case when the original file is empty if (original.getLineCount() === 1 && original.getLineMaxColumn(1) === 1) { + if (modified.getLineCount() === 1 && modified.getLineMaxColumn(1) === 1) { + return { + changes: [], + identical: true, + quitEarly: false, + moves: [], + }; + } + return { changes: [ new LineRangeMapping( @@ -86,6 +96,16 @@ export class WorkerBasedDocumentDiffProvider implements IDocumentDiffProvider, I timedOut: result?.quitEarly ?? true, }); + if (cancellationToken.isCancellationRequested) { + // Text models might be disposed! + return { + changes: [], + identical: false, + quitEarly: true, + moves: [], + }; + } + if (!result) { throw new Error('no diff result available'); } diff --git a/src/vs/editor/common/config/editorConfigurationSchema.ts b/src/vs/editor/common/config/editorConfigurationSchema.ts index 70dd0b515dbd5..b605d1dadf32b 100644 --- a/src/vs/editor/common/config/editorConfigurationSchema.ts +++ b/src/vs/editor/common/config/editorConfigurationSchema.ts @@ -110,6 +110,7 @@ const editorConfiguration: IConfigurationNode = { type: 'boolean', default: false, description: nls.localize('editor.experimental.asyncTokenizationVerification', "Controls whether async tokenization should be verified against legacy background tokenization. Might slow down tokenization. For debugging only."), + tags: ['experimental'], }, 'editor.language.brackets': { type: ['array', 'null'], @@ -162,6 +163,16 @@ const editorConfiguration: IConfigurationNode = { default: true, description: nls.localize('sideBySide', "Controls whether the diff editor shows the diff side by side or inline.") }, + 'diffEditor.renderSideBySideInlineBreakpoint': { + type: 'number', + default: true, + description: nls.localize('renderSideBySideInlineBreakpoint', "If the diff editor width is smaller than this value, the inline view is used.") + }, + 'diffEditor.useInlineViewWhenSpaceIsLimited': { + type: 'boolean', + default: true, + description: nls.localize('useInlineViewWhenSpaceIsLimited', "If enabled and the editor width is too small, the inline view is used.") + }, 'diffEditor.renderMarginRevertIcon': { type: 'boolean', default: true, @@ -195,7 +206,7 @@ const editorConfiguration: IConfigurationNode = { 'diffEditor.diffAlgorithm': { type: 'string', enum: ['legacy', 'advanced'], - default: 'legacy', + default: 'advanced', markdownEnumDescriptions: [ nls.localize('diffAlgorithm.legacy', "Uses the legacy diffing algorithm."), nls.localize('diffAlgorithm.advanced', "Uses the advanced diffing algorithm."), @@ -216,6 +227,7 @@ const editorConfiguration: IConfigurationNode = { type: 'boolean', default: false, description: nls.localize('useVersion2', "Controls whether the diff editor uses the new or the old implementation."), + tags: ['experimental'], }, 'diffEditor.experimental.showEmptyDecorations': { type: 'boolean', diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index 96dbb05c27523..eee7baf03c6f1 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -730,6 +730,11 @@ export interface IEditorOptions { * Controls whether the editor receives tabs or defers them to the workbench for navigation. */ tabFocusMode?: boolean; + + /** + * Controls whether the accessibility hint should be provided to screen reader users when an inline completion is shown. + */ + inlineCompletionsAccessibilityVerbose?: boolean; } /** @@ -755,6 +760,16 @@ export interface IDiffEditorBaseOptions { * Defaults to true. */ renderSideBySide?: boolean; + /** + * When `renderSideBySide` is enabled, `useInlineViewWhenSpaceIsLimited` is set, + * and the diff editor has a width less than `renderSideBySideInlineBreakpoint`, the inline view is used. + */ + renderSideBySideInlineBreakpoint?: number | undefined; + /** + * When `renderSideBySide` is enabled, `useInlineViewWhenSpaceIsLimited` is set, + * and the diff editor has a width less than `renderSideBySideInlineBreakpoint`, the inline view is used. + */ + useInlineViewWhenSpaceIsLimited?: boolean; /** * Timeout in milliseconds after which diff computation is cancelled. * Defaults to 5000. @@ -827,6 +842,11 @@ export interface IDiffEditorBaseOptions { * Defaults to false */ isInEmbeddedEditor?: boolean; + + /** + * If the diff editor should only show the difference review mode. + */ + onlyShowAccessibleDiffViewer?: boolean; } /** @@ -2737,6 +2757,10 @@ export interface IEditorStickyScrollOptions { * Model to choose for sticky scroll by default */ defaultModel?: 'outlineModel' | 'foldingProviderModel' | 'indentationModel'; + /** + * Define whether to scroll sticky scroll with editor horizontal scrollbae + */ + scrollWithEditor?: boolean; } /** @@ -2747,7 +2771,7 @@ export type EditorStickyScrollOptions = Readonly { constructor() { - const defaults: EditorStickyScrollOptions = { enabled: false, maxLineCount: 5, defaultModel: 'outlineModel' }; + const defaults: EditorStickyScrollOptions = { enabled: false, maxLineCount: 5, defaultModel: 'outlineModel', scrollWithEditor: true }; super( EditorOption.stickyScroll, 'stickyScroll', defaults, { @@ -2769,6 +2793,11 @@ class EditorStickyScroll extends BaseEditorOption(input.defaultModel, this.defaultValue.defaultModel, ['outlineModel', 'foldingProviderModel', 'indentationModel']), + scrollWithEditor: boolean(input.scrollWithEditor, this.defaultValue.scrollWithEditor) }; } } @@ -5118,7 +5148,8 @@ export const enum EditorOption { layoutInfo, wrappingInfo, defaultColorDecorators, - colorDecoratorsActivatedOn + colorDecoratorsActivatedOn, + inlineCompletionsAccessibilityVerbose } export const EditorOptions = { @@ -5709,6 +5740,8 @@ export const EditorOptions = { )), suggest: register(new EditorSuggest()), inlineSuggest: register(new InlineEditorSuggest()), + inlineCompletionsAccessibilityVerbose: register(new EditorBooleanOption(EditorOption.inlineCompletionsAccessibilityVerbose, 'inlineCompletionsAccessibilityVerbose', false, + { description: nls.localize('inlineCompletionsAccessibilityVerbose', "Controls whether the accessibility hint should be provided to screen reader users when an inline completion is shown.") })), suggestFontSize: register(new EditorIntOption( EditorOption.suggestFontSize, 'suggestFontSize', 0, 0, 1000, diff --git a/src/vs/editor/common/core/lineRange.ts b/src/vs/editor/common/core/lineRange.ts index d39b5e1901ea1..70acb0476d67b 100644 --- a/src/vs/editor/common/core/lineRange.ts +++ b/src/vs/editor/common/core/lineRange.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { BugIndicatingError } from 'vs/base/common/errors'; +import { OffsetRange } from 'vs/editor/common/core/offsetRange'; import { Range } from 'vs/editor/common/core/range'; /** @@ -154,6 +155,10 @@ export class LineRange { return new LineRange(this.startLineNumber + offset, this.endLineNumberExclusive + offset); } + public deltaLength(offset: number): LineRange { + return new LineRange(this.startLineNumber, this.endLineNumberExclusive + offset); + } + /** * The number of lines this line range spans. */ @@ -219,6 +224,12 @@ export class LineRange { return result; } + public forEach(f: (lineNumber: number) => void): void { + for (let lineNumber = this.startLineNumber; lineNumber < this.endLineNumberExclusive; lineNumber++) { + f(lineNumber); + } + } + /** * @internal */ @@ -229,6 +240,14 @@ export class LineRange { public includes(lineNumber: number): boolean { return this.startLineNumber <= lineNumber && lineNumber < this.endLineNumberExclusive; } + + /** + * Converts this 1-based line range to a 0-based offset range (subtracts 1!). + * @internal + */ + public toOffsetRange(): OffsetRange { + return new OffsetRange(this.startLineNumber - 1, this.endLineNumberExclusive - 1); + } } export type ISerializedLineRange = [startLineNumber: number, endLineNumberExclusive: number]; diff --git a/src/vs/editor/common/core/offsetRange.ts b/src/vs/editor/common/core/offsetRange.ts index 14ff2039fc752..27e60bca2df63 100644 --- a/src/vs/editor/common/core/offsetRange.ts +++ b/src/vs/editor/common/core/offsetRange.ts @@ -34,6 +34,10 @@ export class OffsetRange { return new OffsetRange(start, endExclusive); } + public static ofLength(length: number): OffsetRange { + return new OffsetRange(0, length); + } + constructor(public readonly start: number, public readonly endExclusive: number) { if (start > endExclusive) { throw new BugIndicatingError(`Invalid range: ${this.toString()}`); @@ -48,6 +52,14 @@ export class OffsetRange { return new OffsetRange(this.start + offset, this.endExclusive + offset); } + public deltaStart(offset: number): OffsetRange { + return new OffsetRange(this.start + offset, this.endExclusive); + } + + public deltaEnd(offset: number): OffsetRange { + return new OffsetRange(this.start, this.endExclusive + offset); + } + public get length(): number { return this.endExclusive - this.start; } @@ -90,4 +102,96 @@ export class OffsetRange { } return undefined; } + + public slice(arr: T[]): T[] { + return arr.slice(this.start, this.endExclusive); + } + + /** + * Returns the given value if it is contained in this instance, otherwise the closest value that is contained. + * The range must not be empty. + */ + public clip(value: number): number { + if (this.isEmpty) { + throw new BugIndicatingError(`Invalid clipping range: ${this.toString()}`); + } + return Math.max(this.start, Math.min(this.endExclusive - 1, value)); + } + + /** + * Returns `r := value + k * length` such that `r` is contained in this range. + * The range must not be empty. + * + * E.g. `[5, 10).clipCyclic(10) === 5`, `[5, 10).clipCyclic(11) === 6` and `[5, 10).clipCyclic(4) === 9`. + */ + public clipCyclic(value: number): number { + if (this.isEmpty) { + throw new BugIndicatingError(`Invalid clipping range: ${this.toString()}`); + } + if (value < this.start) { + return this.endExclusive - ((this.start - value) % this.length); + } + if (value >= this.endExclusive) { + return this.start + ((value - this.start) % this.length); + } + return value; + } +} + +export class OffsetRangeSet { + private readonly _sortedRanges: OffsetRange[] = []; + + public addRange(range: OffsetRange): void { + let i = 0; + while (i < this._sortedRanges.length && this._sortedRanges[i].endExclusive < range.start) { + i++; + } + let j = i; + while (j < this._sortedRanges.length && this._sortedRanges[j].start <= range.endExclusive) { + j++; + } + if (i === j) { + this._sortedRanges.splice(i, 0, range); + } else { + const start = Math.min(range.start, this._sortedRanges[i].start); + const end = Math.max(range.endExclusive, this._sortedRanges[j - 1].endExclusive); + this._sortedRanges.splice(i, j - i, new OffsetRange(start, end)); + } + } + + public toString(): string { + return this._sortedRanges.map(r => r.toString()).join(', '); + } + + /** + * Returns of there is a value that is contained in this instance and the given range. + */ + public intersectsStrict(other: OffsetRange): boolean { + // TODO use binary search + let i = 0; + while (i < this._sortedRanges.length && this._sortedRanges[i].endExclusive <= other.start) { + i++; + } + return i < this._sortedRanges.length && this._sortedRanges[i].start < other.endExclusive; + } + + public intersectWithRange(other: OffsetRange): OffsetRangeSet { + // TODO use binary search + slice + const result = new OffsetRangeSet(); + for (const range of this._sortedRanges) { + const intersection = range.intersect(other); + if (intersection) { + result.addRange(intersection); + } + } + return result; + } + + public intersectWithRangeLength(other: OffsetRange): number { + return this.intersectWithRange(other).length; + } + + public get length(): number { + return this._sortedRanges.reduce((prev, cur) => prev + cur.length, 0); + } } diff --git a/src/vs/editor/common/diff/standardLinesDiffComputer.ts b/src/vs/editor/common/diff/advancedLinesDiffComputer.ts similarity index 58% rename from src/vs/editor/common/diff/standardLinesDiffComputer.ts rename to src/vs/editor/common/diff/advancedLinesDiffComputer.ts index 51f62509b024d..a7d9605d78c14 100644 --- a/src/vs/editor/common/diff/standardLinesDiffComputer.ts +++ b/src/vs/editor/common/diff/advancedLinesDiffComputer.ts @@ -3,40 +3,42 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { compareBy, equals, findLastIndex, numberComparator, reverseOrder } from 'vs/base/common/arrays'; import { assertFn, checkAdjacentItems } from 'vs/base/common/assert'; import { CharCode } from 'vs/base/common/charCode'; +import { SetMap } from 'vs/base/common/collections'; import { LineRange } from 'vs/editor/common/core/lineRange'; import { OffsetRange } from 'vs/editor/common/core/offsetRange'; import { Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; import { DateTimeout, ISequence, ITimeout, InfiniteTimeout, SequenceDiff } from 'vs/editor/common/diff/algorithms/diffAlgorithm'; import { DynamicProgrammingDiffing } from 'vs/editor/common/diff/algorithms/dynamicProgrammingDiffing'; -import { optimizeSequenceDiffs, smoothenSequenceDiffs } from 'vs/editor/common/diff/algorithms/joinSequenceDiffs'; +import { optimizeSequenceDiffs, removeRandomLineMatches, removeRandomMatches, smoothenSequenceDiffs } from 'vs/editor/common/diff/algorithms/joinSequenceDiffs'; import { MyersDiffAlgorithm } from 'vs/editor/common/diff/algorithms/myersDiffAlgorithm'; import { ILinesDiffComputer, ILinesDiffComputerOptions, LineRangeMapping, LinesDiff, MovedText, RangeMapping, SimpleLineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; -export class StandardLinesDiffComputer implements ILinesDiffComputer { +export class AdvancedLinesDiffComputer implements ILinesDiffComputer { private readonly dynamicProgrammingDiffing = new DynamicProgrammingDiffing(); private readonly myersDiffingAlgorithm = new MyersDiffAlgorithm(); computeDiff(originalLines: string[], modifiedLines: string[], options: ILinesDiffComputerOptions): LinesDiff { + if (originalLines.length <= 1 && equals(originalLines, modifiedLines, (a, b) => a === b)) { + return new LinesDiff([], [], false); + } + if (originalLines.length === 1 && originalLines[0].length === 0 || modifiedLines.length === 1 && modifiedLines[0].length === 0) { - return { - changes: [ - new LineRangeMapping( - new LineRange(1, originalLines.length + 1), - new LineRange(1, modifiedLines.length + 1), - [ - new RangeMapping( - new Range(1, 1, originalLines.length, originalLines[0].length + 1), - new Range(1, 1, modifiedLines.length, modifiedLines[0].length + 1) - ) - ] - ) - ], - hitTimeout: false, - moves: [], - }; + return new LinesDiff([ + new LineRangeMapping( + new LineRange(1, originalLines.length + 1), + new LineRange(1, modifiedLines.length + 1), + [ + new RangeMapping( + new Range(1, 1, originalLines.length, originalLines[0].length + 1), + new Range(1, 1, modifiedLines.length, modifiedLines[0].length + 1) + ) + ] + ) + ], [], false); } const timeout = options.maxComputationTimeMs === 0 ? InfiniteTimeout.instance : new DateTimeout(options.maxComputationTimeMs); @@ -59,7 +61,7 @@ export class StandardLinesDiffComputer implements ILinesDiffComputer { const sequence2 = new LineSequence(tgtDocLines, modifiedLines); const lineAlignmentResult = (() => { - if (sequence1.length + sequence2.length < 1500) { + if (sequence1.length + sequence2.length < 1700) { // Use the improved algorithm for small files return this.dynamicProgrammingDiffing.compute( sequence1, @@ -83,6 +85,7 @@ export class StandardLinesDiffComputer implements ILinesDiffComputer { let lineAlignments = lineAlignmentResult.diffs; let hitTimeout = lineAlignmentResult.hitTimeout; lineAlignments = optimizeSequenceDiffs(sequence1, sequence2, lineAlignments); + lineAlignments = removeRandomLineMatches(sequence1, sequence2, lineAlignments); const alignments: RangeMapping[] = []; @@ -136,45 +139,205 @@ export class StandardLinesDiffComputer implements ILinesDiffComputer { const changes = lineRangeMappingFromRangeMappings(alignments, originalLines, modifiedLines); - const moves: MovedText[] = []; + let moves: MovedText[] = []; if (options.computeMoves) { - const deletions = changes - .filter(c => c.modifiedRange.isEmpty && c.originalRange.length >= 3) - .map(d => new LineRangeFragment(d.originalRange, originalLines)); - const insertions = new Set(changes - .filter(c => c.originalRange.isEmpty && c.modifiedRange.length >= 3) - .map(d => new LineRangeFragment(d.modifiedRange, modifiedLines))); - - for (const deletion of deletions) { - let highestSimilarity = -1; - let best: LineRangeFragment | undefined; - for (const insertion of insertions) { - const similarity = deletion.computeSimilarity(insertion); - if (similarity > highestSimilarity) { - highestSimilarity = similarity; - best = insertion; - } + moves = this.computeMoves(changes, originalLines, modifiedLines, srcDocLines, tgtDocLines, timeout, considerWhitespaceChanges); + } + + // Make sure all ranges are valid + assertFn(() => { + function validatePosition(pos: Position, lines: string[]): boolean { + if (pos.lineNumber < 1 || pos.lineNumber > lines.length) { return false; } + const line = lines[pos.lineNumber - 1]; + if (pos.column < 1 || pos.column > line.length + 1) { return false; } + return true; + } + + function validateRange(range: LineRange, lines: string[]): boolean { + if (range.startLineNumber < 1 || range.startLineNumber > lines.length + 1) { return false; } + if (range.endLineNumberExclusive < 1 || range.endLineNumberExclusive > lines.length + 1) { return false; } + return true; + } + + for (const c of changes) { + if (!c.innerChanges) { return false; } + for (const ic of c.innerChanges) { + const valid = validatePosition(ic.modifiedRange.getStartPosition(), modifiedLines) && validatePosition(ic.modifiedRange.getEndPosition(), modifiedLines) && + validatePosition(ic.originalRange.getStartPosition(), originalLines) && validatePosition(ic.originalRange.getEndPosition(), originalLines); + if (!valid) { return false; } } + if (!validateRange(c.modifiedRange, modifiedLines) || !validateRange(c.originalRange, originalLines)) { + return false; + } + } + return true; + }); - if (highestSimilarity > 0.90 && best) { - const moveChanges = this.refineDiff(originalLines, modifiedLines, new SequenceDiff( - new OffsetRange(deletion.range.startLineNumber - 1, deletion.range.endLineNumberExclusive - 1), - new OffsetRange(best.range.startLineNumber - 1, best.range.endLineNumberExclusive - 1), - ), timeout, considerWhitespaceChanges); - const mappings = lineRangeMappingFromRangeMappings(moveChanges.mappings, originalLines, modifiedLines, true); + return new LinesDiff(changes, moves, hitTimeout); + } - insertions.delete(best); - moves.push(new MovedText(new SimpleLineRangeMapping(deletion.range, best.range), mappings)); + private computeMoves(changes: LineRangeMapping[], originalLines: string[], modifiedLines: string[], hashedOriginalLines: number[], hashedModifiedLines: number[], timeout: ITimeout, considerWhitespaceChanges: boolean): MovedText[] { + const moves: SimpleLineRangeMapping[] = []; + const deletions = changes + .filter(c => c.modifiedRange.isEmpty && c.originalRange.length >= 3) + .map(d => new LineRangeFragment(d.originalRange, originalLines, d)); + const insertions = new Set(changes + .filter(c => c.originalRange.isEmpty && c.modifiedRange.length >= 3) + .map(d => new LineRangeFragment(d.modifiedRange, modifiedLines, d))); + + const excludedChanges = new Set(); + + for (const deletion of deletions) { + let highestSimilarity = -1; + let best: LineRangeFragment | undefined; + for (const insertion of insertions) { + const similarity = deletion.computeSimilarity(insertion); + if (similarity > highestSimilarity) { + highestSimilarity = similarity; + best = insertion; } } + + if (highestSimilarity > 0.90 && best) { + insertions.delete(best); + moves.push(new SimpleLineRangeMapping(deletion.range, best.range)); + excludedChanges.add(deletion.source); + excludedChanges.add(best.source); + } + + if (!timeout.isValid()) { + return []; + } } - return new LinesDiff(changes, moves, hitTimeout); + const original3LineHashes = new SetMap(); + + for (const change of changes) { + if (excludedChanges.has(change)) { + continue; + } + + for (let i = change.originalRange.startLineNumber; i < change.originalRange.endLineNumberExclusive - 2; i++) { + const key = `${hashedOriginalLines[i - 1]}:${hashedOriginalLines[i + 1 - 1]}:${hashedOriginalLines[i + 2 - 1]}`; + original3LineHashes.add(key, { range: new LineRange(i, i + 3) }); + } + } + + interface PossibleMapping { + modifiedLineRange: LineRange; + originalLineRange: LineRange; + } + + const possibleMappings: PossibleMapping[] = []; + + changes.sort(compareBy(c => c.modifiedRange.startLineNumber, numberComparator)); + + for (const change of changes) { + if (excludedChanges.has(change)) { + continue; + } + + let lastMappings: PossibleMapping[] = []; + for (let i = change.modifiedRange.startLineNumber; i < change.modifiedRange.endLineNumberExclusive - 2; i++) { + const key = `${hashedModifiedLines[i - 1]}:${hashedModifiedLines[i + 1 - 1]}:${hashedModifiedLines[i + 2 - 1]}`; + const currentModifiedRange = new LineRange(i, i + 3); + + const nextMappings: PossibleMapping[] = []; + original3LineHashes.forEach(key, ({ range }) => { + for (const lastMapping of lastMappings) { + // does this match extend some last match? + if (lastMapping.originalLineRange.endLineNumberExclusive + 1 === range.endLineNumberExclusive && + lastMapping.modifiedLineRange.endLineNumberExclusive + 1 === currentModifiedRange.endLineNumberExclusive) { + lastMapping.originalLineRange = new LineRange(lastMapping.originalLineRange.startLineNumber, range.endLineNumberExclusive); + lastMapping.modifiedLineRange = new LineRange(lastMapping.modifiedLineRange.startLineNumber, currentModifiedRange.endLineNumberExclusive); + nextMappings.push(lastMapping); + return; + } + } + + const mapping: PossibleMapping = { + modifiedLineRange: currentModifiedRange, + originalLineRange: range, + }; + possibleMappings.push(mapping); + nextMappings.push(mapping); + }); + lastMappings = nextMappings; + } + + if (!timeout.isValid()) { + return []; + } + } + + possibleMappings.sort(reverseOrder(compareBy(m => m.modifiedLineRange.length, numberComparator))); + + const modifiedSet = new LineRangeSet(); + const originalSet = new LineRangeSet(); + + for (const mapping of possibleMappings) { + + const diffOrigToMod = mapping.modifiedLineRange.startLineNumber - mapping.originalLineRange.startLineNumber; + const modifiedSections = modifiedSet.subtractFrom(mapping.modifiedLineRange); + const originalTranslatedSections = originalSet.subtractFrom(mapping.originalLineRange).map(r => r.delta(diffOrigToMod)); + + const modifiedIntersectedSections = intersectRanges(modifiedSections, originalTranslatedSections); + + for (const s of modifiedIntersectedSections) { + if (s.length < 3) { + continue; + } + const modifiedLineRange = s; + const originalLineRange = s.delta(-diffOrigToMod); + + moves.push(new SimpleLineRangeMapping(originalLineRange, modifiedLineRange)); + + modifiedSet.addRange(modifiedLineRange); + originalSet.addRange(originalLineRange); + } + } + + // join moves + moves.sort(compareBy(m => m.original.startLineNumber, numberComparator)); + if (moves.length === 0) { + return []; + } + const joinedMoves = [moves[0]]; + for (let i = 1; i < moves.length; i++) { + const last = joinedMoves[joinedMoves.length - 1]; + const current = moves[i]; + + const originalDist = current.original.startLineNumber - last.original.endLineNumberExclusive; + const modifiedDist = current.modified.startLineNumber - last.modified.endLineNumberExclusive; + const currentMoveAfterLast = originalDist >= 0 && modifiedDist >= 0; + + if (currentMoveAfterLast && originalDist + modifiedDist <= 2) { + joinedMoves[joinedMoves.length - 1] = last.join(current); + continue; + } + + const originalText = current.original.toOffsetRange().slice(originalLines).map(l => l.trim()).join('\n'); + if (originalText.length <= 10) { + // Ignore small moves + continue; + } + joinedMoves.push(current); + } + + const fullMoves = joinedMoves.map(m => { + const moveChanges = this.refineDiff(originalLines, modifiedLines, new SequenceDiff( + m.original.toOffsetRange(), + m.modified.toOffsetRange(), + ), timeout, considerWhitespaceChanges); + const mappings = lineRangeMappingFromRangeMappings(moveChanges.mappings, originalLines, modifiedLines, true); + return new MovedText(m, mappings); + }); + return fullMoves; } private refineDiff(originalLines: string[], modifiedLines: string[], diff: SequenceDiff, timeout: ITimeout, considerWhitespaceChanges: boolean): { mappings: RangeMapping[]; hitTimeout: boolean } { - const slice1 = new Slice(originalLines, diff.seq1Range, considerWhitespaceChanges); - const slice2 = new Slice(modifiedLines, diff.seq2Range, considerWhitespaceChanges); + const slice1 = new LinesSliceCharSequence(originalLines, diff.seq1Range, considerWhitespaceChanges); + const slice2 = new LinesSliceCharSequence(modifiedLines, diff.seq2Range, considerWhitespaceChanges); const diffResult = slice1.length + slice2.length < 500 ? this.dynamicProgrammingDiffing.compute(slice1, slice2, timeout) @@ -184,6 +347,7 @@ export class StandardLinesDiffComputer implements ILinesDiffComputer { diffs = optimizeSequenceDiffs(slice1, slice2, diffs); diffs = coverFullWords(slice1, slice2, diffs); diffs = smoothenSequenceDiffs(slice1, slice2, diffs); + diffs = removeRandomMatches(slice1, slice2, diffs); const result = diffs.map( (d) => @@ -202,7 +366,101 @@ export class StandardLinesDiffComputer implements ILinesDiffComputer { } } -function coverFullWords(sequence1: Slice, sequence2: Slice, sequenceDiffs: SequenceDiff[]): SequenceDiff[] { +function intersectRanges(ranges1: LineRange[], ranges2: LineRange[]): LineRange[] { + const result: LineRange[] = []; + + let i1 = 0; + let i2 = 0; + while (i1 < ranges1.length && i2 < ranges2.length) { + const r1 = ranges1[i1]; + const r2 = ranges2[i2]; + + const i = r1.intersect(r2); + if (i && !i.isEmpty) { + result.push(i); + } + + if (r1.endLineNumberExclusive < r2.endLineNumberExclusive) { + i1++; + } else { + i2++; + } + } + + return result; +} + +// TODO make this fast +class LineRangeSet { + private readonly _normalizedRanges: LineRange[] = []; + + addRange(range: LineRange): void { + // Idea: Find joinRange such that: + // replaceRange = _normalizedRanges.replaceRange(joinRange, range.joinAll(joinRange.map(idx => this._normalizedRanges[idx]))) + + // idx of first element that touches range or that is after range + const joinRangeStartIdx = mapMinusOne(this._normalizedRanges.findIndex(r => r.endLineNumberExclusive >= range.startLineNumber), this._normalizedRanges.length); + // idx of element after { last element that touches range or that is before range } + const joinRangeEndIdxExclusive = findLastIndex(this._normalizedRanges, r => r.startLineNumber <= range.endLineNumberExclusive) + 1; + + if (joinRangeStartIdx === joinRangeEndIdxExclusive) { + // If there is no element that touches range, then joinRangeStartIdx === joinRangeEndIdxExclusive and that value is the index of the element after range + this._normalizedRanges.splice(joinRangeStartIdx, 0, range); + } else if (joinRangeStartIdx === joinRangeEndIdxExclusive - 1) { + // Else, there is an element that touches range and in this case it is both the first and last element. Thus we can replace it + const joinRange = this._normalizedRanges[joinRangeStartIdx]; + this._normalizedRanges[joinRangeStartIdx] = joinRange.join(range); + } else { + // First and last element are different - we need to replace the entire range + const joinRange = this._normalizedRanges[joinRangeStartIdx].join(this._normalizedRanges[joinRangeEndIdxExclusive - 1]).join(range); + this._normalizedRanges.splice(joinRangeStartIdx, joinRangeEndIdxExclusive - joinRangeStartIdx, joinRange); + } + } + + intersects(range: LineRange): boolean { + for (const r of this._normalizedRanges) { + if (r.intersectsStrict(range)) { + return true; + } + } + return false; + } + + /** + * Subtracts all ranges in this set from `range` and returns the result. + */ + subtractFrom(range: LineRange): LineRange[] { + // idx of first element that touches range or that is after range + const joinRangeStartIdx = mapMinusOne(this._normalizedRanges.findIndex(r => r.endLineNumberExclusive >= range.startLineNumber), this._normalizedRanges.length); + // idx of element after { last element that touches range or that is before range } + const joinRangeEndIdxExclusive = findLastIndex(this._normalizedRanges, r => r.startLineNumber <= range.endLineNumberExclusive) + 1; + + if (joinRangeStartIdx === joinRangeEndIdxExclusive) { + return [range]; + } + + const result: LineRange[] = []; + let startLineNumber = range.startLineNumber; + for (let i = joinRangeStartIdx; i < joinRangeEndIdxExclusive; i++) { + const r = this._normalizedRanges[i]; + if (r.startLineNumber > startLineNumber) { + result.push(new LineRange(startLineNumber, r.startLineNumber)); + } + startLineNumber = r.endLineNumberExclusive; + } + if (startLineNumber < range.endLineNumberExclusive) { + result.push(new LineRange(startLineNumber, range.endLineNumberExclusive)); + } + + return result; + } +} + +function mapMinusOne(idx: number, mapTo: number): number { + return idx === -1 ? mapTo : idx; +} + +function coverFullWords(sequence1: LinesSliceCharSequence, sequence2: LinesSliceCharSequence, sequenceDiffs: SequenceDiff[]): SequenceDiff[] { const additional: SequenceDiff[] = []; let lastModifiedWord: { added: number; deleted: number; count: number; s1Range: OffsetRange; s2Range: OffsetRange } | undefined = undefined; @@ -407,6 +665,14 @@ export class LineSequence implements ISequence { const indentationAfter = length === this.lines.length ? 0 : getIndentation(this.lines[length]); return 1000 - (indentationBefore + indentationAfter); } + + getText(range: OffsetRange): string { + return this.lines.slice(range.start, range.endExclusive).join('\n'); + } + + isStronglyEqual(offset1: number, offset2: number): boolean { + return this.lines[offset1] === this.lines[offset2]; + } } function getIndentation(str: string): number { @@ -417,12 +683,12 @@ function getIndentation(str: string): number { return i; } -class Slice implements ISequence { +export class LinesSliceCharSequence implements ISequence { private readonly elements: number[] = []; private readonly firstCharOffsetByLineMinusOne: number[] = []; public readonly lineRange: OffsetRange; // To account for trimming - private readonly offsetByLine: number[] = []; + private readonly additionalOffsetByLine: number[] = []; constructor(public readonly lines: string[], lineRange: OffsetRange, public readonly considerWhitespaceChanges: boolean) { // This slice has to have lineRange.length many \n! (otherwise diffing against an empty slice will be problematic) @@ -450,7 +716,7 @@ class Slice implements ISequence { line = trimmedStartLine.trimEnd(); } - this.offsetByLine.push(offset); + this.additionalOffsetByLine.push(offset); for (let i = 0; i < line.length; i++) { this.elements.push(line.charCodeAt(i)); @@ -463,7 +729,7 @@ class Slice implements ISequence { } } // To account for the last line - this.offsetByLine.push(0); + this.additionalOffsetByLine.push(0); } toString() { @@ -471,7 +737,11 @@ class Slice implements ISequence { } get text(): string { - return [...this.elements].map(e => String.fromCharCode(e)).join(''); + return this.getText(new OffsetRange(0, this.length)); + } + + getText(range: OffsetRange): string { + return this.elements.slice(range.start, range.endExclusive).map(e => String.fromCharCode(e)).join(''); } getElement(offset: number): number { @@ -526,7 +796,7 @@ class Slice implements ISequence { } const offsetOfFirstCharInLine = i === 0 ? 0 : this.firstCharOffsetByLineMinusOne[i - 1]; - return new Position(this.lineRange.start + i + 1, offset - offsetOfFirstCharInLine + 1 + this.offsetByLine[i]); + return new Position(this.lineRange.start + i + 1, offset - offsetOfFirstCharInLine + 1 + this.additionalOffsetByLine[i]); } public translateRange(range: OffsetRange): Range { @@ -559,6 +829,57 @@ class Slice implements ISequence { return new OffsetRange(start, end); } + + public countLinesIn(range: OffsetRange): number { + return this.translateOffset(range.endExclusive).lineNumber - this.translateOffset(range.start).lineNumber; + } + + public isStronglyEqual(offset1: number, offset2: number): boolean { + return this.elements[offset1] === this.elements[offset2]; + } + + public extendToFullLines(range: OffsetRange): OffsetRange { + const firstIdx = findLastIdxMonotonous(this.firstCharOffsetByLineMinusOne, x => x <= range.start); + const lastIdx = findFirstIdxMonotonous(this.firstCharOffsetByLineMinusOne, x => range.endExclusive <= x); + + const start = firstIdx === -1 ? 0 : this.firstCharOffsetByLineMinusOne[firstIdx]; + const end = lastIdx === this.firstCharOffsetByLineMinusOne.length ? this.elements.length : this.firstCharOffsetByLineMinusOne[lastIdx]; + return new OffsetRange(start, end); + } +} + +/** + * @returns -1 if predicate is false for all items + */ +function findLastIdxMonotonous(arr: T[], predicate: (item: T) => boolean): number { + let i = 0; + let j = arr.length; + while (i < j) { + const k = Math.floor((i + j) / 2); + if (predicate(arr[k])) { + i = k + 1; + } else { + j = k; + } + } + return i - 1; +} + +/** + * @returns arr.length if predicate is false for all items + */ +function findFirstIdxMonotonous(arr: T[], predicate: (item: T) => boolean): number { + let i = 0; + let j = arr.length; + while (i < j) { + const k = Math.floor((i + j) / 2); + if (predicate(arr[k])) { + j = k; + } else { + i = k + 1; + } + } + return i; } function isWordChar(charCode: number): boolean { @@ -633,6 +954,7 @@ class LineRangeFragment { constructor( public readonly range: LineRange, public readonly lines: string[], + public readonly source: LineRangeMapping, ) { let counter = 0; for (let i = range.startLineNumber - 1; i < range.endLineNumberExclusive - 1; i++) { diff --git a/src/vs/editor/common/diff/algorithms/diffAlgorithm.ts b/src/vs/editor/common/diff/algorithms/diffAlgorithm.ts index 8628534a5140e..ce23a58ceb3c3 100644 --- a/src/vs/editor/common/diff/algorithms/diffAlgorithm.ts +++ b/src/vs/editor/common/diff/algorithms/diffAlgorithm.ts @@ -68,6 +68,13 @@ export interface ISequence { * Must not be negative. */ getBoundaryScore?(length: number): number; + + /** + * For line sequences, getElement returns a number representing trimmed lines. + * This however checks equality for the original lines. + * It prevents shifting to less matching lines. + */ + isStronglyEqual(offset1: number, offset2: number): boolean; } export interface ITimeout { diff --git a/src/vs/editor/common/diff/algorithms/joinSequenceDiffs.ts b/src/vs/editor/common/diff/algorithms/joinSequenceDiffs.ts index 5afffbae37036..cef14d466c843 100644 --- a/src/vs/editor/common/diff/algorithms/joinSequenceDiffs.ts +++ b/src/vs/editor/common/diff/algorithms/joinSequenceDiffs.ts @@ -5,6 +5,7 @@ import { OffsetRange } from 'vs/editor/common/core/offsetRange'; import { ISequence, SequenceDiff } from 'vs/editor/common/diff/algorithms/diffAlgorithm'; +import { LineSequence, LinesSliceCharSequence } from 'vs/editor/common/diff/advancedLinesDiffComputer'; export function optimizeSequenceDiffs(sequence1: ISequence, sequence2: ISequence, sequenceDiffs: SequenceDiff[]): SequenceDiff[] { let result = sequenceDiffs; @@ -32,6 +33,148 @@ export function smoothenSequenceDiffs(sequence1: ISequence, sequence2: ISequence return result; } +export function removeRandomLineMatches(sequence1: LineSequence, _sequence2: LineSequence, sequenceDiffs: SequenceDiff[]): SequenceDiff[] { + let diffs = sequenceDiffs; + if (diffs.length === 0) { + return diffs; + } + + let counter = 0; + let shouldRepeat: boolean; + do { + shouldRepeat = false; + + const result: SequenceDiff[] = [ + diffs[0] + ]; + + for (let i = 1; i < diffs.length; i++) { + const cur = diffs[i]; + const lastResult = result[result.length - 1]; + + function shouldJoinDiffs(before: SequenceDiff, after: SequenceDiff): boolean { + const unchangedRange = new OffsetRange(lastResult.seq1Range.endExclusive, cur.seq1Range.start); + + const unchangedText = sequence1.getText(unchangedRange); + const unchangedTextWithoutWs = unchangedText.replace(/\s/g, ''); + if (unchangedTextWithoutWs.length <= 4 + && (before.seq1Range.length + before.seq2Range.length > 5 || after.seq1Range.length + after.seq2Range.length > 5)) { + return true; + } + + return false; + } + + const shouldJoin = shouldJoinDiffs(lastResult, cur); + if (shouldJoin) { + shouldRepeat = true; + result[result.length - 1] = result[result.length - 1].join(cur); + } else { + result.push(cur); + } + } + + diffs = result; + } while (counter++ < 10 && shouldRepeat); + + return diffs; +} + + +export function removeRandomMatches(sequence1: LinesSliceCharSequence, sequence2: LinesSliceCharSequence, sequenceDiffs: SequenceDiff[]): SequenceDiff[] { + let diffs = sequenceDiffs; + if (diffs.length === 0) { + return diffs; + } + + let counter = 0; + let shouldRepeat: boolean; + do { + shouldRepeat = false; + + const result: SequenceDiff[] = [ + diffs[0] + ]; + + for (let i = 1; i < diffs.length; i++) { + const cur = diffs[i]; + const lastResult = result[result.length - 1]; + + function shouldJoinDiffs(before: SequenceDiff, after: SequenceDiff): boolean { + const unchangedRange = new OffsetRange(lastResult.seq1Range.endExclusive, cur.seq1Range.start); + + const unchangedLineCount = sequence1.countLinesIn(unchangedRange); + if (unchangedLineCount > 5 || unchangedRange.length > 500) { + return false; + } + + const unchangedText = sequence1.getText(unchangedRange).trim(); + if (unchangedText.length > 20 || unchangedText.split(/\r\n|\r|\n/).length > 1) { + return false; + } + + const beforeLineCount1 = sequence1.countLinesIn(before.seq1Range); + const beforeSeq1Length = before.seq1Range.length; + const beforeLineCount2 = sequence2.countLinesIn(before.seq2Range); + const beforeSeq2Length = before.seq2Range.length; + + const afterLineCount1 = sequence1.countLinesIn(after.seq1Range); + const afterSeq1Length = after.seq1Range.length; + const afterLineCount2 = sequence2.countLinesIn(after.seq2Range); + const afterSeq2Length = after.seq2Range.length; + + // TODO: Maybe a neural net can be used to derive the result from these numbers + + const max = 2 * 40 + 50; + function cap(v: number): number { + return Math.min(v, max); + } + + if (Math.pow(Math.pow(cap(beforeLineCount1 * 40 + beforeSeq1Length), 1.5) + Math.pow(cap(beforeLineCount2 * 40 + beforeSeq2Length), 1.5), 1.5) + + Math.pow(Math.pow(cap(afterLineCount1 * 40 + afterSeq1Length), 1.5) + Math.pow(cap(afterLineCount2 * 40 + afterSeq2Length), 1.5), 1.5) > ((max ** 1.5) ** 1.5) * 1.3) { + return true; + } + return false; + } + + const shouldJoin = shouldJoinDiffs(lastResult, cur); + if (shouldJoin) { + shouldRepeat = true; + result[result.length - 1] = result[result.length - 1].join(cur); + } else { + result.push(cur); + } + } + + diffs = result; + } while (counter++ < 10 && shouldRepeat); + + // Remove short suffixes/prefixes + for (let i = 0; i < diffs.length; i++) { + const cur = diffs[i]; + + let range1 = cur.seq1Range; + let range2 = cur.seq2Range; + + const fullRange1 = sequence1.extendToFullLines(cur.seq1Range); + const prefix = sequence1.getText(new OffsetRange(fullRange1.start, cur.seq1Range.start)); + if (prefix.length > 0 && prefix.trim().length <= 3 && cur.seq1Range.length + cur.seq2Range.length > 100) { + range1 = cur.seq1Range.deltaStart(-prefix.length); + range2 = cur.seq2Range.deltaStart(-prefix.length); + } + + const suffix = sequence1.getText(new OffsetRange(cur.seq1Range.endExclusive, fullRange1.endExclusive)); + if (suffix.length > 0 && (suffix.trim().length <= 3 && cur.seq1Range.length + cur.seq2Range.length > 150)) { + range1 = range1.deltaEnd(suffix.length); + range2 = range2.deltaEnd(suffix.length); + } + + diffs[i] = new SequenceDiff(range1, range2); + } + + return diffs; +} + /** * This function fixes issues like this: * ``` @@ -173,8 +316,7 @@ function shiftDiffToBetterPosition(diff: SequenceDiff, sequence1: ISequence, seq while ( diff.seq1Range.start - deltaBefore >= seq1ValidRange.start && diff.seq2Range.start - deltaBefore >= seq2ValidRange.start && - sequence2.getElement(diff.seq2Range.start - deltaBefore) === - sequence2.getElement(diff.seq2Range.endExclusive - deltaBefore) && deltaBefore < maxShiftLimit + sequence2.isStronglyEqual(diff.seq2Range.start - deltaBefore, diff.seq2Range.endExclusive - deltaBefore) && deltaBefore < maxShiftLimit ) { deltaBefore++; } @@ -184,8 +326,7 @@ function shiftDiffToBetterPosition(diff: SequenceDiff, sequence1: ISequence, seq while ( diff.seq1Range.start + deltaAfter < seq1ValidRange.endExclusive && diff.seq2Range.endExclusive + deltaAfter < seq2ValidRange.endExclusive && - sequence2.getElement(diff.seq2Range.start + deltaAfter) === - sequence2.getElement(diff.seq2Range.endExclusive + deltaAfter) && deltaAfter < maxShiftLimit + sequence2.isStronglyEqual(diff.seq2Range.start + deltaAfter, diff.seq2Range.endExclusive + deltaAfter) && deltaAfter < maxShiftLimit ) { deltaAfter++; } diff --git a/src/vs/editor/common/diff/documentDiffProvider.ts b/src/vs/editor/common/diff/documentDiffProvider.ts index ad707d114b5ad..02907dddca3f8 100644 --- a/src/vs/editor/common/diff/documentDiffProvider.ts +++ b/src/vs/editor/common/diff/documentDiffProvider.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { CancellationToken } from 'vs/base/common/cancellation'; import { Event } from 'vs/base/common/event'; import { LineRangeMapping, MovedText } from 'vs/editor/common/diff/linesDiffComputer'; import { ITextModel } from 'vs/editor/common/model'; @@ -14,7 +15,7 @@ export interface IDocumentDiffProvider { /** * Computes the diff between the text models `original` and `modified`. */ - computeDiff(original: ITextModel, modified: ITextModel, options: IDocumentDiffProviderOptions): Promise; + computeDiff(original: ITextModel, modified: ITextModel, options: IDocumentDiffProviderOptions, cancellationToken: CancellationToken): Promise; /** * Is fired when settings of the diff algorithm change that could alter the result of the diffing computation. diff --git a/src/vs/editor/common/diff/smartLinesDiffComputer.ts b/src/vs/editor/common/diff/legacyLinesDiffComputer.ts similarity index 99% rename from src/vs/editor/common/diff/smartLinesDiffComputer.ts rename to src/vs/editor/common/diff/legacyLinesDiffComputer.ts index fe7fdcdc5bfb7..5ea6524a41ee7 100644 --- a/src/vs/editor/common/diff/smartLinesDiffComputer.ts +++ b/src/vs/editor/common/diff/legacyLinesDiffComputer.ts @@ -13,7 +13,7 @@ import { LineRange } from 'vs/editor/common/core/lineRange'; const MINIMUM_MATCHING_CHARACTER_LENGTH = 3; -export class SmartLinesDiffComputer implements ILinesDiffComputer { +export class LegacyLinesDiffComputer implements ILinesDiffComputer { computeDiff(originalLines: string[], modifiedLines: string[], options: ILinesDiffComputerOptions): LinesDiff { const diffComputer = new DiffComputer(originalLines, modifiedLines, { maxComputationTime: options.maxComputationTimeMs, diff --git a/src/vs/editor/common/diff/linesDiffComputer.ts b/src/vs/editor/common/diff/linesDiffComputer.ts index a096042419f28..d10888cb93f83 100644 --- a/src/vs/editor/common/diff/linesDiffComputer.ts +++ b/src/vs/editor/common/diff/linesDiffComputer.ts @@ -140,19 +140,27 @@ export class RangeMapping { } } +// TODO@hediet: Make LineRangeMapping extend from this! export class SimpleLineRangeMapping { constructor( - public readonly originalRange: LineRange, - public readonly modifiedRange: LineRange, + public readonly original: LineRange, + public readonly modified: LineRange, ) { } public toString(): string { - return `{${this.originalRange.toString()}->${this.modifiedRange.toString()}}`; + return `{${this.original.toString()}->${this.modified.toString()}}`; } public flip(): SimpleLineRangeMapping { - return new SimpleLineRangeMapping(this.modifiedRange, this.originalRange); + return new SimpleLineRangeMapping(this.modified, this.original); + } + + public join(other: SimpleLineRangeMapping): SimpleLineRangeMapping { + return new SimpleLineRangeMapping( + this.original.join(other.original), + this.modified.join(other.modified), + ); } } diff --git a/src/vs/editor/common/diff/linesDiffComputers.ts b/src/vs/editor/common/diff/linesDiffComputers.ts index 415c72e8f04bd..727b91455b79d 100644 --- a/src/vs/editor/common/diff/linesDiffComputers.ts +++ b/src/vs/editor/common/diff/linesDiffComputers.ts @@ -3,10 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { SmartLinesDiffComputer } from 'vs/editor/common/diff/smartLinesDiffComputer'; -import { StandardLinesDiffComputer } from 'vs/editor/common/diff/standardLinesDiffComputer'; +import { LegacyLinesDiffComputer } from 'vs/editor/common/diff/legacyLinesDiffComputer'; +import { AdvancedLinesDiffComputer } from 'vs/editor/common/diff/advancedLinesDiffComputer'; export const linesDiffComputers = { - getLegacy: () => new SmartLinesDiffComputer(), - getAdvanced: () => new StandardLinesDiffComputer(), + getLegacy: () => new LegacyLinesDiffComputer(), + getAdvanced: () => new AdvancedLinesDiffComputer(), }; diff --git a/src/vs/editor/common/editorContextKeys.ts b/src/vs/editor/common/editorContextKeys.ts index 899ad35781f3e..a2b1a88cc446b 100644 --- a/src/vs/editor/common/editorContextKeys.ts +++ b/src/vs/editor/common/editorContextKeys.ts @@ -27,6 +27,9 @@ export namespace EditorContextKeys { export const readOnly = new RawContextKey('editorReadonly', false, nls.localize('editorReadonly', "Whether the editor is read-only")); export const inDiffEditor = new RawContextKey('inDiffEditor', false, nls.localize('inDiffEditor', "Whether the context is a diff editor")); export const isEmbeddedDiffEditor = new RawContextKey('isEmbeddedDiffEditor', false, nls.localize('isEmbeddedDiffEditor', "Whether the context is an embedded diff editor")); + export const comparingMovedCode = new RawContextKey('comparingMovedCode', false, nls.localize('comparingMovedCode', "Whether a moved code block is selected for comparison")); + export const accessibleDiffViewerVisible = new RawContextKey('accessibleDiffViewerVisible', false, nls.localize('accessibleDiffViewerVisible', "Whether the accessible diff viewer is visible")); + export const diffEditorRenderSideBySideInlineBreakpointReached = new RawContextKey('diffEditorRenderSideBySideInlineBreakpointReached', false, nls.localize('diffEditorRenderSideBySideInlineBreakpointReached', "Whether the diff editor render side by side inline breakpoint is reached")); export const columnSelection = new RawContextKey('editorColumnSelection', false, nls.localize('editorColumnSelection', "Whether `editor.columnSelection` is enabled")); export const writable = readOnly.toNegated(); export const hasNonEmptySelection = new RawContextKey('editorHasSelection', false, nls.localize('editorHasSelection', "Whether the editor has text selected")); diff --git a/src/vs/editor/common/languages.ts b/src/vs/editor/common/languages.ts index d589e8aa27510..15b63cf03864c 100644 --- a/src/vs/editor/common/languages.ts +++ b/src/vs/editor/common/languages.ts @@ -16,11 +16,12 @@ import { URI, UriComponents } from 'vs/base/common/uri'; import { EditOperation, ISingleEditOperation } from 'vs/editor/common/core/editOperation'; import { IPosition, Position } from 'vs/editor/common/core/position'; import { IRange, Range } from 'vs/editor/common/core/range'; -import { Selection } from 'vs/editor/common/core/selection'; +import { ISelection, Selection } from 'vs/editor/common/core/selection'; import { LanguageId } from 'vs/editor/common/encodedTokenAttributes'; import * as model from 'vs/editor/common/model'; import { TokenizationRegistry as TokenizationRegistryImpl } from 'vs/editor/common/tokenizationRegistry'; import { ContiguousMultilineTokens } from 'vs/editor/common/tokens/contiguousMultilineTokens'; +import { localize } from 'vs/nls'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { IMarkerData } from 'vs/platform/markers/common/markers'; @@ -79,22 +80,6 @@ export class EncodedTokenizationResult { } } -/** - * @internal - */ -export interface IBackgroundTokenizer extends IDisposable { - /** - * Instructs the background tokenizer to set the tokens for the given range again. - * - * This might be necessary if the renderer overwrote those tokens with heuristically computed ones for some viewport, - * when the change does not even propagate to that viewport. - */ - requestTokens(startLineNumber: number, endLineNumberExclusive: number): void; - - reportMismatchingTokens?(lineNumber: number): void; -} - - /** * @internal */ @@ -117,6 +102,21 @@ export interface ITokenizationSupport { createBackgroundTokenizer?(textModel: model.ITextModel, store: IBackgroundTokenizationStore): IBackgroundTokenizer | undefined; } +/** + * @internal + */ +export interface IBackgroundTokenizer extends IDisposable { + /** + * Instructs the background tokenizer to set the tokens for the given range again. + * + * This might be necessary if the renderer overwrote those tokens with heuristically computed ones for some viewport, + * when the change does not even propagate to that viewport. + */ + requestTokens(startLineNumber: number, endLineNumberExclusive: number): void; + + reportMismatchingTokens?(lineNumber: number): void; +} + /** * @internal */ @@ -802,10 +802,10 @@ export interface CodeActionProvider { * @internal */ export interface DocumentPasteEdit { - readonly id: string; readonly label: string; readonly detail: string; - readonly priority: number; + readonly handledMimeType?: string; + readonly yieldTo?: readonly DropYieldTo[]; insertText: string | { readonly snippet: string }; additionalEdit?: WorkspaceEdit; } @@ -815,7 +815,7 @@ export interface DocumentPasteEdit { */ export interface DocumentPasteEditProvider { - readonly id?: string; + readonly id: string; readonly copyMimeTypes?: readonly string[]; readonly pasteMimeTypes?: readonly string[]; @@ -1142,6 +1142,45 @@ export const enum SymbolKind { TypeParameter = 25 } +/** + * @internal + */ +export const symbolKindNames: { [symbol: number]: string } = { + [SymbolKind.Array]: localize('Array', "array"), + [SymbolKind.Boolean]: localize('Boolean', "boolean"), + [SymbolKind.Class]: localize('Class', "class"), + [SymbolKind.Constant]: localize('Constant', "constant"), + [SymbolKind.Constructor]: localize('Constructor', "constructor"), + [SymbolKind.Enum]: localize('Enum', "enumeration"), + [SymbolKind.EnumMember]: localize('EnumMember', "enumeration member"), + [SymbolKind.Event]: localize('Event', "event"), + [SymbolKind.Field]: localize('Field', "field"), + [SymbolKind.File]: localize('File', "file"), + [SymbolKind.Function]: localize('Function', "function"), + [SymbolKind.Interface]: localize('Interface', "interface"), + [SymbolKind.Key]: localize('Key', "key"), + [SymbolKind.Method]: localize('Method', "method"), + [SymbolKind.Module]: localize('Module', "module"), + [SymbolKind.Namespace]: localize('Namespace', "namespace"), + [SymbolKind.Null]: localize('Null', "null"), + [SymbolKind.Number]: localize('Number', "number"), + [SymbolKind.Object]: localize('Object', "object"), + [SymbolKind.Operator]: localize('Operator', "operator"), + [SymbolKind.Package]: localize('Package', "package"), + [SymbolKind.Property]: localize('Property', "property"), + [SymbolKind.String]: localize('String', "string"), + [SymbolKind.Struct]: localize('Struct', "struct"), + [SymbolKind.TypeParameter]: localize('TypeParameter', "type parameter"), + [SymbolKind.Variable]: localize('Variable', "variable"), +}; + +/** + * @internal + */ +export function getAriaLabelForSymbol(symbolName: string, kind: SymbolKind): string { + return localize('symbolAriaLabel', '{0} ({1})', symbolName, symbolKindNames[kind]); +} + export const enum SymbolTag { Deprecated = 1, } @@ -1969,13 +2008,18 @@ export enum ExternalUriOpenerPriority { Preferred = 3, } +/** + * @internal + */ +export type DropYieldTo = { readonly providerId: string } | { readonly mimeType: string }; + /** * @internal */ export interface DocumentOnDropEdit { - readonly id: string; readonly label: string; - readonly priority: number; + readonly handledMimeType?: string; + readonly yieldTo?: readonly DropYieldTo[]; insertText: string | { readonly snippet: string }; additionalEdit?: WorkspaceEdit; } @@ -1984,7 +2028,38 @@ export interface DocumentOnDropEdit { * @internal */ export interface DocumentOnDropEditProvider { + readonly id?: string; readonly dropMimeTypes?: readonly string[]; provideDocumentOnDropEdits(model: model.ITextModel, position: IPosition, dataTransfer: IReadonlyVSDataTransfer, token: CancellationToken): ProviderResult; } + +export interface RelatedContextItem { + readonly uri: URI; + readonly range: IRange; +} + +export interface MappedEditsContext { + selections: ISelection[]; + related: RelatedContextItem[]; +} + +export interface MappedEditsProvider { + + /** + * Provider maps code blocks from the chat into a workspace edit. + * + * @param document The document to provide mapped edits for. + * @param codeBlocks Code blocks that come from an LLM's reply. + * "Insert at cursor" in the panel chat only sends one edit that the user clicks on, but inline chat can send multiple blocks and let the lang server decide what to do with them. + * @param context The context for providing mapped edits. + * @param token A cancellation token. + * @returns A provider result of text edits. + */ + provideMappedEdits( + document: model.ITextModel, + codeBlocks: string[], + context: MappedEditsContext, + token: CancellationToken + ): Promise; +} diff --git a/src/vs/editor/common/model/textModelTokens.ts b/src/vs/editor/common/model/textModelTokens.ts index deb5fbf628f37..0139d8b20558b 100644 --- a/src/vs/editor/common/model/textModelTokens.ts +++ b/src/vs/editor/common/model/textModelTokens.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { IdleDeadline, runWhenIdle } from 'vs/base/common/async'; -import { onUnexpectedError } from 'vs/base/common/errors'; +import { BugIndicatingError, onUnexpectedError } from 'vs/base/common/errors'; import { setTimeout0 } from 'vs/base/common/platform'; import { StopWatch } from 'vs/base/common/stopwatch'; import { countEOL } from 'vs/editor/common/core/eolCounter'; @@ -25,7 +25,7 @@ const enum Constants { } export class TokenizerWithStateStore { - private readonly initialState = this.tokenizationSupport.getInitialState(); + private readonly initialState = this.tokenizationSupport.getInitialState() as TState; public readonly store: TrackingTokenizationStateStore; @@ -37,10 +37,11 @@ export class TokenizerWithStateStore { } public getStartState(lineNumber: number): TState | null { - if (lineNumber === 1) { - return this.initialState as TState; - } - return this.store.getEndState(lineNumber - 1); + return this.store.getStartState(lineNumber, this.initialState); + } + + public getFirstInvalidLine(): { lineNumber: number; startState: TState } | null { + return this.store.getFirstInvalidLine(this.initialState); } } @@ -58,17 +59,16 @@ export class TokenizerWithStateStoreAndTextModel const languageId = this._textModel.getLanguageId(); while (true) { - const nextLineNumber = this.store.getFirstInvalidEndStateLineNumber(); - if (!nextLineNumber || nextLineNumber > lineNumber) { + const lineToTokenize = this.getFirstInvalidLine(); + if (!lineToTokenize || lineToTokenize.lineNumber > lineNumber) { break; } - const text = this._textModel.getLineContent(nextLineNumber); - const lineStartState = this.getStartState(nextLineNumber); + const text = this._textModel.getLineContent(lineToTokenize.lineNumber); - const r = safeTokenize(this._languageIdCodec, languageId, this.tokenizationSupport, text, true, lineStartState!); - builder.add(nextLineNumber, r.tokens); - this!.store.setEndState(nextLineNumber, r.endState as TState); + const r = safeTokenize(this._languageIdCodec, languageId, this.tokenizationSupport, text, true, lineToTokenize.startState); + builder.add(lineToTokenize.lineNumber, r.tokens); + this.store.setEndState(lineToTokenize.lineNumber, r.endState as TState); } } @@ -204,8 +204,13 @@ export class TokenizerWithStateStoreAndTextModel } } +/** + * **Invariant:** + * If the text model is retokenized from line 1 to {@link getFirstInvalidEndStateLineNumber}() - 1, + * then the recomputed end state for line l will be equal to {@link getEndState}(l). + */ export class TrackingTokenizationStateStore { - private readonly tokenizationStateStore = new TokenizationStateStore(); + private readonly _tokenizationStateStore = new TokenizationStateStore(); private readonly _invalidEndStatesLineNumbers = new RangePriorityQueueImpl(); constructor(private lineCount: number) { @@ -213,20 +218,19 @@ export class TrackingTokenizationStateStore { } public getEndState(lineNumber: number): TState | null { - return this.tokenizationStateStore.getEndState(lineNumber); + return this._tokenizationStateStore.getEndState(lineNumber); } + /** + * @returns if the end state has changed. + */ public setEndState(lineNumber: number, state: TState): boolean { - while (true) { - const min = this._invalidEndStatesLineNumbers.min; - if (min !== null && min <= lineNumber) { - this._invalidEndStatesLineNumbers.removeMin(); - } else { - break; - } + if (!state) { + throw new BugIndicatingError('Cannot set null/undefined state'); } - const r = this.tokenizationStateStore.setEndState(lineNumber, state); + this._invalidEndStatesLineNumbers.delete(lineNumber); + const r = this._tokenizationStateStore.setEndState(lineNumber, state); if (r && lineNumber < this.lineCount) { // because the state changed, we cannot trust the next state anymore and have to invalidate it. this._invalidEndStatesLineNumbers.addRange(new OffsetRange(lineNumber + 1, lineNumber + 2)); @@ -237,7 +241,7 @@ export class TrackingTokenizationStateStore { public acceptChange(range: LineRange, newLineCount: number): void { this.lineCount += newLineCount - range.length; - this.tokenizationStateStore.acceptChange(range, newLineCount); + this._tokenizationStateStore.acceptChange(range, newLineCount); this._invalidEndStatesLineNumbers.addRangeAndResize(new OffsetRange(range.startLineNumber, range.endLineNumberExclusive), newLineCount); } @@ -252,16 +256,30 @@ export class TrackingTokenizationStateStore { this._invalidEndStatesLineNumbers.addRange(new OffsetRange(range.startLineNumber, range.endLineNumberExclusive)); } - public getFirstInvalidEndStateLineNumber(): number | null { - return this._invalidEndStatesLineNumbers.min; - } + public getFirstInvalidEndStateLineNumber(): number | null { return this._invalidEndStatesLineNumbers.min; } public getFirstInvalidEndStateLineNumberOrMax(): number { - return this._invalidEndStatesLineNumbers.min || Number.MAX_SAFE_INTEGER; + return this.getFirstInvalidEndStateLineNumber() || Number.MAX_SAFE_INTEGER; + } + + public allStatesValid(): boolean { return this._invalidEndStatesLineNumbers.min === null; } + + public getStartState(lineNumber: number, initialState: TState): TState | null { + if (lineNumber === 1) { return initialState; } + return this.getEndState(lineNumber - 1); } - public isTokenizationComplete(): boolean { - return this._invalidEndStatesLineNumbers.min === null; + public getFirstInvalidLine(initialState: TState): { lineNumber: number; startState: TState } | null { + const lineNumber = this.getFirstInvalidEndStateLineNumber(); + if (lineNumber === null) { + return null; + } + const startState = this.getStartState(lineNumber, initialState); + if (!startState) { + throw new BugIndicatingError('Start state must be defined'); + } + + return { lineNumber, startState }; } } @@ -338,6 +356,26 @@ export class RangePriorityQueueImpl implements RangePriorityQueue { return range.start; } + public delete(value: number): void { + const idx = this._ranges.findIndex(r => r.contains(value)); + if (idx !== -1) { + const range = this._ranges[idx]; + if (range.start === value) { + if (range.endExclusive === value + 1) { + this._ranges.splice(idx, 1); + } else { + this._ranges[idx] = new OffsetRange(value + 1, range.endExclusive); + } + } else { + if (range.endExclusive === value + 1) { + this._ranges[idx] = new OffsetRange(range.start, value); + } else { + this._ranges.splice(idx, 1, new OffsetRange(range.start, value), new OffsetRange(value + 1, range.endExclusive)); + } + } + } + } + public addRange(range: OffsetRange): void { OffsetRange.addRange(range, this._ranges); } @@ -490,23 +528,23 @@ export class DefaultBackgroundTokenizer implements IBackgroundTokenizer { if (!this._tokenizerWithStateStore) { return false; } - return !this._tokenizerWithStateStore.store.isTokenizationComplete(); + return !this._tokenizerWithStateStore.store.allStatesValid(); } private _tokenizeOneInvalidLine(builder: ContiguousMultilineTokensBuilder): number { - if (!this._tokenizerWithStateStore || !this._hasLinesToTokenize()) { + const firstInvalidLine = this._tokenizerWithStateStore?.getFirstInvalidLine(); + if (!firstInvalidLine) { return this._tokenizerWithStateStore._textModel.getLineCount() + 1; } - const lineNumber = this._tokenizerWithStateStore.store.getFirstInvalidEndStateLineNumber()!; - this._tokenizerWithStateStore.updateTokensUntilLine(builder, lineNumber); - return lineNumber; + this._tokenizerWithStateStore.updateTokensUntilLine(builder, firstInvalidLine.lineNumber); + return firstInvalidLine.lineNumber; } public checkFinished(): void { if (this._isDisposed) { return; } - if (this._tokenizerWithStateStore.store.isTokenizationComplete()) { + if (this._tokenizerWithStateStore.store.allStatesValid()) { this._backgroundTokenStore.backgroundTokenizationFinished(); } } diff --git a/src/vs/editor/common/model/tokenizationTextModelPart.ts b/src/vs/editor/common/model/tokenizationTextModelPart.ts index c203f53ad7647..54476c26f2017 100644 --- a/src/vs/editor/common/model/tokenizationTextModelPart.ts +++ b/src/vs/editor/common/model/tokenizationTextModelPart.ts @@ -449,12 +449,10 @@ class GrammarTokens extends Disposable { this._onDidChangeBackgroundTokenizationState.fire(); }, setEndState: (lineNumber, state) => { - if (!state) { - throw new BugIndicatingError(); - } - const firstInvalidEndStateLineNumber = this._tokenizer?.store.getFirstInvalidEndStateLineNumber() ?? undefined; - if (firstInvalidEndStateLineNumber !== undefined && lineNumber >= firstInvalidEndStateLineNumber) { - // Don't accept states for definitely valid states + if (!this._tokenizer) { return; } + const firstInvalidEndStateLineNumber = this._tokenizer.store.getFirstInvalidEndStateLineNumber(); + // Don't accept states for definitely valid states, the renderer is ahead of the worker! + if (firstInvalidEndStateLineNumber !== null && lineNumber >= firstInvalidEndStateLineNumber) { this._tokenizer?.store.setEndState(lineNumber, state); } }, diff --git a/src/vs/editor/common/services/editorSimpleWorker.ts b/src/vs/editor/common/services/editorSimpleWorker.ts index 2f51814946b8f..ca8364f62d3a4 100644 --- a/src/vs/editor/common/services/editorSimpleWorker.ts +++ b/src/vs/editor/common/services/editorSimpleWorker.ts @@ -20,7 +20,7 @@ import { createMonacoBaseAPI } from 'vs/editor/common/services/editorBaseApi'; import { IEditorWorkerHost } from 'vs/editor/common/services/editorWorkerHost'; import { StopWatch } from 'vs/base/common/stopwatch'; import { UnicodeTextModelHighlighter, UnicodeHighlighterOptions } from 'vs/editor/common/services/unicodeTextModelHighlighter'; -import { DiffComputer, IChange } from 'vs/editor/common/diff/smartLinesDiffComputer'; +import { DiffComputer, IChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; import { ILinesDiffComputer, ILinesDiffComputerOptions, LineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; import { linesDiffComputers } from 'vs/editor/common/diff/linesDiffComputers'; import { createProxyObject, getAllMethodNames } from 'vs/base/common/objects'; @@ -440,10 +440,10 @@ export class EditorSimpleWorker implements IRequestHandler, IDisposable { quitEarly: result.hitTimeout, changes: getLineChanges(result.changes), moves: result.moves.map(m => ([ - m.lineRangeMapping.originalRange.startLineNumber, - m.lineRangeMapping.originalRange.endLineNumberExclusive, - m.lineRangeMapping.modifiedRange.startLineNumber, - m.lineRangeMapping.modifiedRange.endLineNumberExclusive, + m.lineRangeMapping.original.startLineNumber, + m.lineRangeMapping.original.endLineNumberExclusive, + m.lineRangeMapping.modified.startLineNumber, + m.lineRangeMapping.modified.endLineNumberExclusive, getLineChanges(m.changes) ])), }; diff --git a/src/vs/editor/common/services/editorWorker.ts b/src/vs/editor/common/services/editorWorker.ts index 9038e313a9c5c..9e1cca8a460de 100644 --- a/src/vs/editor/common/services/editorWorker.ts +++ b/src/vs/editor/common/services/editorWorker.ts @@ -6,7 +6,7 @@ import { URI } from 'vs/base/common/uri'; import { IRange } from 'vs/editor/common/core/range'; import { IDocumentDiff, IDocumentDiffProviderOptions } from 'vs/editor/common/diff/documentDiffProvider'; -import { IChange } from 'vs/editor/common/diff/smartLinesDiffComputer'; +import { IChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; import { IInplaceReplaceSupportResult, TextEdit } from 'vs/editor/common/languages'; import { UnicodeHighlighterOptions } from 'vs/editor/common/services/unicodeTextModelHighlighter'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; diff --git a/src/vs/editor/common/services/languageFeatures.ts b/src/vs/editor/common/services/languageFeatures.ts index 2c80887df1a54..df53beaecdb0d 100644 --- a/src/vs/editor/common/services/languageFeatures.ts +++ b/src/vs/editor/common/services/languageFeatures.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { LanguageFeatureRegistry, NotebookInfoResolver } from 'vs/editor/common/languageFeatureRegistry'; -import { CodeActionProvider, CodeLensProvider, CompletionItemProvider, DeclarationProvider, DefinitionProvider, DocumentColorProvider, DocumentFormattingEditProvider, DocumentHighlightProvider, DocumentOnDropEditProvider, DocumentPasteEditProvider, DocumentRangeFormattingEditProvider, DocumentRangeSemanticTokensProvider, DocumentSemanticTokensProvider, DocumentSymbolProvider, EvaluatableExpressionProvider, FoldingRangeProvider, HoverProvider, ImplementationProvider, InlayHintsProvider, InlineCompletionsProvider, InlineValuesProvider, LinkedEditingRangeProvider, LinkProvider, OnTypeFormattingEditProvider, ReferenceProvider, RenameProvider, SelectionRangeProvider, SignatureHelpProvider, TypeDefinitionProvider } from 'vs/editor/common/languages'; +import { CodeActionProvider, CodeLensProvider, CompletionItemProvider, DeclarationProvider, DefinitionProvider, DocumentColorProvider, DocumentFormattingEditProvider, DocumentHighlightProvider, DocumentOnDropEditProvider, DocumentPasteEditProvider, DocumentRangeFormattingEditProvider, DocumentRangeSemanticTokensProvider, DocumentSemanticTokensProvider, DocumentSymbolProvider, EvaluatableExpressionProvider, FoldingRangeProvider, HoverProvider, ImplementationProvider, InlayHintsProvider, InlineCompletionsProvider, InlineValuesProvider, LinkedEditingRangeProvider, LinkProvider, MappedEditsProvider, OnTypeFormattingEditProvider, ReferenceProvider, RenameProvider, SelectionRangeProvider, SignatureHelpProvider, TypeDefinitionProvider } from 'vs/editor/common/languages'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; export const ILanguageFeaturesService = createDecorator('ILanguageFeaturesService'); @@ -71,6 +71,8 @@ export interface ILanguageFeaturesService { readonly documentOnDropEditProvider: LanguageFeatureRegistry; + readonly mappedEditsProvider: LanguageFeatureRegistry; + // -- setNotebookTypeResolver(resolver: NotebookInfoResolver | undefined): void; diff --git a/src/vs/editor/common/services/languageFeaturesService.ts b/src/vs/editor/common/services/languageFeaturesService.ts index 35d321b4ef2fa..3ef13891fb76a 100644 --- a/src/vs/editor/common/services/languageFeaturesService.ts +++ b/src/vs/editor/common/services/languageFeaturesService.ts @@ -5,7 +5,7 @@ import { URI } from 'vs/base/common/uri'; import { LanguageFeatureRegistry, NotebookInfo, NotebookInfoResolver } from 'vs/editor/common/languageFeatureRegistry'; -import { CodeActionProvider, CodeLensProvider, CompletionItemProvider, DocumentPasteEditProvider, DeclarationProvider, DefinitionProvider, DocumentColorProvider, DocumentFormattingEditProvider, DocumentHighlightProvider, DocumentOnDropEditProvider, DocumentRangeFormattingEditProvider, DocumentRangeSemanticTokensProvider, DocumentSemanticTokensProvider, DocumentSymbolProvider, EvaluatableExpressionProvider, FoldingRangeProvider, HoverProvider, ImplementationProvider, InlayHintsProvider, InlineCompletionsProvider, InlineValuesProvider, LinkedEditingRangeProvider, LinkProvider, OnTypeFormattingEditProvider, ReferenceProvider, RenameProvider, SelectionRangeProvider, SignatureHelpProvider, TypeDefinitionProvider } from 'vs/editor/common/languages'; +import { CodeActionProvider, CodeLensProvider, CompletionItemProvider, DocumentPasteEditProvider, DeclarationProvider, DefinitionProvider, DocumentColorProvider, DocumentFormattingEditProvider, DocumentHighlightProvider, DocumentOnDropEditProvider, DocumentRangeFormattingEditProvider, DocumentRangeSemanticTokensProvider, DocumentSemanticTokensProvider, DocumentSymbolProvider, EvaluatableExpressionProvider, FoldingRangeProvider, HoverProvider, ImplementationProvider, InlayHintsProvider, InlineCompletionsProvider, InlineValuesProvider, LinkedEditingRangeProvider, LinkProvider, OnTypeFormattingEditProvider, ReferenceProvider, RenameProvider, SelectionRangeProvider, SignatureHelpProvider, TypeDefinitionProvider, MappedEditsProvider } from 'vs/editor/common/languages'; import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; @@ -42,6 +42,7 @@ export class LanguageFeaturesService implements ILanguageFeaturesService { readonly documentSemanticTokensProvider = new LanguageFeatureRegistry(this._score.bind(this)); readonly documentOnDropEditProvider = new LanguageFeatureRegistry(this._score.bind(this)); readonly documentPasteEditProvider = new LanguageFeatureRegistry(this._score.bind(this)); + readonly mappedEditsProvider: LanguageFeatureRegistry = new LanguageFeatureRegistry(this._score.bind(this)); private _notebookTypeResolver?: NotebookInfoResolver; diff --git a/src/vs/editor/common/standalone/standaloneEnums.ts b/src/vs/editor/common/standalone/standaloneEnums.ts index d92f0c1272e48..7cc3add3df1bf 100644 --- a/src/vs/editor/common/standalone/standaloneEnums.ts +++ b/src/vs/editor/common/standalone/standaloneEnums.ts @@ -318,7 +318,8 @@ export enum EditorOption { layoutInfo = 142, wrappingInfo = 143, defaultColorDecorators = 144, - colorDecoratorsActivatedOn = 145 + colorDecoratorsActivatedOn = 145, + inlineCompletionsAccessibilityVerbose = 146 } /** diff --git a/src/vs/editor/common/tokenizationRegistry.ts b/src/vs/editor/common/tokenizationRegistry.ts index 2d5ab7781a5a0..d9fb1bba82f2b 100644 --- a/src/vs/editor/common/tokenizationRegistry.ts +++ b/src/vs/editor/common/tokenizationRegistry.ts @@ -78,8 +78,6 @@ export class TokenizationRegistry implements ITokenizationRegistry { return this.get(languageId); } - - public isResolved(languageId: string): boolean { const tokenizationSupport = this.get(languageId); if (tokenizationSupport) { diff --git a/src/vs/editor/common/viewLayout/viewLayout.ts b/src/vs/editor/common/viewLayout/viewLayout.ts index 3514fd4cb8274..96fa2e77c8cfa 100644 --- a/src/vs/editor/common/viewLayout/viewLayout.ts +++ b/src/vs/editor/common/viewLayout/viewLayout.ts @@ -156,6 +156,8 @@ export class ViewLayout extends Disposable implements IViewLayout { private readonly _configuration: IEditorConfiguration; private readonly _linesLayout: LinesLayout; + private _maxLineWidth: number; + private _overlayWidgetsMinWidth: number; private readonly _scrollable: EditorScrollable; public readonly onDidScroll: Event; @@ -170,6 +172,8 @@ export class ViewLayout extends Disposable implements IViewLayout { const padding = options.get(EditorOption.padding); this._linesLayout = new LinesLayout(lineCount, options.get(EditorOption.lineHeight), padding.top, padding.bottom); + this._maxLineWidth = 0; + this._overlayWidgetsMinWidth = 0; this._scrollable = this._register(new EditorScrollable(0, scheduleAtNextAnimationFrame)); this._configureSmoothScrollDuration(); @@ -308,8 +312,9 @@ export class ViewLayout extends Disposable implements IViewLayout { ); } - private _computeContentWidth(maxLineWidth: number): number { + private _computeContentWidth(): number { const options = this._configuration.options; + const maxLineWidth = this._maxLineWidth; const wrappingInfo = options.get(EditorOption.wrappingInfo); const fontInfo = options.get(EditorOption.fontInfo); const layoutInfo = options.get(EditorOption.layoutInfo); @@ -326,16 +331,25 @@ export class ViewLayout extends Disposable implements IViewLayout { } else { const extraHorizontalSpace = options.get(EditorOption.scrollBeyondLastColumn) * fontInfo.typicalHalfwidthCharacterWidth; const whitespaceMinWidth = this._linesLayout.getWhitespaceMinWidth(); - return Math.max(maxLineWidth + extraHorizontalSpace + layoutInfo.verticalScrollbarWidth, whitespaceMinWidth); + return Math.max(maxLineWidth + extraHorizontalSpace + layoutInfo.verticalScrollbarWidth, whitespaceMinWidth, this._overlayWidgetsMinWidth); } } public setMaxLineWidth(maxLineWidth: number): void { + this._maxLineWidth = maxLineWidth; + this._updateContentWidth(); + } + + public setOverlayWidgetsMinWidth(maxMinWidth: number): void { + this._overlayWidgetsMinWidth = maxMinWidth; + this._updateContentWidth(); + } + + private _updateContentWidth(): void { const scrollDimensions = this._scrollable.getScrollDimensions(); - // const newScrollWidth = ; this._scrollable.setScrollDimensions(new EditorScrollDimensions( scrollDimensions.width, - this._computeContentWidth(maxLineWidth), + this._computeContentWidth(), scrollDimensions.height, scrollDimensions.contentHeight )); diff --git a/src/vs/editor/common/viewModel.ts b/src/vs/editor/common/viewModel.ts index ff08d5fa24b43..e61ba01dc1575 100644 --- a/src/vs/editor/common/viewModel.ts +++ b/src/vs/editor/common/viewModel.ts @@ -114,6 +114,7 @@ export interface IViewLayout { validateScrollPosition(scrollPosition: INewScrollPosition): IScrollPosition; setMaxLineWidth(maxLineWidth: number): void; + setOverlayWidgetsMinWidth(overlayWidgetsMinWidth: number): void; getLinesViewportData(): IPartialViewLinesViewportData; getLinesViewportDataAtScrollTop(scrollTop: number): IPartialViewLinesViewportData; diff --git a/src/vs/editor/common/viewModel/modelLineProjection.ts b/src/vs/editor/common/viewModel/modelLineProjection.ts index 81be5db0a101f..e66499cd98e18 100644 --- a/src/vs/editor/common/viewModel/modelLineProjection.ts +++ b/src/vs/editor/common/viewModel/modelLineProjection.ts @@ -193,7 +193,7 @@ class ModelLineProjection implements IModelLineProjection { if (options.inlineClassName) { const offset = (outputLineIndex > 0 ? lineBreakData.wrappedTextIndentLength : 0); const start = offset + Math.max(injectedTextStartOffsetInInputWithInjections - lineStartOffsetInInputWithInjections, 0); - const end = offset + Math.min(injectedTextEndOffsetInInputWithInjections - lineStartOffsetInInputWithInjections, lineEndOffsetInInputWithInjections); + const end = offset + Math.min(injectedTextEndOffsetInInputWithInjections - lineStartOffsetInInputWithInjections, lineEndOffsetInInputWithInjections - lineStartOffsetInInputWithInjections); if (start !== end) { inlineDecorations.push(new SingleLineInlineDecoration(start, end, options.inlineClassName, options.inlineClassNameAffectsLetterSpacing!)); } diff --git a/src/vs/editor/contrib/bracketMatching/test/browser/bracketMatching.test.ts b/src/vs/editor/contrib/bracketMatching/test/browser/bracketMatching.test.ts index c16f4d7e9af45..289fe8aa96a61 100644 --- a/src/vs/editor/contrib/bracketMatching/test/browser/bracketMatching.test.ts +++ b/src/vs/editor/contrib/bracketMatching/test/browser/bracketMatching.test.ts @@ -12,9 +12,9 @@ import { instantiateTextModel } from 'vs/editor/test/common/testTextModel'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; import { ILanguageService } from 'vs/editor/common/languages/language'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; suite('bracket matching', () => { - let disposables: DisposableStore; let instantiationService: TestInstantiationService; let languageConfigurationService: ILanguageConfigurationService; @@ -31,6 +31,8 @@ suite('bracket matching', () => { disposables.dispose(); }); + ensureNoDisposablesAreLeakedInTestSuite(); + function createTextModelWithBrackets(text: string) { const languageId = 'bracketMode'; disposables.add(languageService.registerLanguage({ id: languageId })); diff --git a/src/vs/editor/contrib/codeAction/browser/codeActionController.ts b/src/vs/editor/contrib/codeAction/browser/codeActionController.ts index 5b8d6576b14e1..14307f031e5fd 100644 --- a/src/vs/editor/contrib/codeAction/browser/codeActionController.ts +++ b/src/vs/editor/contrib/codeAction/browser/codeActionController.ts @@ -3,8 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -/* eslint-disable local/code-no-native-private */ - import { getDomNodePagePosition } from 'vs/base/browser/dom'; import { IAnchor } from 'vs/base/browser/ui/contextview/contextview'; import { IAction } from 'vs/base/common/actions'; diff --git a/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts b/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts index 0f645908a5ff6..fc33e04fdd0ae 100644 --- a/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts +++ b/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts @@ -22,13 +22,13 @@ interface ActionGroup { const uncategorizedCodeActionGroup = Object.freeze({ kind: CodeActionKind.Empty, title: localize('codeAction.widget.id.more', 'More Actions...') }); const codeActionGroups = Object.freeze([ - { kind: CodeActionKind.QuickFix, title: localize('codeAction.widget.id.quickfix', 'Quick Fix...') }, - { kind: CodeActionKind.RefactorExtract, title: localize('codeAction.widget.id.extract', 'Extract...'), icon: Codicon.wrench }, - { kind: CodeActionKind.RefactorInline, title: localize('codeAction.widget.id.inline', 'Inline...'), icon: Codicon.wrench }, - { kind: CodeActionKind.RefactorRewrite, title: localize('codeAction.widget.id.convert', 'Rewrite...'), icon: Codicon.wrench }, - { kind: CodeActionKind.RefactorMove, title: localize('codeAction.widget.id.move', 'Move...'), icon: Codicon.wrench }, - { kind: CodeActionKind.SurroundWith, title: localize('codeAction.widget.id.surround', 'Surround With...'), icon: Codicon.symbolSnippet }, - { kind: CodeActionKind.Source, title: localize('codeAction.widget.id.source', 'Source Action...'), icon: Codicon.symbolFile }, + { kind: CodeActionKind.QuickFix, title: localize('codeAction.widget.id.quickfix', 'Quick Fix:') }, + { kind: CodeActionKind.RefactorExtract, title: localize('codeAction.widget.id.extract', 'Extract:'), icon: Codicon.wrench }, + { kind: CodeActionKind.RefactorInline, title: localize('codeAction.widget.id.inline', 'Inline:'), icon: Codicon.wrench }, + { kind: CodeActionKind.RefactorRewrite, title: localize('codeAction.widget.id.convert', 'Rewrite:'), icon: Codicon.wrench }, + { kind: CodeActionKind.RefactorMove, title: localize('codeAction.widget.id.move', 'Move:'), icon: Codicon.wrench }, + { kind: CodeActionKind.SurroundWith, title: localize('codeAction.widget.id.surround', 'Surround With:'), icon: Codicon.symbolSnippet }, + { kind: CodeActionKind.Source, title: localize('codeAction.widget.id.source', 'Source Action:'), icon: Codicon.symbolFile }, uncategorizedCodeActionGroup, ]); diff --git a/src/vs/editor/contrib/codeAction/browser/codeActionModel.ts b/src/vs/editor/contrib/codeAction/browser/codeActionModel.ts index 19963bfe57f62..b21d5f2dc5d2e 100644 --- a/src/vs/editor/contrib/codeAction/browser/codeActionModel.ts +++ b/src/vs/editor/contrib/codeAction/browser/codeActionModel.ts @@ -3,8 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -/* eslint-disable local/code-no-native-private */ - import { CancelablePromise, createCancelablePromise, TimeoutTimer } from 'vs/base/common/async'; import { isCancellationError } from 'vs/base/common/errors'; import { Emitter } from 'vs/base/common/event'; diff --git a/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts b/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts index 948e4d7d6bbd0..035c456ac5a98 100644 --- a/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts +++ b/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts @@ -9,7 +9,6 @@ import { Codicon } from 'vs/base/common/codicons'; import { Emitter, Event } from 'vs/base/common/event'; import { Disposable } from 'vs/base/common/lifecycle'; import { ThemeIcon } from 'vs/base/common/themables'; -import { withNullAsUndefined } from 'vs/base/common/types'; import 'vs/css!./lightBulbWidget'; import { ContentWidgetPositionPreference, ICodeEditor, IContentWidget, IContentWidgetPosition } from 'vs/editor/browser/editorBrowser'; import { EditorOption } from 'vs/editor/common/config/editorOptions'; @@ -122,8 +121,8 @@ export class LightBulbWidget extends Disposable implements IContentWidget { })); this._register(Event.runAndSubscribe(keybindingService.onDidUpdateKeybindings, () => { - this._preferredKbLabel = withNullAsUndefined(keybindingService.lookupKeybinding(autoFixCommandId)?.getLabel()); - this._quickFixKbLabel = withNullAsUndefined(keybindingService.lookupKeybinding(quickFixCommandId)?.getLabel()); + this._preferredKbLabel = keybindingService.lookupKeybinding(autoFixCommandId)?.getLabel() ?? undefined; + this._quickFixKbLabel = keybindingService.lookupKeybinding(quickFixCommandId)?.getLabel() ?? undefined; this._updateLightBulbTitleAndIcon(); })); diff --git a/src/vs/editor/contrib/colorPicker/browser/colorContributions.ts b/src/vs/editor/contrib/colorPicker/browser/colorContributions.ts index 7ff5f54f24892..2c041f1c7490c 100644 --- a/src/vs/editor/contrib/colorPicker/browser/colorContributions.ts +++ b/src/vs/editor/contrib/colorPicker/browser/colorContributions.ts @@ -60,7 +60,7 @@ export class ColorContribution extends Disposable implements IEditorContribution if (!hoverController) { return; } - if (!hoverController.isColorPickerVisible()) { + if (!hoverController.isColorPickerVisible) { const range = new Range(target.range.startLineNumber, target.range.startColumn + 1, target.range.endLineNumber, target.range.endColumn + 1); hoverController.showContentHover(range, HoverStartMode.Immediate, HoverStartSource.Mouse, false, true); } diff --git a/src/vs/editor/contrib/colorPicker/browser/colorHoverParticipant.ts b/src/vs/editor/contrib/colorPicker/browser/colorHoverParticipant.ts index e321fae6dfd53..982ecbf505324 100644 --- a/src/vs/editor/contrib/colorPicker/browser/colorHoverParticipant.ts +++ b/src/vs/editor/contrib/colorPicker/browser/colorHoverParticipant.ts @@ -20,6 +20,7 @@ import { HoverAnchor, HoverAnchorType, IEditorHoverParticipant, IEditorHoverRend import { IThemeService } from 'vs/platform/theme/common/themeService'; import { ISingleEditOperation } from 'vs/editor/common/core/editOperation'; import { LanguageFeatureRegistry } from 'vs/editor/common/languageFeatureRegistry'; +import { Dimension } from 'vs/base/browser/dom'; export class ColorHover implements IHoverPart { @@ -181,6 +182,10 @@ function renderHoverParts(participant: ColorHoverParticipant | StandaloneColorPi if (hoverParts.length === 0 || !editor.hasModel()) { return Disposable.None; } + if (context.setMinimumDimensions) { + const minimumHeight = editor.getOption(EditorOption.lineHeight) + 8; + context.setMinimumDimensions(new Dimension(302, minimumHeight)); + } const disposables = new DisposableStore(); const colorHover = hoverParts[0]; diff --git a/src/vs/editor/contrib/colorPicker/browser/colorPicker.css b/src/vs/editor/contrib/colorPicker/browser/colorPicker.css index 62f891080feb9..f484517caba97 100644 --- a/src/vs/editor/contrib/colorPicker/browser/colorPicker.css +++ b/src/vs/editor/contrib/colorPicker/browser/colorPicker.css @@ -48,13 +48,19 @@ cursor: pointer; color: white; flex: 1; + white-space: nowrap; + overflow: hidden; +} + +.colorpicker-header .picked-color .picked-color-presentation { + white-space: nowrap; + margin-left: 5px; + margin-right: 5px; } .colorpicker-header .picked-color .codicon { color: inherit; font-size: 14px; - position: absolute; - left: 8px; } .colorpicker-header .picked-color.light { diff --git a/src/vs/editor/contrib/colorPicker/browser/colorPickerWidget.ts b/src/vs/editor/contrib/colorPicker/browser/colorPickerWidget.ts index 24b6e6408b3dd..2f25409976fe4 100644 --- a/src/vs/editor/contrib/colorPicker/browser/colorPickerWidget.ts +++ b/src/vs/editor/contrib/colorPicker/browser/colorPickerWidget.ts @@ -26,6 +26,7 @@ export class ColorPickerHeader extends Disposable { private readonly _domNode: HTMLElement; private readonly _pickedColorNode: HTMLElement; + private readonly _pickedColorPresentation: HTMLElement; private readonly _originalColorNode: HTMLElement; private readonly _closeButton: CloseButton | null = null; private backgroundColor: Color; @@ -37,6 +38,9 @@ export class ColorPickerHeader extends Disposable { dom.append(container, this._domNode); this._pickedColorNode = dom.append(this._domNode, $('.picked-color')); + dom.append(this._pickedColorNode, $('span.codicon.codicon-color-mode')); + this._pickedColorPresentation = dom.append(this._pickedColorNode, document.createElement('span')); + this._pickedColorPresentation.classList.add('picked-color-presentation'); const tooltip = localize('clickToToggleColorOptions', "Click to toggle color options (rgb/hsl/hex)"); this._pickedColorNode.setAttribute('title', tooltip); @@ -91,8 +95,7 @@ export class ColorPickerHeader extends Disposable { } private onDidChangePresentation(): void { - this._pickedColorNode.textContent = this.model.presentation ? this.model.presentation.label : ''; - this._pickedColorNode.prepend($('.codicon.codicon-color-mode')); + this._pickedColorPresentation.textContent = this.model.presentation ? this.model.presentation.label : ''; } } @@ -318,11 +321,13 @@ class SaturationBox extends Disposable { this.selection.style.top = `${this.height - v * this.height}px`; } - private onDidChangeColor(): void { + private onDidChangeColor(color: Color): void { if (this.monitor && this.monitor.isMonitoring()) { return; } this.paint(); + const hsva = color.hsva; + this.paintSelection(hsva.s, hsva.v); } } @@ -352,6 +357,7 @@ abstract class Strip extends Disposable { this.slider.style.top = `0px`; this._register(dom.addDisposableListener(this.domNode, dom.EventType.POINTER_DOWN, e => this.onPointerDown(e))); + this._register(model.onDidChangeColor(this.onDidChangeColor, this)); this.layout(); } @@ -362,6 +368,11 @@ abstract class Strip extends Disposable { this.updateSliderPosition(value); } + protected onDidChangeColor(color: Color) { + const value = this.getValue(color); + this.updateSliderPosition(value); + } + private onPointerDown(e: PointerEvent): void { if (!e.target || !(e.target instanceof Element)) { return; @@ -404,11 +415,11 @@ class OpacityStrip extends Strip { super(container, model, showingStandaloneColorPicker); this.domNode.classList.add('opacity-strip'); - this._register(model.onDidChangeColor(this.onDidChangeColor, this)); this.onDidChangeColor(this.model.color); } - private onDidChangeColor(color: Color): void { + protected override onDidChangeColor(color: Color): void { + super.onDidChangeColor(color); const { r, g, b } = color.rgba; const opaque = new Color(new RGBA(r, g, b, 1)); const transparent = new Color(new RGBA(r, g, b, 0)); diff --git a/src/vs/editor/contrib/colorPicker/browser/standaloneColorPickerWidget.ts b/src/vs/editor/contrib/colorPicker/browser/standaloneColorPickerWidget.ts index 6d874e71d4b0b..a6ef1b751165e 100644 --- a/src/vs/editor/contrib/colorPicker/browser/standaloneColorPickerWidget.ts +++ b/src/vs/editor/contrib/colorPicker/browser/standaloneColorPickerWidget.ts @@ -87,11 +87,10 @@ export class StandaloneColorPickerWidget extends Disposable implements IContentW static readonly ID = 'editor.contrib.standaloneColorPickerWidget'; readonly allowEditorOverflow = true; - private body: HTMLElement = document.createElement('div'); - private readonly _position: Position | undefined = undefined; private readonly _standaloneColorPickerParticipant: StandaloneColorPickerParticipant; + private _body: HTMLElement = document.createElement('div'); private _colorHover: StandaloneColorPickerHover | null = null; private _selectionSetInEditor: boolean = false; @@ -120,7 +119,7 @@ export class StandaloneColorPickerWidget extends Disposable implements IContentW endLineNumber: editorSelection.endLineNumber, endColumn: editorSelection.endColumn } : { startLineNumber: 0, endLineNumber: 0, endColumn: 0, startColumn: 0 }; - const focusTracker = this._register(dom.trackFocus(this.body)); + const focusTracker = this._register(dom.trackFocus(this._body)); this._register(focusTracker.onDidBlur(_ => { this.hide(); })); @@ -146,6 +145,7 @@ export class StandaloneColorPickerWidget extends Disposable implements IContentW this._render(result.value, result.foundInEditor); })); this._start(selection); + this._body.style.zIndex = '50'; this._editor.addContentWidget(this); } @@ -160,7 +160,7 @@ export class StandaloneColorPickerWidget extends Disposable implements IContentW } public getDomNode(): HTMLElement { - return this.body; + return this._body; } public getPosition(): IContentWidgetPosition | null { @@ -186,7 +186,7 @@ export class StandaloneColorPickerWidget extends Disposable implements IContentW public focus(): void { this._standaloneColorPickerFocused.set(true); - this.body.focus(); + this._body.focus(); } private async _start(selection: IRange) { @@ -230,11 +230,11 @@ export class StandaloneColorPickerWidget extends Disposable implements IContentW if (colorPickerWidget === undefined) { return; } - this.body.classList.add('standalone-colorpicker-body'); - this.body.style.maxHeight = Math.max(this._editor.getLayoutInfo().height / 4, 250) + 'px'; - this.body.style.maxWidth = Math.max(this._editor.getLayoutInfo().width * 0.66, 500) + 'px'; - this.body.tabIndex = 0; - this.body.appendChild(fragment); + this._body.classList.add('standalone-colorpicker-body'); + this._body.style.maxHeight = Math.max(this._editor.getLayoutInfo().height / 4, 250) + 'px'; + this._body.style.maxWidth = Math.max(this._editor.getLayoutInfo().width * 0.66, 500) + 'px'; + this._body.tabIndex = 0; + this._body.appendChild(fragment); colorPickerWidget.layout(); const colorPickerBody = colorPickerWidget.body; diff --git a/src/vs/editor/contrib/contextmenu/browser/contextmenu.ts b/src/vs/editor/contrib/contextmenu/browser/contextmenu.ts index 4eef122381b1f..e6f6c2b49e4b2 100644 --- a/src/vs/editor/contrib/contextmenu/browser/contextmenu.ts +++ b/src/vs/editor/contrib/contextmenu/browser/contextmenu.ts @@ -5,7 +5,7 @@ import * as dom from 'vs/base/browser/dom'; import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent'; -import { IMouseWheelEvent } from 'vs/base/browser/mouseEvent'; +import { IMouseEvent, IMouseWheelEvent } from 'vs/base/browser/mouseEvent'; import { ActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems'; import { IAnchor } from 'vs/base/browser/ui/contextview/contextview'; import { IAction, Separator, SubmenuAction } from 'vs/base/common/actions'; @@ -103,7 +103,7 @@ export class ContextMenuController implements IEditorContribution { e.event.stopPropagation(); if (e.target.type === MouseTargetType.SCROLLBAR) { - return this._showScrollbarContextMenu({ x: e.event.posx - 1, width: 2, y: e.event.posy - 1, height: 2 }); + return this._showScrollbarContextMenu(e.event); } if (e.target.type !== MouseTargetType.CONTENT_TEXT && e.target.type !== MouseTargetType.CONTENT_EMPTY && e.target.type !== MouseTargetType.TEXTAREA) { @@ -129,16 +129,16 @@ export class ContextMenuController implements IEditorContribution { } // Unless the user triggerd the context menu through Shift+F10, use the mouse position as menu position - let anchor: IAnchor | null = null; + let anchor: IMouseEvent | null = null; if (e.target.type !== MouseTargetType.TEXTAREA) { - anchor = { x: e.event.posx - 1, width: 2, y: e.event.posy - 1, height: 2 }; + anchor = e.event; } // Show the context menu this.showContextMenu(anchor); } - public showContextMenu(anchor?: IAnchor | null): void { + public showContextMenu(anchor?: IMouseEvent | null): void { if (!this._editor.getOption(EditorOption.contextmenu)) { return; // Context menu is turned off through configuration } @@ -193,7 +193,7 @@ export class ContextMenuController implements IEditorContribution { return result; } - private _doShowContextMenu(actions: IAction[], anchor: IAnchor | null = null): void { + private _doShowContextMenu(actions: IAction[], event: IMouseEvent | null = null): void { if (!this._editor.hasModel()) { return; } @@ -206,6 +206,7 @@ export class ContextMenuController implements IEditorContribution { } }); + let anchor: IMouseEvent | IAnchor | null = event; if (!anchor) { // Ensure selection is visible this._editor.revealPosition(this._editor.getPosition(), ScrollType.Immediate); @@ -259,7 +260,7 @@ export class ContextMenuController implements IEditorContribution { }); } - private _showScrollbarContextMenu(anchor: IAnchor): void { + private _showScrollbarContextMenu(anchor: IMouseEvent): void { if (!this._editor.hasModel()) { return; } diff --git a/src/vs/editor/contrib/dropOrPasteInto/browser/copyPasteController.ts b/src/vs/editor/contrib/dropOrPasteInto/browser/copyPasteController.ts index 3ff93ce28e10e..30e79607eb199 100644 --- a/src/vs/editor/contrib/dropOrPasteInto/browser/copyPasteController.ts +++ b/src/vs/editor/contrib/dropOrPasteInto/browser/copyPasteController.ts @@ -11,7 +11,6 @@ import { UriList, VSDataTransfer, createStringDataTransferItem, matchesMimeType import { Disposable } from 'vs/base/common/lifecycle'; import { Mimes } from 'vs/base/common/mime'; import * as platform from 'vs/base/common/platform'; -import { withUndefinedAsNull } from 'vs/base/common/types'; import { generateUuid } from 'vs/base/common/uuid'; import { ClipboardEventUtils } from 'vs/editor/browser/controller/textAreaInput'; import { toExternalVSDataTransfer, toVSDataTransfer } from 'vs/editor/browser/dnd'; @@ -24,7 +23,7 @@ import { Handler, IEditorContribution, PastePayload } from 'vs/editor/common/edi import { DocumentPasteEdit, DocumentPasteEditProvider } from 'vs/editor/common/languages'; import { ITextModel } from 'vs/editor/common/model'; import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; -import { createCombinedWorkspaceEdit } from 'vs/editor/contrib/dropOrPasteInto/browser/edit'; +import { createCombinedWorkspaceEdit, sortEditsByYieldTo } from 'vs/editor/contrib/dropOrPasteInto/browser/edit'; import { CodeEditorStateFlag, EditorStateCancellationTokenSource } from 'vs/editor/contrib/editorState/browser/editorState'; import { InlineProgressManager } from 'vs/editor/contrib/inlineProgress/browser/inlineProgress'; import { localize } from 'vs/nls'; @@ -284,12 +283,6 @@ export class CopyPasteController extends Disposable implements IEditorContributi return; } - // If the only edit returned is a text edit, use the default paste handler - if (providerEdits.length === 1 && providerEdits[0].id === 'text') { - await this.applyDefaultPasteHandler(dataTransfer, metadata, tokenSource.token); - return; - } - if (providerEdits.length) { const canShowWidget = editor.getOption(EditorOption.pasteAs).showPasteSelector === 'afterPaste'; return this._postPasteWidgetManager.applyEditAndShowIfNeeded(selections, { activeEditIndex: 0, allEdits: providerEdits }, canShowWidget, tokenSource.token); @@ -324,7 +317,11 @@ export class CopyPasteController extends Disposable implements IEditorContributi } // Filter out any providers the don't match the full data transfer we will send them. - const supportedProviders = allProviders.filter(provider => isSupportedPasteProvider(provider, dataTransfer)); + let supportedProviders = allProviders.filter(provider => isSupportedPasteProvider(provider, dataTransfer)); + if (preferredId) { + // We are looking for a specific edit + supportedProviders = supportedProviders.filter(edit => edit.id === preferredId); + } const providerEdits = await this.getPasteEdits(supportedProviders, dataTransfer, model, selections, tokenSource.token); if (tokenSource.token.isCancellationRequested) { @@ -336,14 +333,13 @@ export class CopyPasteController extends Disposable implements IEditorContributi } let pickedEdit: DocumentPasteEdit | undefined; - if (typeof preferredId === 'string') { - // We are looking for a specific edit - pickedEdit = providerEdits.find(edit => edit.id === preferredId); + if (preferredId) { + pickedEdit = providerEdits.at(0); } else { const selected = await this._quickInputService.pick( providerEdits.map((edit): IQuickPickItem & { edit: DocumentPasteEdit } => ({ label: edit.label, - description: edit.id, + description: edit.providerId, detail: edit.detail, edit, })), { @@ -398,7 +394,7 @@ export class CopyPasteController extends Disposable implements IEditorContributi return { defaultPastePayload: { mode: metadata.mode, - multicursorText: withUndefinedAsNull(metadata.multicursorText), + multicursorText: metadata.multicursorText ?? null, pasteOnNewLine: !!metadata.isFromEmptySelection, }, }; @@ -431,19 +427,23 @@ export class CopyPasteController extends Disposable implements IEditorContributi } } - private async getPasteEdits(providers: readonly DocumentPasteEditProvider[], dataTransfer: VSDataTransfer, model: ITextModel, selections: readonly Selection[], token: CancellationToken): Promise { - const result = await raceCancellation( - Promise.all(providers.map(provider => { + private async getPasteEdits(providers: readonly DocumentPasteEditProvider[], dataTransfer: VSDataTransfer, model: ITextModel, selections: readonly Selection[], token: CancellationToken): Promise> { + const results = await raceCancellation( + Promise.all(providers.map(async provider => { try { - return provider.provideDocumentPasteEdits?.(model, selections, dataTransfer, token); + const edit = await provider.provideDocumentPasteEdits?.(model, selections, dataTransfer, token); + if (edit) { + return { ...edit, providerId: provider.id }; + } } catch (err) { console.error(err); - return undefined; } - })).then(coalesce), + return undefined; + })), token); - result?.sort((a, b) => b.priority - a.priority); - return result ?? []; + const edits = coalesce(results ?? []); + sortEditsByYieldTo(edits); + return edits; } private async applyDefaultPasteHandler(dataTransfer: VSDataTransfer, metadata: CopyMetadata | undefined, token: CancellationToken) { diff --git a/src/vs/editor/contrib/dropOrPasteInto/browser/defaultProviders.ts b/src/vs/editor/contrib/dropOrPasteInto/browser/defaultProviders.ts index f0f6ac8348d7c..69ff4dc318181 100644 --- a/src/vs/editor/contrib/dropOrPasteInto/browser/defaultProviders.ts +++ b/src/vs/editor/contrib/dropOrPasteInto/browser/defaultProviders.ts @@ -29,12 +29,12 @@ abstract class SimplePasteAndDropProvider implements DocumentOnDropEditProvider, async provideDocumentPasteEdits(_model: ITextModel, _ranges: readonly IRange[], dataTransfer: IReadonlyVSDataTransfer, token: CancellationToken): Promise { const edit = await this.getEdit(dataTransfer, token); - return edit ? { id: this.id, insertText: edit.insertText, label: edit.label, detail: edit.detail, priority: edit.priority } : undefined; + return edit ? { insertText: edit.insertText, label: edit.label, detail: edit.detail, handledMimeType: edit.handledMimeType, yieldTo: edit.yieldTo } : undefined; } async provideDocumentOnDropEdits(_model: ITextModel, _position: IPosition, dataTransfer: IReadonlyVSDataTransfer, token: CancellationToken): Promise { const edit = await this.getEdit(dataTransfer, token); - return edit ? { id: this.id, insertText: edit.insertText, label: edit.label, priority: edit.priority } : undefined; + return edit ? { insertText: edit.insertText, label: edit.label, handledMimeType: edit.handledMimeType, yieldTo: edit.yieldTo } : undefined; } protected abstract getEdit(dataTransfer: IReadonlyVSDataTransfer, token: CancellationToken): Promise; @@ -46,7 +46,7 @@ class DefaultTextProvider extends SimplePasteAndDropProvider { readonly dropMimeTypes = [Mimes.text]; readonly pasteMimeTypes = [Mimes.text]; - protected async getEdit(dataTransfer: IReadonlyVSDataTransfer, _token: CancellationToken) { + protected async getEdit(dataTransfer: IReadonlyVSDataTransfer, _token: CancellationToken): Promise { const textEntry = dataTransfer.get(Mimes.text); if (!textEntry) { return; @@ -60,8 +60,7 @@ class DefaultTextProvider extends SimplePasteAndDropProvider { const insertText = await textEntry.asString(); return { - id: this.id, - priority: 0, + handledMimeType: Mimes.text, label: localize('text.label', "Insert Plain Text"), detail: builtInLabel, insertText @@ -75,7 +74,7 @@ class PathProvider extends SimplePasteAndDropProvider { readonly dropMimeTypes = [Mimes.uriList]; readonly pasteMimeTypes = [Mimes.uriList]; - protected async getEdit(dataTransfer: IReadonlyVSDataTransfer, token: CancellationToken) { + protected async getEdit(dataTransfer: IReadonlyVSDataTransfer, token: CancellationToken): Promise { const entries = await extractUriList(dataTransfer); if (!entries.length || token.isCancellationRequested) { return; @@ -107,8 +106,7 @@ class PathProvider extends SimplePasteAndDropProvider { } return { - id: this.id, - priority: 0, + handledMimeType: Mimes.uriList, insertText, label, detail: builtInLabel, @@ -128,7 +126,7 @@ class RelativePathProvider extends SimplePasteAndDropProvider { super(); } - protected async getEdit(dataTransfer: IReadonlyVSDataTransfer, token: CancellationToken) { + protected async getEdit(dataTransfer: IReadonlyVSDataTransfer, token: CancellationToken): Promise { const entries = await extractUriList(dataTransfer); if (!entries.length || token.isCancellationRequested) { return; @@ -144,8 +142,7 @@ class RelativePathProvider extends SimplePasteAndDropProvider { } return { - id: this.id, - priority: 0, + handledMimeType: Mimes.uriList, insertText: relativeUris.join(' '), label: entries.length > 1 ? localize('defaultDropProvider.uriList.relativePaths', "Insert Relative Paths") diff --git a/src/vs/editor/contrib/dropOrPasteInto/browser/dropIntoEditorContribution.ts b/src/vs/editor/contrib/dropOrPasteInto/browser/dropIntoEditorContribution.ts index a57d194fc7f88..4817431d18934 100644 --- a/src/vs/editor/contrib/dropOrPasteInto/browser/dropIntoEditorContribution.ts +++ b/src/vs/editor/contrib/dropOrPasteInto/browser/dropIntoEditorContribution.ts @@ -6,11 +6,14 @@ import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { EditorCommand, EditorContributionInstantiation, ServicesAccessor, registerEditorCommand, registerEditorContribution } from 'vs/editor/browser/editorExtensions'; +import { editorConfigurationBaseNode } from 'vs/editor/common/config/editorConfigurationSchema'; import { registerEditorFeature } from 'vs/editor/common/editorFeatures'; import { DefaultDropProvidersFeature } from 'vs/editor/contrib/dropOrPasteInto/browser/defaultProviders'; +import * as nls from 'vs/nls'; +import { Extensions as ConfigurationExtensions, ConfigurationScope, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; -import { DropIntoEditorController, changeDropTypeCommandId, dropWidgetVisibleCtx } from './dropIntoEditorController'; - +import { Registry } from 'vs/platform/registry/common/platform'; +import { DropIntoEditorController, changeDropTypeCommandId, defaultProviderConfig, dropWidgetVisibleCtx } from './dropIntoEditorController'; registerEditorContribution(DropIntoEditorController.ID, DropIntoEditorController, EditorContributionInstantiation.BeforeFirstInteraction); @@ -32,3 +35,18 @@ registerEditorCommand(new class extends EditorCommand { }); registerEditorFeature(DefaultDropProvidersFeature); + +Registry.as(ConfigurationExtensions.Configuration).registerConfiguration({ + ...editorConfigurationBaseNode, + properties: { + [defaultProviderConfig]: { + type: 'object', + scope: ConfigurationScope.LANGUAGE_OVERRIDABLE, + description: nls.localize('defaultProviderDescription', "Configures the default drop provider to use for content of a given mime type."), + default: {}, + additionalProperties: { + type: 'string', + }, + }, + } +}); diff --git a/src/vs/editor/contrib/dropOrPasteInto/browser/dropIntoEditorController.ts b/src/vs/editor/contrib/dropOrPasteInto/browser/dropIntoEditorController.ts index d9ce83283726d..48dae75565c4c 100644 --- a/src/vs/editor/contrib/dropOrPasteInto/browser/dropIntoEditorController.ts +++ b/src/vs/editor/contrib/dropOrPasteInto/browser/dropIntoEditorController.ts @@ -5,7 +5,7 @@ import { coalesce } from 'vs/base/common/arrays'; import { CancelablePromise, createCancelablePromise, raceCancellation } from 'vs/base/common/async'; -import { VSDataTransfer } from 'vs/base/common/dataTransfer'; +import { VSDataTransfer, matchesMimeType } from 'vs/base/common/dataTransfer'; import { Disposable } from 'vs/base/common/lifecycle'; import { toExternalVSDataTransfer } from 'vs/editor/browser/dnd'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; @@ -13,7 +13,7 @@ import { EditorOption } from 'vs/editor/common/config/editorOptions'; import { IPosition } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; import { IEditorContribution } from 'vs/editor/common/editorCommon'; -import { DocumentOnDropEditProvider } from 'vs/editor/common/languages'; +import { DocumentOnDropEdit, DocumentOnDropEditProvider } from 'vs/editor/common/languages'; import { ITextModel } from 'vs/editor/common/model'; import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; import { DraggedTreeItemsIdentifier } from 'vs/editor/common/services/treeViewsDnd'; @@ -21,11 +21,15 @@ import { ITreeViewsDnDService } from 'vs/editor/common/services/treeViewsDndServ import { CodeEditorStateFlag, EditorStateCancellationTokenSource } from 'vs/editor/contrib/editorState/browser/editorState'; import { InlineProgressManager } from 'vs/editor/contrib/inlineProgress/browser/inlineProgress'; import { localize } from 'vs/nls'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { LocalSelectionTransfer } from 'vs/platform/dnd/browser/dnd'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { sortEditsByYieldTo } from './edit'; import { PostEditWidgetManager } from './postEditWidget'; +export const defaultProviderConfig = 'editor.experimental.dropIntoEditor.defaultProvider'; + export const changeDropTypeCommandId = 'editor.changeDropType'; export const dropWidgetVisibleCtx = new RawContextKey('dropWidgetVisible', false, localize('dropWidgetVisible', "Whether the drop widget is showing")); @@ -48,6 +52,7 @@ export class DropIntoEditorController extends Disposable implements IEditorContr constructor( editor: ICodeEditor, @IInstantiationService instantiationService: IInstantiationService, + @IConfigurationService private readonly _configService: IConfigurationService, @ILanguageFeaturesService private readonly _languageFeaturesService: ILanguageFeaturesService, @ITreeViewsDnDService private readonly _treeViewsDragAndDropService: ITreeViewsDnDService ) { @@ -107,9 +112,10 @@ export class DropIntoEditorController extends Disposable implements IEditorContr } if (edits.length) { + const activeEditIndex = this.getInitialActiveEditIndex(model, edits); const canShowWidget = editor.getOption(EditorOption.dropIntoEditor).showDropSelector === 'afterDrop'; // Pass in the parent token here as it tracks cancelling the entire drop operation - await this._postDropWidgetManager.applyEditAndShowIfNeeded([Range.fromPositions(position)], { activeEditIndex: 0, allEdits: edits }, canShowWidget, token); + await this._postDropWidgetManager.applyEditAndShowIfNeeded([Range.fromPositions(position)], { activeEditIndex, allEdits: edits }, canShowWidget, token); } } finally { tokenSource.dispose(); @@ -123,13 +129,34 @@ export class DropIntoEditorController extends Disposable implements IEditorContr this._currentOperation = p; } - private async getDropEdits(providers: DocumentOnDropEditProvider[], model: ITextModel, position: IPosition, dataTransfer: VSDataTransfer, tokenSource: EditorStateCancellationTokenSource) { - const results = await raceCancellation(Promise.all(providers.map(provider => { - return provider.provideDocumentOnDropEdits(model, position, dataTransfer, tokenSource.token); + private async getDropEdits(providers: readonly DocumentOnDropEditProvider[], model: ITextModel, position: IPosition, dataTransfer: VSDataTransfer, tokenSource: EditorStateCancellationTokenSource) { + const results = await raceCancellation(Promise.all(providers.map(async provider => { + try { + const edit = await provider.provideDocumentOnDropEdits(model, position, dataTransfer, tokenSource.token); + if (edit) { + return { ...edit, providerId: provider.id }; + } + } catch (err) { + console.error(err); + } + return undefined; })), tokenSource.token); + const edits = coalesce(results ?? []); - edits.sort((a, b) => b.priority - a.priority); - return edits; + return sortEditsByYieldTo(edits); + } + + private getInitialActiveEditIndex(model: ITextModel, edits: ReadonlyArray) { + const preferredProviders = this._configService.getValue>(defaultProviderConfig, { resource: model.uri }); + for (const [configMime, desiredId] of Object.entries(preferredProviders)) { + const editIndex = edits.findIndex(edit => + desiredId === edit.providerId + && edit.handledMimeType && matchesMimeType(configMime, [edit.handledMimeType])); + if (editIndex >= 0) { + return editIndex; + } + } + return 0; } private async extractDataTransferData(dragEvent: DragEvent): Promise { diff --git a/src/vs/editor/contrib/dropOrPasteInto/browser/edit.ts b/src/vs/editor/contrib/dropOrPasteInto/browser/edit.ts index f57ad7c191249..e7b42fe784307 100644 --- a/src/vs/editor/contrib/dropOrPasteInto/browser/edit.ts +++ b/src/vs/editor/contrib/dropOrPasteInto/browser/edit.ts @@ -5,7 +5,7 @@ import { URI } from 'vs/base/common/uri'; import { ResourceTextEdit } from 'vs/editor/browser/services/bulkEditService'; -import { WorkspaceEdit } from 'vs/editor/common/languages'; +import { DropYieldTo, WorkspaceEdit } from 'vs/editor/common/languages'; import { Range } from 'vs/editor/common/core/range'; export interface DropOrPasteEdit { @@ -27,3 +27,73 @@ export function createCombinedWorkspaceEdit(uri: URI, ranges: readonly Range[], ] }; } + +export function sortEditsByYieldTo(edits: readonly T[]): T[] { + function yieldsTo(yTo: DropYieldTo, other: T): boolean { + return ('providerId' in yTo && yTo.providerId === other.providerId) + || ('mimeType' in yTo && yTo.mimeType === other.handledMimeType); + } + + // Build list of nodes each node yields to + const yieldsToMap = new Map(); + for (const edit of edits) { + for (const yTo of edit.yieldTo ?? []) { + for (const other of edits) { + if (other === edit) { + continue; + } + + if (yieldsTo(yTo, other)) { + let arr = yieldsToMap.get(edit); + if (!arr) { + arr = []; + yieldsToMap.set(edit, arr); + } + arr.push(other); + } + } + } + } + + if (!yieldsToMap.size) { + return Array.from(edits); + } + + // Topological sort + const visited = new Set(); + const tempStack: T[] = []; + + function visit(nodes: T[]): T[] { + if (!nodes.length) { + return []; + } + + const node = nodes[0]; + if (tempStack.includes(node)) { + console.warn(`Yield to cycle detected for ${node.providerId}`); + return nodes; + } + + if (visited.has(node)) { + return visit(nodes.slice(1)); + } + + let pre: T[] = []; + const yTo = yieldsToMap.get(node); + if (yTo) { + tempStack.push(node); + pre = visit(yTo); + tempStack.pop(); + } + + visited.add(node); + + return [...pre, node, ...visit(nodes.slice(1))]; + } + + return visit(Array.from(edits)); +} diff --git a/src/vs/editor/contrib/dropOrPasteInto/test/browser/editSort.test.ts b/src/vs/editor/contrib/dropOrPasteInto/test/browser/editSort.test.ts new file mode 100644 index 0000000000000..44939652de36d --- /dev/null +++ b/src/vs/editor/contrib/dropOrPasteInto/test/browser/editSort.test.ts @@ -0,0 +1,65 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import * as assert from 'assert'; +import { DocumentOnDropEdit } from 'vs/editor/common/languages'; +import { sortEditsByYieldTo } from 'vs/editor/contrib/dropOrPasteInto/browser/edit'; + +type DropEdit = DocumentOnDropEdit & { providerId: string | undefined }; + +function createTestEdit(providerId: string, args?: Partial): DropEdit { + return { + label: '', + insertText: '', + providerId, + ...args, + }; +} + +suite('sortEditsByYieldTo', () => { + test('Should noop for empty edits', () => { + const edits: DropEdit[] = []; + + assert.deepStrictEqual(sortEditsByYieldTo(edits), []); + }); + + test('Yielded to edit should get sorted after target', () => { + const edits: DropEdit[] = [ + createTestEdit('a', { yieldTo: [{ providerId: 'b' }] }), + createTestEdit('b'), + ]; + assert.deepStrictEqual(sortEditsByYieldTo(edits).map(x => x.providerId), ['b', 'a']); + }); + + test('Should handle chain of yield to', () => { + { + const edits: DropEdit[] = [ + createTestEdit('c', { yieldTo: [{ providerId: 'a' }] }), + createTestEdit('a', { yieldTo: [{ providerId: 'b' }] }), + createTestEdit('b'), + ]; + + assert.deepStrictEqual(sortEditsByYieldTo(edits).map(x => x.providerId), ['b', 'a', 'c']); + } + { + const edits: DropEdit[] = [ + createTestEdit('a', { yieldTo: [{ providerId: 'b' }] }), + createTestEdit('c', { yieldTo: [{ providerId: 'a' }] }), + createTestEdit('b'), + ]; + + assert.deepStrictEqual(sortEditsByYieldTo(edits).map(x => x.providerId), ['b', 'a', 'c']); + } + }); + + test(`Should not reorder when yield to isn't used`, () => { + const edits: DropEdit[] = [ + createTestEdit('c', { yieldTo: [{ providerId: 'x' }] }), + createTestEdit('a', { yieldTo: [{ providerId: 'y' }] }), + createTestEdit('b'), + ]; + + assert.deepStrictEqual(sortEditsByYieldTo(edits).map(x => x.providerId), ['c', 'a', 'b']); + }); +}); diff --git a/src/vs/editor/contrib/find/test/browser/findController.test.ts b/src/vs/editor/contrib/find/test/browser/findController.test.ts index 2cfca11f54718..86f44277667e2 100644 --- a/src/vs/editor/contrib/find/test/browser/findController.test.ts +++ b/src/vs/editor/contrib/find/test/browser/findController.test.ts @@ -63,14 +63,14 @@ function executeAction(instantiationService: IInstantiationService, editor: ICod }); } -suite('FindController', async () => { +suite('FindController', () => { const queryState: { [key: string]: any } = {}; let clipboardState = ''; const serviceCollection = new ServiceCollection(); serviceCollection.set(IStorageService, { _serviceBrand: undefined, onDidChangeTarget: Event.None, - onDidChangeValue: Event.None, + onDidChangeValue: () => Event.None, onWillSaveState: Event.None, get: (key: string) => queryState[key], getBoolean: (key: string) => !!queryState[key], @@ -495,7 +495,7 @@ suite('FindController', async () => { }); }); -suite('FindController query options persistence', async () => { +suite('FindController query options persistence', () => { let queryState: { [key: string]: any } = {}; queryState['editor.isRegex'] = false; queryState['editor.matchCase'] = false; @@ -504,7 +504,7 @@ suite('FindController query options persistence', async () => { serviceCollection.set(IStorageService, { _serviceBrand: undefined, onDidChangeTarget: Event.None, - onDidChangeValue: Event.None, + onDidChangeValue: () => Event.None, onWillSaveState: Event.None, get: (key: string) => queryState[key], getBoolean: (key: string) => !!queryState[key], diff --git a/src/vs/editor/contrib/folding/browser/folding.ts b/src/vs/editor/contrib/folding/browser/folding.ts index 8fe86b49ed82a..6134f4fa40194 100644 --- a/src/vs/editor/contrib/folding/browser/folding.ts +++ b/src/vs/editor/contrib/folding/browser/folding.ts @@ -407,7 +407,7 @@ export class FoldingController extends Disposable implements IEditorContribution switch (e.target.type) { case MouseTargetType.GUTTER_LINE_DECORATIONS: { const data = e.target.detail; - const offsetLeftInGutter = (e.target.element as HTMLElement).offsetLeft; + const offsetLeftInGutter = e.target.element!.offsetLeft; const gutterOffsetX = data.offsetX - offsetLeftInGutter; // const gutterOffsetX = data.offsetX - data.glyphMarginWidth - data.lineNumbersWidth - data.glyphMarginLeft; @@ -908,13 +908,13 @@ class UnfoldAllRegionsAction extends FoldingAction { } } -class FoldAllRegionsExceptAction extends FoldingAction { +class FoldAllExceptAction extends FoldingAction { constructor() { super({ id: 'editor.foldAllExcept', - label: nls.localize('foldAllExcept.label', "Fold All Regions Except Selected"), - alias: 'Fold All Regions Except Selected', + label: nls.localize('foldAllExcept.label', "Fold All Except Selected"), + alias: 'Fold All Except Selected', precondition: CONTEXT_FOLDING_ENABLED, kbOpts: { kbExpr: EditorContextKeys.editorTextFocus, @@ -931,13 +931,13 @@ class FoldAllRegionsExceptAction extends FoldingAction { } -class UnfoldAllRegionsExceptAction extends FoldingAction { +class UnfoldAllExceptAction extends FoldingAction { constructor() { super({ id: 'editor.unfoldAllExcept', - label: nls.localize('unfoldAllExcept.label', "Unfold All Regions Except Selected"), - alias: 'Unfold All Regions Except Selected', + label: nls.localize('unfoldAllExcept.label', "Unfold All Except Selected"), + alias: 'Unfold All Except Selected', precondition: CONTEXT_FOLDING_ENABLED, kbOpts: { kbExpr: EditorContextKeys.editorTextFocus, @@ -1194,8 +1194,8 @@ registerEditorAction(UnfoldAllAction); registerEditorAction(FoldAllBlockCommentsAction); registerEditorAction(FoldAllRegionsAction); registerEditorAction(UnfoldAllRegionsAction); -registerEditorAction(FoldAllRegionsExceptAction); -registerEditorAction(UnfoldAllRegionsExceptAction); +registerEditorAction(FoldAllExceptAction); +registerEditorAction(UnfoldAllExceptAction); registerEditorAction(ToggleFoldAction); registerEditorAction(GotoParentFoldAction); registerEditorAction(GotoPreviousFoldAction); diff --git a/src/vs/editor/contrib/gotoSymbol/browser/link/clickLinkGesture.ts b/src/vs/editor/contrib/gotoSymbol/browser/link/clickLinkGesture.ts index a5777a6153932..2e74af467a926 100644 --- a/src/vs/editor/contrib/gotoSymbol/browser/link/clickLinkGesture.ts +++ b/src/vs/editor/contrib/gotoSymbol/browser/link/clickLinkGesture.ts @@ -100,6 +100,13 @@ function createOptions(multiCursorModifier: 'altKey' | 'ctrlKey' | 'metaKey'): C return new ClickLinkOptions(KeyCode.Alt, 'altKey', KeyCode.Ctrl, 'ctrlKey'); } +export interface IClickLinkGestureOptions { + /** + * Return 0 if the mouse event should not be considered. + */ + extractLineNumberFromMouseEvent?: (e: ClickLinkMouseEvent) => number; +} + export class ClickLinkGesture extends Disposable { private readonly _onMouseMoveOrRelevantKeyDown: Emitter<[ClickLinkMouseEvent, ClickLinkKeyboardEvent | null]> = this._register(new Emitter<[ClickLinkMouseEvent, ClickLinkKeyboardEvent | null]>()); @@ -112,18 +119,18 @@ export class ClickLinkGesture extends Disposable { public readonly onCancel: Event = this._onCancel.event; private readonly _editor: ICodeEditor; - private readonly _alwaysFireExecuteOnMouseUp?: boolean; + private readonly _extractLineNumberFromMouseEvent: (e: ClickLinkMouseEvent) => number; private _opts: ClickLinkOptions; private _lastMouseMoveEvent: ClickLinkMouseEvent | null; private _hasTriggerKeyOnMouseDown: boolean; private _lineNumberOnMouseDown: number; - constructor(editor: ICodeEditor, alwaysFireOnMouseUp?: boolean) { + constructor(editor: ICodeEditor, opts?: IClickLinkGestureOptions) { super(); this._editor = editor; - this._alwaysFireExecuteOnMouseUp = alwaysFireOnMouseUp; + this._extractLineNumberFromMouseEvent = opts?.extractLineNumberFromMouseEvent ?? ((e) => e.target.position ? e.target.position.lineNumber : 0); this._opts = createOptions(this._editor.getOption(EditorOption.multiCursorModifier)); this._lastMouseMoveEvent = null; @@ -178,12 +185,12 @@ export class ClickLinkGesture extends Disposable { // release the mouse button without wanting to do the navigation. // With this flag we prevent goto definition if the mouse was down before the trigger key was pressed. this._hasTriggerKeyOnMouseDown = mouseEvent.hasTriggerModifier; - this._lineNumberOnMouseDown = mouseEvent.target.position ? mouseEvent.target.position.lineNumber : 0; + this._lineNumberOnMouseDown = this._extractLineNumberFromMouseEvent(mouseEvent); } private _onEditorMouseUp(mouseEvent: ClickLinkMouseEvent): void { - const currentLineNumber = mouseEvent.target.position ? mouseEvent.target.position.lineNumber : 0; - if (this._hasTriggerKeyOnMouseDown && this._lineNumberOnMouseDown && this._lineNumberOnMouseDown === currentLineNumber || this._alwaysFireExecuteOnMouseUp) { + const currentLineNumber = this._extractLineNumberFromMouseEvent(mouseEvent); + if (this._hasTriggerKeyOnMouseDown && this._lineNumberOnMouseDown && this._lineNumberOnMouseDown === currentLineNumber) { this._onExecute.fire(mouseEvent); } } diff --git a/src/vs/editor/contrib/gotoSymbol/browser/link/goToDefinitionAtPosition.ts b/src/vs/editor/contrib/gotoSymbol/browser/link/goToDefinitionAtPosition.ts index a71163b6deb8c..f5a08f94c1eb7 100644 --- a/src/vs/editor/contrib/gotoSymbol/browser/link/goToDefinitionAtPosition.ts +++ b/src/vs/editor/contrib/gotoSymbol/browser/link/goToDefinitionAtPosition.ts @@ -9,7 +9,6 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { onUnexpectedError } from 'vs/base/common/errors'; import { MarkdownString } from 'vs/base/common/htmlContent'; import { DisposableStore } from 'vs/base/common/lifecycle'; -import { withNullAsUndefined } from 'vs/base/common/types'; import 'vs/css!./goToDefinitionAtPosition'; import { CodeEditorStateFlag, EditorState } from 'vs/editor/contrib/editorState/browser/editorState'; import { ICodeEditor, MouseTargetType } from 'vs/editor/browser/editorBrowser'; @@ -58,7 +57,7 @@ export class GotoDefinitionAtPositionEditorContribution implements IEditorContri this.toUnhook.add(linkGesture); this.toUnhook.add(linkGesture.onMouseMoveOrRelevantKeyDown(([mouseEvent, keyboardEvent]) => { - this.startFindDefinitionFromMouse(mouseEvent, withNullAsUndefined(keyboardEvent)); + this.startFindDefinitionFromMouse(mouseEvent, keyboardEvent ?? undefined); })); this.toUnhook.add(linkGesture.onExecute((mouseEvent: ClickLinkMouseEvent) => { diff --git a/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesWidget.ts b/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesWidget.ts index ca4597bc57e6d..d23e38b81abd5 100644 --- a/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesWidget.ts +++ b/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesWidget.ts @@ -305,7 +305,7 @@ export class ReferenceWidget extends peekView.PeekViewWidget { useShadows: true, verticalHasArrows: false, horizontalHasArrows: false, - alwaysConsumeMouseWheel: false + alwaysConsumeMouseWheel: true }, overviewRulerLanes: 2, fixedOverflowWidgets: true, diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index e284a83811646..c06e6bac4a747 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as dom from 'vs/base/browser/dom'; -import { HoverAction, HoverWidget } from 'vs/base/browser/ui/hover/hoverWidget'; +import { HoverAction, HoverWidget, getHoverAccessibleViewHint } from 'vs/base/browser/ui/hover/hoverWidget'; import { coalesce } from 'vs/base/common/arrays'; import { CancellationToken } from 'vs/base/common/cancellation'; import { KeyCode } from 'vs/base/common/keyCodes'; @@ -24,13 +24,16 @@ import { AsyncIterableObject } from 'vs/base/common/async'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { ResizableContentWidget } from 'vs/editor/contrib/hover/browser/resizableContentWidget'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; + const $ = dom.$; export class ContentHoverController extends Disposable { private readonly _participants: IEditorHoverParticipant[]; - private readonly _widget = this._register(this._instantiationService.createInstance(ContentHoverWidget, this._editor)); + private readonly _widget: ContentHoverWidget; getWidgetContent(): string | undefined { const node = this._widget.getDomNode(); @@ -52,6 +55,8 @@ export class ContentHoverController extends Disposable { ) { super(); + this._widget = this._register(this._instantiationService.createInstance(ContentHoverWidget, this._editor)); + // Instantiate participants and sort them by `hoverOrdinal` which is relevant for rendering order. this._participants = []; for (const participant of HoverParticipantRegistry.getAll()) { @@ -215,18 +220,26 @@ export class ContentHoverController extends Disposable { this._setCurrentResult(null); } - public isColorPickerVisible(): boolean { + public get isColorPickerVisible(): boolean { return this._widget.isColorPickerVisible; } - public isVisibleFromKeyboard(): boolean { + public get isVisibleFromKeyboard(): boolean { return this._widget.isVisibleFromKeyboard; } - public isVisible(): boolean { + public get isVisible(): boolean { return this._widget.isVisible; } + public get isFocused(): boolean { + return this._widget.isFocused; + } + + public get isResizing(): boolean { + return this._widget.isResizing; + } + public containsNode(node: Node | null | undefined): boolean { return (node ? this._widget.getDomNode().contains(node) : false); } @@ -276,6 +289,7 @@ export class ContentHoverController extends Disposable { statusBar, setColorPicker: (widget) => colorPicker = widget, onContentsChanged: () => this._widget.onContentsChanged(), + setMinimumDimensions: (dimensions: dom.Dimension) => this._widget.setMinimumDimensions(dimensions), hide: () => this.hide() }; @@ -459,6 +473,8 @@ export class ContentHoverWidget extends ResizableContentWidget { private _visibleData: ContentHoverVisibleData | undefined; private _positionPreference: ContentWidgetPositionPreference | undefined; + private _minimumSize: dom.Dimension; + private _contentWidth: number | undefined; private readonly _hover: HoverWidget = this._register(new HoverWidget()); private readonly _hoverVisibleKey: IContextKey; @@ -476,11 +492,22 @@ export class ContentHoverWidget extends ResizableContentWidget { return this._hoverVisibleKey.get() ?? false; } + public get isFocused(): boolean { + return this._hoverFocusedKey.get() ?? false; + } + constructor( editor: ICodeEditor, - @IContextKeyService contextKeyService: IContextKeyService + @IContextKeyService contextKeyService: IContextKeyService, + @IConfigurationService private readonly _configurationService: IConfigurationService, + @IAccessibilityService private readonly _accessibilityService: IAccessibilityService, + @IKeybindingService private readonly _keybindingService: IKeybindingService ) { - super(editor); + const minimumHeight = editor.getOption(EditorOption.lineHeight) + 8; + const minimumWidth = 150; + const minimumSize = new dom.Dimension(minimumWidth, minimumHeight); + super(editor, minimumSize); + this._minimumSize = minimumSize; this._hoverVisibleKey = EditorContextKeys.hoverVisible.bindTo(contextKeyService); this._hoverFocusedKey = EditorContextKeys.hoverFocused.bindTo(contextKeyService); @@ -538,12 +565,18 @@ export class ContentHoverWidget extends ResizableContentWidget { this._layoutContentWidget(); } - private _setContentsDomNodeMaxDimensions(width: number | string, height: number | string): void { + private static _applyMaxDimensions(container: HTMLElement, width: number | string, height: number | string) { const transformedWidth = typeof width === 'number' ? `${width}px` : width; const transformedHeight = typeof height === 'number' ? `${height}px` : height; - const contentsDomNode = this._hover.contentsDomNode; - contentsDomNode.style.maxWidth = transformedWidth; - contentsDomNode.style.maxHeight = transformedHeight; + container.style.maxWidth = transformedWidth; + container.style.maxHeight = transformedHeight; + } + + private _setHoverWidgetMaxDimensions(width: number | string, height: number | string): void { + ContentHoverWidget._applyMaxDimensions(this._hover.contentsDomNode, width, height); + ContentHoverWidget._applyMaxDimensions(this._hover.containerDomNode, width, height); + this._hover.containerDomNode.style.setProperty('--vscode-hover-maxWidth', typeof width === 'number' ? `${width}px` : width); + this._layoutContentWidget(); } private _hasHorizontalScrollbar(): boolean { @@ -561,7 +594,7 @@ export class ContentHoverWidget extends ResizableContentWidget { } private _setAdjustedHoverWidgetDimensions(size: dom.Dimension): void { - this._setContentsDomNodeMaxDimensions('none', 'none'); + this._setHoverWidgetMaxDimensions('none', 'none'); const width = size.width; const height = size.height; this._setHoverWidgetDimensions(width, height); @@ -572,17 +605,18 @@ export class ContentHoverWidget extends ResizableContentWidget { } } - private _setResizableNodeMaxDimensions(): void { + private _updateResizableNodeMaxDimensions(): void { const maxRenderingWidth = this._findMaximumRenderingWidth() ?? Infinity; const maxRenderingHeight = this._findMaximumRenderingHeight() ?? Infinity; this._resizableNode.maxSize = new dom.Dimension(maxRenderingWidth, maxRenderingHeight); + this._setHoverWidgetMaxDimensions(maxRenderingWidth, maxRenderingHeight); } protected override _resize(size: dom.Dimension): void { ContentHoverWidget._lastDimensions = new dom.Dimension(size.width, size.height); this._setAdjustedHoverWidgetDimensions(size); this._resizableNode.layout(size.height, size.width); - this._setResizableNodeMaxDimensions(); + this._updateResizableNodeMaxDimensions(); this._hover.scrollbar.scanDomNode(); this._editor.layoutContentWidget(this); this._visibleData?.colorPicker?.layout(); @@ -612,13 +646,41 @@ export class ContentHoverWidget extends ResizableContentWidget { return Math.min(availableSpace, maximumHeight); } + private _isHoverTextOverflowing(): boolean { + // To find out if the text is overflowing, we will disable wrapping, check the widths, and then re-enable wrapping + this._hover.containerDomNode.style.setProperty('--vscode-hover-whiteSpace', 'nowrap'); + this._hover.containerDomNode.style.setProperty('--vscode-hover-sourceWhiteSpace', 'nowrap'); + + const overflowing = Array.from(this._hover.contentsDomNode.children).some((hoverElement) => { + return hoverElement.scrollWidth > hoverElement.clientWidth; + }); + + this._hover.containerDomNode.style.removeProperty('--vscode-hover-whiteSpace'); + this._hover.containerDomNode.style.removeProperty('--vscode-hover-sourceWhiteSpace'); + + return overflowing; + } + private _findMaximumRenderingWidth(): number | undefined { if (!this._editor || !this._editor.hasModel()) { return; } - const bodyBoxWidth = dom.getClientArea(document.body).width; - const horizontalPadding = 14; - return bodyBoxWidth - horizontalPadding; + + const overflowing = this._isHoverTextOverflowing(); + + const initialWidth = ( + typeof this._contentWidth === 'undefined' + ? 0 + : this._contentWidth - 2 // - 2 for the borders + ); + + if (overflowing || this._hover.containerDomNode.clientWidth < initialWidth) { + const bodyBoxWidth = dom.getClientArea(document.body).width; + const horizontalPadding = 14; + return bodyBoxWidth - horizontalPadding; + } else { + return this._hover.containerDomNode.clientWidth + 2; + } } public isMouseGettingCloser(posx: number, posy: number): boolean { @@ -652,13 +714,11 @@ export class ContentHoverWidget extends ResizableContentWidget { } private _layout(): void { - const height = Math.max(this._editor.getLayoutInfo().height / 4, 250, ContentHoverWidget._lastDimensions.height); - const width = Math.max(this._editor.getLayoutInfo().width * 0.66, 500, ContentHoverWidget._lastDimensions.width); const { fontSize, lineHeight } = this._editor.getOption(EditorOption.fontInfo); const contentsDomNode = this._hover.contentsDomNode; contentsDomNode.style.fontSize = `${fontSize}px`; contentsDomNode.style.lineHeight = `${lineHeight / fontSize}`; - this._setContentsDomNodeMaxDimensions(width, height); + this._updateMaxDimensions(); } private _updateFont(): void { @@ -678,17 +738,17 @@ export class ContentHoverWidget extends ResizableContentWidget { this._hover.onContentsChanged(); } - private _updateContentsDomNodeMaxDimensions() { + private _updateMaxDimensions() { const height = Math.max(this._editor.getLayoutInfo().height / 4, 250, ContentHoverWidget._lastDimensions.height); const width = Math.max(this._editor.getLayoutInfo().width * 0.66, 500, ContentHoverWidget._lastDimensions.width); - this._setContentsDomNodeMaxDimensions(width, height); + this._setHoverWidgetMaxDimensions(width, height); } private _render(node: DocumentFragment, hoverData: ContentHoverVisibleData) { this._setHoverData(hoverData); this._updateFont(); this._updateContent(node); - this._updateContentsDomNodeMaxDimensions(); + this._updateMaxDimensions(); this.onContentsChanged(); // Simply force a synchronous render on the editor // such that the widget does not really render with left = '0px' @@ -723,6 +783,12 @@ export class ContentHoverWidget extends ResizableContentWidget { this._hover.containerDomNode.focus(); } hoverData.colorPicker?.layout(); + + // The aria label overrides the label, so if we add to it, add the contents of the hover + const accessibleViewHint = getHoverAccessibleViewHint(this._configurationService.getValue('accessibility.verbosity.hover') === true && this._accessibilityService.isScreenReaderOptimized(), this._keybindingService.lookupKeybinding('editor.action.accessibleView')?.getAriaLabel() ?? ''); + if (accessibleViewHint) { + this._hover.contentsDomNode.ariaLabel = this._hover.contentsDomNode.textContent + ', ' + accessibleViewHint; + } } public hide(): void { @@ -755,6 +821,25 @@ export class ContentHoverWidget extends ResizableContentWidget { this._setContentsDomNodeDimensions(dom.getTotalWidth(contentsDomNode), Math.min(maxRenderingHeight, height - SCROLLBAR_WIDTH)); } + public setMinimumDimensions(dimensions: dom.Dimension): void { + // We combine the new minimum dimensions with the previous ones + this._minimumSize = new dom.Dimension( + Math.max(this._minimumSize.width, dimensions.width), + Math.max(this._minimumSize.height, dimensions.height) + ); + this._updateMinimumWidth(); + } + + private _updateMinimumWidth(): void { + const width = ( + typeof this._contentWidth === 'undefined' + ? this._minimumSize.width + : Math.min(this._contentWidth, this._minimumSize.width) + ); + // We want to avoid that the hover is artificially large, so we use the content width as minimum width + this._resizableNode.minSize = new dom.Dimension(width, this._minimumSize.height); + } + public onContentsChanged(): void { this._removeConstraintsRenderNormally(); const containerDomNode = this._hover.containerDomNode; @@ -767,12 +852,18 @@ export class ContentHoverWidget extends ResizableContentWidget { height = dom.getTotalHeight(containerDomNode); width = dom.getTotalWidth(containerDomNode); + this._contentWidth = width; + this._updateMinimumWidth(); this._resizableNode.layout(height, width); if (this._hasHorizontalScrollbar()) { this._adjustContentsBottomPadding(); this._adjustHoverHeightForScrollbar(height); } + if (this._visibleData?.showAtPosition) { + const widgetHeight = dom.getTotalHeight(this._hover.containerDomNode); + this._positionPreference = this._findPositionPreference(widgetHeight, this._visibleData.showAtPosition); + } this._layoutContentWidget(); } diff --git a/src/vs/editor/contrib/hover/browser/hover.ts b/src/vs/editor/contrib/hover/browser/hover.ts index 46c94e313df48..2c1e2b2611e7e 100644 --- a/src/vs/editor/contrib/hover/browser/hover.ts +++ b/src/vs/editor/contrib/hover/browser/hover.ts @@ -155,6 +155,10 @@ export class ModesHoverController implements IEditorContribution { private _onEditorMouseMove(mouseEvent: IEditorMouseEvent): void { const target = mouseEvent.target; + if (this._contentWidget?.isFocused || this._contentWidget?.isResizing) { + return; + } + if (this._isMouseDown && this._hoverClicked) { return; } @@ -171,7 +175,7 @@ export class ModesHoverController implements IEditorContribution { if ( !this._isHoverSticky && target.type === MouseTargetType.CONTENT_WIDGET && target.detail === ContentHoverWidget.ID - && this._contentWidget?.isColorPickerVisible() + && this._contentWidget?.isColorPickerVisible ) { // though the hover is not sticky, the color picker needs to. return; @@ -182,7 +186,7 @@ export class ModesHoverController implements IEditorContribution { return; } - if (this._isHoverSticky && this._contentWidget?.isVisibleFromKeyboard()) { + if (this._isHoverSticky && this._contentWidget?.isVisibleFromKeyboard) { // Sticky mode is on and the hover has been shown via keyboard // so moving the mouse has no effect return; @@ -216,9 +220,10 @@ export class ModesHoverController implements IEditorContribution { this._glyphWidget.startShowingAt(target.position.lineNumber); return; } - if (!this._contentWidget?.widget.isResizing && !_sticky) { - this._hideWidgets(); + if (_sticky) { + return; } + this._hideWidgets(); } private _onKeyDown(e: IKeyboardEvent): void { @@ -228,7 +233,7 @@ export class ModesHoverController implements IEditorContribution { const resolvedKeyboardEvent = this._keybindingService.softDispatch(e, this._editor.getDomNode()); // If the beginning of a multi-chord keybinding is pressed, or the command aims to focus the hover, set the variable to true, otherwise false - const mightTriggerFocus = (resolvedKeyboardEvent.kind === ResultKind.MoreChordsNeeded || (resolvedKeyboardEvent.kind === ResultKind.KbFound && resolvedKeyboardEvent.commandId === 'editor.action.showHover' && this._contentWidget?.isVisible())); + const mightTriggerFocus = (resolvedKeyboardEvent.kind === ResultKind.MoreChordsNeeded || (resolvedKeyboardEvent.kind === ResultKind.KbFound && resolvedKeyboardEvent.commandId === 'editor.action.showHover' && this._contentWidget?.isVisible)); if (e.keyCode !== KeyCode.Ctrl && e.keyCode !== KeyCode.Alt && e.keyCode !== KeyCode.Meta && e.keyCode !== KeyCode.Shift && !mightTriggerFocus) { @@ -241,7 +246,7 @@ export class ModesHoverController implements IEditorContribution { if (_sticky) { return; } - if ((this._isMouseDown && this._hoverClicked && this._contentWidget?.isColorPickerVisible()) || InlineSuggestionHintsContentWidget.dropDownVisible) { + if ((this._isMouseDown && this._hoverClicked && this._contentWidget?.isColorPickerVisible) || InlineSuggestionHintsContentWidget.dropDownVisible) { return; } this._hoverActivatedByColorDecoratorClick = false; @@ -257,10 +262,6 @@ export class ModesHoverController implements IEditorContribution { return this._contentWidget; } - public isColorPickerVisible(): boolean { - return this._contentWidget?.isColorPickerVisible() || false; - } - public showContentHover(range: Range, mode: HoverStartMode, source: HoverStartSource, focus: boolean, activatedByColorDecoratorClick: boolean = false): void { this._hoverActivatedByColorDecoratorClick = activatedByColorDecoratorClick; this._getOrCreateContentWidget().startShowingAtRange(range, mode, source, focus); @@ -302,8 +303,12 @@ export class ModesHoverController implements IEditorContribution { this._contentWidget?.goToBottom(); } - public isHoverVisible(): boolean | undefined { - return this._contentWidget?.isVisible(); + public get isColorPickerVisible(): boolean | undefined { + return this._contentWidget?.isColorPickerVisible; + } + + public get isHoverVisible(): boolean | undefined { + return this._contentWidget?.isVisible; } public dispose(): void { @@ -367,7 +372,7 @@ class ShowOrFocusHoverAction extends EditorAction { const range = new Range(position.lineNumber, position.column, position.lineNumber, position.column); const focus = editor.getOption(EditorOption.accessibilitySupport) === AccessibilitySupport.Enabled || !!args?.focus; - if (controller.isHoverVisible()) { + if (controller.isHoverVisible) { controller.focus(); } else { controller.showContentHover(range, HoverStartMode.Immediate, HoverStartSource.Keyboard, focus); diff --git a/src/vs/editor/contrib/hover/browser/hoverTypes.ts b/src/vs/editor/contrib/hover/browser/hoverTypes.ts index 93d4104b197dd..aadc1851a011f 100644 --- a/src/vs/editor/contrib/hover/browser/hoverTypes.ts +++ b/src/vs/editor/contrib/hover/browser/hoverTypes.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { Dimension } from 'vs/base/browser/dom'; import { AsyncIterableObject } from 'vs/base/common/async'; import { CancellationToken } from 'vs/base/common/cancellation'; import { IDisposable } from 'vs/base/common/lifecycle'; @@ -110,6 +111,10 @@ export interface IEditorHoverRenderContext { * The contents rendered inside the fragment have been changed, which means that the hover should relayout. */ onContentsChanged(): void; + /** + * Set the minimum dimensions of the resizable hover + */ + setMinimumDimensions?(dimensions: Dimension): void; /** * Hide the hover. */ diff --git a/src/vs/editor/contrib/hover/browser/resizableContentWidget.ts b/src/vs/editor/contrib/hover/browser/resizableContentWidget.ts index 69b72483fb367..0243d9e88bf48 100644 --- a/src/vs/editor/contrib/hover/browser/resizableContentWidget.ts +++ b/src/vs/editor/contrib/hover/browser/resizableContentWidget.ts @@ -25,13 +25,13 @@ export abstract class ResizableContentWidget extends Disposable implements ICont constructor( protected readonly _editor: ICodeEditor, - initialSize: dom.IDimension = new dom.Dimension(10, 10) + minimumSize: dom.IDimension = new dom.Dimension(10, 10) ) { super(); this._resizableNode.domNode.style.position = 'absolute'; - this._resizableNode.minSize = new dom.Dimension(10, 10); + this._resizableNode.minSize = dom.Dimension.lift(minimumSize); + this._resizableNode.layout(minimumSize.height, minimumSize.width); this._resizableNode.enableSashes(true, true, true, true); - this._resizableNode.layout(initialSize.height, initialSize.width); this._register(this._resizableNode.onDidResize(e => { this._resize(new dom.Dimension(e.dimension.width, e.dimension.height)); if (e.done) { diff --git a/src/vs/editor/contrib/inlineCompletions/browser/commands.ts b/src/vs/editor/contrib/inlineCompletions/browser/commands.ts index 799433568e0a0..ac7535f923173 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/commands.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/commands.ts @@ -148,7 +148,8 @@ export class AcceptInlineCompletion extends EditorAction { InlineCompletionContextKeys.inlineSuggestionVisible, EditorContextKeys.tabMovesFocus.toNegated(), InlineCompletionContextKeys.inlineSuggestionHasIndentationLessThanTabSize, - SuggestContext.Visible.toNegated() + SuggestContext.Visible.toNegated(), + EditorContextKeys.hoverFocused.toNegated(), ), } }); diff --git a/src/vs/editor/contrib/inlineCompletions/browser/ghostText.ts b/src/vs/editor/contrib/inlineCompletions/browser/ghostText.ts index 7c77ba19a3c9c..abd73b8f0dea5 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/ghostText.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/ghostText.ts @@ -118,6 +118,30 @@ export class GhostTextReplacement { isEmpty(): boolean { return this.parts.every(p => p.lines.length === 0); } + + equals(other: GhostTextReplacement): boolean { + return this.lineNumber === other.lineNumber && + this.columnRange.equals(other.columnRange) && + this.newLines.length === other.newLines.length && + this.newLines.every((line, index) => line === other.newLines[index]) && + this.additionalReservedLineCount === other.additionalReservedLineCount; + } } export type GhostTextOrReplacement = GhostText | GhostTextReplacement; + +export function ghostTextOrReplacementEquals(a: GhostTextOrReplacement | undefined, b: GhostTextOrReplacement | undefined): boolean { + if (a === b) { + return true; + } + if (!a || !b) { + return false; + } + if (a instanceof GhostText && b instanceof GhostText) { + return a.equals(b); + } + if (a instanceof GhostTextReplacement && b instanceof GhostTextReplacement) { + return a.equals(b); + } + return false; +} diff --git a/src/vs/editor/contrib/inlineCompletions/browser/ghostTextWidget.ts b/src/vs/editor/contrib/inlineCompletions/browser/ghostTextWidget.ts index e2c2fa9d796a6..a43c994c2492a 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/ghostTextWidget.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/ghostTextWidget.ts @@ -46,7 +46,8 @@ export class GhostTextWidget extends Disposable { this._register(applyObservableDecorations(this.editor, this.decorations)); } - private readonly uiState = derived('uiState', reader => { + private readonly uiState = derived(reader => { + /** @description uiState */ if (this.isDisposed.read(reader)) { return undefined; } @@ -125,7 +126,8 @@ export class GhostTextWidget extends Disposable { }; }); - private readonly decorations = derived('decorations', reader => { + private readonly decorations = derived(reader => { + /** @description decorations */ const uiState = this.uiState.read(reader); if (!uiState) { return []; @@ -165,7 +167,8 @@ export class GhostTextWidget extends Disposable { new AdditionalLinesWidget( this.editor, this.languageService.languageIdCodec, - derived('lines', (reader) => { + derived(reader => { + /** @description lines */ const uiState = this.uiState.read(reader); return uiState ? { lineNumber: uiState.lineNumber, @@ -204,7 +207,8 @@ class AdditionalLinesWidget extends Disposable { ) { super(); - this._register(autorun('update view zone', reader => { + this._register(autorun(reader => { + /** @description update view zone */ const lines = this.lines.read(reader); this.editorOptionsChanged.read(reader); diff --git a/src/vs/editor/contrib/inlineCompletions/browser/hoverParticipant.ts b/src/vs/editor/contrib/inlineCompletions/browser/hoverParticipant.ts index 1d74b99cb8695..a5f143ee42da8 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/hoverParticipant.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/hoverParticipant.ts @@ -139,7 +139,8 @@ export class InlineCompletionsHoverParticipant implements IEditorHoverParticipan hoverContentsElement.replaceChildren(renderedContents.element); }; - disposableStore.add(autorun('update hover', (reader) => { + disposableStore.add(autorun(reader => { + /** @description update hover */ const ghostText = part.controller.model.read(reader)?.ghostText.read(reader); if (ghostText) { const lineText = this._editor.getModel()!.getLineContent(ghostText.lineNumber); diff --git a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionContextKeys.ts b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionContextKeys.ts index b027df1b39cd3..1e9a7fbbbd00f 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionContextKeys.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionContextKeys.ts @@ -28,18 +28,21 @@ export class InlineCompletionContextKeys extends Disposable { ) { super(); - this._register(autorun('update context key: inlineCompletionVisible, suppressSuggestions', (reader) => { + this._register(autorun(reader => { + /** @description update context key: inlineCompletionVisible, suppressSuggestions */ const model = this.model.read(reader); - const suggestion = model?.selectedInlineCompletion.read(reader); - const ghostText = model?.ghostText.read(reader); - this.inlineCompletionVisible.set(ghostText !== undefined && !ghostText.isEmpty()); + const state = model?.state.read(reader); + + const isInlineCompletionVisible = !!state?.inlineCompletion && state?.ghostText !== undefined && !state?.ghostText.isEmpty(); + this.inlineCompletionVisible.set(isInlineCompletionVisible); - if (ghostText && suggestion) { - this.suppressSuggestions.set(suggestion.inlineCompletion.source.inlineCompletions.suppressSuggestions); + if (state?.ghostText && state?.inlineCompletion) { + this.suppressSuggestions.set(state.inlineCompletion.inlineCompletion.source.inlineCompletions.suppressSuggestions); } })); - this._register(autorun('update context key: inlineCompletionSuggestsIndentation, inlineCompletionSuggestsIndentationLessThanTabSize', (reader) => { + this._register(autorun(reader => { + /** @description update context key: inlineCompletionSuggestsIndentation, inlineCompletionSuggestsIndentationLessThanTabSize */ const model = this.model.read(reader); let startsWithIndentation = false; diff --git a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsController.ts b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsController.ts index e8699277b347f..094393e32c5b2 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsController.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsController.ts @@ -6,8 +6,7 @@ import { alert } from 'vs/base/browser/ui/aria/aria'; import { Event } from 'vs/base/common/event'; import { Disposable, toDisposable } from 'vs/base/common/lifecycle'; -import { autorun, constObservable, observableFromEvent, observableValue } from 'vs/base/common/observable'; -import { ITransaction, disposableObservableValue, transaction } from 'vs/base/common/observableImpl/base'; +import { ITransaction, autorun, constObservable, disposableObservableValue, observableFromEvent, observableValue, transaction } from 'vs/base/common/observable'; import { CoreEditingCommands } from 'vs/editor/browser/coreCommands'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { EditorOption } from 'vs/editor/common/config/editorOptions'; @@ -23,11 +22,13 @@ import { InlineCompletionContextKeys } from 'vs/editor/contrib/inlineCompletions import { InlineCompletionsHintsWidget, InlineSuggestionHintsContentWidget } from 'vs/editor/contrib/inlineCompletions/browser/inlineCompletionsHintsWidget'; import { InlineCompletionsModel, VersionIdChangeReason } from 'vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel'; import { SuggestWidgetAdaptor } from 'vs/editor/contrib/inlineCompletions/browser/suggestWidgetInlineCompletionProvider'; +import { localize } from 'vs/nls'; import { AudioCue, IAudioCueService } from 'vs/platform/audioCues/browser/audioCueService'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; export class InlineCompletionsController extends Disposable { static ID = 'editor.contrib.inlineCompletionsController'; @@ -42,7 +43,14 @@ export class InlineCompletionsController extends Disposable { private readonly suggestWidgetAdaptor = this._register(new SuggestWidgetAdaptor( this.editor, () => this.model.get()?.selectedInlineCompletion.get()?.toSingleTextEdit(undefined), - (tx) => this.updateObservables(tx, VersionIdChangeReason.Other) + (tx) => this.updateObservables(tx, VersionIdChangeReason.Other), + (item) => { + transaction(tx => { + /** @description handleSuggestAccepted */ + this.updateObservables(tx, VersionIdChangeReason.Other); + this.model.get()?.handleSuggestAccepted(item); + }); + } )); private readonly _enabled = observableFromEvent(this.editor.onDidChangeConfiguration, () => this.editor.getOption(EditorOption.inlineSuggest).enabled); @@ -67,11 +75,11 @@ export class InlineCompletionsController extends Disposable { @ILanguageFeatureDebounceService private readonly debounceService: ILanguageFeatureDebounceService, @ILanguageFeaturesService private readonly languageFeaturesService: ILanguageFeaturesService, @IAudioCueService private readonly audioCueService: IAudioCueService, + @IKeybindingService private readonly _keybindingService: IKeybindingService ) { super(); this._register(new InlineCompletionContextKeys(this.contextKeyService, this.model)); - this._register(Event.runAndSubscribe(editor.onDidChangeModel, () => transaction(tx => { /** @description onDidChangeModel */ this.model.set(undefined, tx); @@ -109,7 +117,7 @@ export class InlineCompletionsController extends Disposable { this._register(editor.onDidChangeCursorPosition(e => transaction(tx => { /** @description onDidChangeCursorPosition */ this.updateObservables(tx, VersionIdChangeReason.Other); - if (e.reason === CursorChangeReason.Explicit) { + if (e.reason === CursorChangeReason.Explicit || e.source === 'api') { this.model.get()?.stop(tx); } }))); @@ -141,7 +149,7 @@ export class InlineCompletionsController extends Disposable { this._register(this.editor.onDidBlurEditorWidget(() => { // This is a hidden setting very useful for debugging - if (this.configurationService.getValue('editor.inlineSuggest.keepOnBlur') || + if (this.contextKeyService.getContextKeyValue('accessibleViewIsShown') || this.configurationService.getValue('editor.inlineSuggest.keepOnBlur') || editor.getOption(EditorOption.inlineSuggest).keepOnBlur) { return; } @@ -154,7 +162,8 @@ export class InlineCompletionsController extends Disposable { }); })); - this._register(autorun('forceRenderingAbove', reader => { + this._register(autorun(reader => { + /** @description forceRenderingAbove */ const state = this.model.read(reader)?.state.read(reader); if (state?.suggestItem) { if (state.ghostText.lineCount >= 2) { @@ -169,26 +178,43 @@ export class InlineCompletionsController extends Disposable { })); let lastInlineCompletionId: string | undefined = undefined; - this._register(autorun('play audio cue & read suggestion', reader => { + this._register(autorun(reader => { + /** @description play audio cue & read suggestion */ const model = this.model.read(reader); const state = model?.state.read(reader); - if (!model || !state || !state.completion) { + if (!model || !state || !state.inlineCompletion) { lastInlineCompletionId = undefined; return; } - if (state.completion.semanticId !== lastInlineCompletionId) { - lastInlineCompletionId = state.completion.semanticId; + if (state.inlineCompletion.semanticId !== lastInlineCompletionId) { + lastInlineCompletionId = state.inlineCompletion.semanticId; + const lineText = model.textModel.getLineContent(state.ghostText.lineNumber); this.audioCueService.playAudioCue(AudioCue.inlineSuggestion).then(() => { if (this.editor.getOption(EditorOption.screenReaderAnnounceInlineSuggestion)) { - const lineText = model.textModel.getLineContent(state.ghostText.lineNumber); - alert(state.ghostText.renderForScreenReader(lineText)); + this.provideScreenReaderUpdate(state.ghostText.renderForScreenReader(lineText)); } }); } })); this._register(new InlineCompletionsHintsWidget(this.editor, this.model, this.instantiationService)); + this._register(this.configurationService.onDidChangeConfiguration(e => { + if (e.affectsConfiguration('accessibility.verbosity.inlineCompletions')) { + this.editor.updateOptions({ inlineCompletionsAccessibilityVerbose: this.configurationService.getValue('accessibility.verbosity.inlineCompletions') }); + } + })); + this.editor.updateOptions({ inlineCompletionsAccessibilityVerbose: this.configurationService.getValue('accessibility.verbosity.inlineCompletions') }); + } + + private provideScreenReaderUpdate(content: string): void { + const accessibleViewShowing = this.contextKeyService.getContextKeyValue('accessibleViewIsShown'); + const accessibleViewKeybinding = this._keybindingService.lookupKeybinding('editor.action.accessibleView'); + let hint: string | undefined; + if (!accessibleViewShowing && accessibleViewKeybinding && this.editor.getOption(EditorOption.inlineCompletionsAccessibilityVerbose)) { + hint = localize('showAccessibleViewHint', "Inspect this in the accessible view ({0})", accessibleViewKeybinding.getAriaLabel()); + } + hint ? alert(content + ', ' + hint) : alert(content); } /** diff --git a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsHintsWidget.css b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsHintsWidget.css index 642e6c51d7aa9..196307cc49e53 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsHintsWidget.css +++ b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsHintsWidget.css @@ -29,7 +29,7 @@ padding: 2px 3px; } -.monaco-editor .inlineSuggestionsHints .custom-actions .action-item:nth-child(2) a { +.monaco-editor .inlineSuggestionsHints .availableSuggestionCount a { display: flex; min-width: 19px; justify-content: center; diff --git a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsHintsWidget.ts b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsHintsWidget.ts index c1c4376977bb2..0cde6e9a9b5f8 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsHintsWidget.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsHintsWidget.ts @@ -4,15 +4,14 @@ *--------------------------------------------------------------------------------------------*/ import { h } from 'vs/base/browser/dom'; -import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; +import { ActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems'; import { KeybindingLabel, unthemedKeybindingLabelOptions } from 'vs/base/browser/ui/keybindingLabel/keybindingLabel'; import { Action, IAction, Separator } from 'vs/base/common/actions'; import { equals } from 'vs/base/common/arrays'; import { RunOnceScheduler } from 'vs/base/common/async'; import { Codicon } from 'vs/base/common/codicons'; import { Disposable, toDisposable } from 'vs/base/common/lifecycle'; -import { IObservable, autorun, derived, observableFromEvent } from 'vs/base/common/observable'; -import { autorunWithStore2 } from 'vs/base/common/observableImpl/autorun'; +import { IObservable, autorun, autorunWithStore, derived, observableFromEvent } from 'vs/base/common/observable'; import { OS } from 'vs/base/common/platform'; import { ThemeIcon } from 'vs/base/common/themables'; import 'vs/css!./inlineCompletionsHintsWidget'; @@ -21,10 +20,10 @@ import { EditorOption } from 'vs/editor/common/config/editorOptions'; import { Position } from 'vs/editor/common/core/position'; import { Command, InlineCompletionTriggerKind } from 'vs/editor/common/languages'; import { PositionAffinity } from 'vs/editor/common/model'; -import { showPreviousInlineSuggestionActionId, showNextInlineSuggestionActionId } from 'vs/editor/contrib/inlineCompletions/browser/commandIds'; +import { showNextInlineSuggestionActionId, showPreviousInlineSuggestionActionId } from 'vs/editor/contrib/inlineCompletions/browser/commandIds'; import { InlineCompletionsModel } from 'vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel'; import { localize } from 'vs/nls'; -import { createAndFillInActionBarActions, MenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem'; +import { MenuEntryActionViewItem, createAndFillInActionBarActions } from 'vs/platform/actions/browser/menuEntryActionViewItem'; import { IMenuWorkbenchToolBarOptions, WorkbenchToolBar } from 'vs/platform/actions/browser/toolbar'; import { IMenuService, MenuId, MenuItemAction } from 'vs/platform/actions/common/actions'; import { ICommandService } from 'vs/platform/commands/common/commands'; @@ -40,7 +39,8 @@ export class InlineCompletionsHintsWidget extends Disposable { private sessionPosition: Position | undefined = undefined; - private readonly position = derived('position', reader => { + private readonly position = derived(reader => { + /** @description position */ const ghostText = this.model.read(reader)?.ghostText.read(reader); if (!this.alwaysShowToolbar.read(reader) || !ghostText || ghostText.parts.length === 0) { @@ -65,7 +65,8 @@ export class InlineCompletionsHintsWidget extends Disposable { ) { super(); - this._register(autorunWithStore2('setup content widget', (reader, store) => { + this._register(autorunWithStore((reader, store) => { + /** @description setup content widget */ const model = this.model.read(reader); if (!model || !this.alwaysShowToolbar.read(reader)) { return; @@ -83,7 +84,8 @@ export class InlineCompletionsHintsWidget extends Disposable { editor.addContentWidget(contentWidget); store.add(toDisposable(() => editor.removeContentWidget(contentWidget))); - store.add(autorun('request explicit', reader => { + store.add(autorun(reader => { + /** @description request explicit */ const position = this.position.read(reader); if (!position) { return; @@ -110,10 +112,7 @@ export class InlineSuggestionHintsContentWidget extends Disposable implements IC public readonly suppressMouseDown = false; private readonly nodes = h('div.inlineSuggestionsHints', { className: this.withBorder ? '.withBorder' : '' }, [ - h('div', { style: { display: 'flex' } }, [ - h('div@actionBar', { className: 'custom-actions' }), - h('div@toolBar'), - ]) + h('div@toolBar'), ]); private createCommandAction(commandId: string, label: string, iconClassName: string): Action { @@ -171,31 +170,41 @@ export class InlineSuggestionHintsContentWidget extends Disposable implements IC ) { super(); - const actionBar = this._register(new ActionBar(this.nodes.actionBar)); - - actionBar.push(this.previousAction, { icon: true, label: false }); - actionBar.push(this.availableSuggestionCountAction); - actionBar.push(this.nextAction, { icon: true, label: false }); - this.toolBar = this._register(instantiationService.createInstance(CustomizedMenuWorkbenchToolBar, this.nodes.toolBar, MenuId.InlineSuggestionToolbar, { menuOptions: { renderShortTitle: true }, toolbarOptions: { primaryGroup: g => g.startsWith('primary') }, actionViewItemProvider: (action, options) => { - return action instanceof MenuItemAction ? instantiationService.createInstance(StatusBarViewItem, action, undefined) : undefined; + if (action instanceof MenuItemAction) { + return instantiationService.createInstance(StatusBarViewItem, action, undefined); + } + if (action === this.availableSuggestionCountAction) { + const a = new ActionViewItemWithClassName(undefined, action, { label: true, icon: false }); + a.setClass('availableSuggestionCount'); + return a; + } + return undefined; }, telemetrySource: 'InlineSuggestionToolbar', })); + this.toolBar.setPrependedPrimaryActions([ + this.previousAction, + this.availableSuggestionCountAction, + this.nextAction, + ]); + this._register(this.toolBar.onDidChangeDropdownVisibility(e => { InlineSuggestionHintsContentWidget._dropDownVisible = e; })); - this._register(autorun('update position', (reader) => { + this._register(autorun(reader => { + /** @description update position */ this._position.read(reader); this.editor.layoutContentWidget(this); })); - this._register(autorun('counts', (reader) => { + this._register(autorun(reader => { + /** @description counts */ const suggestionCount = this._suggestionCount.read(reader); const currentSuggestionIdx = this._currentSuggestionIdx.read(reader); @@ -214,7 +223,8 @@ export class InlineSuggestionHintsContentWidget extends Disposable implements IC } })); - this._register(autorun('extra commands', (reader) => { + this._register(autorun(reader => { + /** @description extra commands */ const extraCommands = this._extraCommands.read(reader); if (equals(this.lastCommands, extraCommands)) { // nothing to update @@ -265,6 +275,21 @@ export class InlineSuggestionHintsContentWidget extends Disposable implements IC } } +class ActionViewItemWithClassName extends ActionViewItem { + private _className: string | undefined = undefined; + + setClass(className: string | undefined): void { + this._className = className; + } + + override render(container: HTMLElement): void { + super.render(container); + if (this._className) { + container.classList.add(this._className); + } + } +} + class StatusBarViewItem extends MenuEntryActionViewItem { protected override updateLabel() { const kb = this._keybindingService.lookupKeybinding(this._action.id, this._contextKeyService); @@ -286,6 +311,7 @@ class StatusBarViewItem extends MenuEntryActionViewItem { export class CustomizedMenuWorkbenchToolBar extends WorkbenchToolBar { private readonly menu = this._store.add(this.menuService.createMenu(this.menuId, this.contextKeyService, { emitEventsForSubmenuChanges: true })); private additionalActions: IAction[] = []; + private prependedPrimaryActions: IAction[] = []; constructor( container: HTMLElement, @@ -314,12 +340,21 @@ export class CustomizedMenuWorkbenchToolBar extends WorkbenchToolBar { ); secondary.push(...this.additionalActions); + primary.unshift(...this.prependedPrimaryActions); this.setActions(primary, secondary); } + setPrependedPrimaryActions(actions: IAction[]): void { + if (equals(this.prependedPrimaryActions, actions, (a, b) => a === b)) { + return; + } + + this.prependedPrimaryActions = actions; + this.updateToolbar(); + } + setAdditionalSecondaryActions(actions: IAction[]): void { if (equals(this.additionalActions, actions, (a, b) => a === b)) { - // don't update if the actions are the same return; } diff --git a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts index 05d6de2fed1f9..252f9ca5f9f90 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts @@ -6,9 +6,7 @@ import { mapFind } from 'vs/base/common/arrays'; import { BugIndicatingError, onUnexpectedExternalError } from 'vs/base/common/errors'; import { Disposable } from 'vs/base/common/lifecycle'; -import { IObservable, ITransaction, autorun, derived, keepAlive, observableSignal, observableValue, transaction } from 'vs/base/common/observable'; -import { subtransaction } from 'vs/base/common/observableImpl/base'; -import { derivedHandleChanges } from 'vs/base/common/observableImpl/derived'; +import { IObservable, IReader, ITransaction, autorun, derived, derivedHandleChanges, derivedOpts, keepAlive, observableSignal, observableValue, subtransaction, transaction } from 'vs/base/common/observable'; import { isDefined } from 'vs/base/common/types'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { EditOperation } from 'vs/editor/common/core/editOperation'; @@ -18,8 +16,9 @@ import { InlineCompletionContext, InlineCompletionTriggerKind } from 'vs/editor/ import { ILanguageConfigurationService } from 'vs/editor/common/languages/languageConfigurationRegistry'; import { EndOfLinePreference, ITextModel } from 'vs/editor/common/model'; import { IFeatureDebounceInformation } from 'vs/editor/common/services/languageFeatureDebounce'; -import { GhostText, GhostTextOrReplacement } from 'vs/editor/contrib/inlineCompletions/browser/ghostText'; +import { GhostText, GhostTextOrReplacement, ghostTextOrReplacementEquals } from 'vs/editor/contrib/inlineCompletions/browser/ghostText'; import { InlineCompletionWithUpdatedRange, InlineCompletionsSource } from 'vs/editor/contrib/inlineCompletions/browser/inlineCompletionsSource'; +import { SingleTextEdit } from 'vs/editor/contrib/inlineCompletions/browser/singleTextEdit'; import { SuggestItemInfo } from 'vs/editor/contrib/inlineCompletions/browser/suggestWidgetInlineCompletionProvider'; import { addPositions, lengthOfText } from 'vs/editor/contrib/inlineCompletions/browser/utils'; import { SnippetController2 } from 'vs/editor/contrib/snippet/browser/snippetController2'; @@ -63,9 +62,10 @@ export class InlineCompletionsModel extends Disposable { this._register(keepAlive(this._fetchInlineCompletions, true)); let lastItem: InlineCompletionWithUpdatedRange | undefined = undefined; - this._register(autorun('call handleItemDidShow', reader => { + this._register(autorun(reader => { + /** @description call handleItemDidShow */ const item = this.state.read(reader); - const completion = item?.completion; + const completion = item?.inlineCompletion; if (completion?.semanticId !== lastItem?.semanticId) { lastItem = completion; if (completion) { @@ -150,7 +150,8 @@ export class InlineCompletionsModel extends Disposable { }); } - private readonly _filteredInlineCompletionItems = derived('filteredInlineCompletionItems', (reader) => { + private readonly _filteredInlineCompletionItems = derived(reader => { + /** @description _filteredInlineCompletionItems */ const c = this._source.inlineCompletions.read(reader); if (!c) { return []; } const cursorPosition = this.cursorPosition.read(reader); @@ -158,7 +159,8 @@ export class InlineCompletionsModel extends Disposable { return filteredCompletions; }); - public readonly selectedInlineCompletionIndex = derived('selectedCachedCompletionIndex', (reader) => { + public readonly selectedInlineCompletionIndex = derived((reader) => { + /** @description selectedInlineCompletionIndex */ const selectedInlineCompletionId = this._selectedInlineCompletionId.read(reader); const filteredCompletions = this._filteredInlineCompletionItems.read(reader); const idx = this._selectedInlineCompletionId === undefined ? -1 @@ -171,7 +173,8 @@ export class InlineCompletionsModel extends Disposable { return idx; }); - public readonly selectedInlineCompletion = derived('selectedCachedCompletion', (reader) => { + public readonly selectedInlineCompletion = derived((reader) => { + /** @description selectedCachedCompletion */ const filteredCompletions = this._filteredInlineCompletionItems.read(reader); const idx = this.selectedInlineCompletionIndex.read(reader); return filteredCompletions[idx]; @@ -181,7 +184,8 @@ export class InlineCompletionsModel extends Disposable { v => /** @description lastTriggerKind */ v?.request.context.triggerKind ); - public readonly inlineCompletionsCount = derived('selectedInlineCompletionsCount', reader => { + public readonly inlineCompletionsCount = derived(reader => { + /** @description inlineCompletionsCount */ if (this.lastTriggerKind.read(reader) === InlineCompletionTriggerKind.Explicit) { return this._filteredInlineCompletionItems.read(reader).length; } else { @@ -189,32 +193,28 @@ export class InlineCompletionsModel extends Disposable { } }); - public readonly state = derived<{ + public readonly state = derivedOpts<{ suggestItem: SuggestItemInfo | undefined; - completion: InlineCompletionWithUpdatedRange | undefined; + inlineCompletion: InlineCompletionWithUpdatedRange | undefined; ghostText: GhostTextOrReplacement; - } | undefined>('ghostTextAndCompletion', (reader) => { + } | undefined>({ + equalityComparer: (a, b) => { + if (!a || !b) { return a === b; } + return ghostTextOrReplacementEquals(a.ghostText, b.ghostText) + && a.inlineCompletion === b.inlineCompletion + && a.suggestItem === b.suggestItem; + } + }, (reader) => { + /** @description ghostTextAndCompletion */ const model = this.textModel; const suggestItem = this.selectedSuggestItem.read(reader); if (suggestItem) { - const suggestWidgetInlineCompletions = this._source.suggestWidgetInlineCompletions.read(reader); - const candidateInlineCompletions = suggestWidgetInlineCompletions - ? suggestWidgetInlineCompletions.inlineCompletions - : [this.selectedInlineCompletion.read(reader)].filter(isDefined); - const suggestCompletion = suggestItem.toSingleTextEdit().removeCommonPrefix(model); - - const augmentedCompletion = mapFind(candidateInlineCompletions, completion => { - let r = completion.toSingleTextEdit(reader); - r = r.removeCommonPrefix(model, Range.fromPositions(r.range.getStartPosition(), suggestItem.range.getEndPosition())); - return r.augments(suggestCompletion) ? { edit: r, completion } : undefined; - }); + const augmentedCompletion = this._computeAugmentedCompletion(suggestCompletion, reader); const isSuggestionPreviewEnabled = this._suggestPreviewEnabled.read(reader); - if (!isSuggestionPreviewEnabled && !augmentedCompletion) { - return undefined; - } + if (!isSuggestionPreviewEnabled && !augmentedCompletion) { return undefined; } const edit = augmentedCompletion?.edit ?? suggestCompletion; const editPreviewLength = augmentedCompletion ? augmentedCompletion.edit.text.length - suggestCompletion.text.length : 0; @@ -225,7 +225,7 @@ export class InlineCompletionsModel extends Disposable { // Show an invisible ghost text to reserve space const ghostText = newGhostText ?? new GhostText(edit.range.endLineNumber, []); - return { ghostText, completion: augmentedCompletion?.completion, suggestItem }; + return { ghostText, inlineCompletion: augmentedCompletion?.completion, suggestItem }; } else { if (!this._isActive.read(reader)) { return undefined; } const item = this.selectedInlineCompletion.read(reader); @@ -235,11 +235,30 @@ export class InlineCompletionsModel extends Disposable { const mode = this._inlineSuggestMode.read(reader); const cursor = this.cursorPosition.read(reader); const ghostText = replacement.computeGhostText(model, mode, cursor); - return ghostText ? { ghostText, completion: item, suggestItem: undefined } : undefined; + return ghostText ? { ghostText, inlineCompletion: item, suggestItem: undefined } : undefined; } }); - public readonly ghostText = derived('ghostText', (reader) => { + private _computeAugmentedCompletion(suggestCompletion: SingleTextEdit, reader: IReader | undefined) { + const model = this.textModel; + const suggestWidgetInlineCompletions = this._source.suggestWidgetInlineCompletions.read(reader); + const candidateInlineCompletions = suggestWidgetInlineCompletions + ? suggestWidgetInlineCompletions.inlineCompletions + : [this.selectedInlineCompletion.read(reader)].filter(isDefined); + + const augmentedCompletion = mapFind(candidateInlineCompletions, completion => { + let r = completion.toSingleTextEdit(reader); + r = r.removeCommonPrefix(model, Range.fromPositions(r.range.getStartPosition(), suggestCompletion.range.getEndPosition())); + return r.augments(suggestCompletion) ? { edit: r, completion } : undefined; + }); + + return augmentedCompletion; + } + + public readonly ghostText = derivedOpts({ + equalityComparer: ghostTextOrReplacementEquals + }, reader => { + /** @description ghostText */ const v = this.state.read(reader); if (!v) { return undefined; } return v.ghostText; @@ -271,10 +290,10 @@ export class InlineCompletionsModel extends Disposable { } const state = this.state.get(); - if (!state || state.ghostText.isEmpty() || !state.completion) { + if (!state || state.ghostText.isEmpty() || !state.inlineCompletion) { return; } - const completion = state.completion.toInlineCompletion(undefined); + const completion = state.inlineCompletion.toInlineCompletion(undefined); editor.pushUndoStop(); if (completion.snippetInfo) { @@ -363,11 +382,11 @@ export class InlineCompletionsModel extends Disposable { } const state = this.state.get(); - if (!state || state.ghostText.isEmpty() || !state.completion) { + if (!state || state.ghostText.isEmpty() || !state.inlineCompletion) { return; } const ghostText = state.ghostText; - const completion = state.completion.toInlineCompletion(undefined); + const completion = state.inlineCompletion.toInlineCompletion(undefined); if (completion.snippetInfo || completion.filterText !== completion.insertText) { // not in WYSIWYG mode, partial commit might change completion, thus it is not supported @@ -410,4 +429,17 @@ export class InlineCompletionsModel extends Disposable { ); } } + + public handleSuggestAccepted(item: SuggestItemInfo) { + const itemEdit = item.toSingleTextEdit().removeCommonPrefix(this.textModel); + const augmentedCompletion = this._computeAugmentedCompletion(itemEdit, undefined); + if (!augmentedCompletion) { return; } + + const inlineCompletion = augmentedCompletion.completion.inlineCompletion; + inlineCompletion.source.provider.handlePartialAccept?.( + inlineCompletion.source.inlineCompletions, + inlineCompletion.sourceInlineCompletion, + itemEdit.text.length, + ); + } } diff --git a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsSource.ts b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsSource.ts index c844e63e8a17b..14a7cdf1f444c 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsSource.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsSource.ts @@ -6,8 +6,7 @@ import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; import { matchesSubString } from 'vs/base/common/filters'; import { Disposable, IDisposable, MutableDisposable } from 'vs/base/common/lifecycle'; -import { ITransaction, derived } from 'vs/base/common/observable'; -import { IObservable, IReader, disposableObservableValue, transaction } from 'vs/base/common/observableImpl/base'; +import { IObservable, IReader, ITransaction, derived, disposableObservableValue, transaction } from 'vs/base/common/observable'; import { Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; import { InlineCompletionContext, InlineCompletionTriggerKind } from 'vs/editor/common/languages'; @@ -15,8 +14,8 @@ import { ILanguageConfigurationService } from 'vs/editor/common/languages/langua import { EndOfLinePreference, ITextModel } from 'vs/editor/common/model'; import { IFeatureDebounceInformation } from 'vs/editor/common/services/languageFeatureDebounce'; import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; -import { SingleTextEdit } from 'vs/editor/contrib/inlineCompletions/browser/singleTextEdit'; import { InlineCompletionItem, InlineCompletionProviderResult, provideInlineCompletions } from 'vs/editor/contrib/inlineCompletions/browser/provideInlineCompletions'; +import { SingleTextEdit } from 'vs/editor/contrib/inlineCompletions/browser/singleTextEdit'; export class InlineCompletionsSource extends Disposable { private readonly _updateOperation = this._register(new MutableDisposable()); @@ -91,6 +90,7 @@ export class InlineCompletionsSource extends Disposable { this._updateOperation.clear(); transaction(tx => { + /** @description Update completions with provider result */ target.set(completions, tx); }); @@ -183,7 +183,8 @@ export class UpToDateInlineCompletions implements IDisposable { private readonly _prependedInlineCompletionItems: InlineCompletionItem[] = []; private _rangeVersionIdValue = 0; - private readonly _rangeVersionId = derived('ranges', reader => { + private readonly _rangeVersionId = derived(reader => { + /** @description ranges */ this.versionId.read(reader); let changed = false; for (const i of this._inlineCompletions) { @@ -221,7 +222,13 @@ export class UpToDateInlineCompletions implements IDisposable { public dispose(): void { this._refCount--; if (this._refCount === 0) { - this.textModel.deltaDecorations(this._inlineCompletions.map(i => i.decorationId), []); + setTimeout(() => { + // To fix https://github.com/microsoft/vscode/issues/188348 + if (!this.textModel.isDisposed()) { + // This is just cleanup. It's ok if it happens with a delay. + this.textModel.deltaDecorations(this._inlineCompletions.map(i => i.decorationId), []); + } + }, 0); this.inlineCompletionProviderResult.dispose(); for (const i of this._prependedInlineCompletionItems) { i.source.removeRef(); diff --git a/src/vs/editor/contrib/inlineCompletions/browser/suggestWidgetInlineCompletionProvider.ts b/src/vs/editor/contrib/inlineCompletions/browser/suggestWidgetInlineCompletionProvider.ts index b2e56cdea96f6..7c26816b47380 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/suggestWidgetInlineCompletionProvider.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/suggestWidgetInlineCompletionProvider.ts @@ -34,6 +34,7 @@ export class SuggestWidgetAdaptor extends Disposable { private readonly editor: ICodeEditor, private readonly suggestControllerPreselector: () => SingleTextEdit | undefined, private readonly checkModelVersion: (tx: ITransaction) => void, + private readonly onWillAccept: (item: SuggestItemInfo) => void, ) { super(); @@ -111,6 +112,22 @@ export class SuggestWidgetAdaptor extends Disposable { this._register(Event.once(suggestController.model.onDidTrigger)(e => { bindToSuggestWidget(); })); + + this._register(suggestController.onWillInsertSuggestItem(e => { + const position = this.editor.getPosition(); + const model = this.editor.getModel(); + if (!position || !model) { return undefined; } + + const suggestItemInfo = SuggestItemInfo.fromSuggestion( + suggestController, + model, + position, + e.item, + this.isShiftKeyPressed + ); + + this.onWillAccept(suggestItemInfo); + })); } this.update(this._isActive); } @@ -123,6 +140,7 @@ export class SuggestWidgetAdaptor extends Disposable { this._currentSuggestItemInfo = newInlineCompletion; transaction(tx => { + /** @description Update state from suggest widget */ this.checkModelVersion(tx); this._selectedItem.set(this._isActive ? this._currentSuggestItemInfo : undefined, tx); }); diff --git a/src/vs/editor/contrib/inlineCompletions/browser/utils.ts b/src/vs/editor/contrib/inlineCompletions/browser/utils.ts index b256d9dc8d723..a1876c8a6fcf7 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/utils.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/utils.ts @@ -5,7 +5,7 @@ import { BugIndicatingError } from 'vs/base/common/errors'; import { DisposableStore, IDisposable } from 'vs/base/common/lifecycle'; -import { IObservable, autorun } from 'vs/base/common/observable'; +import { IObservable, autorunOpts } from 'vs/base/common/observable'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { Position } from 'vs/editor/common/core/position'; import { IRange, Range } from 'vs/editor/common/core/range'; @@ -67,12 +67,17 @@ export class ColumnRange { toRange(lineNumber: number): Range { return new Range(lineNumber, this.startColumn, lineNumber, this.endColumnExclusive); } + + equals(other: ColumnRange): boolean { + return this.startColumn === other.startColumn + && this.endColumnExclusive === other.endColumnExclusive; + } } export function applyObservableDecorations(editor: ICodeEditor, decorations: IObservable): IDisposable { const d = new DisposableStore(); const decorationsCollection = editor.createDecorationsCollection(); - d.add(autorun(`Apply decorations from ${decorations.debugName}`, reader => { + d.add(autorunOpts({ debugName: () => `Apply decorations from ${decorations.debugName}` }, reader => { const d = decorations.read(reader); decorationsCollection.set(d); })); diff --git a/src/vs/editor/contrib/inlineCompletions/test/browser/suggestWidgetModel.test.ts b/src/vs/editor/contrib/inlineCompletions/test/browser/suggestWidgetModel.test.ts index 661894710d7d9..e46c38499f14b 100644 --- a/src/vs/editor/contrib/inlineCompletions/test/browser/suggestWidgetModel.test.ts +++ b/src/vs/editor/contrib/inlineCompletions/test/browser/suggestWidgetModel.test.ts @@ -50,7 +50,8 @@ suite('Suggest Widget Model', () => { async ({ editor, editorViewModel, context, model }) => { let last: boolean | undefined = undefined; const history = new Array(); - const d = autorun('debug', reader => { + const d = autorun(reader => { + /** @description debug */ const selectedSuggestItem = !!model.selectedSuggestItem.read(reader); if (last !== selectedSuggestItem) { last = selectedSuggestItem; diff --git a/src/vs/editor/contrib/inlineCompletions/test/browser/utils.ts b/src/vs/editor/contrib/inlineCompletions/test/browser/utils.ts index b25536d370303..c3c25e22f9c14 100644 --- a/src/vs/editor/contrib/inlineCompletions/test/browser/utils.ts +++ b/src/vs/editor/contrib/inlineCompletions/test/browser/utils.ts @@ -80,7 +80,8 @@ export class GhostTextContext extends Disposable { constructor(model: InlineCompletionsModel, private readonly editor: ITestCodeEditor) { super(); - this._register(autorun('update', reader => { + this._register(autorun(reader => { + /** @description update */ const ghostText = model.ghostText.read(reader); let view: string | undefined; if (ghostText) { diff --git a/src/vs/editor/contrib/linesOperations/browser/linesOperations.ts b/src/vs/editor/contrib/linesOperations/browser/linesOperations.ts index 0e3355907afad..11a5c6c4f2728 100644 --- a/src/vs/editor/contrib/linesOperations/browser/linesOperations.ts +++ b/src/vs/editor/contrib/linesOperations/browser/linesOperations.ts @@ -953,8 +953,8 @@ export class TransposeAction extends EditorAction { constructor() { super({ id: 'editor.action.transpose', - label: nls.localize('editor.transpose', "Transpose characters around the cursor"), - alias: 'Transpose characters around the cursor', + label: nls.localize('editor.transpose', "Transpose Characters around the Cursor"), + alias: 'Transpose Characters around the Cursor', precondition: EditorContextKeys.writable }); } diff --git a/src/vs/editor/contrib/linesOperations/browser/moveLinesCommand.ts b/src/vs/editor/contrib/linesOperations/browser/moveLinesCommand.ts index 6193ce53e26a2..8db880a15adc5 100644 --- a/src/vs/editor/contrib/linesOperations/browser/moveLinesCommand.ts +++ b/src/vs/editor/contrib/linesOperations/browser/moveLinesCommand.ts @@ -117,7 +117,7 @@ export class MoveLinesCommand implements ICommand { const oldIndentation = strings.getLeadingWhitespace(model.getLineContent(movingLineNumber)); const newSpaceCnt = movingLineMatchResult + indentUtils.getSpaceCnt(oldIndentation, tabSize); const newIndentation = indentUtils.generateIndent(newSpaceCnt, tabSize, insertSpaces); - insertingText = newIndentation + this.trimLeft(movingLineText); + insertingText = newIndentation + this.trimStart(movingLineText); } else { // no enter rule matches, let's check indentatin rules then. virtualModel.getLineContent = (lineNumber: number) => { @@ -141,7 +141,7 @@ export class MoveLinesCommand implements ICommand { const oldSpaceCnt = indentUtils.getSpaceCnt(oldIndentation, tabSize); if (newSpaceCnt !== oldSpaceCnt) { const newIndentation = indentUtils.generateIndent(newSpaceCnt, tabSize, insertSpaces); - insertingText = newIndentation + this.trimLeft(movingLineText); + insertingText = newIndentation + this.trimStart(movingLineText); } } } @@ -272,7 +272,7 @@ export class MoveLinesCommand implements ICommand { enterPrefix = indentConverter.unshiftIndent(enter.indentation) + enter.appendText; } const movingLineText = model.getLineContent(line); - if (this.trimLeft(movingLineText).indexOf(this.trimLeft(enterPrefix)) >= 0) { + if (this.trimStart(movingLineText).indexOf(this.trimStart(enterPrefix)) >= 0) { const oldIndentation = strings.getLeadingWhitespace(model.getLineContent(line)); let newIndentation = strings.getLeadingWhitespace(enterPrefix); const indentMetadataOfMovelingLine = getIndentMetadata(model, line, this._languageConfigurationService); @@ -354,7 +354,7 @@ export class MoveLinesCommand implements ICommand { return this.parseEnterResult(model, indentConverter, tabSize, line, enter); } - private trimLeft(str: string) { + private trimStart(str: string) { return str.replace(/^\s+/, ''); } diff --git a/src/vs/editor/contrib/multicursor/test/browser/multicursor.test.ts b/src/vs/editor/contrib/multicursor/test/browser/multicursor.test.ts index dffb158ed252e..e19fc94e97cdb 100644 --- a/src/vs/editor/contrib/multicursor/test/browser/multicursor.test.ts +++ b/src/vs/editor/contrib/multicursor/test/browser/multicursor.test.ts @@ -86,7 +86,8 @@ suite('Multicursor selection', () => { const serviceCollection = new ServiceCollection(); serviceCollection.set(IStorageService, { _serviceBrand: undefined, - onDidChangeValue: Event.None, + onDidChangeValue: () => { throw new Error(); }, + onDidChangeValue2: Event.None, onDidChangeTarget: Event.None, onWillSaveState: Event.None, get: (key: string) => queryState[key], diff --git a/src/vs/editor/contrib/quickAccess/browser/editorNavigationQuickAccess.ts b/src/vs/editor/contrib/quickAccess/browser/editorNavigationQuickAccess.ts index 4336914a3ce8e..d4082fc5a2747 100644 --- a/src/vs/editor/contrib/quickAccess/browser/editorNavigationQuickAccess.ts +++ b/src/vs/editor/contrib/quickAccess/browser/editorNavigationQuickAccess.ts @@ -7,7 +7,6 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { Event } from 'vs/base/common/event'; import { once } from 'vs/base/common/functional'; import { DisposableStore, IDisposable, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle'; -import { withNullAsUndefined } from 'vs/base/common/types'; import { getCodeEditor, isDiffEditor } from 'vs/editor/browser/editorBrowser'; import { IRange } from 'vs/editor/common/core/range'; import { IDiffEditor, IEditor, ScrollType } from 'vs/editor/common/editorCommon'; @@ -95,9 +94,9 @@ export abstract class AbstractEditorNavigationQuickAccessProvider implements IQu // changes even later because it could be that the user has // configured quick access to remain open when focus is lost and // we always want to restore the current location. - let lastKnownEditorViewState = withNullAsUndefined(editor.saveViewState()); + let lastKnownEditorViewState = editor.saveViewState() ?? undefined; disposables.add(codeEditor.onDidChangeCursorPosition(() => { - lastKnownEditorViewState = withNullAsUndefined(editor.saveViewState()); + lastKnownEditorViewState = editor.saveViewState() ?? undefined; })); context.restoreViewState = () => { diff --git a/src/vs/editor/contrib/quickAccess/browser/gotoSymbolQuickAccess.ts b/src/vs/editor/contrib/quickAccess/browser/gotoSymbolQuickAccess.ts index d6c3feb2a3187..77197c2f9d4fe 100644 --- a/src/vs/editor/contrib/quickAccess/browser/gotoSymbolQuickAccess.ts +++ b/src/vs/editor/contrib/quickAccess/browser/gotoSymbolQuickAccess.ts @@ -14,7 +14,7 @@ import { format, trim } from 'vs/base/common/strings'; import { IRange, Range } from 'vs/editor/common/core/range'; import { ScrollType } from 'vs/editor/common/editorCommon'; import { ITextModel } from 'vs/editor/common/model'; -import { DocumentSymbol, SymbolKind, SymbolKinds, SymbolTag } from 'vs/editor/common/languages'; +import { DocumentSymbol, SymbolKind, SymbolKinds, SymbolTag, getAriaLabelForSymbol } from 'vs/editor/common/languages'; import { IOutlineModelService } from 'vs/editor/contrib/documentSymbols/browser/outlineModel'; import { AbstractEditorNavigationQuickAccessProvider, IEditorNavigationQuickAccessOptions, IQuickAccessTextEditorContext } from 'vs/editor/contrib/quickAccess/browser/editorNavigationQuickAccess'; import { localize } from 'vs/nls'; @@ -316,7 +316,7 @@ export abstract class AbstractGotoSymbolQuickAccessProvider extends AbstractEdit kind: symbol.kind, score: symbolScore, label: symbolLabelWithIcon, - ariaLabel: symbolLabel, + ariaLabel: getAriaLabelForSymbol(symbol.name, symbol.kind), description: containerLabel, highlights: deprecated ? undefined : { label: symbolMatches, diff --git a/src/vs/editor/contrib/snippet/browser/snippetSession.ts b/src/vs/editor/contrib/snippet/browser/snippetSession.ts index 78b6a87e8b28b..80a9959f47506 100644 --- a/src/vs/editor/contrib/snippet/browser/snippetSession.ts +++ b/src/vs/editor/contrib/snippet/browser/snippetSession.ts @@ -7,7 +7,6 @@ import { groupBy } from 'vs/base/common/arrays'; import { CharCode } from 'vs/base/common/charCode'; import { dispose } from 'vs/base/common/lifecycle'; import { getLeadingWhitespace } from 'vs/base/common/strings'; -import { withNullAsUndefined } from 'vs/base/common/types'; import 'vs/css!./snippetSession'; import { IActiveCodeEditor } from 'vs/editor/browser/editorBrowser'; import { EditorOption } from 'vs/editor/common/config/editorOptions'; @@ -346,7 +345,7 @@ export class OneSnippet { let result: Range | undefined; const model = this._editor.getModel(); for (const decorationId of this._placeholderDecorations!.values()) { - const placeholderRange = withNullAsUndefined(model.getDecorationRange(decorationId)); + const placeholderRange = model.getDecorationRange(decorationId) ?? undefined; if (!result) { result = placeholderRange; } else { diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.css b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.css index 757fc92d81d3c..8b1c053ad780a 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.css +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.css @@ -3,23 +3,45 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -.monaco-editor .sticky-line { - color: var(--vscode-editorLineNumber-foreground); +.monaco-editor .sticky-widget { overflow: hidden; - white-space: nowrap; - display: inline-block; } -.monaco-editor .sticky-line-number { - text-align: right; +.monaco-editor .sticky-widget-line-numbers { float: left; + background-color: inherit; } -.monaco-editor .sticky-line-root { - background-color: inherit; +.monaco-editor .sticky-widget-lines-scrollable { + display: inline-block; + position: absolute; overflow: hidden; + width: var(--vscode-editorStickyScroll-scrollableWidth); + background-color: inherit; +} + +.monaco-editor .sticky-widget-lines { + position: absolute; + background-color: inherit; +} + +.monaco-editor .sticky-line-number, .monaco-editor .sticky-line-content { + color: var(--vscode-editorLineNumber-foreground); white-space: nowrap; - width: 100%; + display: inline-block; + position: absolute; + background-color: inherit; +} + +.monaco-editor .sticky-line-content { + width: var(--vscode-editorStickyScroll-scrollableWidth); + background-color: inherit; + white-space: nowrap; +} + +.monaco-editor .sticky-line-number-inner { + display: block; + text-align: right; } .monaco-editor.hc-black .sticky-widget, @@ -27,7 +49,7 @@ border-bottom: 1px solid var(--vscode-contrastBorder); } -.monaco-editor .sticky-line-root:hover { +.monaco-editor .sticky-line-content:hover { background-color: var(--vscode-editorStickyScrollHover-background); cursor: pointer; } diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollActions.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollActions.ts index 3d5b49426907d..ece8daa4e51a5 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollActions.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollActions.ts @@ -33,7 +33,7 @@ export class ToggleStickyScroll extends Action2 { }, menu: [ { id: MenuId.CommandPalette }, - { id: MenuId.MenubarViewMenu, group: '5_editor', order: 2 }, + { id: MenuId.MenubarAppearanceMenu, group: '4_editor', order: 3 }, { id: MenuId.StickyScrollContext } ] }); diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollController.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollController.ts index fb7adfb064a0f..53a7aa18f3c4b 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollController.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollController.ts @@ -3,9 +3,9 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Disposable, DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; -import { IActiveCodeEditor, ICodeEditor } from 'vs/editor/browser/editorBrowser'; -import { IEditorContribution } from 'vs/editor/common/editorCommon'; +import { Disposable, DisposableStore, toDisposable } from 'vs/base/common/lifecycle'; +import { IActiveCodeEditor, ICodeEditor, MouseTargetType } from 'vs/editor/browser/editorBrowser'; +import { IEditorContribution, ScrollType } from 'vs/editor/common/editorCommon'; import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; import { EditorOption, RenderLineNumbersType } from 'vs/editor/common/config/editorOptions'; import { StickyScrollWidget, StickyScrollWidgetState } from './stickyScrollWidget'; @@ -16,7 +16,7 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView import { MenuId } from 'vs/platform/actions/common/actions'; import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; -import { ClickLinkGesture } from 'vs/editor/contrib/gotoSymbol/browser/link/clickLinkGesture'; +import { ClickLinkGesture, ClickLinkMouseEvent } from 'vs/editor/contrib/gotoSymbol/browser/link/clickLinkGesture'; import { IRange, Range } from 'vs/editor/common/core/range'; import { getDefinitionsAtPosition } from 'vs/editor/contrib/gotoSymbol/browser/goToSymbol'; import { goToDefinitionWithLocation } from 'vs/editor/contrib/inlayHints/browser/inlayHintsLocations'; @@ -26,11 +26,7 @@ import { ILanguageConfigurationService } from 'vs/editor/common/languages/langua import { ILanguageFeatureDebounceService } from 'vs/editor/common/services/languageFeatureDebounce'; import * as dom from 'vs/base/browser/dom'; import { StickyRange } from 'vs/editor/contrib/stickyScroll/browser/stickyScrollElement'; - -interface CustomMouseEvent { - detail: string; - element: HTMLElement; -} +import { IMouseEvent, StandardMouseEvent } from 'vs/base/browser/mouseEvent'; export interface IStickyScrollController { get stickyScrollCandidateProvider(): IStickyLineCandidateProvider; @@ -61,13 +57,14 @@ export class StickyScrollController extends Disposable implements IEditorContrib private _stickyScrollFocusedContextKey: IContextKey; private _stickyScrollVisibleContextKey: IContextKey; - private _stickyElements: HTMLCollection | undefined; private _focusDisposableStore: DisposableStore | undefined; private _focusedStickyElementIndex: number = -1; private _enabled = false; private _focused = false; private _positionRevealed = false; private _onMouseDown = false; + private _endLineNumbers: number[] = []; + private _showEndForLine: number | null = null; constructor( private readonly _editor: ICodeEditor, @@ -84,24 +81,24 @@ export class StickyScrollController extends Disposable implements IEditorContrib this._register(this._stickyScrollWidget); this._register(this._stickyLineCandidateProvider); - this._widgetState = new StickyScrollWidgetState([], 0); + this._widgetState = new StickyScrollWidgetState([], [], 0); this._readConfiguration(); + const stickyScrollDomNode = this._stickyScrollWidget.getDomNode(); this._register(this._editor.onDidChangeConfiguration(e => { - if (e.hasChanged(EditorOption.stickyScroll)) { + if (e.hasChanged(EditorOption.stickyScroll) || e.hasChanged(EditorOption.minimap)) { this._readConfiguration(); } })); - this._register(dom.addDisposableListener(this._stickyScrollWidget.getDomNode(), dom.EventType.CONTEXT_MENU, async (event: MouseEvent) => { + this._register(dom.addDisposableListener(stickyScrollDomNode, dom.EventType.CONTEXT_MENU, async (event: MouseEvent) => { this._onContextMenu(event); })); this._stickyScrollFocusedContextKey = EditorContextKeys.stickyScrollFocused.bindTo(this._contextKeyService); this._stickyScrollVisibleContextKey = EditorContextKeys.stickyScrollVisible.bindTo(this._contextKeyService); - const focusTracker = this._register(dom.trackFocus(this._stickyScrollWidget.getDomNode())); + const focusTracker = this._register(dom.trackFocus(stickyScrollDomNode)); this._register(focusTracker.onDidBlur(_ => { - const height = this._stickyScrollWidget.getDomNode().clientHeight; // Suppose that the blurring is caused by scrolling, then keep the focus on the sticky scroll // This is determined by the fact that the height of the widget has become zero and there has been no position revealing - if (this._positionRevealed === false && height === 0) { + if (this._positionRevealed === false && stickyScrollDomNode.clientHeight === 0) { this._focusedStickyElementIndex = -1; this.focus(); @@ -114,9 +111,9 @@ export class StickyScrollController extends Disposable implements IEditorContrib this._register(focusTracker.onDidFocus(_ => { this.focus(); })); - this._register(this._createClickLinkGesture()); + this._registerMouseListeners(); // Suppose that mouse down on the sticky scroll, then do not focus on the sticky scroll because this will be followed by the revealing of a position - this._register(dom.addDisposableListener(this._stickyScrollWidget.getDomNode(), dom.EventType.MOUSE_DOWN, (e) => { + this._register(dom.addDisposableListener(stickyScrollDomNode, dom.EventType.MOUSE_DOWN, (e) => { this._onMouseDown = true; })); } @@ -155,14 +152,12 @@ export class StickyScrollController extends Disposable implements IEditorContrib this._focused = true; this._focusDisposableStore = new DisposableStore(); this._stickyScrollFocusedContextKey.set(true); - const rootNode = this._stickyScrollWidget.getDomNode(); - (rootNode.lastElementChild! as HTMLDivElement).focus(); - this._stickyElements = rootNode.children; this._focusedStickyElementIndex = this._stickyScrollWidget.lineNumbers.length - 1; + this._stickyScrollWidget.focusLineWithIndex(this._focusedStickyElementIndex); } public focusNext(): void { - if (this._focusedStickyElementIndex < this._stickyElements!.length - 1) { + if (this._focusedStickyElementIndex < this._stickyScrollWidget.lineNumberCount - 1) { this._focusNav(true); } } @@ -180,7 +175,7 @@ export class StickyScrollController extends Disposable implements IEditorContrib // True is next, false is previous private _focusNav(direction: boolean): void { this._focusedStickyElementIndex = direction ? this._focusedStickyElementIndex + 1 : this._focusedStickyElementIndex - 1; - (this._stickyElements!.item(this._focusedStickyElementIndex) as HTMLDivElement).focus(); + this._stickyScrollWidget.focusLineWithIndex(this._focusedStickyElementIndex); } public goToFocused(): void { @@ -190,107 +185,183 @@ export class StickyScrollController extends Disposable implements IEditorContrib } private _revealPosition(position: IPosition): void { + this._reveaInEditor(position, () => this._editor.revealPosition(position)); + } + + private _revealLineInCenterIfOutsideViewport(position: IPosition): void { + this._reveaInEditor(position, () => this._editor.revealLineInCenterIfOutsideViewport(position.lineNumber, ScrollType.Smooth)); + } + + private _reveaInEditor(position: IPosition, revealFunction: () => void): void { + if (this._focused) { + this._disposeFocusStickyScrollStore(); + } this._positionRevealed = true; - this._editor.revealPosition(position); + revealFunction(); this._editor.setSelection(Range.fromPositions(position)); this._editor.focus(); } - private _createClickLinkGesture(): IDisposable { + private _registerMouseListeners(): void { - const linkGestureStore = new DisposableStore(); - const sessionStore = new DisposableStore(); - linkGestureStore.add(sessionStore); - const gesture = new ClickLinkGesture(this._editor, true); - linkGestureStore.add(gesture); + const sessionStore = this._register(new DisposableStore()); + const gesture = this._register(new ClickLinkGesture(this._editor, { + extractLineNumberFromMouseEvent: (e) => { + const position = this._stickyScrollWidget.getEditorPositionFromNode(e.target.element); + return position ? position.lineNumber : 0; + } + })); - linkGestureStore.add(gesture.onMouseMoveOrRelevantKeyDown(([mouseEvent, _keyboardEvent]) => { - if (!this._editor.hasModel() || !mouseEvent.hasTriggerModifier) { - sessionStore.clear(); + const getMouseEventTarget = (mouseEvent: ClickLinkMouseEvent): { range: Range; textElement: HTMLElement } | null => { + if (!this._editor.hasModel()) { + return null; + } + if (mouseEvent.target.type !== MouseTargetType.OVERLAY_WIDGET || mouseEvent.target.detail !== this._stickyScrollWidget.getId()) { + // not hovering over our widget + return null; + } + const mouseTargetElement = mouseEvent.target.element; + if (!mouseTargetElement || mouseTargetElement.innerText !== mouseTargetElement.innerHTML) { + // not on a span element rendering text + return null; + } + const position = this._stickyScrollWidget.getEditorPositionFromNode(mouseTargetElement); + if (!position) { + // not hovering a sticky scroll line + return null; + } + return { + range: new Range(position.lineNumber, position.column, position.lineNumber, position.column + mouseTargetElement.innerText.length), + textElement: mouseTargetElement + }; + }; + + const stickyScrollWidgetDomNode = this._stickyScrollWidget.getDomNode(); + this._register(dom.addStandardDisposableListener(stickyScrollWidgetDomNode, dom.EventType.CLICK, (mouseEvent: IMouseEvent) => { + if (mouseEvent.ctrlKey || mouseEvent.altKey || mouseEvent.metaKey) { + // modifier pressed return; } - const targetMouseEvent = mouseEvent.target as unknown as CustomMouseEvent; - if (targetMouseEvent.detail === this._stickyScrollWidget.getId() - && targetMouseEvent.element.innerText === targetMouseEvent.element.innerHTML) { - - const text = targetMouseEvent.element.innerText; - if (this._stickyScrollWidget.hoverOnColumn === -1) { + if (!mouseEvent.leftButton) { + // not left click + return; + } + if (mouseEvent.shiftKey) { + // shift click + const lineIndex = this._stickyScrollWidget.getStickyLineIndexFromChildDomNode(mouseEvent.target); + if (lineIndex === null) { return; } - const lineNumber = this._stickyScrollWidget.hoverOnLine; - const column = this._stickyScrollWidget.hoverOnColumn; - - const stickyPositionProjectedOnEditor = new Range(lineNumber, column, lineNumber, column + text.length); - if (!stickyPositionProjectedOnEditor.equalsRange(this._stickyRangeProjectedOnEditor)) { - this._stickyRangeProjectedOnEditor = stickyPositionProjectedOnEditor; - sessionStore.clear(); - } else if (targetMouseEvent.element.style.textDecoration === 'underline') { + const position = new Position(this._endLineNumbers[lineIndex], 1); + this._revealLineInCenterIfOutsideViewport(position); + return; + } + // normal click + let position = this._stickyScrollWidget.getEditorPositionFromNode(mouseEvent.target); + if (!position) { + const lineNumber = this._stickyScrollWidget.getLineNumberFromChildDomNode(mouseEvent.target); + if (lineNumber === null) { + // not hovering a sticky scroll line return; } + position = new Position(lineNumber, 1); + } + this._revealPosition(position); + })); + this._register(dom.addStandardDisposableListener(stickyScrollWidgetDomNode, dom.EventType.MOUSE_MOVE, (mouseEvent: IMouseEvent) => { + if (mouseEvent.shiftKey) { + const currentEndForLineIndex = this._stickyScrollWidget.getStickyLineIndexFromChildDomNode(mouseEvent.target); + if (currentEndForLineIndex === null || this._showEndForLine !== null && this._showEndForLine === currentEndForLineIndex) { + return; + } + this._showEndForLine = currentEndForLineIndex; + this._renderStickyScroll(); + return; + } + if (this._showEndForLine !== null) { + this._showEndForLine = null; + this._renderStickyScroll(); + } + })); + this._register(dom.addDisposableListener(stickyScrollWidgetDomNode, dom.EventType.MOUSE_LEAVE, (e) => { + if (this._showEndForLine !== null) { + this._showEndForLine = null; + this._renderStickyScroll(); + } + })); - const cancellationToken = new CancellationTokenSource(); - sessionStore.add(toDisposable(() => cancellationToken.dispose(true))); + this._register(gesture.onMouseMoveOrRelevantKeyDown(([mouseEvent, _keyboardEvent]) => { + const mouseTarget = getMouseEventTarget(mouseEvent); + if (!mouseTarget || !mouseEvent.hasTriggerModifier || !this._editor.hasModel()) { + sessionStore.clear(); + return; + } + const { range, textElement } = mouseTarget; - let currentHTMLChild: HTMLElement; + if (!range.equalsRange(this._stickyRangeProjectedOnEditor)) { + this._stickyRangeProjectedOnEditor = range; + sessionStore.clear(); + } else if (textElement.style.textDecoration === 'underline') { + return; + } - getDefinitionsAtPosition(this._languageFeaturesService.definitionProvider, this._editor.getModel(), new Position(lineNumber, column + 1), cancellationToken.token).then((candidateDefinitions => { - if (cancellationToken.token.isCancellationRequested) { - return; - } - if (candidateDefinitions.length !== 0) { - this._candidateDefinitionsLength = candidateDefinitions.length; - const childHTML: HTMLElement = targetMouseEvent.element; - if (currentHTMLChild !== childHTML) { - sessionStore.clear(); - currentHTMLChild = childHTML; - currentHTMLChild.style.textDecoration = 'underline'; - sessionStore.add(toDisposable(() => { - currentHTMLChild.style.textDecoration = 'none'; - })); - } else if (!currentHTMLChild) { - currentHTMLChild = childHTML; - currentHTMLChild.style.textDecoration = 'underline'; - sessionStore.add(toDisposable(() => { - currentHTMLChild.style.textDecoration = 'none'; - })); - } - } else { + const cancellationToken = new CancellationTokenSource(); + sessionStore.add(toDisposable(() => cancellationToken.dispose(true))); + + let currentHTMLChild: HTMLElement; + + getDefinitionsAtPosition(this._languageFeaturesService.definitionProvider, this._editor.getModel(), new Position(range.startLineNumber, range.startColumn + 1), cancellationToken.token).then((candidateDefinitions => { + if (cancellationToken.token.isCancellationRequested) { + return; + } + if (candidateDefinitions.length !== 0) { + this._candidateDefinitionsLength = candidateDefinitions.length; + const childHTML: HTMLElement = textElement; + if (currentHTMLChild !== childHTML) { sessionStore.clear(); + currentHTMLChild = childHTML; + currentHTMLChild.style.textDecoration = 'underline'; + sessionStore.add(toDisposable(() => { + currentHTMLChild.style.textDecoration = 'none'; + })); + } else if (!currentHTMLChild) { + currentHTMLChild = childHTML; + currentHTMLChild.style.textDecoration = 'underline'; + sessionStore.add(toDisposable(() => { + currentHTMLChild.style.textDecoration = 'none'; + })); } - })); - } else { - sessionStore.clear(); - } + } else { + sessionStore.clear(); + } + })); })); - linkGestureStore.add(gesture.onCancel(() => { + this._register(gesture.onCancel(() => { sessionStore.clear(); })); - linkGestureStore.add(gesture.onExecute(async e => { - if ((e.target as unknown as CustomMouseEvent).detail !== this._stickyScrollWidget.getId()) { + this._register(gesture.onExecute(async e => { + if (e.target.type !== MouseTargetType.OVERLAY_WIDGET || e.target.detail !== this._stickyScrollWidget.getId()) { + // not hovering over our widget return; } - if (e.hasTriggerModifier) { - // Control click - if (this._candidateDefinitionsLength > 1) { - if (this._focused) { - this._disposeFocusStickyScrollStore(); - } - this._revealPosition({ lineNumber: this._stickyScrollWidget.hoverOnLine, column: 1 }); - } - this._instaService.invokeFunction(goToDefinitionWithLocation, e, this._editor as IActiveCodeEditor, { uri: this._editor.getModel()!.uri, range: this._stickyRangeProjectedOnEditor! }); - - } else if (!e.isRightClick) { - // Normal click + const position = this._stickyScrollWidget.getEditorPositionFromNode(e.target.element); + if (!position) { + // not hovering a sticky scroll line + return; + } + if (this._candidateDefinitionsLength > 1) { if (this._focused) { this._disposeFocusStickyScrollStore(); } - this._revealPosition({ lineNumber: this._stickyScrollWidget.hoverOnLine, column: this._stickyScrollWidget.hoverOnColumn }); + this._revealPosition({ lineNumber: position.lineNumber, column: 1 }); } + this._instaService.invokeFunction(goToDefinitionWithLocation, e, this._editor as IActiveCodeEditor, { uri: this._editor.getModel()!.uri, range: this._stickyRangeProjectedOnEditor! }); })); - return linkGestureStore; } - private _onContextMenu(event: MouseEvent) { + private _onContextMenu(e: MouseEvent) { + const event = new StandardMouseEvent(e); + this._contextMenuService.showContextMenu({ menuId: MenuId.StickyScrollContext, getAnchor: () => event, @@ -299,7 +370,6 @@ export class StickyScrollController extends Disposable implements IEditorContrib private _readConfiguration() { const options = this._editor.getOption(EditorOption.stickyScroll); - if (options.enabled === false) { this._editor.removeOverlayWidget(this._stickyScrollWidget); this._sessionStore.clear(); @@ -308,16 +378,27 @@ export class StickyScrollController extends Disposable implements IEditorContrib } else if (options.enabled && !this._enabled) { // When sticky scroll was just enabled, add the listeners on the sticky scroll this._editor.addOverlayWidget(this._stickyScrollWidget); - this._sessionStore.add(this._editor.onDidScrollChange(() => this._renderStickyScroll())); + this._sessionStore.add(this._editor.onDidScrollChange((e) => { + if (e.scrollTopChanged) { + this._showEndForLine = null; + this._renderStickyScroll(); + } + })); this._sessionStore.add(this._editor.onDidLayoutChange(() => this._onDidResize())); this._sessionStore.add(this._editor.onDidChangeModelTokens((e) => this._onTokensChange(e))); - this._sessionStore.add(this._stickyLineCandidateProvider.onDidChangeStickyScroll(() => this._renderStickyScroll())); + this._sessionStore.add(this._stickyLineCandidateProvider.onDidChangeStickyScroll(() => { + this._showEndForLine = null; + this._renderStickyScroll(); + })); this._enabled = true; } const lineNumberOption = this._editor.getOption(EditorOption.lineNumbers); if (lineNumberOption.renderType === RenderLineNumbersType.Relative) { - this._sessionStore.add(this._editor.onDidChangeCursorPosition(() => this._renderStickyScroll())); + this._sessionStore.add(this._editor.onDidChangeCursorPosition(() => { + this._showEndForLine = null; + this._renderStickyScroll(); + })); } } @@ -341,39 +422,37 @@ export class StickyScrollController extends Disposable implements IEditorContrib private _onDidResize() { const layoutInfo = this._editor.getLayoutInfo(); - const width = layoutInfo.width - layoutInfo.minimap.minimapCanvasOuterWidth - layoutInfo.verticalScrollbarWidth; - this._stickyScrollWidget.getDomNode().style.width = `${width}px`; // Make sure sticky scroll doesn't take up more than 25% of the editor const theoreticalLines = layoutInfo.height / this._editor.getOption(EditorOption.lineHeight); this._maxStickyLines = Math.round(theoreticalLines * .25); } private _renderStickyScroll() { - if (!(this._editor.hasModel())) { + const model = this._editor.getModel(); + if (!model || model.isTooLargeForTokenization()) { + this._stickyScrollWidget.setState(undefined); return; } - const model = this._editor.getModel(); const stickyLineVersion = this._stickyLineCandidateProvider.getVersionId(); if (stickyLineVersion === undefined || stickyLineVersion === model.getVersionId()) { this._widgetState = this.findScrollWidgetState(); - this._stickyScrollVisibleContextKey.set(!(this._widgetState.lineNumbers.length === 0)); + this._stickyScrollVisibleContextKey.set(!(this._widgetState.startLineNumbers.length === 0)); if (!this._focused) { this._stickyScrollWidget.setState(this._widgetState); } else { - this._stickyElements = this._stickyScrollWidget.getDomNode().children; // Suppose that previously the sticky scroll widget had height 0, then if there are visible lines, set the last line as focused if (this._focusedStickyElementIndex === -1) { this._stickyScrollWidget.setState(this._widgetState); - this._focusedStickyElementIndex = this._stickyElements.length - 1; + this._focusedStickyElementIndex = this._stickyScrollWidget.lineNumberCount - 1; if (this._focusedStickyElementIndex !== -1) { - (this._stickyElements.item(this._focusedStickyElementIndex) as HTMLDivElement).focus(); + this._stickyScrollWidget.focusLineWithIndex(this._focusedStickyElementIndex); } } else { const focusedStickyElementLineNumber = this._stickyScrollWidget.lineNumbers[this._focusedStickyElementIndex]; this._stickyScrollWidget.setState(this._widgetState); // Suppose that after setting the state, there are no sticky lines, set the focused index to -1 - if (this._stickyElements.length === 0) { + if (this._stickyScrollWidget.lineNumberCount === 0) { this._focusedStickyElementIndex = -1; } else { const previousFocusedLineNumberExists = this._stickyScrollWidget.lineNumbers.includes(focusedStickyElementLineNumber); @@ -381,9 +460,9 @@ export class StickyScrollController extends Disposable implements IEditorContrib // If the line number is still there, do not change anything // If the line number is not there, set the new focused line to be the last line if (!previousFocusedLineNumberExists) { - this._focusedStickyElementIndex = this._stickyElements.length - 1; + this._focusedStickyElementIndex = this._stickyScrollWidget.lineNumberCount - 1; } - (this._stickyElements.item(this._focusedStickyElementIndex) as HTMLDivElement).focus(); + this._stickyScrollWidget.focusLineWithIndex(this._focusedStickyElementIndex); } } } @@ -395,7 +474,8 @@ export class StickyScrollController extends Disposable implements IEditorContrib const maxNumberStickyLines = Math.min(this._maxStickyLines, this._editor.getOption(EditorOption.stickyScroll).maxLineCount); const scrollTop: number = this._editor.getScrollTop(); let lastLineRelativePosition: number = 0; - const lineNumbers: number[] = []; + const startLineNumbers: number[] = []; + const endLineNumbers: number[] = []; const arrayVisibleRanges = this._editor.getVisibleRanges(); if (arrayVisibleRanges.length !== 0) { const fullVisibleRange = new StickyRange(arrayVisibleRanges[0].startLineNumber, arrayVisibleRanges[arrayVisibleRanges.length - 1].endLineNumber); @@ -413,20 +493,23 @@ export class StickyScrollController extends Disposable implements IEditorContrib const bottomOfEndLine = this._editor.getBottomForLineNumber(end) - scrollTop; if (topOfElementAtDepth > topOfEndLine && topOfElementAtDepth <= bottomOfEndLine) { - lineNumbers.push(start); + startLineNumbers.push(start); + endLineNumbers.push(end + 1); lastLineRelativePosition = bottomOfEndLine - bottomOfElementAtDepth; break; } else if (bottomOfElementAtDepth > bottomOfBeginningLine && bottomOfElementAtDepth <= bottomOfEndLine) { - lineNumbers.push(start); + startLineNumbers.push(start); + endLineNumbers.push(end + 1); } - if (lineNumbers.length === maxNumberStickyLines) { + if (startLineNumbers.length === maxNumberStickyLines) { break; } } } } - return new StickyScrollWidgetState(lineNumbers, lastLineRelativePosition); + this._endLineNumbers = endLineNumbers; + return new StickyScrollWidgetState(startLineNumbers, endLineNumbers, lastLineRelativePosition, this._showEndForLine); } override dispose(): void { diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollModelProvider.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollModelProvider.ts index cf549710a754f..f1f50f9ced7da 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollModelProvider.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollModelProvider.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { DisposableStore } from 'vs/base/common/lifecycle'; +import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; import { OutlineElement, OutlineGroup, OutlineModel } from 'vs/editor/contrib/documentSymbols/browser/outlineModel'; @@ -45,18 +45,20 @@ export interface IStickyModelProvider { update(textModel: ITextModel, textModelVersionId: number, token: CancellationToken): Promise; } -export class StickyModelProvider implements IStickyModelProvider { +export class StickyModelProvider extends Disposable implements IStickyModelProvider { private _modelProviders: IStickyModelCandidateProvider[] = []; private _modelPromise: CancelablePromise | null = null; - private _updateScheduler: Delayer = new Delayer(300); - private readonly _store: DisposableStore; + private _updateScheduler: Delayer = this._register(new Delayer(300)); + private readonly _updateOperation: DisposableStore = this._register(new DisposableStore()); constructor( private readonly _editor: ICodeEditor, @ILanguageConfigurationService readonly _languageConfigurationService: ILanguageConfigurationService, @ILanguageFeaturesService readonly _languageFeaturesService: ILanguageFeaturesService, - defaultModel: string) { + defaultModel: string + ) { + super(); const stickyModelFromCandidateOutlineProvider = new StickyModelFromCandidateOutlineProvider(_languageFeaturesService); const stickyModelFromSyntaxFoldingProvider = new StickyModelFromCandidateSyntaxFoldingProvider(this._editor, _languageFeaturesService); @@ -76,8 +78,6 @@ export class StickyModelProvider implements IStickyModelProvider { this._modelProviders.push(stickyModelFromIndentationFoldingProvider); break; } - - this._store = new DisposableStore(); } private _cancelModelPromise(): void { @@ -89,11 +89,11 @@ export class StickyModelProvider implements IStickyModelProvider { public async update(textModel: ITextModel, textModelVersionId: number, token: CancellationToken): Promise { - this._store.clear(); - this._store.add({ + this._updateOperation.clear(); + this._updateOperation.add({ dispose: () => { this._cancelModelPromise(); - this._updateScheduler?.cancel(); + this._updateScheduler.cancel(); } }); this._cancelModelPromise(); @@ -113,13 +113,16 @@ export class StickyModelProvider implements IStickyModelProvider { } switch (status) { case Status.CANCELED: - this._store.clear(); + this._updateOperation.clear(); return null; case Status.VALID: return modelProvider.stickyModel; } } return null; + }).catch((error) => { + onUnexpectedError(error); + return null; }); } } diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollProvider.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollProvider.ts index 391ddd6c97801..3269b037cd60d 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollProvider.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollProvider.ts @@ -11,7 +11,6 @@ import { EditorOption, IEditorStickyScrollOptions } from 'vs/editor/common/confi import { RunOnceScheduler } from 'vs/base/common/async'; import { Range } from 'vs/editor/common/core/range'; import { binarySearch } from 'vs/base/common/arrays'; -import { isEqual } from 'vs/base/common/resources'; import { Event, Emitter } from 'vs/base/common/event'; import { ILanguageConfigurationService } from 'vs/editor/common/languages/languageConfigurationRegistry'; import { StickyModelProvider, IStickyModelProvider } from 'vs/editor/contrib/stickyScroll/browser/stickyScrollModelProvider'; @@ -39,7 +38,7 @@ export class StickyLineCandidateProvider extends Disposable implements IStickyLi static readonly ID = 'store.contrib.stickyScrollController'; - private readonly _onDidChangeStickyScroll = this._store.add(new Emitter()); + private readonly _onDidChangeStickyScroll = this._register(new Emitter()); public readonly onDidChangeStickyScroll = this._onDidChangeStickyScroll.event; private readonly _editor: ICodeEditor; @@ -58,7 +57,7 @@ export class StickyLineCandidateProvider extends Disposable implements IStickyLi ) { super(); this._editor = editor; - this._sessionStore = new DisposableStore(); + this._sessionStore = this._register(new DisposableStore()); this._updateSoon = this._register(new RunOnceScheduler(() => this.update(), 50)); this._register(this._editor.onDidChangeConfiguration(e => { @@ -69,27 +68,31 @@ export class StickyLineCandidateProvider extends Disposable implements IStickyLi this.readConfiguration(); } - override dispose(): void { - super.dispose(); - this._sessionStore.dispose(); - } - private readConfiguration() { + this._stickyModelProvider = null; + this._sessionStore.clear(); + this._options = this._editor.getOption(EditorOption.stickyScroll); if (!this._options.enabled) { - this._sessionStore.clear(); return; } - this._stickyModelProvider = new StickyModelProvider( + this._stickyModelProvider = this._sessionStore.add(new StickyModelProvider( this._editor, this._languageConfigurationService, this._languageFeaturesService, this._options.defaultModel - ); + )); - this._sessionStore.add(this._editor.onDidChangeModel(() => this.update())); + this._sessionStore.add(this._editor.onDidChangeModel(() => { + // We should not show an old model for a different file, it will always be wrong. + // So we clear the model here immediately and then trigger an update. + this._model = null; + this._onDidChangeStickyScroll.fire(); + + this.update(); + })); this._sessionStore.add(this._editor.onDidChangeHiddenAreas(() => this.update())); this._sessionStore.add(this._editor.onDidChangeModelContent(() => this._updateSoon.schedule())); this._sessionStore.add(this._languageFeaturesService.documentSymbolProvider.onDidChange(() => this.update())); @@ -110,24 +113,20 @@ export class StickyLineCandidateProvider extends Disposable implements IStickyLi private async updateStickyModel(token: CancellationToken): Promise { if (!this._editor.hasModel() || !this._stickyModelProvider) { + this._model = null; return; } const textModel = this._editor.getModel(); const modelVersionId = textModel.getVersionId(); - const isDifferentModel = this._model ? !isEqual(this._model.uri, textModel.uri) : false; - // Clear sticky scroll to not show stale data for too long - const resetHandle = isDifferentModel ? setTimeout(() => { - if (!token.isCancellationRequested) { - this._model = new StickyModel(textModel.uri, textModel.getVersionId(), undefined, undefined); - this._onDidChangeStickyScroll.fire(); - } - }, 75) : undefined; - - this._model = await this._stickyModelProvider.update(textModel, modelVersionId, token); + const model = await this._stickyModelProvider.update(textModel, modelVersionId, token); + if (token.isCancellationRequested) { + // the computation was canceled, so do not overwrite the model + return; + } - clearTimeout(resetHandle); + this._model = model; } private updateIndex(index: number) { diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts index 7c7260203bf93..607dcb730685f 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts @@ -4,68 +4,94 @@ *--------------------------------------------------------------------------------------------*/ import * as dom from 'vs/base/browser/dom'; -import { StandardMouseEvent } from 'vs/base/browser/mouseEvent'; import { createTrustedTypesPolicy } from 'vs/base/browser/trustedTypes'; -import { equals } from 'vs/base/common/arrays'; -import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; +import { Disposable } from 'vs/base/common/lifecycle'; import 'vs/css!./stickyScroll'; import { ICodeEditor, IOverlayWidget, IOverlayWidgetPosition } from 'vs/editor/browser/editorBrowser'; +import { getColumnOfNodeOffset } from 'vs/editor/browser/viewParts/lines/viewLine'; import { EmbeddedCodeEditorWidget } from 'vs/editor/browser/widget/embeddedCodeEditorWidget'; import { EditorLayoutInfo, EditorOption, RenderLineNumbersType } from 'vs/editor/common/config/editorOptions'; import { Position } from 'vs/editor/common/core/position'; import { StringBuilder } from 'vs/editor/common/core/stringBuilder'; import { LineDecoration } from 'vs/editor/common/viewLayout/lineDecorations'; -import { RenderLineInput, renderViewLine } from 'vs/editor/common/viewLayout/viewLineRenderer'; +import { CharacterMapping, RenderLineInput, renderViewLine } from 'vs/editor/common/viewLayout/viewLineRenderer'; export class StickyScrollWidgetState { constructor( - readonly lineNumbers: number[], - readonly lastLineRelativePosition: number + readonly startLineNumbers: number[], + readonly endLineNumbers: number[], + readonly lastLineRelativePosition: number, + readonly showEndForLine: number | null = null ) { } - - public equals(other: StickyScrollWidgetState | undefined): boolean { - return !!other && this.lastLineRelativePosition === other.lastLineRelativePosition && equals(this.lineNumbers, other.lineNumbers); - } } const _ttPolicy = createTrustedTypesPolicy('stickyScrollViewLayer', { createHTML: value => value }); +const STICKY_LINE_INDEX_ATTR = 'data-sticky-line-index'; export class StickyScrollWidget extends Disposable implements IOverlayWidget { - private readonly _layoutInfo: EditorLayoutInfo; private readonly _rootDomNode: HTMLElement = document.createElement('div'); - private readonly _disposableStore = this._register(new DisposableStore()); + private readonly _lineNumbersDomNode: HTMLElement = document.createElement('div'); + private readonly _linesDomNodeScrollable: HTMLElement = document.createElement('div'); + private readonly _linesDomNode: HTMLElement = document.createElement('div'); + private _stickyLines: RenderedStickyLine[] = []; private _lineNumbers: number[] = []; private _lastLineRelativePosition: number = 0; - private _hoverOnLine: number = -1; - private _hoverOnColumn: number = -1; - private _state: StickyScrollWidgetState | undefined; + private _minContentWidthInPx: number = 0; constructor( private readonly _editor: ICodeEditor ) { super(); - this._layoutInfo = this._editor.getLayoutInfo(); - this._rootDomNode = document.createElement('div'); + + this._lineNumbersDomNode.className = 'sticky-widget-line-numbers'; + this._lineNumbersDomNode.setAttribute('role', 'none'); + + this._linesDomNode.className = 'sticky-widget-lines'; + this._linesDomNode.setAttribute('role', 'list'); + + this._linesDomNodeScrollable.className = 'sticky-widget-lines-scrollable'; + this._linesDomNodeScrollable.appendChild(this._linesDomNode); + this._rootDomNode.className = 'sticky-widget'; this._rootDomNode.classList.toggle('peek', _editor instanceof EmbeddedCodeEditorWidget); - this._rootDomNode.style.width = `${this._layoutInfo.width - this._layoutInfo.minimap.minimapCanvasOuterWidth - this._layoutInfo.verticalScrollbarWidth}px`; - } + this._rootDomNode.appendChild(this._lineNumbersDomNode); + this._rootDomNode.appendChild(this._linesDomNodeScrollable); - get hoverOnLine(): number { - return this._hoverOnLine; - } + const updateScrollLeftPosition = () => { + this._linesDomNode.style.left = this._editor.getOption(EditorOption.stickyScroll).scrollWithEditor ? `-${this._editor.getScrollLeft()}px` : '0px'; + }; + this._register(this._editor.onDidChangeConfiguration((e) => { + if (e.hasChanged(EditorOption.stickyScroll)) { + updateScrollLeftPosition(); + } + })); + this._register(this._editor.onDidScrollChange((e) => { + if (e.scrollLeftChanged) { + updateScrollLeftPosition(); + } + if (e.scrollWidthChanged) { + this._updateWidgetWidth(); + } + })); + this._register(this._editor.onDidChangeModel(() => { + updateScrollLeftPosition(); + this._updateWidgetWidth(); + })); + updateScrollLeftPosition(); - get hoverOnColumn(): number { - return this._hoverOnColumn; + this._register(this._editor.onDidLayoutChange((e) => { + this._updateWidgetWidth(); + })); + this._updateWidgetWidth(); } get lineNumbers(): number[] { return this._lineNumbers; } - get codeLineCount(): number { + get lineNumberCount(): number { return this._lineNumbers.length; } @@ -73,20 +99,22 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget { return this._lineNumbers; } - setState(state: StickyScrollWidgetState): void { - if (state.equals(this._state)) { + setState(state: StickyScrollWidgetState | undefined): void { + this._clearStickyWidget(); + if (!state) { return; } - this._state = state; - dom.clearNode(this._rootDomNode); - this._disposableStore.clear(); - this._lineNumbers.length = 0; + this._stickyLines = []; const editorLineHeight = this._editor.getOption(EditorOption.lineHeight); - const futureWidgetHeight = state.lineNumbers.length * editorLineHeight + state.lastLineRelativePosition; + const futureWidgetHeight = state.startLineNumbers.length * editorLineHeight + state.lastLineRelativePosition; if (futureWidgetHeight > 0) { this._lastLineRelativePosition = state.lastLineRelativePosition; - this._lineNumbers = state.lineNumbers; + const lineNumbers = [...state.startLineNumbers]; + if (state.showEndForLine !== null) { + lineNumbers[state.showEndForLine] = state.endLineNumbers[state.showEndForLine]; + } + this._lineNumbers = lineNumbers; } else { this._lastLineRelativePosition = 0; this._lineNumbers = []; @@ -94,36 +122,60 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget { this._renderRootNode(); } + private _updateWidgetWidth(): void { + const layoutInfo = this._editor.getLayoutInfo(); + const minimapSide = this._editor.getOption(EditorOption.minimap).side; + const lineNumbersWidth = minimapSide === 'left' ? layoutInfo.contentLeft - layoutInfo.minimap.minimapCanvasOuterWidth : layoutInfo.contentLeft; + this._lineNumbersDomNode.style.width = `${lineNumbersWidth}px`; + this._linesDomNodeScrollable.style.setProperty('--vscode-editorStickyScroll-scrollableWidth', `${this._editor.getScrollWidth() - layoutInfo.verticalScrollbarWidth}px`); + this._rootDomNode.style.width = `${layoutInfo.width - layoutInfo.minimap.minimapCanvasOuterWidth - layoutInfo.verticalScrollbarWidth}px`; + } + + private _clearStickyWidget() { + dom.clearNode(this._lineNumbersDomNode); + dom.clearNode(this._linesDomNode); + this._rootDomNode.style.display = 'none'; + } + private _renderRootNode(): void { if (!this._editor._getViewModel()) { return; } + + const layoutInfo = this._editor.getLayoutInfo(); for (const [index, line] of this._lineNumbers.entries()) { - const childNode = this._renderChildNode(index, line); - this._rootDomNode.appendChild(childNode); + const { lineNumberHTMLNode, renderedStickyLine } = this._renderChildNode(index, line, layoutInfo); + this._lineNumbersDomNode.appendChild(lineNumberHTMLNode); + this._linesDomNode.appendChild(renderedStickyLine.domNode); + this._stickyLines.push(renderedStickyLine); } const editorLineHeight = this._editor.getOption(EditorOption.lineHeight); const widgetHeight: number = this._lineNumbers.length * editorLineHeight + this._lastLineRelativePosition; - this._rootDomNode.style.display = widgetHeight > 0 ? 'block' : 'none'; - this._rootDomNode.style.height = widgetHeight.toString() + 'px'; - this._rootDomNode.setAttribute('role', 'list'); + if (widgetHeight === 0) { + this._clearStickyWidget(); + return; + } + this._rootDomNode.style.display = 'block'; + this._lineNumbersDomNode.style.height = `${widgetHeight}px`; + this._linesDomNodeScrollable.style.height = `${widgetHeight}px`; + this._rootDomNode.style.height = `${widgetHeight}px`; const minimapSide = this._editor.getOption(EditorOption.minimap).side; if (minimapSide === 'left') { - this._rootDomNode.style.marginLeft = this._editor.getLayoutInfo().minimap.minimapCanvasOuterWidth + 'px'; + this._rootDomNode.style.marginLeft = layoutInfo.minimap.minimapCanvasOuterWidth + 'px'; + } else { + this._rootDomNode.style.marginLeft = '0px'; } + this._updateMinContentWidth(); + this._editor.layoutOverlayWidget(this); } - private _renderChildNode(index: number, line: number): HTMLDivElement { - - const child = document.createElement('div'); + private _renderChildNode(index: number, line: number, layoutInfo: EditorLayoutInfo): { lineNumberHTMLNode: HTMLSpanElement; renderedStickyLine: RenderedStickyLine } { const viewModel = this._editor._getViewModel(); const viewLineNumber = viewModel!.coordinatesConverter.convertModelPositionToViewPosition(new Position(line, 1)).lineNumber; const lineRenderingData = viewModel!.getViewLineRenderingData(viewLineNumber); - const layoutInfo = this._editor.getLayoutInfo(); - const width = layoutInfo.width - layoutInfo.minimap.minimapCanvasOuterWidth - layoutInfo.verticalScrollbarWidth; const minimapSide = this._editor.getOption(EditorOption.minimap).side; const lineHeight = this._editor.getOption(EditorOption.lineHeight); const lineNumberOption = this._editor.getOption(EditorOption.lineNumbers); @@ -144,7 +196,7 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget { ); const sb = new StringBuilder(2000); - renderViewLine(renderLineInput, sb); + const renderOutput = renderViewLine(renderLineInput, sb); let newLine; if (_ttPolicy) { @@ -154,19 +206,14 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget { } const lineHTMLNode = document.createElement('span'); - lineHTMLNode.className = 'sticky-line'; + lineHTMLNode.className = 'sticky-line-content'; lineHTMLNode.classList.add(`stickyLine${line}`); lineHTMLNode.style.lineHeight = `${lineHeight}px`; lineHTMLNode.innerHTML = newLine as string; const lineNumberHTMLNode = document.createElement('span'); - lineNumberHTMLNode.className = 'sticky-line'; + lineNumberHTMLNode.className = 'sticky-line-number'; lineNumberHTMLNode.style.lineHeight = `${lineHeight}px`; - if (minimapSide === 'left') { - lineNumberHTMLNode.style.width = `${layoutInfo.contentLeft - layoutInfo.minimap.minimapCanvasOuterWidth}px`; - } else if (minimapSide === 'right') { - lineNumberHTMLNode.style.width = `${layoutInfo.contentLeft}px`; - } const innerLineNumberHTML = document.createElement('span'); if (lineNumberOption.renderType === RenderLineNumbersType.On || lineNumberOption.renderType === RenderLineNumbersType.Interval && line % 10 === 0) { @@ -174,7 +221,7 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget { } else if (lineNumberOption.renderType === RenderLineNumbersType.Relative) { innerLineNumberHTML.innerText = Math.abs(line - this._editor.getPosition()!.lineNumber).toString(); } - innerLineNumberHTML.className = 'sticky-line-number'; + innerLineNumberHTML.className = 'sticky-line-number-inner'; innerLineNumberHTML.style.lineHeight = `${lineHeight}px`; innerLineNumberHTML.style.width = `${layoutInfo.lineNumbersWidth}px`; if (minimapSide === 'left') { @@ -187,38 +234,42 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget { this._editor.applyFontInfo(lineHTMLNode); this._editor.applyFontInfo(innerLineNumberHTML); - child.appendChild(lineNumberHTMLNode); - child.appendChild(lineHTMLNode); + lineHTMLNode.setAttribute('role', 'listitem'); + lineHTMLNode.setAttribute(STICKY_LINE_INDEX_ATTR, String(index)); + lineHTMLNode.tabIndex = 0; - child.className = 'sticky-line-root'; - child.setAttribute('role', 'listitem'); - child.tabIndex = 0; - child.style.lineHeight = `${lineHeight}px`; - child.style.width = `${width}px`; - child.style.height = `${lineHeight}px`; - child.style.zIndex = '0'; + lineNumberHTMLNode.style.lineHeight = `${lineHeight}px`; + lineHTMLNode.style.lineHeight = `${lineHeight}px`; + lineNumberHTMLNode.style.height = `${lineHeight}px`; + lineHTMLNode.style.height = `${lineHeight}px`; // Special case for the last line of sticky scroll - if (index === this._lineNumbers.length - 1) { - child.style.position = 'relative'; - child.style.zIndex = '-1'; - child.style.top = this._lastLineRelativePosition + 'px'; - } - - // Each child has a listener which fires when the mouse hovers over the child - this._disposableStore.add(dom.addDisposableListener(child, 'mouseover', (e) => { - if (this._editor.hasModel()) { - const mouseOverEvent = new StandardMouseEvent(e); - const text = mouseOverEvent.target.innerText; - - // Line and column number of the hover needed for the control clicking feature - this._hoverOnLine = line; - // TODO: workaround to find the column index, perhaps need a more solid solution - this._hoverOnColumn = this._editor.getModel().getLineContent(line).indexOf(text) + 1 || -1; - } - })); + const isLastLine = index === this._lineNumbers.length - 1; + + const lastLineZIndex = '0'; + const intermediateLineZIndex = '1'; + lineHTMLNode.style.zIndex = isLastLine ? lastLineZIndex : intermediateLineZIndex; + lineNumberHTMLNode.style.zIndex = isLastLine ? lastLineZIndex : intermediateLineZIndex; + + const lastLineTop = `${index * lineHeight + this._lastLineRelativePosition}px`; + const intermediateLineTop = `${index * lineHeight}px`; + lineHTMLNode.style.top = isLastLine ? lastLineTop : intermediateLineTop; + lineNumberHTMLNode.style.top = isLastLine ? lastLineTop : intermediateLineTop; - return child; + return { + lineNumberHTMLNode, + renderedStickyLine: new RenderedStickyLine(line, lineHTMLNode, renderOutput.characterMapping) + }; + } + + private _updateMinContentWidth() { + this._minContentWidthInPx = 0; + for (const stickyLine of this._stickyLines) { + if (stickyLine.domNode.scrollWidth > this._minContentWidthInPx) { + this._minContentWidthInPx = stickyLine.domNode.scrollWidth; + } + } + this._minContentWidthInPx += this._editor.getLayoutInfo().verticalScrollbarWidth; } getId(): string { @@ -234,4 +285,65 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget { preference: null }; } + + getMinContentWidthInPx(): number { + return this._minContentWidthInPx; + } + + focusLineWithIndex(index: number) { + if (0 <= index && index < this._stickyLines.length) { + this._stickyLines[index].domNode.focus(); + } + } + + /** + * Given a leaf dom node, tries to find the editor position. + */ + getEditorPositionFromNode(spanDomNode: HTMLElement | null): Position | null { + if (!spanDomNode || spanDomNode.children.length > 0) { + // This is not a leaf node + return null; + } + const renderedStickyLine = this._getRenderedStickyLineFromChildDomNode(spanDomNode); + if (!renderedStickyLine) { + return null; + } + const column = getColumnOfNodeOffset(renderedStickyLine.characterMapping, spanDomNode, 0); + return new Position(renderedStickyLine.lineNumber, column); + } + + getLineNumberFromChildDomNode(domNode: HTMLElement | null): number | null { + return this._getRenderedStickyLineFromChildDomNode(domNode)?.lineNumber ?? null; + } + + private _getRenderedStickyLineFromChildDomNode(domNode: HTMLElement | null): RenderedStickyLine | null { + const index = this.getStickyLineIndexFromChildDomNode(domNode); + if (index === null || index < 0 || index >= this._stickyLines.length) { + return null; + } + return this._stickyLines[index]; + } + + /** + * Given a child dom node, tries to find the line number attribute + * that was stored in the node. Returns null if none is found. + */ + getStickyLineIndexFromChildDomNode(domNode: HTMLElement | null): number | null { + while (domNode && domNode !== this._rootDomNode) { + const line = domNode.getAttribute(STICKY_LINE_INDEX_ATTR); + if (line) { + return parseInt(line, 10); + } + domNode = domNode.parentElement; + } + return null; + } +} + +class RenderedStickyLine { + constructor( + public readonly lineNumber: number, + public readonly domNode: HTMLElement, + public readonly characterMapping: CharacterMapping + ) { } } diff --git a/src/vs/editor/contrib/stickyScroll/test/browser/stickyScroll.test.ts b/src/vs/editor/contrib/stickyScroll/test/browser/stickyScroll.test.ts index 909bddf980186..906d1299bb841 100644 --- a/src/vs/editor/contrib/stickyScroll/test/browser/stickyScroll.test.ts +++ b/src/vs/editor/contrib/stickyScroll/test/browser/stickyScroll.test.ts @@ -161,27 +161,27 @@ suite('Sticky Scroll Tests', () => { editor.setScrollTop(1); state = stickyScrollController.findScrollWidgetState(); - assert.deepStrictEqual(state.lineNumbers, [1]); + assert.deepStrictEqual(state.startLineNumbers, [1]); editor.setScrollTop(lineHeight + 1); state = stickyScrollController.findScrollWidgetState(); - assert.deepStrictEqual(state.lineNumbers, [1]); + assert.deepStrictEqual(state.startLineNumbers, [1]); editor.setScrollTop(4 * lineHeight + 1); state = stickyScrollController.findScrollWidgetState(); - assert.deepStrictEqual(state.lineNumbers, []); + assert.deepStrictEqual(state.startLineNumbers, []); editor.setScrollTop(8 * lineHeight + 1); state = stickyScrollController.findScrollWidgetState(); - assert.deepStrictEqual(state.lineNumbers, [7, 9]); + assert.deepStrictEqual(state.startLineNumbers, [7, 9]); editor.setScrollTop(9 * lineHeight + 1); state = stickyScrollController.findScrollWidgetState(); - assert.deepStrictEqual(state.lineNumbers, [7, 9]); + assert.deepStrictEqual(state.startLineNumbers, [7, 9]); editor.setScrollTop(10 * lineHeight + 1); state = stickyScrollController.findScrollWidgetState(); - assert.deepStrictEqual(state.lineNumbers, [7]); + assert.deepStrictEqual(state.startLineNumbers, [7]); stickyScrollController.dispose(); stickyScrollController.stickyScrollCandidateProvider.dispose(); @@ -212,23 +212,23 @@ suite('Sticky Scroll Tests', () => { editor.setScrollTop(1); state = stickyScrollController.findScrollWidgetState(); - assert.deepStrictEqual(state.lineNumbers, [1]); + assert.deepStrictEqual(state.startLineNumbers, [1]); editor.setScrollTop(lineHeight + 1); state = stickyScrollController.findScrollWidgetState(); - assert.deepStrictEqual(state.lineNumbers, []); + assert.deepStrictEqual(state.startLineNumbers, []); editor.setScrollTop(6 * lineHeight + 1); state = stickyScrollController.findScrollWidgetState(); - assert.deepStrictEqual(state.lineNumbers, [7, 9]); + assert.deepStrictEqual(state.startLineNumbers, [7, 9]); editor.setScrollTop(7 * lineHeight + 1); state = stickyScrollController.findScrollWidgetState(); - assert.deepStrictEqual(state.lineNumbers, [7]); + assert.deepStrictEqual(state.startLineNumbers, [7]); editor.setScrollTop(10 * lineHeight + 1); state = stickyScrollController.findScrollWidgetState(); - assert.deepStrictEqual(state.lineNumbers, []); + assert.deepStrictEqual(state.startLineNumbers, []); stickyScrollController.dispose(); stickyScrollController.stickyScrollCandidateProvider.dispose(); @@ -306,23 +306,23 @@ suite('Sticky Scroll Tests', () => { editor.setScrollTop(1); state = stickyScrollController.findScrollWidgetState(); - assert.deepStrictEqual(state.lineNumbers, [1, 2]); + assert.deepStrictEqual(state.startLineNumbers, [1, 2]); editor.setScrollTop(lineHeight + 1); state = stickyScrollController.findScrollWidgetState(); - assert.deepStrictEqual(state.lineNumbers, [1, 2]); + assert.deepStrictEqual(state.startLineNumbers, [1, 2]); editor.setScrollTop(2 * lineHeight + 1); state = stickyScrollController.findScrollWidgetState(); - assert.deepStrictEqual(state.lineNumbers, [1]); + assert.deepStrictEqual(state.startLineNumbers, [1]); editor.setScrollTop(3 * lineHeight + 1); state = stickyScrollController.findScrollWidgetState(); - assert.deepStrictEqual(state.lineNumbers, [1]); + assert.deepStrictEqual(state.startLineNumbers, [1]); editor.setScrollTop(4 * lineHeight + 1); state = stickyScrollController.findScrollWidgetState(); - assert.deepStrictEqual(state.lineNumbers, []); + assert.deepStrictEqual(state.startLineNumbers, []); stickyScrollController.dispose(); stickyScrollController.stickyScrollCandidateProvider.dispose(); diff --git a/src/vs/editor/contrib/suggest/browser/suggestController.ts b/src/vs/editor/contrib/suggest/browser/suggestController.ts index ddd57946496a2..6450e989bcebf 100644 --- a/src/vs/editor/contrib/suggest/browser/suggestController.ts +++ b/src/vs/editor/contrib/suggest/browser/suggestController.ts @@ -8,7 +8,7 @@ import { isNonEmptyArray } from 'vs/base/common/arrays'; import { IdleValue } from 'vs/base/common/async'; import { CancellationTokenSource } from 'vs/base/common/cancellation'; import { onUnexpectedError, onUnexpectedExternalError } from 'vs/base/common/errors'; -import { Event } from 'vs/base/common/event'; +import { Emitter, Event } from 'vs/base/common/event'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { KeyCodeChord } from 'vs/base/common/keybindings'; import { DisposableStore, dispose, IDisposable, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle'; @@ -119,6 +119,9 @@ export class SuggestController implements IEditorContribution { private readonly _overtypingCapturer: IdleValue; private readonly _selectors = new PriorityRegistry(s => s.priority); + private readonly _onWillInsertSuggestItem = new Emitter<{ item: CompletionItem }>(); + readonly onWillInsertSuggestItem: Event<{ item: CompletionItem }> = this._onWillInsertSuggestItem.event; + constructor( editor: ICodeEditor, @ISuggestMemoryService private readonly _memoryService: ISuggestMemoryService, @@ -140,7 +143,7 @@ export class SuggestController implements IEditorContribution { // context key: update insert/replace mode const ctxInsertMode = SuggestContext.InsertMode.bindTo(_contextKeyService); ctxInsertMode.set(editor.getOption(EditorOption.suggest).insertMode); - this.model.onDidTrigger(() => ctxInsertMode.set(editor.getOption(EditorOption.suggest).insertMode)); + this._toDispose.add(this.model.onDidTrigger(() => ctxInsertMode.set(editor.getOption(EditorOption.suggest).insertMode))); this.widget = this._toDispose.add(new IdleValue(() => { @@ -292,6 +295,7 @@ export class SuggestController implements IEditorContribution { this.widget.dispose(); this.model.dispose(); this._lineSuffix.dispose(); + this._onWillInsertSuggestItem.dispose(); } protected _insertSuggestion( @@ -312,6 +316,8 @@ export class SuggestController implements IEditorContribution { return; } + this._onWillInsertSuggestItem.fire({ item: event.item }); + const model = this.editor.getModel(); const modelVersionNow = model.getAlternativeVersionId(); const { item } = event; diff --git a/src/vs/editor/contrib/suggest/browser/suggestWidget.ts b/src/vs/editor/contrib/suggest/browser/suggestWidget.ts index d2e86783c8a0f..09ebd2bdda058 100644 --- a/src/vs/editor/contrib/suggest/browser/suggestWidget.ts +++ b/src/vs/editor/contrib/suggest/browser/suggestWidget.ts @@ -34,6 +34,7 @@ import { CompletionItem, Context as SuggestContext, suggestWidgetStatusbarMenu } import { canExpandCompletionItem, SuggestDetailsOverlay, SuggestDetailsWidget } from './suggestWidgetDetails'; import { getAriaId, ItemRenderer } from './suggestWidgetRenderer'; import { getListStyles } from 'vs/platform/theme/browser/defaultStyles'; +import { status } from 'vs/base/browser/ui/aria/aria'; /** * Suggest widget colors @@ -237,9 +238,9 @@ export class SuggestWidget implements IDisposable { if (typeof item.completion.label !== 'string') { const { detail, description } = item.completion.label; if (detail && description) { - label = nls.localize('label.full', '{0}{1}, {2}', label, detail, description); + label = nls.localize('label.full', '{0} {1}, {2}', label, detail, description); } else if (detail) { - label = nls.localize('label.detail', '{0}{1}', label, detail); + label = nls.localize('label.detail', '{0} {1}', label, detail); } else if (description) { label = nls.localize('label.desc', '{0}, {1}', label, description); } @@ -463,6 +464,7 @@ export class SuggestWidget implements IDisposable { this._details.hide(); this._show(); this._focusedItem = undefined; + status(SuggestWidget.LOADING_MESSAGE); break; case State.Empty: this.element.domNode.classList.add('message'); @@ -472,6 +474,7 @@ export class SuggestWidget implements IDisposable { this._details.hide(); this._show(); this._focusedItem = undefined; + status(SuggestWidget.NO_SUGGESTIONS_MESSAGE); break; case State.Open: dom.hide(this._messageElement); diff --git a/src/vs/editor/contrib/suggest/test/browser/suggest.test.ts b/src/vs/editor/contrib/suggest/test/browser/suggest.test.ts index 1ff62f2cb35e7..d4df28ea332bc 100644 --- a/src/vs/editor/contrib/suggest/test/browser/suggest.test.ts +++ b/src/vs/editor/contrib/suggest/test/browser/suggest.test.ts @@ -12,10 +12,10 @@ import { CompletionItemKind, CompletionItemProvider } from 'vs/editor/common/lan import { CompletionOptions, provideSuggestionItems, SnippetSortOrder } from 'vs/editor/contrib/suggest/browser/suggest'; import { createTextModel } from 'vs/editor/test/common/testTextModel'; import { LanguageFeatureRegistry } from 'vs/editor/common/languageFeatureRegistry'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; suite('Suggest', function () { - let model: TextModel; let registration: IDisposable; let registry: LanguageFeatureRegistry; @@ -54,37 +54,43 @@ suite('Suggest', function () { model.dispose(); }); + ensureNoDisposablesAreLeakedInTestSuite(); + test('sort - snippet inline', async function () { - const { items } = await provideSuggestionItems(registry, model, new Position(1, 1), new CompletionOptions(SnippetSortOrder.Inline)); + const { items, disposable } = await provideSuggestionItems(registry, model, new Position(1, 1), new CompletionOptions(SnippetSortOrder.Inline)); assert.strictEqual(items.length, 3); assert.strictEqual(items[0].completion.label, 'aaa'); assert.strictEqual(items[1].completion.label, 'fff'); assert.strictEqual(items[2].completion.label, 'zzz'); + disposable.dispose(); }); test('sort - snippet top', async function () { - const { items } = await provideSuggestionItems(registry, model, new Position(1, 1), new CompletionOptions(SnippetSortOrder.Top)); + const { items, disposable } = await provideSuggestionItems(registry, model, new Position(1, 1), new CompletionOptions(SnippetSortOrder.Top)); assert.strictEqual(items.length, 3); assert.strictEqual(items[0].completion.label, 'aaa'); assert.strictEqual(items[1].completion.label, 'zzz'); assert.strictEqual(items[2].completion.label, 'fff'); + disposable.dispose(); }); test('sort - snippet bottom', async function () { - const { items } = await provideSuggestionItems(registry, model, new Position(1, 1), new CompletionOptions(SnippetSortOrder.Bottom)); + const { items, disposable } = await provideSuggestionItems(registry, model, new Position(1, 1), new CompletionOptions(SnippetSortOrder.Bottom)); assert.strictEqual(items.length, 3); assert.strictEqual(items[0].completion.label, 'fff'); assert.strictEqual(items[1].completion.label, 'aaa'); assert.strictEqual(items[2].completion.label, 'zzz'); + disposable.dispose(); }); test('sort - snippet none', async function () { - const { items } = await provideSuggestionItems(registry, model, new Position(1, 1), new CompletionOptions(undefined, new Set().add(CompletionItemKind.Snippet))); + const { items, disposable } = await provideSuggestionItems(registry, model, new Position(1, 1), new CompletionOptions(undefined, new Set().add(CompletionItemKind.Snippet))); assert.strictEqual(items.length, 1); assert.strictEqual(items[0].completion.label, 'fff'); + disposable.dispose(); }); - test('only from', function () { + test('only from', function (callback) { const foo: any = { triggerCharacters: [], @@ -102,11 +108,13 @@ suite('Suggest', function () { }; const registration = registry.register({ pattern: 'bar/path', scheme: 'foo' }, foo); - provideSuggestionItems(registry, model, new Position(1, 1), new CompletionOptions(undefined, undefined, new Set().add(foo))).then(({ items }) => { + provideSuggestionItems(registry, model, new Position(1, 1), new CompletionOptions(undefined, undefined, new Set().add(foo))).then(({ items, disposable }) => { registration.dispose(); assert.strictEqual(items.length, 1); assert.ok(items[0].provider === foo); + disposable.dispose(); + callback(); }); }); @@ -142,7 +150,7 @@ suite('Suggest', function () { }; const registration = registry.register({ pattern: 'bar/path', scheme: 'foo' }, foo); - const { items } = await provideSuggestionItems(registry, model, new Position(0, 0), new CompletionOptions(undefined, undefined, new Set().add(foo))); + const { items, disposable } = await provideSuggestionItems(registry, model, new Position(0, 0), new CompletionOptions(undefined, undefined, new Set().add(foo))); registration.dispose(); assert.strictEqual(items.length, 2); @@ -152,5 +160,6 @@ suite('Suggest', function () { assert.strictEqual(a.isInvalid, false); assert.strictEqual(b.completion.label, 'two'); assert.strictEqual(b.isInvalid, true); + disposable.dispose(); }); }); diff --git a/src/vs/editor/contrib/unicodeHighlighter/browser/unicodeHighlighter.ts b/src/vs/editor/contrib/unicodeHighlighter/browser/unicodeHighlighter.ts index 9b77b25b72eba..eea1de6f65bc8 100644 --- a/src/vs/editor/contrib/unicodeHighlighter/browser/unicodeHighlighter.ts +++ b/src/vs/editor/contrib/unicodeHighlighter/browser/unicodeHighlighter.ts @@ -429,6 +429,7 @@ export class UnicodeHighlighterHoverParticipant implements IEditorHoverParticipa } const result: MarkdownHover[] = []; + const existedReason = new Set(); let index = 300; for (const d of lineDecorations) { @@ -480,6 +481,11 @@ export class UnicodeHighlighterHoverParticipant implements IEditorHoverParticipa break; } + if (existedReason.has(reason)) { + continue; + } + existedReason.add(reason); + const adjustSettingsArgs: ShowExcludeOptionsArgs = { codePoint: codePoint, reason: highlightInfo.reason, diff --git a/src/vs/editor/standalone/browser/quickAccess/standaloneCommandsQuickAccess.ts b/src/vs/editor/standalone/browser/quickAccess/standaloneCommandsQuickAccess.ts index 5e87aa8f71050..171a395e6f30b 100644 --- a/src/vs/editor/standalone/browser/quickAccess/standaloneCommandsQuickAccess.ts +++ b/src/vs/editor/standalone/browser/quickAccess/standaloneCommandsQuickAccess.ts @@ -10,7 +10,6 @@ import { ICommandQuickPick } from 'vs/platform/quickinput/browser/commandsQuickA import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; import { AbstractEditorCommandsQuickAccessProvider } from 'vs/editor/contrib/quickAccess/browser/commandsQuickAccess'; import { IEditor } from 'vs/editor/common/editorCommon'; -import { withNullAsUndefined } from 'vs/base/common/types'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { ICommandService } from 'vs/platform/commands/common/commands'; @@ -24,7 +23,7 @@ import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; export class StandaloneCommandsQuickAccessProvider extends AbstractEditorCommandsQuickAccessProvider { - protected get activeTextEditorControl(): IEditor | undefined { return withNullAsUndefined(this.codeEditorService.getFocusedCodeEditor()); } + protected get activeTextEditorControl(): IEditor | undefined { return this.codeEditorService.getFocusedCodeEditor() ?? undefined; } constructor( @IInstantiationService instantiationService: IInstantiationService, diff --git a/src/vs/editor/standalone/browser/quickAccess/standaloneGotoLineQuickAccess.ts b/src/vs/editor/standalone/browser/quickAccess/standaloneGotoLineQuickAccess.ts index 71cfc2ec4bac0..c6ccecf960cfd 100644 --- a/src/vs/editor/standalone/browser/quickAccess/standaloneGotoLineQuickAccess.ts +++ b/src/vs/editor/standalone/browser/quickAccess/standaloneGotoLineQuickAccess.ts @@ -7,7 +7,6 @@ import { AbstractGotoLineQuickAccessProvider } from 'vs/editor/contrib/quickAcce import { Registry } from 'vs/platform/registry/common/platform'; import { IQuickAccessRegistry, Extensions } from 'vs/platform/quickinput/common/quickAccess'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; -import { withNullAsUndefined } from 'vs/base/common/types'; import { GoToLineNLS } from 'vs/editor/common/standaloneStrings'; import { Event } from 'vs/base/common/event'; import { EditorAction, registerEditorAction, ServicesAccessor } from 'vs/editor/browser/editorExtensions'; @@ -25,7 +24,7 @@ export class StandaloneGotoLineQuickAccessProvider extends AbstractGotoLineQuick } protected get activeTextEditorControl() { - return withNullAsUndefined(this.editorService.getFocusedCodeEditor()); + return this.editorService.getFocusedCodeEditor() ?? undefined; } } diff --git a/src/vs/editor/standalone/browser/quickAccess/standaloneGotoSymbolQuickAccess.ts b/src/vs/editor/standalone/browser/quickAccess/standaloneGotoSymbolQuickAccess.ts index d7bf0d9400274..0c2cfb8617b70 100644 --- a/src/vs/editor/standalone/browser/quickAccess/standaloneGotoSymbolQuickAccess.ts +++ b/src/vs/editor/standalone/browser/quickAccess/standaloneGotoSymbolQuickAccess.ts @@ -9,7 +9,6 @@ import { AbstractGotoSymbolQuickAccessProvider } from 'vs/editor/contrib/quickAc import { Registry } from 'vs/platform/registry/common/platform'; import { IQuickAccessRegistry, Extensions } from 'vs/platform/quickinput/common/quickAccess'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; -import { withNullAsUndefined } from 'vs/base/common/types'; import { QuickOutlineNLS } from 'vs/editor/common/standaloneStrings'; import { Event } from 'vs/base/common/event'; import { EditorAction, registerEditorAction } from 'vs/editor/browser/editorExtensions'; @@ -34,7 +33,7 @@ export class StandaloneGotoSymbolQuickAccessProvider extends AbstractGotoSymbolQ } protected get activeTextEditorControl() { - return withNullAsUndefined(this.editorService.getFocusedCodeEditor()); + return this.editorService.getFocusedCodeEditor() ?? undefined; } } diff --git a/src/vs/editor/standalone/browser/quickInput/standaloneQuickInputService.ts b/src/vs/editor/standalone/browser/quickInput/standaloneQuickInputService.ts index 4aa2558480f26..8c35ee5b26940 100644 --- a/src/vs/editor/standalone/browser/quickInput/standaloneQuickInputService.ts +++ b/src/vs/editor/standalone/browser/quickInput/standaloneQuickInputService.ts @@ -8,13 +8,13 @@ import { ICodeEditor, IOverlayWidget, IOverlayWidgetPosition, OverlayWidgetPosit import { EditorContributionInstantiation, registerEditorContribution } from 'vs/editor/browser/editorExtensions'; import { IEditorContribution } from 'vs/editor/common/editorCommon'; import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { IQuickInputService, IQuickInputButton, IQuickPickItem, IQuickPick, IInputBox, IQuickNavigateConfiguration, IPickOptions, QuickPickInput, IInputOptions } from 'vs/platform/quickinput/common/quickInput'; +import { IQuickInputService, IQuickInputButton, IQuickPickItem, IQuickPick, IInputBox, IQuickNavigateConfiguration, IPickOptions, QuickPickInput, IInputOptions, IQuickWidget } from 'vs/platform/quickinput/common/quickInput'; import { CancellationToken } from 'vs/base/common/cancellation'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { EditorScopedLayoutService } from 'vs/editor/standalone/browser/standaloneLayoutService'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; -import { IQuickInputControllerHost, QuickInputController } from 'vs/platform/quickinput/browser/quickInput'; +import { QuickInputController, IQuickInputControllerHost } from 'vs/platform/quickinput/browser/quickInputController'; import { QuickInputService } from 'vs/platform/quickinput/browser/quickInputService'; import { once } from 'vs/base/common/functional'; import { IQuickAccessController } from 'vs/platform/quickinput/common/quickAccess'; @@ -111,6 +111,10 @@ export class StandaloneQuickInputService implements IQuickInputService { return this.activeService.createInputBox(); } + createQuickWidget(): IQuickWidget { + return this.activeService.createQuickWidget(); + } + focus(): void { return this.activeService.focus(); } diff --git a/src/vs/editor/standalone/browser/standaloneCodeEditor.ts b/src/vs/editor/standalone/browser/standaloneCodeEditor.ts index 43e1f1eef10e8..d9a8d83cf09fa 100644 --- a/src/vs/editor/standalone/browser/standaloneCodeEditor.ts +++ b/src/vs/editor/standalone/browser/standaloneCodeEditor.ts @@ -38,6 +38,7 @@ import { ILanguageConfigurationService } from 'vs/editor/common/languages/langua import { IEditorConstructionOptions } from 'vs/editor/browser/config/editorConfiguration'; import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; import { DiffEditorWidget2 } from 'vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2'; +import { IAudioCueService } from 'vs/platform/audioCues/browser/audioCueService'; /** * Description of an action contribution @@ -572,7 +573,8 @@ export class StandaloneDiffEditor2 extends DiffEditorWidget2 implements IStandal @IConfigurationService configurationService: IConfigurationService, @IContextMenuService contextMenuService: IContextMenuService, @IEditorProgressService editorProgressService: IEditorProgressService, - @IClipboardService clipboardService: IClipboardService + @IClipboardService clipboardService: IClipboardService, + @IAudioCueService audioCueService: IAudioCueService, ) { const options = { ..._options }; updateConfigurationService(configurationService, options, true); @@ -591,6 +593,7 @@ export class StandaloneDiffEditor2 extends DiffEditorWidget2 implements IStandal contextKeyService, instantiationService, codeEditorService, + audioCueService, ); this._configurationService = configurationService; diff --git a/src/vs/editor/standalone/browser/standaloneLanguages.ts b/src/vs/editor/standalone/browser/standaloneLanguages.ts index 78d683d2fe5db..939d33910346a 100644 --- a/src/vs/editor/standalone/browser/standaloneLanguages.ts +++ b/src/vs/editor/standalone/browser/standaloneLanguages.ts @@ -54,16 +54,18 @@ export function getEncodedLanguageId(languageId: string): number { * @event */ export function onLanguage(languageId: string, callback: () => void): IDisposable { - const languageService = StandaloneServices.get(ILanguageService); - const disposable = languageService.onDidRequestRichLanguageFeatures((encounteredLanguageId) => { - if (encounteredLanguageId === languageId) { - // stop listening - disposable.dispose(); - // invoke actual listener - callback(); - } + return StandaloneServices.withServices(() => { + const languageService = StandaloneServices.get(ILanguageService); + const disposable = languageService.onDidRequestRichLanguageFeatures((encounteredLanguageId) => { + if (encounteredLanguageId === languageId) { + // stop listening + disposable.dispose(); + // invoke actual listener + callback(); + } + }); + return disposable; }); - return disposable; } /** @@ -72,16 +74,18 @@ export function onLanguage(languageId: string, callback: () => void): IDisposabl * @event */ export function onLanguageEncountered(languageId: string, callback: () => void): IDisposable { - const languageService = StandaloneServices.get(ILanguageService); - const disposable = languageService.onDidRequestBasicLanguageFeatures((encounteredLanguageId) => { - if (encounteredLanguageId === languageId) { - // stop listening - disposable.dispose(); - // invoke actual listener - callback(); - } + return StandaloneServices.withServices(() => { + const languageService = StandaloneServices.get(ILanguageService); + const disposable = languageService.onDidRequestBasicLanguageFeatures((encounteredLanguageId) => { + if (encounteredLanguageId === languageId) { + // stop listening + disposable.dispose(); + // invoke actual listener + callback(); + } + }); + return disposable; }); - return disposable; } /** diff --git a/src/vs/editor/standalone/browser/standaloneServices.ts b/src/vs/editor/standalone/browser/standaloneServices.ts index cc2ede5219cda..e729736101311 100644 --- a/src/vs/editor/standalone/browser/standaloneServices.ts +++ b/src/vs/editor/standalone/browser/standaloneServices.ts @@ -87,7 +87,7 @@ import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; import { IStorageService, InMemoryStorageService } from 'vs/platform/storage/common/storage'; import { DefaultConfiguration } from 'vs/platform/configuration/common/configurations'; import { WorkspaceEdit } from 'vs/editor/common/languages'; -import { AudioCue, AudioCueGroupId, IAudioCueService, Sound } from 'vs/platform/audioCues/browser/audioCueService'; +import { AudioCue, IAudioCueService, Sound } from 'vs/platform/audioCues/browser/audioCueService'; import { LogService } from 'vs/platform/log/common/logService'; import { getEditorFeatures } from 'vs/editor/common/editorFeatures'; import { onUnexpectedError } from 'vs/base/common/errors'; @@ -1039,7 +1039,7 @@ class StandaloneContextMenuService extends ContextMenuService { class StandaloneAudioService implements IAudioCueService { _serviceBrand: undefined; - async playAudioCue(cue: AudioCue, allowManyInParallel?: boolean | undefined): Promise { + async playAudioCue(cue: AudioCue, options: {}): Promise { } async playAudioCues(cues: AudioCue[]): Promise { @@ -1058,8 +1058,6 @@ class StandaloneAudioService implements IAudioCueService { playAudioCueLoop(cue: AudioCue): IDisposable { return toDisposable(() => { }); } - playRandomAudioCue(groupId: AudioCueGroupId, allowManyInParallel?: boolean): void { - } } export interface IEditorOverrideServices { @@ -1128,6 +1126,7 @@ export module StandaloneServices { } let initialized = false; + const onDidInitialize = new Emitter(); export function initialize(overrides: IEditorOverrideServices): IInstantiationService { if (initialized) { return instantiationService; @@ -1163,6 +1162,27 @@ export module StandaloneServices { } } + onDidInitialize.fire(); + return instantiationService; } + + /** + * Executes callback once services are initialized. + */ + export function withServices(callback: () => IDisposable): IDisposable { + if (initialized) { + return callback(); + } + + const disposable = new DisposableStore(); + + const listener = disposable.add(onDidInitialize.event(() => { + listener.dispose(); + disposable.add(callback()); + })); + + return disposable; + } + } diff --git a/src/vs/editor/standalone/browser/standaloneThemeService.ts b/src/vs/editor/standalone/browser/standaloneThemeService.ts index ec49af70ecebf..a391249e6e0cb 100644 --- a/src/vs/editor/standalone/browser/standaloneThemeService.ts +++ b/src/vs/editor/standalone/browser/standaloneThemeService.ts @@ -392,7 +392,7 @@ export class StandaloneThemeService extends Disposable implements IStandaloneThe colorVariables.push(`${asCssVariableName(item.id)}: ${color.toString()};`); } } - ruleCollector.addRule(`.monaco-editor { ${colorVariables.join('\n')} }`); + ruleCollector.addRule(`.monaco-editor, .monaco-diff-editor { ${colorVariables.join('\n')} }`); const colorMap = this._colorMapOverride || this._theme.tokenTheme.getColorMap(); ruleCollector.addRule(generateTokensCSSForColorMap(colorMap)); diff --git a/src/vs/editor/test/browser/testCodeEditor.ts b/src/vs/editor/test/browser/testCodeEditor.ts index acca9e7cde383..28a17729768b6 100644 --- a/src/vs/editor/test/browser/testCodeEditor.ts +++ b/src/vs/editor/test/browser/testCodeEditor.ts @@ -45,7 +45,8 @@ import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { BrandedService, IInstantiationService, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; -import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService'; +import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; +import { MockContextKeyService, MockKeybindingService } from 'vs/platform/keybinding/test/common/mockKeybindingService'; import { ILogService, NullLogService } from 'vs/platform/log/common/log'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService'; @@ -176,6 +177,7 @@ export function createCodeEditorServices(disposables: DisposableStore, services: }; define(IAccessibilityService, TestAccessibilityService); + define(IKeybindingService, MockKeybindingService); define(IClipboardService, TestClipboardService); define(IEditorWorkerService, TestEditorWorkerService); defineInstance(IOpenerService, NullOpenerService); diff --git a/src/vs/editor/test/browser/viewModel/modelLineProjection.test.ts b/src/vs/editor/test/browser/viewModel/modelLineProjection.test.ts index 06de7665c0271..530ae84b56285 100644 --- a/src/vs/editor/test/browser/viewModel/modelLineProjection.test.ts +++ b/src/vs/editor/test/browser/viewModel/modelLineProjection.test.ts @@ -921,7 +921,7 @@ suite('SplitLinesCollection', () => { })), [ { inlineDecorations: [{ startOffset: 8, endOffset: 23 }] }, - { inlineDecorations: [{ startOffset: 4, endOffset: 42 }] }, + { inlineDecorations: [{ startOffset: 4, endOffset: 30 }] }, { inlineDecorations: [{ startOffset: 4, endOffset: 16 }] }, { inlineDecorations: undefined }, { inlineDecorations: undefined }, diff --git a/src/vs/editor/test/common/diff/diffComputer.test.ts b/src/vs/editor/test/common/diff/diffComputer.test.ts index a8eb52b07c18e..aca599dc6e50d 100644 --- a/src/vs/editor/test/common/diff/diffComputer.test.ts +++ b/src/vs/editor/test/common/diff/diffComputer.test.ts @@ -5,7 +5,7 @@ import * as assert from 'assert'; import { Constants } from 'vs/base/common/uint'; import { Range } from 'vs/editor/common/core/range'; -import { DiffComputer, ICharChange, ILineChange } from 'vs/editor/common/diff/smartLinesDiffComputer'; +import { DiffComputer, ICharChange, ILineChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; import { IIdentifiedSingleEditOperation, ITextModel } from 'vs/editor/common/model'; import { createTextModel } from 'vs/editor/test/common/testTextModel'; diff --git a/src/vs/editor/test/common/model/bracketPairColorizer/brackets.test.ts b/src/vs/editor/test/common/model/bracketPairColorizer/brackets.test.ts index abf6200a8fa69..2a21907778def 100644 --- a/src/vs/editor/test/common/model/bracketPairColorizer/brackets.test.ts +++ b/src/vs/editor/test/common/model/bracketPairColorizer/brackets.test.ts @@ -5,12 +5,15 @@ import * as assert from 'assert'; import { DisposableStore } from 'vs/base/common/lifecycle'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; import { LanguageAgnosticBracketTokens } from 'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/brackets'; import { SmallImmutableSet, DenseKeyProvider } from 'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/smallImmutableSet'; import { Token, TokenKind } from 'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/tokenizer'; import { TestLanguageConfigurationService } from 'vs/editor/test/common/modes/testLanguageConfigurationService'; suite('Bracket Pair Colorizer - Brackets', () => { + ensureNoDisposablesAreLeakedInTestSuite(); + test('Basic', () => { const languageId = 'testMode1'; const denseKeyProvider = new DenseKeyProvider(); @@ -24,7 +27,7 @@ suite('Bracket Pair Colorizer - Brackets', () => { }; const disposableStore = new DisposableStore(); - const languageConfigService = new TestLanguageConfigurationService(); + const languageConfigService = disposableStore.add(new TestLanguageConfigurationService()); disposableStore.add(languageConfigService.register(languageId, { brackets: [ ['{', '}'], ['[', ']'], ['(', ')'], diff --git a/src/vs/editor/test/common/services/testEditorWorkerService.ts b/src/vs/editor/test/common/services/testEditorWorkerService.ts index 640a3e4b59676..e6693d821e99d 100644 --- a/src/vs/editor/test/common/services/testEditorWorkerService.ts +++ b/src/vs/editor/test/common/services/testEditorWorkerService.ts @@ -8,7 +8,7 @@ import { IRange } from 'vs/editor/common/core/range'; import { DiffAlgorithmName, IEditorWorkerService, IUnicodeHighlightsResult } from 'vs/editor/common/services/editorWorker'; import { TextEdit, IInplaceReplaceSupportResult } from 'vs/editor/common/languages'; import { IDocumentDiff, IDocumentDiffProviderOptions } from 'vs/editor/common/diff/documentDiffProvider'; -import { IChange } from 'vs/editor/common/diff/smartLinesDiffComputer'; +import { IChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; export class TestEditorWorkerService implements IEditorWorkerService { diff --git a/src/vs/editor/test/node/diffing/diffingFixture.test.ts b/src/vs/editor/test/node/diffing/diffingFixture.test.ts index 2cdcb08d472c5..a04f2edf9d87b 100644 --- a/src/vs/editor/test/node/diffing/diffingFixture.test.ts +++ b/src/vs/editor/test/node/diffing/diffingFixture.test.ts @@ -9,8 +9,8 @@ import { join, resolve } from 'path'; import { setUnexpectedErrorHandler } from 'vs/base/common/errors'; import { FileAccess } from 'vs/base/common/network'; import { LineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; -import { SmartLinesDiffComputer } from 'vs/editor/common/diff/smartLinesDiffComputer'; -import { StandardLinesDiffComputer } from 'vs/editor/common/diff/standardLinesDiffComputer'; +import { LegacyLinesDiffComputer } from 'vs/editor/common/diff/legacyLinesDiffComputer'; +import { AdvancedLinesDiffComputer } from 'vs/editor/common/diff/advancedLinesDiffComputer'; suite('diff fixtures', () => { setup(() => { @@ -38,7 +38,7 @@ suite('diff fixtures', () => { const secondContent = readFileSync(join(folderPath, secondFileName), 'utf8').replaceAll('\r\n', '\n').replaceAll('\r', '\n'); const secondContentLines = secondContent.split(/\n/); - const diffingAlgo = diffingAlgoName === 'legacy' ? new SmartLinesDiffComputer() : new StandardLinesDiffComputer(); + const diffingAlgo = diffingAlgoName === 'legacy' ? new LegacyLinesDiffComputer() : new AdvancedLinesDiffComputer(); const ignoreTrimWhitespace = folder.indexOf('trimws') >= 0; const diff = diffingAlgo.computeDiff(firstContentLines, secondContentLines, { ignoreTrimWhitespace, maxComputationTimeMs: Number.MAX_SAFE_INTEGER, computeMoves: false }); @@ -59,8 +59,8 @@ suite('diff fixtures', () => { modified: { content: secondContent, fileName: `./${secondFileName}` }, diffs: getDiffs(diff.changes), moves: diff.moves.map(v => ({ - originalRange: v.lineRangeMapping.originalRange.toString(), - modifiedRange: v.lineRangeMapping.modifiedRange.toString(), + originalRange: v.lineRangeMapping.original.toString(), + modifiedRange: v.lineRangeMapping.modified.toString(), changes: getDiffs(v.changes), })) }; diff --git a/src/vs/editor/test/node/diffing/fixtures/bracket-aligning/advanced.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/bracket-aligning/advanced.expected.diff.json index 18845aa6ccd84..85083dedd288d 100644 --- a/src/vs/editor/test/node/diffing/fixtures/bracket-aligning/advanced.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/bracket-aligning/advanced.expected.diff.json @@ -67,8 +67,8 @@ ] }, { - "originalRange": "[86,99)", - "modifiedRange": "[88,102)", + "originalRange": "[86,95)", + "modifiedRange": "[88,98)", "innerChanges": [ { "originalRange": "[86,1 -> 86,1]", @@ -108,23 +108,7 @@ }, { "originalRange": "[95,1 -> 95,1]", - "modifiedRange": "[97,1 -> 97,2]" - }, - { - "originalRange": "[96,1 -> 96,1]", - "modifiedRange": "[98,1 -> 98,2]" - }, - { - "originalRange": "[97,1 -> 97,1]", - "modifiedRange": "[99,1 -> 99,2]" - }, - { - "originalRange": "[98,1 -> 98,1]", - "modifiedRange": "[100,1 -> 100,2]" - }, - { - "originalRange": "[99,1 -> 99,1]", - "modifiedRange": "[101,1 -> 102,1]" + "modifiedRange": "[97,1 -> 98,1]" } ] } diff --git a/src/vs/editor/test/node/diffing/fixtures/class-replacement/advanced.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/class-replacement/advanced.expected.diff.json index c6bc13330029d..5cbd3c45666de 100644 --- a/src/vs/editor/test/node/diffing/fixtures/class-replacement/advanced.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/class-replacement/advanced.expected.diff.json @@ -9,64 +9,22 @@ }, "diffs": [ { - "originalRange": "[29,34)", - "modifiedRange": "[29,31)", + "originalRange": "[29,61)", + "modifiedRange": "[29,37)", "innerChanges": [ { - "originalRange": "[29,1 -> 33,1]", - "modifiedRange": "[29,1 -> 29,1]" - }, - { - "originalRange": "[33,14 -> 33,41]", - "modifiedRange": "[29,14 -> 30,54]" - } - ] - }, - { - "originalRange": "[35,36)", - "modifiedRange": "[32,33)", - "innerChanges": [ - { - "originalRange": "[35,2 -> 35,26]", - "modifiedRange": "[32,2 -> 32,48]" - } - ] - }, - { - "originalRange": "[37,40)", - "modifiedRange": "[34,35)", - "innerChanges": [ - { - "originalRange": "[37,2 -> 39,3]", - "modifiedRange": "[34,2 -> 34,64]" - } - ] - }, - { - "originalRange": "[41,46)", - "modifiedRange": "[36,37)", - "innerChanges": [ - { - "originalRange": "[41,9 -> 41,18]", - "modifiedRange": "[36,9 -> 36,44]" - }, - { - "originalRange": "[41,26 -> 42,34]", - "modifiedRange": "[36,52 -> 36,64]" - }, - { - "originalRange": "[43,1 -> 46,1]", - "modifiedRange": "[37,1 -> 37,1]" + "originalRange": "[29,1 -> 61,1]", + "modifiedRange": "[29,1 -> 37,1]" } ] }, { - "originalRange": "[48,72)", + "originalRange": "[63,72)", "modifiedRange": "[39,40)", "innerChanges": [ { - "originalRange": "[48,9 -> 63,48]", - "modifiedRange": "[39,9 -> 39,43]" + "originalRange": "[63,9 -> 63,43]", + "modifiedRange": "[39,9 -> 39,38]" }, { "originalRange": "[64,1 -> 72,1]", diff --git a/src/vs/editor/test/node/diffing/fixtures/difficult-move/advanced.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/difficult-move/advanced.expected.diff.json index 6d0a4cf9977ca..b2155f7f62582 100644 --- a/src/vs/editor/test/node/diffing/fixtures/difficult-move/advanced.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/difficult-move/advanced.expected.diff.json @@ -43,60 +43,8 @@ "modifiedRange": "[226,234)", "innerChanges": [ { - "originalRange": "[222,17 -> 222,19]", - "modifiedRange": "[226,17 -> 226,17]" - }, - { - "originalRange": "[223,4 -> 223,28]", - "modifiedRange": "[227,4 -> 227,37]" - }, - { - "originalRange": "[223,32 -> 223,49]", - "modifiedRange": "[227,41 -> 227,48]" - }, - { - "originalRange": "[223,54 -> 223,65]", - "modifiedRange": "[227,53 -> 227,62]" - }, - { - "originalRange": "[224,4 -> 224,29]", - "modifiedRange": "[228,4 -> 228,55]" - }, - { - "originalRange": "[224,43 -> 225,63]", - "modifiedRange": "[228,69 -> 228,108]" - }, - { - "originalRange": "[225,78 -> 226,8]", - "modifiedRange": "[228,123 -> 228,152]" - }, - { - "originalRange": "[226,22 -> 226,25]", - "modifiedRange": "[228,166 -> 228,169]" - }, - { - "originalRange": "[227,5 -> 227,93]", - "modifiedRange": "[229,5 -> 229,67]" - }, - { - "originalRange": "[228,5 -> 228,51]", - "modifiedRange": "[230,5 -> 230,30]" - }, - { - "originalRange": "[229,6 -> 229,143]", - "modifiedRange": "[231,6 -> 231,40]" - }, - { - "originalRange": "[230,5 -> 232,42]", - "modifiedRange": "[232,5 -> 232,19]" - }, - { - "originalRange": "[232,48 -> 232,98]", - "modifiedRange": "[232,25 -> 233,58]" - }, - { - "originalRange": "[233,1 -> 234,1]", - "modifiedRange": "[234,1 -> 234,1]" + "originalRange": "[222,17 -> 234,1]", + "modifiedRange": "[226,17 -> 234,1]" } ] } diff --git a/src/vs/editor/test/node/diffing/fixtures/fuzzy-matching/advanced.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/fuzzy-matching/advanced.expected.diff.json index ed6c0fe7ff124..4059da96da892 100644 --- a/src/vs/editor/test/node/diffing/fixtures/fuzzy-matching/advanced.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/fuzzy-matching/advanced.expected.diff.json @@ -9,22 +9,40 @@ }, "diffs": [ { - "originalRange": "[1,1)", - "modifiedRange": "[1,9)", + "originalRange": "[1,9)", + "modifiedRange": "[1,10)", "innerChanges": [ { - "originalRange": "[1,1 -> 1,1]", - "modifiedRange": "[1,1 -> 9,1]" - } - ] - }, - { - "originalRange": "[2,9)", - "modifiedRange": "[10,10)", - "innerChanges": [ + "originalRange": "[1,1 -> 2,1]", + "modifiedRange": "[1,1 -> 1,1]" + }, + { + "originalRange": "[2,15 -> 2,15]", + "modifiedRange": "[1,15 -> 1,16]" + }, + { + "originalRange": "[3,15 -> 3,15]", + "modifiedRange": "[2,15 -> 2,16]" + }, + { + "originalRange": "[4,15 -> 4,15]", + "modifiedRange": "[3,15 -> 3,16]" + }, + { + "originalRange": "[5,15 -> 5,15]", + "modifiedRange": "[4,15 -> 5,1]" + }, + { + "originalRange": "[6,15 -> 6,15]", + "modifiedRange": "[6,15 -> 6,16]" + }, + { + "originalRange": "[7,15 -> 7,15]", + "modifiedRange": "[7,15 -> 7,16]" + }, { - "originalRange": "[2,1 -> 9,1]", - "modifiedRange": "[10,1 -> 10,1]" + "originalRange": "[8,15 -> 8,15]", + "modifiedRange": "[8,15 -> 9,1]" } ] } diff --git a/src/vs/editor/test/node/diffing/fixtures/indentation/advanced.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/indentation/advanced.expected.diff.json index 2e7031437fa75..431762545388c 100644 --- a/src/vs/editor/test/node/diffing/fixtures/indentation/advanced.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/indentation/advanced.expected.diff.json @@ -27,8 +27,8 @@ ] }, { - "originalRange": "[12,24)", - "modifiedRange": "[13,26)", + "originalRange": "[12,23)", + "modifiedRange": "[13,25)", "innerChanges": [ { "originalRange": "[12,1 -> 12,1]", @@ -76,11 +76,7 @@ }, { "originalRange": "[23,1 -> 23,1]", - "modifiedRange": "[24,1 -> 24,2]" - }, - { - "originalRange": "[24,1 -> 24,1]", - "modifiedRange": "[25,1 -> 26,1]" + "modifiedRange": "[24,1 -> 25,1]" } ] } diff --git a/src/vs/editor/test/node/diffing/fixtures/issue-185779/advanced.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/issue-185779/advanced.expected.diff.json index d3a24ad44f2ef..a7ea515c057c2 100644 --- a/src/vs/editor/test/node/diffing/fixtures/issue-185779/advanced.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/issue-185779/advanced.expected.diff.json @@ -9,8 +9,8 @@ }, "diffs": [ { - "originalRange": "[26,33)", - "modifiedRange": "[26,43)", + "originalRange": "[26,32)", + "modifiedRange": "[26,42)", "innerChanges": [ { "originalRange": "[26,10 -> 26,10]", @@ -38,11 +38,7 @@ }, { "originalRange": "[32,1 -> 32,1]", - "modifiedRange": "[41,1 -> 41,2]" - }, - { - "originalRange": "[33,1 -> 33,1]", - "modifiedRange": "[42,1 -> 43,1]" + "modifiedRange": "[41,1 -> 42,1]" } ] } diff --git a/src/vs/editor/test/node/diffing/fixtures/method-splitting/advanced.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/method-splitting/advanced.expected.diff.json index 8bc08d08086cb..b1de25a5907cb 100644 --- a/src/vs/editor/test/node/diffing/fixtures/method-splitting/advanced.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/method-splitting/advanced.expected.diff.json @@ -9,50 +9,24 @@ }, "diffs": [ { - "originalRange": "[6,10)", - "modifiedRange": "[6,8)", + "originalRange": "[6,15)", + "modifiedRange": "[6,11)", "innerChanges": [ { - "originalRange": "[6,2 -> 6,9]", - "modifiedRange": "[6,2 -> 6,11]" + "originalRange": "[6,1 -> 11,49]", + "modifiedRange": "[6,1 -> 6,91]" }, { - "originalRange": "[6,12 -> 6,18]", - "modifiedRange": "[6,14 -> 6,14]" + "originalRange": "[12,76 -> 12,76]", + "modifiedRange": "[7,76 -> 7,80]" }, { - "originalRange": "[6,29 -> 6,54]", - "modifiedRange": "[6,25 -> 6,91]" + "originalRange": "[12,153 -> 12,153]", + "modifiedRange": "[7,157 -> 7,181]" }, { - "originalRange": "[6,57 -> 6,75]", - "modifiedRange": "[6,94 -> 6,118]" - }, - { - "originalRange": "[7,9 -> 7,38]", - "modifiedRange": "[7,9 -> 7,27]" - }, - { - "originalRange": "[7,61 -> 7,105]", - "modifiedRange": "[7,50 -> 7,85]" - }, - { - "originalRange": "[7,112 -> 8,10]", - "modifiedRange": "[7,92 -> 7,130]" - }, - { - "originalRange": "[8,15 -> 10,1]", - "modifiedRange": "[7,135 -> 8,1]" - } - ] - }, - { - "originalRange": "[11,15)", - "modifiedRange": "[9,11)", - "innerChanges": [ - { - "originalRange": "[11,1 -> 13,1]", - "modifiedRange": "[9,1 -> 9,1]" + "originalRange": "[13,1 -> 13,1]", + "modifiedRange": "[8,1 -> 9,1]" }, { "originalRange": "[13,31 -> 13,31]", diff --git a/src/vs/editor/test/node/diffing/fixtures/noise-1/1.tst b/src/vs/editor/test/node/diffing/fixtures/noise-1/1.tst new file mode 100644 index 0000000000000..bd5594cabb4fb --- /dev/null +++ b/src/vs/editor/test/node/diffing/fixtures/noise-1/1.tst @@ -0,0 +1,57 @@ +this._sash = derivedWithStore('sash', (reader, store) => { + const showSash = this._options.renderSideBySide.read(reader); + this.elements.root.classList.toggle('side-by-side', showSash); + if (!showSash) { return undefined; } + const result = store.add(new DiffEditorSash( + this._options, + this.elements.root, + { + height: this._rootSizeObserver.height, + width: this._rootSizeObserver.width.map((w, reader) => w - (this._options.renderOverviewRuler.read(reader) ? OverviewRulerPart.ENTIRE_DIFF_OVERVIEW_WIDTH : 0)), + } + )); + store.add(autorun('setBoundarySashes', reader => { + const boundarySashes = this._boundarySashes.read(reader); + if (boundarySashes) { + result.setBoundarySashes(boundarySashes); + } + })); + return result; +}); +this._register(keepAlive(this._sash, true)); + +this._register(autorunWithStore2('UnchangedRangesFeature', (reader, store) => { + this.unchangedRangesFeature = store.add(new (readHotReloadableExport(UnchangedRangesFeature, reader))(this._editors, this._diffModel, this._options)); +})); + +this._register(autorunWithStore2('DiffEditorDecorations', (reader, store) => { + store.add(new (readHotReloadableExport(DiffEditorDecorations, reader))(this._editors, this._diffModel, this._options)); +})); +this._register(autorunWithStore2('ViewZoneManager', (reader, store) => { + store.add(this._instantiationService.createInstance( + readHotReloadableExport(ViewZoneManager, reader), + this._editors, + this._diffModel, + this._options, + this, + () => this.unchangedRangesFeature.isUpdatingViewZones, + )); +})); + +this._register(autorunWithStore2('OverviewRulerPart', (reader, store) => { + store.add(this._instantiationService.createInstance(readHotReloadableExport(OverviewRulerPart, reader), this._editors, + this.elements.root, + this._diffModel, + this._rootSizeObserver.width, + this._rootSizeObserver.height, + this._layoutInfo.map(i => i.modifiedEditor), + this._options, + )); +})); + +this._reviewPane = this._register(this._instantiationService.createInstance(DiffReview2, this)); +this.elements.root.appendChild(this._reviewPane.domNode.domNode); +this.elements.root.appendChild(this._reviewPane.actionBarContainer.domNode); +reviewPaneObservable.set(this._reviewPane, undefined); + +this._createDiffEditorContributions(); diff --git a/src/vs/editor/test/node/diffing/fixtures/noise-1/2.tst b/src/vs/editor/test/node/diffing/fixtures/noise-1/2.tst new file mode 100644 index 0000000000000..0432b64d75f67 --- /dev/null +++ b/src/vs/editor/test/node/diffing/fixtures/noise-1/2.tst @@ -0,0 +1,67 @@ +this._sash = derivedWithStore('sash', (reader, store) => { + const showSash = this._options.renderSideBySide.read(reader); + this.elements.root.classList.toggle('side-by-side', showSash); + if (!showSash) { return undefined; } + const result = store.add(new DiffEditorSash( + this._options, + this.elements.root, + { + height: this._rootSizeObserver.height, + width: this._rootSizeObserver.width.map((w, reader) => w - (this._options.renderOverviewRuler.read(reader) ? OverviewRulerPart.ENTIRE_DIFF_OVERVIEW_WIDTH : 0)), + } + )); + store.add(autorun('setBoundarySashes', reader => { + const boundarySashes = this._boundarySashes.read(reader); + if (boundarySashes) { + result.setBoundarySashes(boundarySashes); + } + })); + return result; +}); +this._register(keepAlive(this._sash, true)); + +this._register(autorunWithStore2('UnchangedRangesFeature', (reader, store) => { + this.unchangedRangesFeature = store.add(new (readHotReloadableExport(UnchangedRangesFeature, reader))(this._editors, this._diffModel, this._options)); +})); + +this._register(autorunWithStore2('DiffEditorDecorations', (reader, store) => { + store.add(new (readHotReloadableExport(DiffEditorDecorations, reader))(this._editors, this._diffModel, this._options)); +})); +this._register(autorunWithStore2('ViewZoneManager', (reader, store) => { + store.add(this._instantiationService.createInstance( + readHotReloadableExport(ViewZoneManager, reader), + this._editors, + this._diffModel, + this._options, + this, + () => this.unchangedRangesFeature.isUpdatingViewZones, + )); +})); + +this._register(autorunWithStore2('OverviewRulerPart', (reader, store) => { + store.add(this._instantiationService.createInstance(readHotReloadableExport(OverviewRulerPart, reader), this._editors, + this.elements.root, + this._diffModel, + this._rootSizeObserver.width, + this._rootSizeObserver.height, + this._layoutInfo.map(i => i.modifiedEditor), + this._options, + )); +})); + +this._register(autorunWithStore2('_accessibleDiffViewer', (reader, store) => { + this._accessibleDiffViewer = store.add(this._register(this._instantiationService.createInstance( + readHotReloadableExport(AccessibleDiffViewer, reader), + this.elements.accessibleDiffViewer, + this._accessibleDiffViewerVisible, + this._rootSizeObserver.width, + this._rootSizeObserver.height, + this._diffModel.map((m, r) => m?.diff.read(r)?.mappings.map(m => m.lineRangeMapping)), + this._editors, + ))); +})); +const visibility = this._accessibleDiffViewerVisible.map(v => v ? 'hidden' : 'visible'); +this._register(applyStyle(this.elements.modified, { visibility })); +this._register(applyStyle(this.elements.original, { visibility })); + +this._createDiffEditorContributions(); diff --git a/src/vs/editor/test/node/diffing/fixtures/noise-1/advanced.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/noise-1/advanced.expected.diff.json new file mode 100644 index 0000000000000..20190a83798bf --- /dev/null +++ b/src/vs/editor/test/node/diffing/fixtures/noise-1/advanced.expected.diff.json @@ -0,0 +1,30 @@ +{ + "original": { + "content": "this._sash = derivedWithStore('sash', (reader, store) => {\n\tconst showSash = this._options.renderSideBySide.read(reader);\n\tthis.elements.root.classList.toggle('side-by-side', showSash);\n\tif (!showSash) { return undefined; }\n\tconst result = store.add(new DiffEditorSash(\n\t\tthis._options,\n\t\tthis.elements.root,\n\t\t{\n\t\t\theight: this._rootSizeObserver.height,\n\t\t\twidth: this._rootSizeObserver.width.map((w, reader) => w - (this._options.renderOverviewRuler.read(reader) ? OverviewRulerPart.ENTIRE_DIFF_OVERVIEW_WIDTH : 0)),\n\t\t}\n\t));\n\tstore.add(autorun('setBoundarySashes', reader => {\n\t\tconst boundarySashes = this._boundarySashes.read(reader);\n\t\tif (boundarySashes) {\n\t\t\tresult.setBoundarySashes(boundarySashes);\n\t\t}\n\t}));\n\treturn result;\n});\nthis._register(keepAlive(this._sash, true));\n\nthis._register(autorunWithStore2('UnchangedRangesFeature', (reader, store) => {\n\tthis.unchangedRangesFeature = store.add(new (readHotReloadableExport(UnchangedRangesFeature, reader))(this._editors, this._diffModel, this._options));\n}));\n\nthis._register(autorunWithStore2('DiffEditorDecorations', (reader, store) => {\n\tstore.add(new (readHotReloadableExport(DiffEditorDecorations, reader))(this._editors, this._diffModel, this._options));\n}));\nthis._register(autorunWithStore2('ViewZoneManager', (reader, store) => {\n\tstore.add(this._instantiationService.createInstance(\n\t\treadHotReloadableExport(ViewZoneManager, reader),\n\t\tthis._editors,\n\t\tthis._diffModel,\n\t\tthis._options,\n\t\tthis,\n\t\t() => this.unchangedRangesFeature.isUpdatingViewZones,\n\t));\n}));\n\nthis._register(autorunWithStore2('OverviewRulerPart', (reader, store) => {\n\tstore.add(this._instantiationService.createInstance(readHotReloadableExport(OverviewRulerPart, reader), this._editors,\n\t\tthis.elements.root,\n\t\tthis._diffModel,\n\t\tthis._rootSizeObserver.width,\n\t\tthis._rootSizeObserver.height,\n\t\tthis._layoutInfo.map(i => i.modifiedEditor),\n\t\tthis._options,\n\t));\n}));\n\nthis._reviewPane = this._register(this._instantiationService.createInstance(DiffReview2, this));\nthis.elements.root.appendChild(this._reviewPane.domNode.domNode);\nthis.elements.root.appendChild(this._reviewPane.actionBarContainer.domNode);\nreviewPaneObservable.set(this._reviewPane, undefined);\n\nthis._createDiffEditorContributions();\n", + "fileName": "./1.tst" + }, + "modified": { + "content": "this._sash = derivedWithStore('sash', (reader, store) => {\n\tconst showSash = this._options.renderSideBySide.read(reader);\n\tthis.elements.root.classList.toggle('side-by-side', showSash);\n\tif (!showSash) { return undefined; }\n\tconst result = store.add(new DiffEditorSash(\n\t\tthis._options,\n\t\tthis.elements.root,\n\t\t{\n\t\t\theight: this._rootSizeObserver.height,\n\t\t\twidth: this._rootSizeObserver.width.map((w, reader) => w - (this._options.renderOverviewRuler.read(reader) ? OverviewRulerPart.ENTIRE_DIFF_OVERVIEW_WIDTH : 0)),\n\t\t}\n\t));\n\tstore.add(autorun('setBoundarySashes', reader => {\n\t\tconst boundarySashes = this._boundarySashes.read(reader);\n\t\tif (boundarySashes) {\n\t\t\tresult.setBoundarySashes(boundarySashes);\n\t\t}\n\t}));\n\treturn result;\n});\nthis._register(keepAlive(this._sash, true));\n\nthis._register(autorunWithStore2('UnchangedRangesFeature', (reader, store) => {\n\tthis.unchangedRangesFeature = store.add(new (readHotReloadableExport(UnchangedRangesFeature, reader))(this._editors, this._diffModel, this._options));\n}));\n\nthis._register(autorunWithStore2('DiffEditorDecorations', (reader, store) => {\n\tstore.add(new (readHotReloadableExport(DiffEditorDecorations, reader))(this._editors, this._diffModel, this._options));\n}));\nthis._register(autorunWithStore2('ViewZoneManager', (reader, store) => {\n\tstore.add(this._instantiationService.createInstance(\n\t\treadHotReloadableExport(ViewZoneManager, reader),\n\t\tthis._editors,\n\t\tthis._diffModel,\n\t\tthis._options,\n\t\tthis,\n\t\t() => this.unchangedRangesFeature.isUpdatingViewZones,\n\t));\n}));\n\nthis._register(autorunWithStore2('OverviewRulerPart', (reader, store) => {\n\tstore.add(this._instantiationService.createInstance(readHotReloadableExport(OverviewRulerPart, reader), this._editors,\n\t\tthis.elements.root,\n\t\tthis._diffModel,\n\t\tthis._rootSizeObserver.width,\n\t\tthis._rootSizeObserver.height,\n\t\tthis._layoutInfo.map(i => i.modifiedEditor),\n\t\tthis._options,\n\t));\n}));\n\nthis._register(autorunWithStore2('_accessibleDiffViewer', (reader, store) => {\n\tthis._accessibleDiffViewer = store.add(this._register(this._instantiationService.createInstance(\n\t\treadHotReloadableExport(AccessibleDiffViewer, reader),\n\t\tthis.elements.accessibleDiffViewer,\n\t\tthis._accessibleDiffViewerVisible,\n\t\tthis._rootSizeObserver.width,\n\t\tthis._rootSizeObserver.height,\n\t\tthis._diffModel.map((m, r) => m?.diff.read(r)?.mappings.map(m => m.lineRangeMapping)),\n\t\tthis._editors,\n\t)));\n}));\nconst visibility = this._accessibleDiffViewerVisible.map(v => v ? 'hidden' : 'visible');\nthis._register(applyStyle(this.elements.modified, { visibility }));\nthis._register(applyStyle(this.elements.original, { visibility }));\n\nthis._createDiffEditorContributions();\n", + "fileName": "./2.tst" + }, + "diffs": [ + { + "originalRange": "[52,56)", + "modifiedRange": "[52,66)", + "innerChanges": [ + { + "originalRange": "[52,7 -> 52,20]", + "modifiedRange": "[52,7 -> 53,2]" + }, + { + "originalRange": "[52,24 -> 52,24]", + "modifiedRange": "[53,6 -> 53,45]" + }, + { + "originalRange": "[52,77 -> 56,1]", + "modifiedRange": "[53,98 -> 66,1]" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/vs/editor/test/node/diffing/fixtures/noise-1/legacy.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/noise-1/legacy.expected.diff.json new file mode 100644 index 0000000000000..65a39f37dbead --- /dev/null +++ b/src/vs/editor/test/node/diffing/fixtures/noise-1/legacy.expected.diff.json @@ -0,0 +1,70 @@ +{ + "original": { + "content": "this._sash = derivedWithStore('sash', (reader, store) => {\n\tconst showSash = this._options.renderSideBySide.read(reader);\n\tthis.elements.root.classList.toggle('side-by-side', showSash);\n\tif (!showSash) { return undefined; }\n\tconst result = store.add(new DiffEditorSash(\n\t\tthis._options,\n\t\tthis.elements.root,\n\t\t{\n\t\t\theight: this._rootSizeObserver.height,\n\t\t\twidth: this._rootSizeObserver.width.map((w, reader) => w - (this._options.renderOverviewRuler.read(reader) ? OverviewRulerPart.ENTIRE_DIFF_OVERVIEW_WIDTH : 0)),\n\t\t}\n\t));\n\tstore.add(autorun('setBoundarySashes', reader => {\n\t\tconst boundarySashes = this._boundarySashes.read(reader);\n\t\tif (boundarySashes) {\n\t\t\tresult.setBoundarySashes(boundarySashes);\n\t\t}\n\t}));\n\treturn result;\n});\nthis._register(keepAlive(this._sash, true));\n\nthis._register(autorunWithStore2('UnchangedRangesFeature', (reader, store) => {\n\tthis.unchangedRangesFeature = store.add(new (readHotReloadableExport(UnchangedRangesFeature, reader))(this._editors, this._diffModel, this._options));\n}));\n\nthis._register(autorunWithStore2('DiffEditorDecorations', (reader, store) => {\n\tstore.add(new (readHotReloadableExport(DiffEditorDecorations, reader))(this._editors, this._diffModel, this._options));\n}));\nthis._register(autorunWithStore2('ViewZoneManager', (reader, store) => {\n\tstore.add(this._instantiationService.createInstance(\n\t\treadHotReloadableExport(ViewZoneManager, reader),\n\t\tthis._editors,\n\t\tthis._diffModel,\n\t\tthis._options,\n\t\tthis,\n\t\t() => this.unchangedRangesFeature.isUpdatingViewZones,\n\t));\n}));\n\nthis._register(autorunWithStore2('OverviewRulerPart', (reader, store) => {\n\tstore.add(this._instantiationService.createInstance(readHotReloadableExport(OverviewRulerPart, reader), this._editors,\n\t\tthis.elements.root,\n\t\tthis._diffModel,\n\t\tthis._rootSizeObserver.width,\n\t\tthis._rootSizeObserver.height,\n\t\tthis._layoutInfo.map(i => i.modifiedEditor),\n\t\tthis._options,\n\t));\n}));\n\nthis._reviewPane = this._register(this._instantiationService.createInstance(DiffReview2, this));\nthis.elements.root.appendChild(this._reviewPane.domNode.domNode);\nthis.elements.root.appendChild(this._reviewPane.actionBarContainer.domNode);\nreviewPaneObservable.set(this._reviewPane, undefined);\n\nthis._createDiffEditorContributions();\n", + "fileName": "./1.tst" + }, + "modified": { + "content": "this._sash = derivedWithStore('sash', (reader, store) => {\n\tconst showSash = this._options.renderSideBySide.read(reader);\n\tthis.elements.root.classList.toggle('side-by-side', showSash);\n\tif (!showSash) { return undefined; }\n\tconst result = store.add(new DiffEditorSash(\n\t\tthis._options,\n\t\tthis.elements.root,\n\t\t{\n\t\t\theight: this._rootSizeObserver.height,\n\t\t\twidth: this._rootSizeObserver.width.map((w, reader) => w - (this._options.renderOverviewRuler.read(reader) ? OverviewRulerPart.ENTIRE_DIFF_OVERVIEW_WIDTH : 0)),\n\t\t}\n\t));\n\tstore.add(autorun('setBoundarySashes', reader => {\n\t\tconst boundarySashes = this._boundarySashes.read(reader);\n\t\tif (boundarySashes) {\n\t\t\tresult.setBoundarySashes(boundarySashes);\n\t\t}\n\t}));\n\treturn result;\n});\nthis._register(keepAlive(this._sash, true));\n\nthis._register(autorunWithStore2('UnchangedRangesFeature', (reader, store) => {\n\tthis.unchangedRangesFeature = store.add(new (readHotReloadableExport(UnchangedRangesFeature, reader))(this._editors, this._diffModel, this._options));\n}));\n\nthis._register(autorunWithStore2('DiffEditorDecorations', (reader, store) => {\n\tstore.add(new (readHotReloadableExport(DiffEditorDecorations, reader))(this._editors, this._diffModel, this._options));\n}));\nthis._register(autorunWithStore2('ViewZoneManager', (reader, store) => {\n\tstore.add(this._instantiationService.createInstance(\n\t\treadHotReloadableExport(ViewZoneManager, reader),\n\t\tthis._editors,\n\t\tthis._diffModel,\n\t\tthis._options,\n\t\tthis,\n\t\t() => this.unchangedRangesFeature.isUpdatingViewZones,\n\t));\n}));\n\nthis._register(autorunWithStore2('OverviewRulerPart', (reader, store) => {\n\tstore.add(this._instantiationService.createInstance(readHotReloadableExport(OverviewRulerPart, reader), this._editors,\n\t\tthis.elements.root,\n\t\tthis._diffModel,\n\t\tthis._rootSizeObserver.width,\n\t\tthis._rootSizeObserver.height,\n\t\tthis._layoutInfo.map(i => i.modifiedEditor),\n\t\tthis._options,\n\t));\n}));\n\nthis._register(autorunWithStore2('_accessibleDiffViewer', (reader, store) => {\n\tthis._accessibleDiffViewer = store.add(this._register(this._instantiationService.createInstance(\n\t\treadHotReloadableExport(AccessibleDiffViewer, reader),\n\t\tthis.elements.accessibleDiffViewer,\n\t\tthis._accessibleDiffViewerVisible,\n\t\tthis._rootSizeObserver.width,\n\t\tthis._rootSizeObserver.height,\n\t\tthis._diffModel.map((m, r) => m?.diff.read(r)?.mappings.map(m => m.lineRangeMapping)),\n\t\tthis._editors,\n\t)));\n}));\nconst visibility = this._accessibleDiffViewerVisible.map(v => v ? 'hidden' : 'visible');\nthis._register(applyStyle(this.elements.modified, { visibility }));\nthis._register(applyStyle(this.elements.original, { visibility }));\n\nthis._createDiffEditorContributions();\n", + "fileName": "./2.tst" + }, + "diffs": [ + { + "originalRange": "[52,56)", + "modifiedRange": "[52,66)", + "innerChanges": [ + { + "originalRange": "[52,9 -> 52,20]", + "modifiedRange": "[52,9 -> 53,41]" + }, + { + "originalRange": "[52,77 -> 52,77]", + "modifiedRange": "[53,98 -> 54,37]" + }, + { + "originalRange": "[52,81 -> 52,84]", + "modifiedRange": "[54,41 -> 54,42]" + }, + { + "originalRange": "[52,87 -> 53,1]", + "modifiedRange": "[54,45 -> 55,3]" + }, + { + "originalRange": "[53,15 -> 53,32]", + "modifiedRange": "[55,17 -> 56,3]" + }, + { + "originalRange": "[53,38 -> 53,41]", + "modifiedRange": "[56,9 -> 56,24]" + }, + { + "originalRange": "[53,44 -> 54,1]", + "modifiedRange": "[56,27 -> 59,3]" + }, + { + "originalRange": "[54,6 -> 54,20]", + "modifiedRange": "[59,8 -> 59,80]" + }, + { + "originalRange": "[54,23 -> 54,32]", + "modifiedRange": "[59,83 -> 63,20]" + }, + { + "originalRange": "[54,38 -> 54,41]", + "modifiedRange": "[63,26 -> 63,41]" + }, + { + "originalRange": "[54,44 -> 54,75]", + "modifiedRange": "[63,44 -> 63,111]" + }, + { + "originalRange": "[55,1 -> 55,26]", + "modifiedRange": "[64,1 -> 65,1]" + }, + { + "originalRange": "[55,34 -> 55,53]", + "modifiedRange": "[65,9 -> 65,66]" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/vs/editor/test/node/diffing/fixtures/noise-2/1.tst b/src/vs/editor/test/node/diffing/fixtures/noise-2/1.tst new file mode 100644 index 0000000000000..684409b3bbbdf --- /dev/null +++ b/src/vs/editor/test/node/diffing/fixtures/noise-2/1.tst @@ -0,0 +1,91 @@ + +const maxPersistedSessions = 25; + +export class ChatService extends Disposable implements IChatService { + + private async _sendRequestAsync(model: ChatModel, provider: IChatProvider, message: string | IChatReplyFollowup, usedSlashCommand?: ISlashCommand): Promise { + const request = model.addRequest(message); + + const resolvedCommand = typeof message === 'string' && message.startsWith('/') ? await this.handleSlashCommand(model.sessionId, message) : message; + + let gotProgress = false; + const requestType = typeof message === 'string' ? + (message.startsWith('/') ? 'slashCommand' : 'string') : + 'followup'; + + const rawResponsePromise = createCancelablePromise(async token => { + const progressCallback = (progress: IChatProgress) => { + if (token.isCancellationRequested) { + return; + } + + gotProgress = true; + if ('content' in progress) { + this.trace('sendRequest', `Provider returned progress for session ${model.sessionId}, ${progress.content.length} chars`); + } else { + this.trace('sendRequest', `Provider returned id for session ${model.sessionId}, ${progress.requestId}`); + } + + model.acceptResponseProgress(request, progress); + }; + + const stopWatch = new StopWatch(false); + token.onCancellationRequested(() => { + this.trace('sendRequest', `Request for session ${model.sessionId} was cancelled`); + this.telemetryService.publicLog2('interactiveSessionProviderInvoked', { + providerId: provider.id, + timeToFirstProgress: -1, + // Normally timings happen inside the EH around the actual provider. For cancellation we can measure how long the user waited before cancelling + totalTime: stopWatch.elapsed(), + result: 'cancelled', + requestType, + slashCommand: usedSlashCommand?.command + }); + + model.cancelRequest(request); + }); + if (usedSlashCommand?.command) { + this._onDidSubmitSlashCommand.fire({ slashCommand: usedSlashCommand.command, sessionId: model.sessionId }); + } + let rawResponse = await provider.provideReply({ session: model.session!, message: resolvedCommand }, progressCallback, token); + if (token.isCancellationRequested) { + return; + } else { + if (!rawResponse) { + this.trace('sendRequest', `Provider returned no response for session ${model.sessionId}`); + rawResponse = { session: model.session!, errorDetails: { message: localize('emptyResponse', "Provider returned null response") } }; + } + + const result = rawResponse.errorDetails?.responseIsFiltered ? 'filtered' : + rawResponse.errorDetails && gotProgress ? 'errorWithOutput' : + rawResponse.errorDetails ? 'error' : + 'success'; + this.telemetryService.publicLog2('interactiveSessionProviderInvoked', { + providerId: provider.id, + timeToFirstProgress: rawResponse.timings?.firstProgress ?? 0, + totalTime: rawResponse.timings?.totalElapsed ?? 0, + result, + requestType, + slashCommand: usedSlashCommand?.command + }); + model.setResponse(request, rawResponse); + this.trace('sendRequest', `Provider returned response for session ${model.sessionId}`); + + // TODO refactor this or rethink the API https://github.com/microsoft/vscode-copilot/issues/593 + if (provider.provideFollowups) { + Promise.resolve(provider.provideFollowups(model.session!, CancellationToken.None)).then(followups => { + model.setFollowups(request, withNullAsUndefined(followups)); + model.completeResponse(request); + }); + } else { + model.completeResponse(request); + } + } + }); + this._pendingRequests.set(model.sessionId, rawResponsePromise); + rawResponsePromise.finally(() => { + this._pendingRequests.delete(model.sessionId); + }); + return rawResponsePromise; + } +} diff --git a/src/vs/editor/test/node/diffing/fixtures/noise-2/2.tst b/src/vs/editor/test/node/diffing/fixtures/noise-2/2.tst new file mode 100644 index 0000000000000..b7778d336a97f --- /dev/null +++ b/src/vs/editor/test/node/diffing/fixtures/noise-2/2.tst @@ -0,0 +1,111 @@ + +const maxPersistedSessions = 25; + +export class ChatService extends Disposable implements IChatService { + + private async _sendRequestAsync(model: ChatModel, provider: IChatProvider, message: string | IChatReplyFollowup, usedSlashCommand?: ISlashCommand): Promise { + const request = model.addRequest(message); + + const resolvedCommand = typeof message === 'string' && message.startsWith('/') ? await this.handleSlashCommand(model.sessionId, message) : message; + + let gotProgress = false; + const requestType = typeof message === 'string' ? + (message.startsWith('/') ? 'slashCommand' : 'string') : + 'followup'; + + const rawResponsePromise = createCancelablePromise(async token => { + const progressCallback = (progress: IChatProgress) => { + if (token.isCancellationRequested) { + return; + } + + gotProgress = true; + if ('content' in progress) { + this.trace('sendRequest', `Provider returned progress for session ${model.sessionId}, ${progress.content.length} chars`); + } else { + this.trace('sendRequest', `Provider returned id for session ${model.sessionId}, ${progress.requestId}`); + } + + model.acceptResponseProgress(request, progress); + }; + + const stopWatch = new StopWatch(false); + token.onCancellationRequested(() => { + this.trace('sendRequest', `Request for session ${model.sessionId} was cancelled`); + this.telemetryService.publicLog2('interactiveSessionProviderInvoked', { + providerId: provider.id, + timeToFirstProgress: -1, + // Normally timings happen inside the EH around the actual provider. For cancellation we can measure how long the user waited before cancelling + totalTime: stopWatch.elapsed(), + result: 'cancelled', + requestType, + slashCommand: usedSlashCommand?.command + }); + + model.cancelRequest(request); + }); + if (usedSlashCommand?.command) { + this._onDidSubmitSlashCommand.fire({ slashCommand: usedSlashCommand.command, sessionId: model.sessionId }); + } + + let rawResponse: IChatResponse | null | undefined; + + if ((typeof resolvedCommand === 'string' && typeof message === 'string' && this.chatSlashCommandService.hasCommand(resolvedCommand))) { + // contributed slash commands + // TODO: spell this out in the UI + const history: IChatMessage[] = []; + for (const request of model.getRequests()) { + if (typeof request.message !== 'string' || !request.response) { + continue; + } + history.push({ role: ChatMessageRole.User, content: request.message }); + history.push({ role: ChatMessageRole.Assistant, content: request.response?.response.value }); + } + await this.chatSlashCommandService.executeCommand(resolvedCommand, message.substring(resolvedCommand.length + 1).trimStart(), new Progress(p => progressCallback(p)), history, token); + rawResponse = { session: model.session! }; + + } else { + rawResponse = await provider.provideReply({ session: model.session!, message: resolvedCommand }, progressCallback, token); + } + + if (token.isCancellationRequested) { + return; + } else { + if (!rawResponse) { + this.trace('sendRequest', `Provider returned no response for session ${model.sessionId}`); + rawResponse = { session: model.session!, errorDetails: { message: localize('emptyResponse', "Provider returned null response") } }; + } + + const result = rawResponse.errorDetails?.responseIsFiltered ? 'filtered' : + rawResponse.errorDetails && gotProgress ? 'errorWithOutput' : + rawResponse.errorDetails ? 'error' : + 'success'; + this.telemetryService.publicLog2('interactiveSessionProviderInvoked', { + providerId: provider.id, + timeToFirstProgress: rawResponse.timings?.firstProgress ?? 0, + totalTime: rawResponse.timings?.totalElapsed ?? 0, + result, + requestType, + slashCommand: usedSlashCommand?.command + }); + model.setResponse(request, rawResponse); + this.trace('sendRequest', `Provider returned response for session ${model.sessionId}`); + + // TODO refactor this or rethink the API https://github.com/microsoft/vscode-copilot/issues/593 + if (provider.provideFollowups) { + Promise.resolve(provider.provideFollowups(model.session!, CancellationToken.None)).then(followups => { + model.setFollowups(request, withNullAsUndefined(followups)); + model.completeResponse(request); + }); + } else { + model.completeResponse(request); + } + } + }); + this._pendingRequests.set(model.sessionId, rawResponsePromise); + rawResponsePromise.finally(() => { + this._pendingRequests.delete(model.sessionId); + }); + return rawResponsePromise; + } +} diff --git a/src/vs/editor/test/node/diffing/fixtures/noise-2/advanced.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/noise-2/advanced.expected.diff.json new file mode 100644 index 0000000000000..a30c65cb9eeef --- /dev/null +++ b/src/vs/editor/test/node/diffing/fixtures/noise-2/advanced.expected.diff.json @@ -0,0 +1,30 @@ +{ + "original": { + "content": "\nconst maxPersistedSessions = 25;\n\nexport class ChatService extends Disposable implements IChatService {\n\n\tprivate async _sendRequestAsync(model: ChatModel, provider: IChatProvider, message: string | IChatReplyFollowup, usedSlashCommand?: ISlashCommand): Promise {\n\t\tconst request = model.addRequest(message);\n\n\t\tconst resolvedCommand = typeof message === 'string' && message.startsWith('/') ? await this.handleSlashCommand(model.sessionId, message) : message;\n\n\t\tlet gotProgress = false;\n\t\tconst requestType = typeof message === 'string' ?\n\t\t\t(message.startsWith('/') ? 'slashCommand' : 'string') :\n\t\t\t'followup';\n\n\t\tconst rawResponsePromise = createCancelablePromise(async token => {\n\t\t\tconst progressCallback = (progress: IChatProgress) => {\n\t\t\t\tif (token.isCancellationRequested) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tgotProgress = true;\n\t\t\t\tif ('content' in progress) {\n\t\t\t\t\tthis.trace('sendRequest', `Provider returned progress for session ${model.sessionId}, ${progress.content.length} chars`);\n\t\t\t\t} else {\n\t\t\t\t\tthis.trace('sendRequest', `Provider returned id for session ${model.sessionId}, ${progress.requestId}`);\n\t\t\t\t}\n\n\t\t\t\tmodel.acceptResponseProgress(request, progress);\n\t\t\t};\n\n\t\t\tconst stopWatch = new StopWatch(false);\n\t\t\ttoken.onCancellationRequested(() => {\n\t\t\t\tthis.trace('sendRequest', `Request for session ${model.sessionId} was cancelled`);\n\t\t\t\tthis.telemetryService.publicLog2('interactiveSessionProviderInvoked', {\n\t\t\t\t\tproviderId: provider.id,\n\t\t\t\t\ttimeToFirstProgress: -1,\n\t\t\t\t\t// Normally timings happen inside the EH around the actual provider. For cancellation we can measure how long the user waited before cancelling\n\t\t\t\t\ttotalTime: stopWatch.elapsed(),\n\t\t\t\t\tresult: 'cancelled',\n\t\t\t\t\trequestType,\n\t\t\t\t\tslashCommand: usedSlashCommand?.command\n\t\t\t\t});\n\n\t\t\t\tmodel.cancelRequest(request);\n\t\t\t});\n\t\t\tif (usedSlashCommand?.command) {\n\t\t\t\tthis._onDidSubmitSlashCommand.fire({ slashCommand: usedSlashCommand.command, sessionId: model.sessionId });\n\t\t\t}\n\t\t\tlet rawResponse = await provider.provideReply({ session: model.session!, message: resolvedCommand }, progressCallback, token);\n\t\t\tif (token.isCancellationRequested) {\n\t\t\t\treturn;\n\t\t\t} else {\n\t\t\t\tif (!rawResponse) {\n\t\t\t\t\tthis.trace('sendRequest', `Provider returned no response for session ${model.sessionId}`);\n\t\t\t\t\trawResponse = { session: model.session!, errorDetails: { message: localize('emptyResponse', \"Provider returned null response\") } };\n\t\t\t\t}\n\n\t\t\t\tconst result = rawResponse.errorDetails?.responseIsFiltered ? 'filtered' :\n\t\t\t\t\trawResponse.errorDetails && gotProgress ? 'errorWithOutput' :\n\t\t\t\t\t\trawResponse.errorDetails ? 'error' :\n\t\t\t\t\t\t\t'success';\n\t\t\t\tthis.telemetryService.publicLog2('interactiveSessionProviderInvoked', {\n\t\t\t\t\tproviderId: provider.id,\n\t\t\t\t\ttimeToFirstProgress: rawResponse.timings?.firstProgress ?? 0,\n\t\t\t\t\ttotalTime: rawResponse.timings?.totalElapsed ?? 0,\n\t\t\t\t\tresult,\n\t\t\t\t\trequestType,\n\t\t\t\t\tslashCommand: usedSlashCommand?.command\n\t\t\t\t});\n\t\t\t\tmodel.setResponse(request, rawResponse);\n\t\t\t\tthis.trace('sendRequest', `Provider returned response for session ${model.sessionId}`);\n\n\t\t\t\t// TODO refactor this or rethink the API https://github.com/microsoft/vscode-copilot/issues/593\n\t\t\t\tif (provider.provideFollowups) {\n\t\t\t\t\tPromise.resolve(provider.provideFollowups(model.session!, CancellationToken.None)).then(followups => {\n\t\t\t\t\t\tmodel.setFollowups(request, withNullAsUndefined(followups));\n\t\t\t\t\t\tmodel.completeResponse(request);\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tmodel.completeResponse(request);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tthis._pendingRequests.set(model.sessionId, rawResponsePromise);\n\t\trawResponsePromise.finally(() => {\n\t\t\tthis._pendingRequests.delete(model.sessionId);\n\t\t});\n\t\treturn rawResponsePromise;\n\t}\n}\n", + "fileName": "./1.tst" + }, + "modified": { + "content": "\nconst maxPersistedSessions = 25;\n\nexport class ChatService extends Disposable implements IChatService {\n\n\tprivate async _sendRequestAsync(model: ChatModel, provider: IChatProvider, message: string | IChatReplyFollowup, usedSlashCommand?: ISlashCommand): Promise {\n\t\tconst request = model.addRequest(message);\n\n\t\tconst resolvedCommand = typeof message === 'string' && message.startsWith('/') ? await this.handleSlashCommand(model.sessionId, message) : message;\n\n\t\tlet gotProgress = false;\n\t\tconst requestType = typeof message === 'string' ?\n\t\t\t(message.startsWith('/') ? 'slashCommand' : 'string') :\n\t\t\t'followup';\n\n\t\tconst rawResponsePromise = createCancelablePromise(async token => {\n\t\t\tconst progressCallback = (progress: IChatProgress) => {\n\t\t\t\tif (token.isCancellationRequested) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tgotProgress = true;\n\t\t\t\tif ('content' in progress) {\n\t\t\t\t\tthis.trace('sendRequest', `Provider returned progress for session ${model.sessionId}, ${progress.content.length} chars`);\n\t\t\t\t} else {\n\t\t\t\t\tthis.trace('sendRequest', `Provider returned id for session ${model.sessionId}, ${progress.requestId}`);\n\t\t\t\t}\n\n\t\t\t\tmodel.acceptResponseProgress(request, progress);\n\t\t\t};\n\n\t\t\tconst stopWatch = new StopWatch(false);\n\t\t\ttoken.onCancellationRequested(() => {\n\t\t\t\tthis.trace('sendRequest', `Request for session ${model.sessionId} was cancelled`);\n\t\t\t\tthis.telemetryService.publicLog2('interactiveSessionProviderInvoked', {\n\t\t\t\t\tproviderId: provider.id,\n\t\t\t\t\ttimeToFirstProgress: -1,\n\t\t\t\t\t// Normally timings happen inside the EH around the actual provider. For cancellation we can measure how long the user waited before cancelling\n\t\t\t\t\ttotalTime: stopWatch.elapsed(),\n\t\t\t\t\tresult: 'cancelled',\n\t\t\t\t\trequestType,\n\t\t\t\t\tslashCommand: usedSlashCommand?.command\n\t\t\t\t});\n\n\t\t\t\tmodel.cancelRequest(request);\n\t\t\t});\n\t\t\tif (usedSlashCommand?.command) {\n\t\t\t\tthis._onDidSubmitSlashCommand.fire({ slashCommand: usedSlashCommand.command, sessionId: model.sessionId });\n\t\t\t}\n\n\t\t\tlet rawResponse: IChatResponse | null | undefined;\n\n\t\t\tif ((typeof resolvedCommand === 'string' && typeof message === 'string' && this.chatSlashCommandService.hasCommand(resolvedCommand))) {\n\t\t\t\t// contributed slash commands\n\t\t\t\t// TODO: spell this out in the UI\n\t\t\t\tconst history: IChatMessage[] = [];\n\t\t\t\tfor (const request of model.getRequests()) {\n\t\t\t\t\tif (typeof request.message !== 'string' || !request.response) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\thistory.push({ role: ChatMessageRole.User, content: request.message });\n\t\t\t\t\thistory.push({ role: ChatMessageRole.Assistant, content: request.response?.response.value });\n\t\t\t\t}\n\t\t\t\tawait this.chatSlashCommandService.executeCommand(resolvedCommand, message.substring(resolvedCommand.length + 1).trimStart(), new Progress(p => progressCallback(p)), history, token);\n\t\t\t\trawResponse = { session: model.session! };\n\n\t\t\t} else {\n\t\t\t\trawResponse = await provider.provideReply({ session: model.session!, message: resolvedCommand }, progressCallback, token);\n\t\t\t}\n\n\t\t\tif (token.isCancellationRequested) {\n\t\t\t\treturn;\n\t\t\t} else {\n\t\t\t\tif (!rawResponse) {\n\t\t\t\t\tthis.trace('sendRequest', `Provider returned no response for session ${model.sessionId}`);\n\t\t\t\t\trawResponse = { session: model.session!, errorDetails: { message: localize('emptyResponse', \"Provider returned null response\") } };\n\t\t\t\t}\n\n\t\t\t\tconst result = rawResponse.errorDetails?.responseIsFiltered ? 'filtered' :\n\t\t\t\t\trawResponse.errorDetails && gotProgress ? 'errorWithOutput' :\n\t\t\t\t\t\trawResponse.errorDetails ? 'error' :\n\t\t\t\t\t\t\t'success';\n\t\t\t\tthis.telemetryService.publicLog2('interactiveSessionProviderInvoked', {\n\t\t\t\t\tproviderId: provider.id,\n\t\t\t\t\ttimeToFirstProgress: rawResponse.timings?.firstProgress ?? 0,\n\t\t\t\t\ttotalTime: rawResponse.timings?.totalElapsed ?? 0,\n\t\t\t\t\tresult,\n\t\t\t\t\trequestType,\n\t\t\t\t\tslashCommand: usedSlashCommand?.command\n\t\t\t\t});\n\t\t\t\tmodel.setResponse(request, rawResponse);\n\t\t\t\tthis.trace('sendRequest', `Provider returned response for session ${model.sessionId}`);\n\n\t\t\t\t// TODO refactor this or rethink the API https://github.com/microsoft/vscode-copilot/issues/593\n\t\t\t\tif (provider.provideFollowups) {\n\t\t\t\t\tPromise.resolve(provider.provideFollowups(model.session!, CancellationToken.None)).then(followups => {\n\t\t\t\t\t\tmodel.setFollowups(request, withNullAsUndefined(followups));\n\t\t\t\t\t\tmodel.completeResponse(request);\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tmodel.completeResponse(request);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tthis._pendingRequests.set(model.sessionId, rawResponsePromise);\n\t\trawResponsePromise.finally(() => {\n\t\t\tthis._pendingRequests.delete(model.sessionId);\n\t\t});\n\t\treturn rawResponsePromise;\n\t}\n}\n", + "fileName": "./2.tst" + }, + "diffs": [ + { + "originalRange": "[50,51)", + "modifiedRange": "[50,71)", + "innerChanges": [ + { + "originalRange": "[50,1 -> 50,1]", + "modifiedRange": "[50,1 -> 51,1]" + }, + { + "originalRange": "[50,19 -> 50,27]", + "modifiedRange": "[51,19 -> 68,24]" + }, + { + "originalRange": "[51,1 -> 51,1]", + "modifiedRange": "[69,1 -> 71,1]" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/vs/editor/test/node/diffing/fixtures/noise-2/legacy.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/noise-2/legacy.expected.diff.json new file mode 100644 index 0000000000000..1c4aecc98996b --- /dev/null +++ b/src/vs/editor/test/node/diffing/fixtures/noise-2/legacy.expected.diff.json @@ -0,0 +1,17 @@ +{ + "original": { + "content": "\nconst maxPersistedSessions = 25;\n\nexport class ChatService extends Disposable implements IChatService {\n\n\tprivate async _sendRequestAsync(model: ChatModel, provider: IChatProvider, message: string | IChatReplyFollowup, usedSlashCommand?: ISlashCommand): Promise {\n\t\tconst request = model.addRequest(message);\n\n\t\tconst resolvedCommand = typeof message === 'string' && message.startsWith('/') ? await this.handleSlashCommand(model.sessionId, message) : message;\n\n\t\tlet gotProgress = false;\n\t\tconst requestType = typeof message === 'string' ?\n\t\t\t(message.startsWith('/') ? 'slashCommand' : 'string') :\n\t\t\t'followup';\n\n\t\tconst rawResponsePromise = createCancelablePromise(async token => {\n\t\t\tconst progressCallback = (progress: IChatProgress) => {\n\t\t\t\tif (token.isCancellationRequested) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tgotProgress = true;\n\t\t\t\tif ('content' in progress) {\n\t\t\t\t\tthis.trace('sendRequest', `Provider returned progress for session ${model.sessionId}, ${progress.content.length} chars`);\n\t\t\t\t} else {\n\t\t\t\t\tthis.trace('sendRequest', `Provider returned id for session ${model.sessionId}, ${progress.requestId}`);\n\t\t\t\t}\n\n\t\t\t\tmodel.acceptResponseProgress(request, progress);\n\t\t\t};\n\n\t\t\tconst stopWatch = new StopWatch(false);\n\t\t\ttoken.onCancellationRequested(() => {\n\t\t\t\tthis.trace('sendRequest', `Request for session ${model.sessionId} was cancelled`);\n\t\t\t\tthis.telemetryService.publicLog2('interactiveSessionProviderInvoked', {\n\t\t\t\t\tproviderId: provider.id,\n\t\t\t\t\ttimeToFirstProgress: -1,\n\t\t\t\t\t// Normally timings happen inside the EH around the actual provider. For cancellation we can measure how long the user waited before cancelling\n\t\t\t\t\ttotalTime: stopWatch.elapsed(),\n\t\t\t\t\tresult: 'cancelled',\n\t\t\t\t\trequestType,\n\t\t\t\t\tslashCommand: usedSlashCommand?.command\n\t\t\t\t});\n\n\t\t\t\tmodel.cancelRequest(request);\n\t\t\t});\n\t\t\tif (usedSlashCommand?.command) {\n\t\t\t\tthis._onDidSubmitSlashCommand.fire({ slashCommand: usedSlashCommand.command, sessionId: model.sessionId });\n\t\t\t}\n\t\t\tlet rawResponse = await provider.provideReply({ session: model.session!, message: resolvedCommand }, progressCallback, token);\n\t\t\tif (token.isCancellationRequested) {\n\t\t\t\treturn;\n\t\t\t} else {\n\t\t\t\tif (!rawResponse) {\n\t\t\t\t\tthis.trace('sendRequest', `Provider returned no response for session ${model.sessionId}`);\n\t\t\t\t\trawResponse = { session: model.session!, errorDetails: { message: localize('emptyResponse', \"Provider returned null response\") } };\n\t\t\t\t}\n\n\t\t\t\tconst result = rawResponse.errorDetails?.responseIsFiltered ? 'filtered' :\n\t\t\t\t\trawResponse.errorDetails && gotProgress ? 'errorWithOutput' :\n\t\t\t\t\t\trawResponse.errorDetails ? 'error' :\n\t\t\t\t\t\t\t'success';\n\t\t\t\tthis.telemetryService.publicLog2('interactiveSessionProviderInvoked', {\n\t\t\t\t\tproviderId: provider.id,\n\t\t\t\t\ttimeToFirstProgress: rawResponse.timings?.firstProgress ?? 0,\n\t\t\t\t\ttotalTime: rawResponse.timings?.totalElapsed ?? 0,\n\t\t\t\t\tresult,\n\t\t\t\t\trequestType,\n\t\t\t\t\tslashCommand: usedSlashCommand?.command\n\t\t\t\t});\n\t\t\t\tmodel.setResponse(request, rawResponse);\n\t\t\t\tthis.trace('sendRequest', `Provider returned response for session ${model.sessionId}`);\n\n\t\t\t\t// TODO refactor this or rethink the API https://github.com/microsoft/vscode-copilot/issues/593\n\t\t\t\tif (provider.provideFollowups) {\n\t\t\t\t\tPromise.resolve(provider.provideFollowups(model.session!, CancellationToken.None)).then(followups => {\n\t\t\t\t\t\tmodel.setFollowups(request, withNullAsUndefined(followups));\n\t\t\t\t\t\tmodel.completeResponse(request);\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tmodel.completeResponse(request);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tthis._pendingRequests.set(model.sessionId, rawResponsePromise);\n\t\trawResponsePromise.finally(() => {\n\t\t\tthis._pendingRequests.delete(model.sessionId);\n\t\t});\n\t\treturn rawResponsePromise;\n\t}\n}\n", + "fileName": "./1.tst" + }, + "modified": { + "content": "\nconst maxPersistedSessions = 25;\n\nexport class ChatService extends Disposable implements IChatService {\n\n\tprivate async _sendRequestAsync(model: ChatModel, provider: IChatProvider, message: string | IChatReplyFollowup, usedSlashCommand?: ISlashCommand): Promise {\n\t\tconst request = model.addRequest(message);\n\n\t\tconst resolvedCommand = typeof message === 'string' && message.startsWith('/') ? await this.handleSlashCommand(model.sessionId, message) : message;\n\n\t\tlet gotProgress = false;\n\t\tconst requestType = typeof message === 'string' ?\n\t\t\t(message.startsWith('/') ? 'slashCommand' : 'string') :\n\t\t\t'followup';\n\n\t\tconst rawResponsePromise = createCancelablePromise(async token => {\n\t\t\tconst progressCallback = (progress: IChatProgress) => {\n\t\t\t\tif (token.isCancellationRequested) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tgotProgress = true;\n\t\t\t\tif ('content' in progress) {\n\t\t\t\t\tthis.trace('sendRequest', `Provider returned progress for session ${model.sessionId}, ${progress.content.length} chars`);\n\t\t\t\t} else {\n\t\t\t\t\tthis.trace('sendRequest', `Provider returned id for session ${model.sessionId}, ${progress.requestId}`);\n\t\t\t\t}\n\n\t\t\t\tmodel.acceptResponseProgress(request, progress);\n\t\t\t};\n\n\t\t\tconst stopWatch = new StopWatch(false);\n\t\t\ttoken.onCancellationRequested(() => {\n\t\t\t\tthis.trace('sendRequest', `Request for session ${model.sessionId} was cancelled`);\n\t\t\t\tthis.telemetryService.publicLog2('interactiveSessionProviderInvoked', {\n\t\t\t\t\tproviderId: provider.id,\n\t\t\t\t\ttimeToFirstProgress: -1,\n\t\t\t\t\t// Normally timings happen inside the EH around the actual provider. For cancellation we can measure how long the user waited before cancelling\n\t\t\t\t\ttotalTime: stopWatch.elapsed(),\n\t\t\t\t\tresult: 'cancelled',\n\t\t\t\t\trequestType,\n\t\t\t\t\tslashCommand: usedSlashCommand?.command\n\t\t\t\t});\n\n\t\t\t\tmodel.cancelRequest(request);\n\t\t\t});\n\t\t\tif (usedSlashCommand?.command) {\n\t\t\t\tthis._onDidSubmitSlashCommand.fire({ slashCommand: usedSlashCommand.command, sessionId: model.sessionId });\n\t\t\t}\n\n\t\t\tlet rawResponse: IChatResponse | null | undefined;\n\n\t\t\tif ((typeof resolvedCommand === 'string' && typeof message === 'string' && this.chatSlashCommandService.hasCommand(resolvedCommand))) {\n\t\t\t\t// contributed slash commands\n\t\t\t\t// TODO: spell this out in the UI\n\t\t\t\tconst history: IChatMessage[] = [];\n\t\t\t\tfor (const request of model.getRequests()) {\n\t\t\t\t\tif (typeof request.message !== 'string' || !request.response) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\thistory.push({ role: ChatMessageRole.User, content: request.message });\n\t\t\t\t\thistory.push({ role: ChatMessageRole.Assistant, content: request.response?.response.value });\n\t\t\t\t}\n\t\t\t\tawait this.chatSlashCommandService.executeCommand(resolvedCommand, message.substring(resolvedCommand.length + 1).trimStart(), new Progress(p => progressCallback(p)), history, token);\n\t\t\t\trawResponse = { session: model.session! };\n\n\t\t\t} else {\n\t\t\t\trawResponse = await provider.provideReply({ session: model.session!, message: resolvedCommand }, progressCallback, token);\n\t\t\t}\n\n\t\t\tif (token.isCancellationRequested) {\n\t\t\t\treturn;\n\t\t\t} else {\n\t\t\t\tif (!rawResponse) {\n\t\t\t\t\tthis.trace('sendRequest', `Provider returned no response for session ${model.sessionId}`);\n\t\t\t\t\trawResponse = { session: model.session!, errorDetails: { message: localize('emptyResponse', \"Provider returned null response\") } };\n\t\t\t\t}\n\n\t\t\t\tconst result = rawResponse.errorDetails?.responseIsFiltered ? 'filtered' :\n\t\t\t\t\trawResponse.errorDetails && gotProgress ? 'errorWithOutput' :\n\t\t\t\t\t\trawResponse.errorDetails ? 'error' :\n\t\t\t\t\t\t\t'success';\n\t\t\t\tthis.telemetryService.publicLog2('interactiveSessionProviderInvoked', {\n\t\t\t\t\tproviderId: provider.id,\n\t\t\t\t\ttimeToFirstProgress: rawResponse.timings?.firstProgress ?? 0,\n\t\t\t\t\ttotalTime: rawResponse.timings?.totalElapsed ?? 0,\n\t\t\t\t\tresult,\n\t\t\t\t\trequestType,\n\t\t\t\t\tslashCommand: usedSlashCommand?.command\n\t\t\t\t});\n\t\t\t\tmodel.setResponse(request, rawResponse);\n\t\t\t\tthis.trace('sendRequest', `Provider returned response for session ${model.sessionId}`);\n\n\t\t\t\t// TODO refactor this or rethink the API https://github.com/microsoft/vscode-copilot/issues/593\n\t\t\t\tif (provider.provideFollowups) {\n\t\t\t\t\tPromise.resolve(provider.provideFollowups(model.session!, CancellationToken.None)).then(followups => {\n\t\t\t\t\t\tmodel.setFollowups(request, withNullAsUndefined(followups));\n\t\t\t\t\t\tmodel.completeResponse(request);\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tmodel.completeResponse(request);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tthis._pendingRequests.set(model.sessionId, rawResponsePromise);\n\t\trawResponsePromise.finally(() => {\n\t\t\tthis._pendingRequests.delete(model.sessionId);\n\t\t});\n\t\treturn rawResponsePromise;\n\t}\n}\n", + "fileName": "./2.tst" + }, + "diffs": [ + { + "originalRange": "[50,51)", + "modifiedRange": "[50,71)", + "innerChanges": null + } + ] +} \ No newline at end of file diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-class/advanced.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-class/advanced.expected.diff.json index 85e7beaa072e5..0b00ea98beb98 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-class/advanced.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-class/advanced.expected.diff.json @@ -47,20 +47,8 @@ "modifiedRange": "[8,12)", "innerChanges": [ { - "originalRange": "[11,10 -> 11,14]", - "modifiedRange": "[8,10 -> 8,11]" - }, - { - "originalRange": "[12,4 -> 13,52]", - "modifiedRange": "[9,4 -> 9,12]" - }, - { - "originalRange": "[13,55 -> 19,67]", - "modifiedRange": "[9,15 -> 9,61]" - }, - { - "originalRange": "[20,17 -> 20,25]", - "modifiedRange": "[10,17 -> 11,51]" + "originalRange": "[11,10 -> 21,1]", + "modifiedRange": "[8,10 -> 12,1]" } ] }, diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-confusing-2/advanced.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-confusing-2/advanced.expected.diff.json index 07656313cdcab..3835a5ceb3c7d 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-confusing-2/advanced.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-confusing-2/advanced.expected.diff.json @@ -43,44 +43,48 @@ "modifiedRange": "[14,18)", "innerChanges": [ { - "originalRange": "[14,120 -> 14,154]", - "modifiedRange": "[14,120 -> 14,162]" - }, - { - "originalRange": "[14,165 -> 14,211]", - "modifiedRange": "[14,173 -> 17,1]" + "originalRange": "[14,120 -> 15,1]", + "modifiedRange": "[14,120 -> 18,1]" } ] }, { "originalRange": "[17,24)", - "modifiedRange": "[20,24)", + "modifiedRange": "[20,22)", "innerChanges": [ { "originalRange": "[17,1 -> 17,1]", "modifiedRange": "[20,1 -> 21,1]" }, { - "originalRange": "[17,8 -> 17,40]", - "modifiedRange": "[21,8 -> 21,43]" + "originalRange": "[17,9 -> 17,21]", + "modifiedRange": "[21,9 -> 21,15]" }, { - "originalRange": "[17,71 -> 17,72]", - "modifiedRange": "[21,74 -> 22,1]" + "originalRange": "[17,24 -> 17,40]", + "modifiedRange": "[21,18 -> 21,43]" }, { - "originalRange": "[18,3 -> 23,4]", - "modifiedRange": "[23,3 -> 23,120]" + "originalRange": "[17,71 -> 24,1]", + "modifiedRange": "[21,74 -> 22,1]" } ] }, { "originalRange": "[25,27)", - "modifiedRange": "[25,25)", + "modifiedRange": "[23,25)", "innerChanges": [ { - "originalRange": "[25,1 -> 27,1]", - "modifiedRange": "[25,1 -> 25,1]" + "originalRange": "[25,9 -> 26,18]", + "modifiedRange": "[23,9 -> 23,18]" + }, + { + "originalRange": "[26,22 -> 26,27]", + "modifiedRange": "[23,22 -> 23,23]" + }, + { + "originalRange": "[27,1 -> 27,1]", + "modifiedRange": "[24,1 -> 25,1]" } ] }, @@ -89,20 +93,8 @@ "modifiedRange": "[26,38)", "innerChanges": [ { - "originalRange": "[28,1 -> 28,1]", - "modifiedRange": "[26,1 -> 27,1]" - }, - { - "originalRange": "[28,15 -> 28,20]", - "modifiedRange": "[27,15 -> 27,16]" - }, - { - "originalRange": "[29,4 -> 29,24]", - "modifiedRange": "[28,4 -> 29,36]" - }, - { - "originalRange": "[30,4 -> 30,31]", - "modifiedRange": "[30,4 -> 37,9]" + "originalRange": "[28,1 -> 31,1]", + "modifiedRange": "[26,1 -> 38,1]" } ] } diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-example1/advanced.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-example1/advanced.expected.diff.json index cc5f77b5dc844..c7cd88a788bb0 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-example1/advanced.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-example1/advanced.expected.diff.json @@ -13,12 +13,8 @@ "modifiedRange": "[9,14)", "innerChanges": [ { - "originalRange": "[9,10 -> 9,10]", - "modifiedRange": "[9,10 -> 9,68]" - }, - { - "originalRange": "[9,15 -> 9,15]", - "modifiedRange": "[9,73 -> 13,16]" + "originalRange": "[9,10 -> 9,15]", + "modifiedRange": "[9,10 -> 13,16]" }, { "originalRange": "[9,35 -> 9,44]", @@ -31,16 +27,8 @@ "modifiedRange": "[17,80)", "innerChanges": [ { - "originalRange": "[13,10 -> 13,41]", - "modifiedRange": "[17,10 -> 35,18]" - }, - { - "originalRange": "[14,2 -> 14,8]", - "modifiedRange": "[36,2 -> 39,8]" - }, - { - "originalRange": "[14,13 -> 14,43]", - "modifiedRange": "[39,13 -> 79,2]" + "originalRange": "[13,10 -> 15,1]", + "modifiedRange": "[17,10 -> 80,1]" } ] } diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-too-much-minimization/advanced.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-too-much-minimization/advanced.expected.diff.json index aa65f823a8599..7a52e0e84aa89 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-too-much-minimization/advanced.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-too-much-minimization/advanced.expected.diff.json @@ -13,8 +13,8 @@ "modifiedRange": "[9,15)", "innerChanges": [ { - "originalRange": "[9,124 -> 9,124]", - "modifiedRange": "[9,124 -> 14,143]" + "originalRange": "[9,124 -> 10,1]", + "modifiedRange": "[9,124 -> 15,1]" } ] } diff --git a/src/vs/editor/test/node/diffing/fixtures/ws-alignment/advanced.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ws-alignment/advanced.expected.diff.json index 92c6e47576141..66e738ab04138 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ws-alignment/advanced.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ws-alignment/advanced.expected.diff.json @@ -23,28 +23,8 @@ "modifiedRange": "[7,18)", "innerChanges": [ { - "originalRange": "[7,5 -> 7,43]", - "modifiedRange": "[7,5 -> 11,140]" - }, - { - "originalRange": "[8,5 -> 9,12]", - "modifiedRange": "[12,5 -> 12,131]" - }, - { - "originalRange": "[10,7 -> 10,22]", - "modifiedRange": "[13,7 -> 13,17]" - }, - { - "originalRange": "[10,30 -> 10,48]", - "modifiedRange": "[13,25 -> 13,118]" - }, - { - "originalRange": "[11,6 -> 11,13]", - "modifiedRange": "[14,6 -> 14,8]" - }, - { - "originalRange": "[12,5 -> 12,17]", - "modifiedRange": "[15,5 -> 16,7]" + "originalRange": "[7,1 -> 13,1]", + "modifiedRange": "[7,1 -> 17,1]" }, { "originalRange": "[13,6 -> 13,11]", @@ -53,4 +33,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/src/vs/editor/test/node/diffing/lineRangeMapping.test.ts b/src/vs/editor/test/node/diffing/lineRangeMapping.test.ts index 5cda2c947945c..f0d0802912daa 100644 --- a/src/vs/editor/test/node/diffing/lineRangeMapping.test.ts +++ b/src/vs/editor/test/node/diffing/lineRangeMapping.test.ts @@ -6,7 +6,7 @@ import * as assert from 'assert'; import { Range } from 'vs/editor/common/core/range'; import { RangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; -import { getLineRangeMapping } from 'vs/editor/common/diff/standardLinesDiffComputer'; +import { getLineRangeMapping } from 'vs/editor/common/diff/advancedLinesDiffComputer'; suite('lineRangeMapping', () => { test('1', () => { diff --git a/src/vs/loader.js b/src/vs/loader.js index cebfe6da858ea..c2d38dfca0ee9 100644 --- a/src/vs/loader.js +++ b/src/vs/loader.js @@ -22,60 +22,60 @@ const _amdLoaderGlobal = this; const _commonjsGlobal = typeof global === 'object' ? global : {}; var AMDLoader; (function (AMDLoader) { - AMDLoader.global = _amdLoaderGlobal; - class Environment { - get isWindows() { - this._detect(); - return this._isWindows; - } - get isNode() { - this._detect(); - return this._isNode; - } - get isElectronRenderer() { - this._detect(); - return this._isElectronRenderer; - } - get isWebWorker() { - this._detect(); - return this._isWebWorker; - } - get isElectronNodeIntegrationWebWorker() { - this._detect(); - return this._isElectronNodeIntegrationWebWorker; - } - constructor() { - this._detected = false; - this._isWindows = false; - this._isNode = false; - this._isElectronRenderer = false; - this._isWebWorker = false; - this._isElectronNodeIntegrationWebWorker = false; - } - _detect() { - if (this._detected) { - return; - } - this._detected = true; - this._isWindows = Environment._isWindows(); - this._isNode = (typeof module !== 'undefined' && !!module.exports); - this._isElectronRenderer = (typeof process !== 'undefined' && typeof process.versions !== 'undefined' && typeof process.versions.electron !== 'undefined' && process.type === 'renderer'); - this._isWebWorker = (typeof AMDLoader.global.importScripts === 'function'); - this._isElectronNodeIntegrationWebWorker = this._isWebWorker && (typeof process !== 'undefined' && typeof process.versions !== 'undefined' && typeof process.versions.electron !== 'undefined' && process.type === 'worker'); - } - static _isWindows() { - if (typeof navigator !== 'undefined') { - if (navigator.userAgent && navigator.userAgent.indexOf('Windows') >= 0) { - return true; - } - } - if (typeof process !== 'undefined') { - return (process.platform === 'win32'); - } - return false; - } - } - AMDLoader.Environment = Environment; + AMDLoader.global = _amdLoaderGlobal; + class Environment { + get isWindows() { + this._detect(); + return this._isWindows; + } + get isNode() { + this._detect(); + return this._isNode; + } + get isElectronRenderer() { + this._detect(); + return this._isElectronRenderer; + } + get isWebWorker() { + this._detect(); + return this._isWebWorker; + } + get isElectronNodeIntegrationWebWorker() { + this._detect(); + return this._isElectronNodeIntegrationWebWorker; + } + constructor() { + this._detected = false; + this._isWindows = false; + this._isNode = false; + this._isElectronRenderer = false; + this._isWebWorker = false; + this._isElectronNodeIntegrationWebWorker = false; + } + _detect() { + if (this._detected) { + return; + } + this._detected = true; + this._isWindows = Environment._isWindows(); + this._isNode = (typeof module !== 'undefined' && !!module.exports); + this._isElectronRenderer = (typeof process !== 'undefined' && typeof process.versions !== 'undefined' && typeof process.versions.electron !== 'undefined' && process.type === 'renderer'); + this._isWebWorker = (typeof AMDLoader.global.importScripts === 'function'); + this._isElectronNodeIntegrationWebWorker = this._isWebWorker && (typeof process !== 'undefined' && typeof process.versions !== 'undefined' && typeof process.versions.electron !== 'undefined' && process.type === 'worker'); + } + static _isWindows() { + if (typeof navigator !== 'undefined') { + if (navigator.userAgent && navigator.userAgent.indexOf('Windows') >= 0) { + return true; + } + } + if (typeof process !== 'undefined') { + return (process.platform === 'win32'); + } + return false; + } + } + AMDLoader.Environment = Environment; })(AMDLoader || (AMDLoader = {})); /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. @@ -83,36 +83,36 @@ var AMDLoader; *--------------------------------------------------------------------------------------------*/ var AMDLoader; (function (AMDLoader) { - class LoaderEvent { - constructor(type, detail, timestamp) { - this.type = type; - this.detail = detail; - this.timestamp = timestamp; - } - } - AMDLoader.LoaderEvent = LoaderEvent; - class LoaderEventRecorder { - constructor(loaderAvailableTimestamp) { - this._events = [new LoaderEvent(1 /* LoaderEventType.LoaderAvailable */, '', loaderAvailableTimestamp)]; - } - record(type, detail) { - this._events.push(new LoaderEvent(type, detail, AMDLoader.Utilities.getHighPerformanceTimestamp())); - } - getEvents() { - return this._events; - } - } - AMDLoader.LoaderEventRecorder = LoaderEventRecorder; - class NullLoaderEventRecorder { - record(type, detail) { - // Nothing to do - } - getEvents() { - return []; - } - } - NullLoaderEventRecorder.INSTANCE = new NullLoaderEventRecorder(); - AMDLoader.NullLoaderEventRecorder = NullLoaderEventRecorder; + class LoaderEvent { + constructor(type, detail, timestamp) { + this.type = type; + this.detail = detail; + this.timestamp = timestamp; + } + } + AMDLoader.LoaderEvent = LoaderEvent; + class LoaderEventRecorder { + constructor(loaderAvailableTimestamp) { + this._events = [new LoaderEvent(1 /* LoaderEventType.LoaderAvailable */, '', loaderAvailableTimestamp)]; + } + record(type, detail) { + this._events.push(new LoaderEvent(type, detail, AMDLoader.Utilities.getHighPerformanceTimestamp())); + } + getEvents() { + return this._events; + } + } + AMDLoader.LoaderEventRecorder = LoaderEventRecorder; + class NullLoaderEventRecorder { + record(type, detail) { + // Nothing to do + } + getEvents() { + return []; + } + } + NullLoaderEventRecorder.INSTANCE = new NullLoaderEventRecorder(); + AMDLoader.NullLoaderEventRecorder = NullLoaderEventRecorder; })(AMDLoader || (AMDLoader = {})); /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. @@ -120,99 +120,99 @@ var AMDLoader; *--------------------------------------------------------------------------------------------*/ var AMDLoader; (function (AMDLoader) { - class Utilities { - /** - * This method does not take care of / vs \ - */ - static fileUriToFilePath(isWindows, uri) { - uri = decodeURI(uri).replace(/%23/g, '#'); - if (isWindows) { - if (/^file:\/\/\//.test(uri)) { - // This is a URI without a hostname => return only the path segment - return uri.substr(8); - } - if (/^file:\/\//.test(uri)) { - return uri.substr(5); - } - } - else { - if (/^file:\/\//.test(uri)) { - return uri.substr(7); - } - } - // Not sure... - return uri; - } - static startsWith(haystack, needle) { - return haystack.length >= needle.length && haystack.substr(0, needle.length) === needle; - } - static endsWith(haystack, needle) { - return haystack.length >= needle.length && haystack.substr(haystack.length - needle.length) === needle; - } - // only check for "?" before "#" to ensure that there is a real Query-String - static containsQueryString(url) { - return /^[^\#]*\?/gi.test(url); - } - /** - * Does `url` start with http:// or https:// or file:// or / ? - */ - static isAbsolutePath(url) { - return /^((http:\/\/)|(https:\/\/)|(file:\/\/)|(\/))/.test(url); - } - static forEachProperty(obj, callback) { - if (obj) { - let key; - for (key in obj) { - if (obj.hasOwnProperty(key)) { - callback(key, obj[key]); - } - } - } - } - static isEmpty(obj) { - let isEmpty = true; - Utilities.forEachProperty(obj, () => { - isEmpty = false; - }); - return isEmpty; - } - static recursiveClone(obj) { - if (!obj || typeof obj !== 'object' || obj instanceof RegExp) { - return obj; - } - if (!Array.isArray(obj) && Object.getPrototypeOf(obj) !== Object.prototype) { - // only clone "simple" objects - return obj; - } - let result = Array.isArray(obj) ? [] : {}; - Utilities.forEachProperty(obj, (key, value) => { - if (value && typeof value === 'object') { - result[key] = Utilities.recursiveClone(value); - } - else { - result[key] = value; - } - }); - return result; - } - static generateAnonymousModule() { - return '===anonymous' + (Utilities.NEXT_ANONYMOUS_ID++) + '==='; - } - static isAnonymousModule(id) { - return Utilities.startsWith(id, '===anonymous'); - } - static getHighPerformanceTimestamp() { - if (!this.PERFORMANCE_NOW_PROBED) { - this.PERFORMANCE_NOW_PROBED = true; - this.HAS_PERFORMANCE_NOW = (AMDLoader.global.performance && typeof AMDLoader.global.performance.now === 'function'); - } - return (this.HAS_PERFORMANCE_NOW ? AMDLoader.global.performance.now() : Date.now()); - } - } - Utilities.NEXT_ANONYMOUS_ID = 1; - Utilities.PERFORMANCE_NOW_PROBED = false; - Utilities.HAS_PERFORMANCE_NOW = false; - AMDLoader.Utilities = Utilities; + class Utilities { + /** + * This method does not take care of / vs \ + */ + static fileUriToFilePath(isWindows, uri) { + uri = decodeURI(uri).replace(/%23/g, '#'); + if (isWindows) { + if (/^file:\/\/\//.test(uri)) { + // This is a URI without a hostname => return only the path segment + return uri.substr(8); + } + if (/^file:\/\//.test(uri)) { + return uri.substr(5); + } + } + else { + if (/^file:\/\//.test(uri)) { + return uri.substr(7); + } + } + // Not sure... + return uri; + } + static startsWith(haystack, needle) { + return haystack.length >= needle.length && haystack.substr(0, needle.length) === needle; + } + static endsWith(haystack, needle) { + return haystack.length >= needle.length && haystack.substr(haystack.length - needle.length) === needle; + } + // only check for "?" before "#" to ensure that there is a real Query-String + static containsQueryString(url) { + return /^[^\#]*\?/gi.test(url); + } + /** + * Does `url` start with http:// or https:// or file:// or / ? + */ + static isAbsolutePath(url) { + return /^((http:\/\/)|(https:\/\/)|(file:\/\/)|(\/))/.test(url); + } + static forEachProperty(obj, callback) { + if (obj) { + let key; + for (key in obj) { + if (obj.hasOwnProperty(key)) { + callback(key, obj[key]); + } + } + } + } + static isEmpty(obj) { + let isEmpty = true; + Utilities.forEachProperty(obj, () => { + isEmpty = false; + }); + return isEmpty; + } + static recursiveClone(obj) { + if (!obj || typeof obj !== 'object' || obj instanceof RegExp) { + return obj; + } + if (!Array.isArray(obj) && Object.getPrototypeOf(obj) !== Object.prototype) { + // only clone "simple" objects + return obj; + } + let result = Array.isArray(obj) ? [] : {}; + Utilities.forEachProperty(obj, (key, value) => { + if (value && typeof value === 'object') { + result[key] = Utilities.recursiveClone(value); + } + else { + result[key] = value; + } + }); + return result; + } + static generateAnonymousModule() { + return '===anonymous' + (Utilities.NEXT_ANONYMOUS_ID++) + '==='; + } + static isAnonymousModule(id) { + return Utilities.startsWith(id, '===anonymous'); + } + static getHighPerformanceTimestamp() { + if (!this.PERFORMANCE_NOW_PROBED) { + this.PERFORMANCE_NOW_PROBED = true; + this.HAS_PERFORMANCE_NOW = (AMDLoader.global.performance && typeof AMDLoader.global.performance.now === 'function'); + } + return (this.HAS_PERFORMANCE_NOW ? AMDLoader.global.performance.now() : Date.now()); + } + } + Utilities.NEXT_ANONYMOUS_ID = 1; + Utilities.PERFORMANCE_NOW_PROBED = false; + Utilities.HAS_PERFORMANCE_NOW = false; + AMDLoader.Utilities = Utilities; })(AMDLoader || (AMDLoader = {})); /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. @@ -220,318 +220,318 @@ var AMDLoader; *--------------------------------------------------------------------------------------------*/ var AMDLoader; (function (AMDLoader) { - function ensureError(err) { - if (err instanceof Error) { - return err; - } - const result = new Error(err.message || String(err) || 'Unknown Error'); - if (err.stack) { - result.stack = err.stack; - } - return result; - } - AMDLoader.ensureError = ensureError; - ; - class ConfigurationOptionsUtil { - /** - * Ensure configuration options make sense - */ - static validateConfigurationOptions(options) { - function defaultOnError(err) { - if (err.phase === 'loading') { - console.error('Loading "' + err.moduleId + '" failed'); - console.error(err); - console.error('Here are the modules that depend on it:'); - console.error(err.neededBy); - return; - } - if (err.phase === 'factory') { - console.error('The factory function of "' + err.moduleId + '" has thrown an exception'); - console.error(err); - console.error('Here are the modules that depend on it:'); - console.error(err.neededBy); - return; - } - } - options = options || {}; - if (typeof options.baseUrl !== 'string') { - options.baseUrl = ''; - } - if (typeof options.isBuild !== 'boolean') { - options.isBuild = false; - } - if (typeof options.paths !== 'object') { - options.paths = {}; - } - if (typeof options.config !== 'object') { - options.config = {}; - } - if (typeof options.catchError === 'undefined') { - options.catchError = false; - } - if (typeof options.recordStats === 'undefined') { - options.recordStats = false; - } - if (typeof options.urlArgs !== 'string') { - options.urlArgs = ''; - } - if (typeof options.onError !== 'function') { - options.onError = defaultOnError; - } - if (!Array.isArray(options.ignoreDuplicateModules)) { - options.ignoreDuplicateModules = []; - } - if (options.baseUrl.length > 0) { - if (!AMDLoader.Utilities.endsWith(options.baseUrl, '/')) { - options.baseUrl += '/'; - } - } - if (typeof options.cspNonce !== 'string') { - options.cspNonce = ''; - } - if (typeof options.preferScriptTags === 'undefined') { - options.preferScriptTags = false; - } - if (options.nodeCachedData && typeof options.nodeCachedData === 'object') { - if (typeof options.nodeCachedData.seed !== 'string') { - options.nodeCachedData.seed = 'seed'; - } - if (typeof options.nodeCachedData.writeDelay !== 'number' || options.nodeCachedData.writeDelay < 0) { - options.nodeCachedData.writeDelay = 1000 * 7; - } - if (!options.nodeCachedData.path || typeof options.nodeCachedData.path !== 'string') { - const err = ensureError(new Error('INVALID cached data configuration, \'path\' MUST be set')); - err.phase = 'configuration'; - options.onError(err); - options.nodeCachedData = undefined; - } - } - return options; - } - static mergeConfigurationOptions(overwrite = null, base = null) { - let result = AMDLoader.Utilities.recursiveClone(base || {}); - // Merge known properties and overwrite the unknown ones - AMDLoader.Utilities.forEachProperty(overwrite, (key, value) => { - if (key === 'ignoreDuplicateModules' && typeof result.ignoreDuplicateModules !== 'undefined') { - result.ignoreDuplicateModules = result.ignoreDuplicateModules.concat(value); - } - else if (key === 'paths' && typeof result.paths !== 'undefined') { - AMDLoader.Utilities.forEachProperty(value, (key2, value2) => result.paths[key2] = value2); - } - else if (key === 'config' && typeof result.config !== 'undefined') { - AMDLoader.Utilities.forEachProperty(value, (key2, value2) => result.config[key2] = value2); - } - else { - result[key] = AMDLoader.Utilities.recursiveClone(value); - } - }); - return ConfigurationOptionsUtil.validateConfigurationOptions(result); - } - } - AMDLoader.ConfigurationOptionsUtil = ConfigurationOptionsUtil; - class Configuration { - constructor(env, options) { - this._env = env; - this.options = ConfigurationOptionsUtil.mergeConfigurationOptions(options); - this._createIgnoreDuplicateModulesMap(); - this._createSortedPathsRules(); - if (this.options.baseUrl === '') { - if (this.options.nodeRequire && this.options.nodeRequire.main && this.options.nodeRequire.main.filename && this._env.isNode) { - let nodeMain = this.options.nodeRequire.main.filename; - let dirnameIndex = Math.max(nodeMain.lastIndexOf('/'), nodeMain.lastIndexOf('\\')); - this.options.baseUrl = nodeMain.substring(0, dirnameIndex + 1); - } - } - } - _createIgnoreDuplicateModulesMap() { - // Build a map out of the ignoreDuplicateModules array - this.ignoreDuplicateModulesMap = {}; - for (let i = 0; i < this.options.ignoreDuplicateModules.length; i++) { - this.ignoreDuplicateModulesMap[this.options.ignoreDuplicateModules[i]] = true; - } - } - _createSortedPathsRules() { - // Create an array our of the paths rules, sorted descending by length to - // result in a more specific -> less specific order - this.sortedPathsRules = []; - AMDLoader.Utilities.forEachProperty(this.options.paths, (from, to) => { - if (!Array.isArray(to)) { - this.sortedPathsRules.push({ - from: from, - to: [to] - }); - } - else { - this.sortedPathsRules.push({ - from: from, - to: to - }); - } - }); - this.sortedPathsRules.sort((a, b) => { - return b.from.length - a.from.length; - }); - } - /** - * Clone current configuration and overwrite options selectively. - * @param options The selective options to overwrite with. - * @result A new configuration - */ - cloneAndMerge(options) { - return new Configuration(this._env, ConfigurationOptionsUtil.mergeConfigurationOptions(options, this.options)); - } - /** - * Get current options bag. Useful for passing it forward to plugins. - */ - getOptionsLiteral() { - return this.options; - } - _applyPaths(moduleId) { - let pathRule; - for (let i = 0, len = this.sortedPathsRules.length; i < len; i++) { - pathRule = this.sortedPathsRules[i]; - if (AMDLoader.Utilities.startsWith(moduleId, pathRule.from)) { - let result = []; - for (let j = 0, lenJ = pathRule.to.length; j < lenJ; j++) { - result.push(pathRule.to[j] + moduleId.substr(pathRule.from.length)); - } - return result; - } - } - return [moduleId]; - } - _addUrlArgsToUrl(url) { - if (AMDLoader.Utilities.containsQueryString(url)) { - return url + '&' + this.options.urlArgs; - } - else { - return url + '?' + this.options.urlArgs; - } - } - _addUrlArgsIfNecessaryToUrl(url) { - if (this.options.urlArgs) { - return this._addUrlArgsToUrl(url); - } - return url; - } - _addUrlArgsIfNecessaryToUrls(urls) { - if (this.options.urlArgs) { - for (let i = 0, len = urls.length; i < len; i++) { - urls[i] = this._addUrlArgsToUrl(urls[i]); - } - } - return urls; - } - /** - * Transform a module id to a location. Appends .js to module ids - */ - moduleIdToPaths(moduleId) { - if (this._env.isNode) { - const isNodeModule = (this.options.amdModulesPattern instanceof RegExp - && !this.options.amdModulesPattern.test(moduleId)); - if (isNodeModule) { - // This is a node module... - if (this.isBuild()) { - // ...and we are at build time, drop it - return ['empty:']; - } - else { - // ...and at runtime we create a `shortcut`-path - return ['node|' + moduleId]; - } - } - } - let result = moduleId; - let results; - if (!AMDLoader.Utilities.endsWith(result, '.js') && !AMDLoader.Utilities.isAbsolutePath(result)) { - results = this._applyPaths(result); - for (let i = 0, len = results.length; i < len; i++) { - if (this.isBuild() && results[i] === 'empty:') { - continue; - } - if (!AMDLoader.Utilities.isAbsolutePath(results[i])) { - results[i] = this.options.baseUrl + results[i]; - } - if (!AMDLoader.Utilities.endsWith(results[i], '.js') && !AMDLoader.Utilities.containsQueryString(results[i])) { - results[i] = results[i] + '.js'; - } - } - } - else { - if (!AMDLoader.Utilities.endsWith(result, '.js') && !AMDLoader.Utilities.containsQueryString(result)) { - result = result + '.js'; - } - results = [result]; - } - return this._addUrlArgsIfNecessaryToUrls(results); - } - /** - * Transform a module id or url to a location. - */ - requireToUrl(url) { - let result = url; - if (!AMDLoader.Utilities.isAbsolutePath(result)) { - result = this._applyPaths(result)[0]; - if (!AMDLoader.Utilities.isAbsolutePath(result)) { - result = this.options.baseUrl + result; - } - } - return this._addUrlArgsIfNecessaryToUrl(result); - } - /** - * Flag to indicate if current execution is as part of a build. - */ - isBuild() { - return this.options.isBuild; - } - shouldInvokeFactory(strModuleId) { - if (!this.options.isBuild) { - // outside of a build, all factories should be invoked - return true; - } - // during a build, only explicitly marked or anonymous modules get their factories invoked - if (AMDLoader.Utilities.isAnonymousModule(strModuleId)) { - return true; - } - if (this.options.buildForceInvokeFactory && this.options.buildForceInvokeFactory[strModuleId]) { - return true; - } - return false; - } - /** - * Test if module `moduleId` is expected to be defined multiple times - */ - isDuplicateMessageIgnoredFor(moduleId) { - return this.ignoreDuplicateModulesMap.hasOwnProperty(moduleId); - } - /** - * Get the configuration settings for the provided module id - */ - getConfigForModule(moduleId) { - if (this.options.config) { - return this.options.config[moduleId]; - } - } - /** - * Should errors be caught when executing module factories? - */ - shouldCatchError() { - return this.options.catchError; - } - /** - * Should statistics be recorded? - */ - shouldRecordStats() { - return this.options.recordStats; - } - /** - * Forward an error to the error handler. - */ - onError(err) { - this.options.onError(err); - } - } - AMDLoader.Configuration = Configuration; + function ensureError(err) { + if (err instanceof Error) { + return err; + } + const result = new Error(err.message || String(err) || 'Unknown Error'); + if (err.stack) { + result.stack = err.stack; + } + return result; + } + AMDLoader.ensureError = ensureError; + ; + class ConfigurationOptionsUtil { + /** + * Ensure configuration options make sense + */ + static validateConfigurationOptions(options) { + function defaultOnError(err) { + if (err.phase === 'loading') { + console.error('Loading "' + err.moduleId + '" failed'); + console.error(err); + console.error('Here are the modules that depend on it:'); + console.error(err.neededBy); + return; + } + if (err.phase === 'factory') { + console.error('The factory function of "' + err.moduleId + '" has thrown an exception'); + console.error(err); + console.error('Here are the modules that depend on it:'); + console.error(err.neededBy); + return; + } + } + options = options || {}; + if (typeof options.baseUrl !== 'string') { + options.baseUrl = ''; + } + if (typeof options.isBuild !== 'boolean') { + options.isBuild = false; + } + if (typeof options.paths !== 'object') { + options.paths = {}; + } + if (typeof options.config !== 'object') { + options.config = {}; + } + if (typeof options.catchError === 'undefined') { + options.catchError = false; + } + if (typeof options.recordStats === 'undefined') { + options.recordStats = false; + } + if (typeof options.urlArgs !== 'string') { + options.urlArgs = ''; + } + if (typeof options.onError !== 'function') { + options.onError = defaultOnError; + } + if (!Array.isArray(options.ignoreDuplicateModules)) { + options.ignoreDuplicateModules = []; + } + if (options.baseUrl.length > 0) { + if (!AMDLoader.Utilities.endsWith(options.baseUrl, '/')) { + options.baseUrl += '/'; + } + } + if (typeof options.cspNonce !== 'string') { + options.cspNonce = ''; + } + if (typeof options.preferScriptTags === 'undefined') { + options.preferScriptTags = false; + } + if (options.nodeCachedData && typeof options.nodeCachedData === 'object') { + if (typeof options.nodeCachedData.seed !== 'string') { + options.nodeCachedData.seed = 'seed'; + } + if (typeof options.nodeCachedData.writeDelay !== 'number' || options.nodeCachedData.writeDelay < 0) { + options.nodeCachedData.writeDelay = 1000 * 7; + } + if (!options.nodeCachedData.path || typeof options.nodeCachedData.path !== 'string') { + const err = ensureError(new Error('INVALID cached data configuration, \'path\' MUST be set')); + err.phase = 'configuration'; + options.onError(err); + options.nodeCachedData = undefined; + } + } + return options; + } + static mergeConfigurationOptions(overwrite = null, base = null) { + let result = AMDLoader.Utilities.recursiveClone(base || {}); + // Merge known properties and overwrite the unknown ones + AMDLoader.Utilities.forEachProperty(overwrite, (key, value) => { + if (key === 'ignoreDuplicateModules' && typeof result.ignoreDuplicateModules !== 'undefined') { + result.ignoreDuplicateModules = result.ignoreDuplicateModules.concat(value); + } + else if (key === 'paths' && typeof result.paths !== 'undefined') { + AMDLoader.Utilities.forEachProperty(value, (key2, value2) => result.paths[key2] = value2); + } + else if (key === 'config' && typeof result.config !== 'undefined') { + AMDLoader.Utilities.forEachProperty(value, (key2, value2) => result.config[key2] = value2); + } + else { + result[key] = AMDLoader.Utilities.recursiveClone(value); + } + }); + return ConfigurationOptionsUtil.validateConfigurationOptions(result); + } + } + AMDLoader.ConfigurationOptionsUtil = ConfigurationOptionsUtil; + class Configuration { + constructor(env, options) { + this._env = env; + this.options = ConfigurationOptionsUtil.mergeConfigurationOptions(options); + this._createIgnoreDuplicateModulesMap(); + this._createSortedPathsRules(); + if (this.options.baseUrl === '') { + if (this.options.nodeRequire && this.options.nodeRequire.main && this.options.nodeRequire.main.filename && this._env.isNode) { + let nodeMain = this.options.nodeRequire.main.filename; + let dirnameIndex = Math.max(nodeMain.lastIndexOf('/'), nodeMain.lastIndexOf('\\')); + this.options.baseUrl = nodeMain.substring(0, dirnameIndex + 1); + } + } + } + _createIgnoreDuplicateModulesMap() { + // Build a map out of the ignoreDuplicateModules array + this.ignoreDuplicateModulesMap = {}; + for (let i = 0; i < this.options.ignoreDuplicateModules.length; i++) { + this.ignoreDuplicateModulesMap[this.options.ignoreDuplicateModules[i]] = true; + } + } + _createSortedPathsRules() { + // Create an array our of the paths rules, sorted descending by length to + // result in a more specific -> less specific order + this.sortedPathsRules = []; + AMDLoader.Utilities.forEachProperty(this.options.paths, (from, to) => { + if (!Array.isArray(to)) { + this.sortedPathsRules.push({ + from: from, + to: [to] + }); + } + else { + this.sortedPathsRules.push({ + from: from, + to: to + }); + } + }); + this.sortedPathsRules.sort((a, b) => { + return b.from.length - a.from.length; + }); + } + /** + * Clone current configuration and overwrite options selectively. + * @param options The selective options to overwrite with. + * @result A new configuration + */ + cloneAndMerge(options) { + return new Configuration(this._env, ConfigurationOptionsUtil.mergeConfigurationOptions(options, this.options)); + } + /** + * Get current options bag. Useful for passing it forward to plugins. + */ + getOptionsLiteral() { + return this.options; + } + _applyPaths(moduleId) { + let pathRule; + for (let i = 0, len = this.sortedPathsRules.length; i < len; i++) { + pathRule = this.sortedPathsRules[i]; + if (AMDLoader.Utilities.startsWith(moduleId, pathRule.from)) { + let result = []; + for (let j = 0, lenJ = pathRule.to.length; j < lenJ; j++) { + result.push(pathRule.to[j] + moduleId.substr(pathRule.from.length)); + } + return result; + } + } + return [moduleId]; + } + _addUrlArgsToUrl(url) { + if (AMDLoader.Utilities.containsQueryString(url)) { + return url + '&' + this.options.urlArgs; + } + else { + return url + '?' + this.options.urlArgs; + } + } + _addUrlArgsIfNecessaryToUrl(url) { + if (this.options.urlArgs) { + return this._addUrlArgsToUrl(url); + } + return url; + } + _addUrlArgsIfNecessaryToUrls(urls) { + if (this.options.urlArgs) { + for (let i = 0, len = urls.length; i < len; i++) { + urls[i] = this._addUrlArgsToUrl(urls[i]); + } + } + return urls; + } + /** + * Transform a module id to a location. Appends .js to module ids + */ + moduleIdToPaths(moduleId) { + if (this._env.isNode) { + const isNodeModule = (this.options.amdModulesPattern instanceof RegExp + && !this.options.amdModulesPattern.test(moduleId)); + if (isNodeModule) { + // This is a node module... + if (this.isBuild()) { + // ...and we are at build time, drop it + return ['empty:']; + } + else { + // ...and at runtime we create a `shortcut`-path + return ['node|' + moduleId]; + } + } + } + let result = moduleId; + let results; + if (!AMDLoader.Utilities.endsWith(result, '.js') && !AMDLoader.Utilities.isAbsolutePath(result)) { + results = this._applyPaths(result); + for (let i = 0, len = results.length; i < len; i++) { + if (this.isBuild() && results[i] === 'empty:') { + continue; + } + if (!AMDLoader.Utilities.isAbsolutePath(results[i])) { + results[i] = this.options.baseUrl + results[i]; + } + if (!AMDLoader.Utilities.endsWith(results[i], '.js') && !AMDLoader.Utilities.containsQueryString(results[i])) { + results[i] = results[i] + '.js'; + } + } + } + else { + if (!AMDLoader.Utilities.endsWith(result, '.js') && !AMDLoader.Utilities.containsQueryString(result)) { + result = result + '.js'; + } + results = [result]; + } + return this._addUrlArgsIfNecessaryToUrls(results); + } + /** + * Transform a module id or url to a location. + */ + requireToUrl(url) { + let result = url; + if (!AMDLoader.Utilities.isAbsolutePath(result)) { + result = this._applyPaths(result)[0]; + if (!AMDLoader.Utilities.isAbsolutePath(result)) { + result = this.options.baseUrl + result; + } + } + return this._addUrlArgsIfNecessaryToUrl(result); + } + /** + * Flag to indicate if current execution is as part of a build. + */ + isBuild() { + return this.options.isBuild; + } + shouldInvokeFactory(strModuleId) { + if (!this.options.isBuild) { + // outside of a build, all factories should be invoked + return true; + } + // during a build, only explicitly marked or anonymous modules get their factories invoked + if (AMDLoader.Utilities.isAnonymousModule(strModuleId)) { + return true; + } + if (this.options.buildForceInvokeFactory && this.options.buildForceInvokeFactory[strModuleId]) { + return true; + } + return false; + } + /** + * Test if module `moduleId` is expected to be defined multiple times + */ + isDuplicateMessageIgnoredFor(moduleId) { + return this.ignoreDuplicateModulesMap.hasOwnProperty(moduleId); + } + /** + * Get the configuration settings for the provided module id + */ + getConfigForModule(moduleId) { + if (this.options.config) { + return this.options.config[moduleId]; + } + } + /** + * Should errors be caught when executing module factories? + */ + shouldCatchError() { + return this.options.catchError; + } + /** + * Should statistics be recorded? + */ + shouldRecordStats() { + return this.options.recordStats; + } + /** + * Forward an error to the error handler. + */ + onError(err) { + this.options.onError(err); + } + } + AMDLoader.Configuration = Configuration; })(AMDLoader || (AMDLoader = {})); /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. @@ -539,503 +539,503 @@ var AMDLoader; *--------------------------------------------------------------------------------------------*/ var AMDLoader; (function (AMDLoader) { - /** - * Load `scriptSrc` only once (avoid multiple