diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 176ea03e..3b686e72 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -2,60 +2,72 @@ name: CI on: push: - branches: [ master ] + branches: [master] pull_request: - branches: [ master ] + branches: [master] jobs: setup: name: Setup runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - name: Cache NPM Install - id: cache-npm - uses: actions/cache@v3 - with: - path: ./node_modules - key: npm-${{ hashFiles('./package-lock.json') }} - - name: Install NPM dependencies - if: steps.cache-npm.outputs.cache-hit != 'true' - run: | - npm install + - uses: actions/checkout@v6 + - name: Setup Node.js + uses: actions/setup-node@v6 + with: + node-version: "22" + - name: Cache NPM Install + id: cache-npm + uses: actions/cache@v5 + with: + path: ./node_modules + key: npm-${{ hashFiles('./package-lock.json') }} + - name: Install NPM dependencies + if: steps.cache-npm.outputs.cache-hit != 'true' + run: | + npm install build: name: Build needs: setup runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - name: Load NPM install - id: cache-npm - uses: actions/cache@v3 - with: - path: ./node_modules - key: npm-${{ hashFiles('./package-lock.json') }} - - name: Install VSCE for packaging - run: npm install vsce - - name: Package Binary - run: ./node_modules/vsce/vsce package -o cortex-debug.vsix - - name: Upload Artifact - uses: actions/upload-artifact@v4 - with: - name: cortex-debug.vsix - path: ./cortex-debug.vsix + - uses: actions/checkout@v6 + - name: Setup Node.js + uses: actions/setup-node@v6 + with: + node-version: "22" + - name: Load NPM install + id: cache-npm + uses: actions/cache@v5 + with: + path: ./node_modules + key: npm-${{ hashFiles('./package-lock.json') }} + - name: Install VSCE for packaging + run: npm install vsce + - name: Package Binary + run: ./node_modules/vsce/vsce package -o cortex-debug.vsix + - name: Upload Artifact + uses: actions/upload-artifact@v7 + with: + name: cortex-debug.vsix + path: ./cortex-debug.vsix lint: name: Lint needs: setup runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - name: Load NPM install - id: cache-npm - uses: actions/cache@v3 - with: - path: ./node_modules - key: npm-${{ hashFiles('./package-lock.json') }} - - name: Lint Project - run: npm run lint + - uses: actions/checkout@v6 + - name: Setup Node.js + uses: actions/setup-node@v6 + with: + node-version: "22" + - name: Load NPM install + id: cache-npm + uses: actions/cache@v5 + with: + path: ./node_modules + key: npm-${{ hashFiles('./package-lock.json') }} + - name: Lint Project + run: npm run lint diff --git a/.vscode/launch.json b/.vscode/launch.json index 14d022a2..bdd03ff3 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -45,7 +45,8 @@ "compounds": [ { "name": "Extension + Debug Server", - "configurations": ["Launch Extension", "Debug Server"] + "configurations": ["Launch Extension", "Debug Server"], + "preLaunchTask": "compile" } ] } diff --git a/.vscode/settings.json b/.vscode/settings.json index 652196a2..3d1ea778 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -35,6 +35,7 @@ "instrs", "jlink", "jtag", + "llength", "Logpoints", "nuttx", "Prio", diff --git a/.vscode/tasks.json b/.vscode/tasks.json index a2ed0e2a..30dc03f1 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -8,6 +8,12 @@ "type": "shell", "command": "npm", "args": ["run-script", "test-compile"] + }, + { + "label": "compile", + "type": "shell", + "command": "npm", + "args": ["run-script", "compile"] } ] } diff --git a/CHANGELOG.md b/CHANGELOG.md index 42dd8c2e..d45e44b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,25 @@ # ChangeLog +# V1.13.0-pre19 +* BugFix[#1215] liveGDB always disconnects without casuing any execution change in the target (like detach does, implicit or explicit) + +# V1.13.0-pre9 +* Backed out change where we try "monitor exit". See [Issue #1185](https://github.com/Marus/cortex-debug/issues/1185) +* Increased server temout to 10 mins +* PR [#1232] Increased gdb timeout to 60 seconds with feedback that we are still waiting +* BugFix[#1215] Proper detach for the liveGDB session (no disconnect) +* Fix for https://github.com/Marus/cortex-debug/issues/1167 Race comdition in parallel reading of multiple symbol files + +# V1.13.0-pre8 +* Added `hardwareBreakpoints: {require: boolean, limit: numer}` to debug configuration. You can force all breakpoints to use hardware breakpoints. You can also ask cortex-debug to limit the number such breakpoints or you can let gdb or your gdb-server enforce a limit. Please use `hardwareBreakpoints` with caution as in most cases it is better to let gdb decide which type of breakpoint to use based on memory types while making sure you are not over the limit -- this is especially true for devices with large SRAMs where you can have near inifite breakpoints and not even have a performance penalty. HW breakpoints are not inherently better than SW breakpoints so long as GDB can read/write to memory locations. +* Also added `hardwareWatchpoints` similar to `hardwareBreakpoints`. Note however that GDB always prefers to use hardware resources for this as doing it in software, while possible, is super slow and unusable. + +# V1.13.0-pre7 +* Added `overridePreEndSessionCommands` to control how a session ends. If the session does not end your way, we sill end the session the normal way +* We try `monitor exit` to exit the server before we try `target-disconnect` for those servers that do not follow the GDB rules +* During GDB server startup, the timeout is now 60 seconds but every 5 seconds, you will some feedback in the debug console that we are stil waiting +* Added preliminary support for HW/SW breakpoints. There are still issues with GDB not counting HW breakpoints correctly. + # V1.13.0-pre6 * Make the advanced decoder work properly for RTT. It now allows a dispose. * Both SWO/RTT OUTPUT panels are now recycled instead of creating a new one every time. You can for a new one by supplying a new outputLabel and/or typeName. @@ -147,7 +167,7 @@ This is a major release. It has been in pre-release for quite a while and some o * You can also use **Microsoft Embedded Tools** and their RTOS views as we are now compatible with each other * Microsoft Embedded Tools also added compatibility for Cortex-Debug for their version of Peripheral Views/Registers. They also helped with integrating Cortex-Debug with MS built-in Hex-Editor. To use MS Peripheral View, use `svdPath` in launch.json. `svdFile` uses the SVD feature from Cortex-Debug. You can use both at the same time if you wish but you should typically use only one. * Fixed a long standing issue with OpenOCD RTT where there was no good way to know when to start the RTT. We can now poll until RTT is detected and enabled. See `rttConfig.rtt_start_retry` in your launch.json to control who the polling works. -* Support for loading alternate symbol files instead of the `"executable"` using a new launch.json property `"symbolFiles"`. See the Wiki [documentation here](https://github.com/Marus/cortex-debug/wiki/Overview#debug-files). This is in addition to the already existing `"loadFiles"` which is used to customizing the programming of the device +* Support for loading alternate symbol files instead of the `"executable"` using a new launch.json property `"symbolFiles"`. See the Wiki [documentation here](https://github.com/Marus/cortex-debug/wiki/Cortex-Debug-Under-the-hood#debug-files). This is in addition to the already existing `"loadFiles"` which is used to customizing the programming of the device * You can now use `breakAfterReset` and `runToEntryPoint` for an `attach` type launch configuration as well but they will only be used on a reset/restart. * For chained configuration, the parent can override properties of children and/or allow children to inherit from itself using `overrides` and `inherits`. * Of course, many issues fixed: thanks to the community with reporting them helping fixing them @@ -181,7 +201,7 @@ This is a major release. It has been in pre-release for quite a while and some o # V1.5.1 ## New features -* Support for loading alternate symbol files instead of the `"executable"` using a new launch.json property `"symbolFiles"`. See the Wiki [documentation here](https://github.com/Marus/cortex-debug/wiki/Overview#debug-files). This is in addition to the already existing `"loadFiles"` which is used to customizing the programming of the device +* Support for loading alternate symbol files instead of the `"executable"` using a new launch.json property `"symbolFiles"`. See the Wiki [documentation here](https://github.com/Marus/cortex-debug/wiki/Cortex-Debug-Under-the-hood#debug-files). This is in addition to the already existing `"loadFiles"` which is used to customizing the programming of the device * You can now use `breakAfterReset` and `runToEntryPoint` for an `attach` type launch configuration as well but they will only be used on a reset/restart. * For chained configuration, the parent can override properties of children and/or allow children to inherit from itself using `overrides` and `inherits`. diff --git a/README.md b/README.md index 6bf05621..4fc17361 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,9 @@ ![Visual Studio Code with Cortex-Debug Installed](./images/vs-code-screenshot.png) -Debugging support for ARM Cortex-M Microcontrollers with the following features: +Debugging support for ARM Cortex-M (and others) Microcontrollers with the following features: +* While we cannot change the extension name due to VSCode Marketplace rules, this extension can be used by non Cortex-M devices and non ARM devices. People have reported using it with Cortex-R/A, Xtensa, RISC-V and even x86. Your mileage may vary. * Highly configurable. See https://github.com/Marus/cortex-debug/blob/master/debug_attributes.md * Support J-Link, OpenOCD GDB Server, STMicroelectronic's ST-LINK GDB server, pyOCD and the Black Magic Probe * Partial support textane/stlink (st-util) GDB Servers (SWO can only be captured via a serial port) @@ -63,6 +64,9 @@ Requirements: See https://github.com/Marus/cortex-debug/wiki for usage information. This needs some help from the community. See https://github.com/Marus/cortex-debug/blob/master/debug_attributes.md for a summary of all properties that are available in your `launch.json` ## How to Build from sources + +Make sure you have git, NodeJS and typescript installed on your PC before you begin. See: https://code.visualstudio.com/docs/setup/additional-components + * `git clone https://github.com/Marus/cortex-debug.git` * `cd cortex-debug` * Optionally switch to a branch: `git checkout ` diff --git a/binary_modules/package-lock.json b/binary_modules/package-lock.json index 68b3781c..e71501dc 100644 --- a/binary_modules/package-lock.json +++ b/binary_modules/package-lock.json @@ -280,9 +280,9 @@ } }, "node_modules/@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.1.tgz", + "integrity": "sha512-HqmEUIGRJ5fSXchkVgR5F7qn48bDBzv0kWj/Kfu5e6uci4UlEeng4331LnBkWffb++Ei3FOVLxo8JJWMFBDMeQ==", "dev": true, "engines": { "node": ">= 10" @@ -559,9 +559,9 @@ } }, "node_modules/cacache/node_modules/minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", + "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -1358,9 +1358,9 @@ } }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "dependencies": { "brace-expansion": "^1.1.7" @@ -2339,9 +2339,9 @@ } }, "@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.1.tgz", + "integrity": "sha512-HqmEUIGRJ5fSXchkVgR5F7qn48bDBzv0kWj/Kfu5e6uci4UlEeng4331LnBkWffb++Ei3FOVLxo8JJWMFBDMeQ==", "dev": true }, "@types/cacheable-request": { @@ -2556,9 +2556,9 @@ } }, "minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", + "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", "dev": true, "requires": { "brace-expansion": "^2.0.1" @@ -3163,9 +3163,9 @@ "dev": true }, "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "requires": { "brace-expansion": "^1.1.7" diff --git a/debug_attributes.md b/debug_attributes.md index 31a14794..e6a326e9 100644 --- a/debug_attributes.md +++ b/debug_attributes.md @@ -32,9 +32,16 @@ If the type is marked as `{...}` it means that it is a complex item can have mul | debuggerArgs | array | Both | Additional arguments to pass to GDB command line | | device | string | Both | Target Device Identifier | | executable | string | Both | Path of executable for symbols and program information. See also `loadFiles`, `symbolFiles` | +| gdbInterruptMode | string | Both | Whether GDB shall be interrupted using "exec-interrupt" (default) or by signaling "SIGINT" | | gdbPath | string | Both | This setting can be used to override the GDB path user/workspace setting for a particular launch configuration. This should be the full pathname to the executable (or name of the executable if it is in your PATH). Note that other toolchain executables with the configured prefix must still be available. | | gdbTarget | string | Both | For externally (servertype = "external") controlled GDB Servers you must specify the GDB target to connect to. This can either be a "hostname:port" combination or path to a serial port | | graphConfig | {object} | Both | Description of how graphing can be done. See our Wiki for details | +| hardwareBreakpoints | object | Both | WARNING: Force only HW breakpoints to be used. By default GDB will use HW or SW breakpoints depending on memory type. Use this only in rare circumstances to work around issues in your gdb-server or hardware. This setting is NOT recommended for general use. | +| hardwareBreakpoints
.limit | number | Both | If limit > 0, enforce a limit on the number of hardware breakpoints that can be used | +| hardwareBreakpoints
.require | boolean | Both | If true, forces the use of hardware breakpoints | +| hardwareWatchpoints | object | Both | WARNING: Force only HW watchpoints to be used. By default GDB will use HW or SW watchpoints depending on memory type. Use this only in rare circumstances | +| hardwareWatchpoints
.limit | number | Both | If limit > 0, enforce a limit on the number of hardware watchpoints that can be used | +| hardwareWatchpoints
.require | boolean | Both | If true, forces the use of hardware watchpoints | | interface | string | Both | Debug Interface type to use for connections (defaults to SWD) - Used for J-Link, ST-LINK and BMP probes. | | ipAddress | string | Both | IP Address for networked J-Link Adapter | | jlinkscript | string | Both | J-Link script file - optional input file for customizing J-Link actions. | @@ -50,6 +57,7 @@ If the type is marked as `{...}` it means that it is a complex item can have mul | overrideAttachCommands | string[] | Attach | Override the commands that are normally executed as part of attaching to a running target. In most cases it is preferable to use preAttachCommands and postAttachCommands to customize the GDB attach sequence. | | overrideGDBServerStartedRegex | string | Both | You can supply a regular expression (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions) in the configuration property to override the output from the GDB Server that is looked for to determine if the GDB Server has started. Under most circumstances this will not be necessary - but could be needed as a result of a change in the output of a GDB Server making it incompatible with cortex-debug. This property has no effect for bmp or external GDB Server types. | | overrideLaunchCommands | string[] | Launch | Override the commands that are normally executed as part of flashing and launching the target. In most cases it is preferable to use preLaunchCommands and postLaunchCommands to customize the GDB launch sequence. | +| overridePreEndSessionCommands | string[] | Both | Override the commands that are normally executed at the start of ending a debug session (e.g. when stopping debugging). | | overrideResetCommands | string[] | Both | Override the commands that are normally executed as part of reset-ing the target. When undefined the deprecated overrideRestartCommands is used if it exists. | | postAttachCommands | string[] | Attach | Additional GDB Commands to be executed after the main attach sequence has finished. | | postLaunchCommands | string[] | Launch | Additional GDB Commands to be executed after the main launch sequence has finished. | @@ -90,8 +98,8 @@ If the type is marked as `{...}` it means that it is a complex item can have mul | swoConfig
.swoEncoding | string | Both | BMP only: SWO encoding data used at the line level. Depends on the probe hardware, native (the original one) supports only Manchester (self-clocked, but slower rates) while most other platforms (e.g. ST-LINK with BMP firmware) support only UART (frequency/baud rate has to match to within ~2%). | | swoConfig
.swoFrequency | number | Both | SWO frequency in Hz. | | swoConfig
.swoPath | string | Both | Path name when source is "file" or "serial", device name regex match when source is "probe" for BMP. Typically a /path-name or a serial-port-name | -| swoConfig
.swoPort | string | Both | When server is "external" && source is "socket", port to connect to. Format [host:]port. For BMP, specifies the regex match of the USB interface contianing raw SWO data. | -| symbolFiles | object[] | Both | Array of ELF files to load symbols from instead of the executable file. Each item in the array cab be a string or an object. Program information is ignored (see `loadFiles`). Can be an empty list to specify none. If this property does not exist, then the executable is used for symbols | +| swoConfig
.swoPort | string | Both | When server is "external" && source is "socket", port to connect to. Format [host:]port. For BMP, specifies the regex match of the USB interface containing raw SWO data. | +| symbolFiles | object[] | Both | Array of ELF files to load symbols from instead of the executable file. Each item in the array can be a string or an object. Program information is ignored (see `loadFiles`). Can be an empty list to specify none. If this property does not exist, then the executable is used for symbols | | targetId | string | number | Both | On BMP this is the ID number that should be passed to the attach command (defaults to 1); for PyOCD this is the target identifier (only needed for custom hardware) | | targetProcessor | number | Both | The processor you want to debug. Zero based integer index. Must be less than 'numberOfProcessors' | | toolchainPrefix | string | Both | This setting can be used to override the toolchainPrefix user setting for a particular launch configuration. Default = "arm-none-eabi" | diff --git a/package-lock.json b/package-lock.json index 5cbca827..8b030f20 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,17 +1,17 @@ { "name": "cortex-debug", - "version": "1.13.0-pre4", + "version": "1.13.0-pre10", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cortex-debug", - "version": "1.13.0-pre4", + "version": "1.13.0-pre10", "license": "MIT", "dependencies": { "@vscode/extension-telemetry": "^0.9.8", "@vscode/webview-ui-toolkit": "^1.4.0", - "binary-parser": "^2.2.1", + "binary-parser": "^2.3.0", "bindings": "^1.5.0", "command-exists": "^1.2.9", "commander": "^13.0.0", @@ -26,16 +26,16 @@ "safe-buffer": "^5.2.1", "serialport": "^13.0.0", "stream-json": "^1.9.1", - "tmp": "^0.2.3", - "universal-analytics": "^0.5.3", + "tmp": "^0.2.7", + "universal-analytics": "^0.5.4", "usb": "^2.14.0", - "uuid": "^11.0.5", + "uuid": "^14.0.1", "vscode-jsonrpc": "^8.2.1" }, "devDependencies": { "@stylistic/eslint-plugin": "^2.13.0", "@types/mocha": "^10.0.10", - "@types/node": "16.x", + "@types/node": "22.x", "@types/vscode": "^1.69.0", "@vscode/debugadapter": "^1.68.0", "@vscode/debugprotocol": "^1.68.0", @@ -45,7 +45,7 @@ "ts-loader": "^9.5.2", "typescript": "^5.7.3", "typescript-eslint": "^8.20.0", - "webpack": "^5.97.1", + "webpack": "^5.105.0", "webpack-cli": "^6.0.1" }, "engines": { @@ -63,9 +63,9 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", - "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", "dev": true, "license": "MIT", "dependencies": { @@ -105,51 +105,39 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.1.tgz", - "integrity": "sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA==", + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz", + "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==", "dev": true, "license": "Apache-2.0", "peer": true, "dependencies": { - "@eslint/object-schema": "^2.1.5", + "@eslint/object-schema": "^2.1.7", "debug": "^4.3.1", - "minimatch": "^3.1.2" + "minimatch": "^3.1.5" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@eslint/config-array/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@eslint/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", + "license": "Apache-2.0", "peer": true, "dependencies": { - "brace-expansion": "^1.1.7" + "@eslint/core": "^0.17.0" }, "engines": { - "node": "*" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/core": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.10.0.tgz", - "integrity": "sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==", + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", "dev": true, "license": "Apache-2.0", "peer": true, @@ -161,21 +149,21 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz", - "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==", + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.6.tgz", + "integrity": "sha512-l2Ul9PrHsPCKcEY/ac7VgFj9D80C7S68sOKc618SyHDPK36s1XcFebXY0iTzUVn4Yq+YbwvSnDmCz9yxjX+QrA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "ajv": "^6.12.4", + "ajv": "^6.14.0", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", + "js-yaml": "^4.3.0", + "minimatch": "^3.1.5", "strip-json-comments": "^3.1.1" }, "engines": { @@ -185,16 +173,22 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, "node_modules/@eslint/eslintrc/node_modules/globals": { @@ -211,35 +205,32 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true, - "license": "ISC", - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } + "license": "MIT", + "peer": true }, "node_modules/@eslint/js": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.18.0.tgz", - "integrity": "sha512-fK6L7rxcq6/z+AaQMtiFTkvbHkBLNlwyRxHpKawP0x3u9+NC6MQTnFW+AdpwC6gfHTW0051cokQgtTN2FqlxQA==", + "version": "9.39.5", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.5.tgz", + "integrity": "sha512-QywQuszQh77pIXCsq998c8hbhSTI/azTty1Z6N53dmAudKHhy573j3yvRLsX2BSp8YpLtoCEG8E9DJe+8zUh4A==", "dev": true, "license": "MIT", "peer": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" } }, "node_modules/@eslint/object-schema": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.5.tgz", - "integrity": "sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==", + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", "dev": true, "license": "Apache-2.0", "peer": true, @@ -248,14 +239,14 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.5.tgz", - "integrity": "sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", "dev": true, "license": "Apache-2.0", "peer": true, "dependencies": { - "@eslint/core": "^0.10.0", + "@eslint/core": "^0.17.0", "levn": "^0.4.1" }, "engines": { @@ -319,9 +310,9 @@ } }, "node_modules/@humanwhocodes/retry": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz", - "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==", + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", "dev": true, "license": "Apache-2.0", "peer": true, @@ -352,18 +343,14 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", - "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" } }, "node_modules/@jridgewell/resolve-uri": { @@ -376,20 +363,10 @@ "node": ">=6.0.0" } }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@jridgewell/source-map": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", - "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", "dev": true, "license": "MIT", "dependencies": { @@ -398,16 +375,16 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "dev": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "dev": true, "license": "MIT", "dependencies": { @@ -580,9 +557,19 @@ } }, "node_modules/@nevware21/ts-utils": { - "version": "0.11.6", - "resolved": "https://registry.npmjs.org/@nevware21/ts-utils/-/ts-utils-0.11.6.tgz", - "integrity": "sha512-OUUJTh3fnaUSzg9DEHgv3d7jC+DnPL65mIO7RaR+jWve7+MmcgIvF79gY97DPQ4frH+IpNR78YAYd/dW4gK3kg==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@nevware21/ts-utils/-/ts-utils-0.14.0.tgz", + "integrity": "sha512-WoeqTIXQ8WPhl+lD2NbMHoAQ4sJl0n7EoRoDmVJui//Usg512enl9q1fdbVobuZt3omnxnmVsDrNIvPBvFgddQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/nevware21" + }, + { + "type": "other", + "url": "https://buymeacoffee.com/nevware21" + } + ], "license": "MIT" }, "node_modules/@nodelib/fs.scandir": { @@ -870,9 +857,9 @@ } }, "node_modules/@stylistic/eslint-plugin/node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", "engines": { @@ -905,9 +892,9 @@ } }, "node_modules/@types/estree": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "dev": true, "license": "MIT" }, @@ -926,11 +913,14 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "16.18.124", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.124.tgz", - "integrity": "sha512-8ADCm5WzM/IpWxjs1Jhtwo6j+Fb8z4yr/CobP5beUUPdyCI0mg87/bqQYxNcqnhZ24Dc9RME8SQWu5eI/FmSGA==", + "version": "22.19.15", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.15.tgz", + "integrity": "sha512-F0R/h2+dsy5wJAUe3tAU6oqa2qbWY5TpNfL/RGmo1y38hiyO1w3x2jPtt76wmuaJI4DQnOBu21cNXQ2STIUUWg==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } }, "node_modules/@types/vscode": { "version": "1.96.0", @@ -1084,13 +1074,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "dev": true, "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^2.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -1431,9 +1421,9 @@ "license": "Apache-2.0" }, "node_modules/acorn": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", - "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", "bin": { @@ -1443,6 +1433,19 @@ "node": ">=0.4.0" } }, + "node_modules/acorn-import-phases": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", + "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "acorn": "^8.14.0" + } + }, "node_modules/acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", @@ -1464,16 +1467,16 @@ } }, "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", "dev": true, "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -1498,50 +1501,6 @@ } } }, - "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true, - "license": "MIT" - }, - "node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/ansi-regex": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", @@ -1571,20 +1530,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -1625,26 +1570,23 @@ ], "license": "MIT" }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "node_modules/baseline-browser-mapping": { + "version": "2.9.19", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz", + "integrity": "sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" } }, "node_modules/binary-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/binary-parser/-/binary-parser-2.2.1.tgz", - "integrity": "sha512-5ATpz/uPDgq5GgEDxTB4ouXCde7q2lqAQlSdBRQVl/AJnxmQmhIfyxJx+0MGu//D5rHQifkfGbWWlaysG0o9NA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-parser/-/binary-parser-2.3.0.tgz", + "integrity": "sha512-TXOlPrhvi+kZUv3vA1qZ+MBdqZdihF8gWw7j/MRINiJqXH652GtLSqFTHNPjG8kHbiMQSCATG9oat9ao6aA8dA==", "license": "MIT", "engines": { - "node": ">=12" + "node": ">=14" } }, "node_modules/bindings": { @@ -1684,9 +1626,9 @@ } }, "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.2.tgz", + "integrity": "sha512-w5JZcKgdhDOgOwm8H+KgbosopHMuGcl6qbulwjtz3SM7I7P3yW1eAjzMPLrIE+NQ9vjgANKHWeMHnrT0OXW1oA==", "dev": true, "license": "MIT", "dependencies": { @@ -1714,9 +1656,9 @@ "license": "ISC" }, "node_modules/browserslist": { - "version": "4.24.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", - "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", "dev": true, "funding": [ { @@ -1734,10 +1676,11 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001688", - "electron-to-chromium": "^1.5.73", - "node-releases": "^2.0.19", - "update-browserslist-db": "^1.1.1" + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" }, "bin": { "browserslist": "cli.js" @@ -1803,9 +1746,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001692", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001692.tgz", - "integrity": "sha512-A95VKan0kdtrsnMubMKxEKUKImOPSuCpYgxSQBo036P5YYgVIcOYJEgt/txJWqObiRQeISNCfef9nvlQ0vbV7A==", + "version": "1.0.30001768", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001768.tgz", + "integrity": "sha512-qY3aDRZC5nWPgHUgIB84WL+nySuo19wk0VJpp/XI9T34lrvkyhRvNVOFJOp2kxClQhiFBu+TaUSudf6oa3vkSA==", "dev": true, "funding": [ { @@ -1854,28 +1797,19 @@ } }, "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", "dev": true, "license": "MIT", "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" + "readdirp": "^4.0.1" }, "engines": { - "node": ">= 8.10.0" + "node": ">= 14.16.0" }, "funding": { "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" } }, "node_modules/chownr": { @@ -1924,15 +1858,18 @@ } }, "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, "license": "ISC", "dependencies": { "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", + "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" } }, "node_modules/cliui/node_modules/ansi-regex": { @@ -2576,9 +2513,9 @@ } }, "node_modules/diff": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", - "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", + "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -2593,9 +2530,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.83", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.83.tgz", - "integrity": "sha512-LcUDPqSt+V0QmI47XLzZrz5OqILSMGsPFkDYus22rIbgorSvBYEFqq854ltTmUdHkY92FSdAAvsh4jWEULMdfQ==", + "version": "1.5.286", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz", + "integrity": "sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==", "dev": true, "license": "ISC" }, @@ -2616,14 +2553,14 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.18.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.0.tgz", - "integrity": "sha512-0/r0MySGYG8YqlayBZ6MuCfECmHFdJ5qyPh8s8wa5Hnm6SaFLSK1VYCbj+NKp090Nm1caZhD+QTnmxO7esYGyQ==", + "version": "5.19.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz", + "integrity": "sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==", "dev": true, "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" + "tapable": "^2.3.0" }, "engines": { "node": ">=10.13.0" @@ -2643,9 +2580,9 @@ } }, "node_modules/es-module-lexer": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", - "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", + "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", "dev": true, "license": "MIT" }, @@ -2673,33 +2610,33 @@ } }, "node_modules/eslint": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.18.0.tgz", - "integrity": "sha512-+waTfRWQlSbpt3KWE+CjrPPYnbq9kfZIYUqapc0uBXyjTp8aYXZDsUH16m39Ryq3NjAVP4tjuF7KaukeqoCoaA==", + "version": "9.39.5", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.5.tgz", + "integrity": "sha512-DgZS62aPLXKlnxILS/AYCoRvHaZeXceIzlXPkkGGzJWSow1aEk0lbTlxUSlyjC8jcaKxAdOnTDz+o1JFSBsyjw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.19.0", - "@eslint/core": "^0.10.0", - "@eslint/eslintrc": "^3.2.0", - "@eslint/js": "9.18.0", - "@eslint/plugin-kit": "^0.2.5", + "@eslint/config-array": "^0.21.2", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.6", + "@eslint/js": "9.39.5", + "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.1", + "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", - "@types/json-schema": "^7.0.15", - "ajv": "^6.12.4", + "ajv": "^6.14.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.2.0", - "eslint-visitor-keys": "^4.2.0", - "espree": "^10.3.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -2711,7 +2648,7 @@ "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", + "minimatch": "^3.1.5", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, @@ -2748,9 +2685,9 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", - "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "dev": true, "license": "Apache-2.0", "engines": { @@ -2760,22 +2697,28 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/eslint/node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, "node_modules/eslint/node_modules/eslint-scope": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", - "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", "dev": true, "license": "BSD-2-Clause", "peer": true, @@ -2815,30 +2758,24 @@ "node": ">=10.13.0" } }, - "node_modules/eslint/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true, - "license": "ISC", - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } + "license": "MIT", + "peer": true }, "node_modules/espree": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", - "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.14.0", + "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.0" + "eslint-visitor-keys": "^4.2.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2970,7 +2907,8 @@ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/fast-levenshtein": { "version": "2.0.6", @@ -2981,9 +2919,9 @@ "peer": true }, "node_modules/fast-uri": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.5.tgz", - "integrity": "sha512-5JnBCWpFlMo0a3ciDy/JckMzzv1U9coZrIhedq+HXxxUfDTAiS0LA8OKVao4G9BxmCVck/jtA5r3KAtRWEyD8Q==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", + "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", "dev": true, "funding": [ { @@ -3093,9 +3031,9 @@ } }, "node_modules/flatted": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", - "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", "dev": true, "license": "ISC", "peer": true @@ -3123,21 +3061,6 @@ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", "license": "MIT" }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -3148,6 +3071,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, "node_modules/github-from-package": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", @@ -3155,9 +3088,9 @@ "license": "MIT" }, "node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", "dev": true, "license": "ISC", "dependencies": { @@ -3196,13 +3129,13 @@ "license": "BSD-2-Clause" }, "node_modules/glob/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "dev": true, "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^2.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -3361,9 +3294,9 @@ "license": "MIT" }, "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, "license": "MIT", "peer": true, @@ -3451,19 +3384,6 @@ "node": ">=10.13.0" } }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "license": "MIT", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/is-core-module": { "version": "2.16.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", @@ -3536,6 +3456,16 @@ "node": ">=0.12.0" } }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", @@ -3628,10 +3558,20 @@ } }, "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz", + "integrity": "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], "license": "MIT", "dependencies": { "argparse": "^2.0.1" @@ -3656,9 +3596,9 @@ "license": "MIT" }, "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true, "license": "MIT" }, @@ -3739,13 +3679,17 @@ } }, "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", + "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==", "dev": true, "license": "MIT", "engines": { "node": ">=6.11.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, "node_modules/locate-path": { @@ -3873,16 +3817,29 @@ } }, "node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", + "peer": true, "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=10" + "node": "*" + } + }, + "node_modules/minimatch/node_modules/brace-expansion": { + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", + "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, "node_modules/minimist": { @@ -3911,31 +3868,32 @@ "license": "MIT" }, "node_modules/mocha": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.0.1.tgz", - "integrity": "sha512-+3GkODfsDG71KSCQhc4IekSW+ItCK/kiez1Z28ksWvYhKXV/syxMlerR/sC7whDp7IyreZ4YxceMLdTs5hQE8A==", + "version": "11.7.6", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.7.6.tgz", + "integrity": "sha512-nS9xOGbw2I3cjCpxwZAEJ9xK9lmJ08vEkQvLtz4du9ZrF9UrjRpeJGiIgl2Z+Qs++pmB4ecDe48Fwsh+j+j7xA==", "dev": true, "license": "MIT", "dependencies": { - "ansi-colors": "^4.1.3", "browser-stdout": "^1.3.1", - "chokidar": "^3.5.3", + "chokidar": "^4.0.1", "debug": "^4.3.5", - "diff": "^5.2.0", + "diff": "^7.0.0", "escape-string-regexp": "^4.0.0", "find-up": "^5.0.0", "glob": "^10.4.5", "he": "^1.2.0", + "is-path-inside": "^3.0.3", "js-yaml": "^4.1.0", "log-symbols": "^4.1.0", - "minimatch": "^5.1.6", + "minimatch": "^9.0.5", "ms": "^2.1.3", + "picocolors": "^1.1.1", "serialize-javascript": "^6.0.2", "strip-json-comments": "^3.1.1", "supports-color": "^8.1.1", - "workerpool": "^6.5.1", - "yargs": "^16.2.0", - "yargs-parser": "^20.2.9", + "workerpool": "^9.2.0", + "yargs": "^17.7.2", + "yargs-parser": "^21.1.1", "yargs-unparser": "^2.0.0" }, "bin": { @@ -3946,6 +3904,22 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/mocha/node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -4023,22 +3997,12 @@ } }, "node_modules/node-releases": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", - "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", "dev": true, "license": "MIT" }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -4297,9 +4261,9 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "dev": true, "license": "MIT", "engines": { @@ -4438,6 +4402,7 @@ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=6" } @@ -4531,16 +4496,17 @@ "license": "MIT" }, "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", "dev": true, "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, "engines": { - "node": ">=8.10.0" + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" } }, "node_modules/rechoir": { @@ -4724,15 +4690,16 @@ "license": "MIT" }, "node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", "dev": true, "license": "MIT", "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" }, "engines": { "node": ">= 10.13.0" @@ -4742,6 +4709,19 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/schema-utils/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, "node_modules/semver": { "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", @@ -5129,19 +5109,23 @@ "license": "MIT" }, "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", "dev": true, "license": "MIT", "engines": { "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, "node_modules/tar-fs": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.2.tgz", - "integrity": "sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz", + "integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==", "license": "MIT", "dependencies": { "chownr": "^1.1.1", @@ -5216,14 +5200,14 @@ } }, "node_modules/terser": { - "version": "5.37.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.37.0.tgz", - "integrity": "sha512-B8wRRkmre4ERucLM/uXx4MOV5cbnOlVAqUst+1+iLKPI0dOgFO28f84ptoQt9HEI537PMzfYa/d+GEPKTRXmYA==", + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz", + "integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", + "acorn": "^8.15.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, @@ -5235,16 +5219,15 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.11", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.11.tgz", - "integrity": "sha512-RVCsMfuD0+cTt3EwX8hSl2Ks56EbFHWmhluwcqoPKtBnfjiT6olaq7PRIRfhyU8nnC2MrnDrBLfrD/RGE+cVXQ==", + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.6.1.tgz", + "integrity": "sha512-201R5j+sJpK8nFWwKVyNfZot8FaJbLZDq5evriVzbV1wDtSXDjRUDRfJzHpAaxFDMEhsZL1QkeqM61wgsS3KaQ==", "dev": true, "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "jest-worker": "^27.4.5", "schema-utils": "^4.3.0", - "serialize-javascript": "^6.0.2", "terser": "^5.31.1" }, "engines": { @@ -5258,74 +5241,44 @@ "webpack": "^5.1.0" }, "peerDependenciesMeta": { + "@minify-html/node": { + "optional": true + }, "@swc/core": { "optional": true }, + "@swc/css": { + "optional": true + }, + "@swc/html": { + "optional": true + }, + "clean-css": { + "optional": true + }, + "cssnano": { + "optional": true + }, + "csso": { + "optional": true + }, "esbuild": { "optional": true }, + "html-minifier-terser": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "postcss": { + "optional": true + }, "uglify-js": { "optional": true } } }, - "node_modules/terser-webpack-plugin/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true, - "license": "MIT" - }, - "node_modules/terser-webpack-plugin/node_modules/schema-utils": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz", - "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/terser/node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", @@ -5334,9 +5287,9 @@ "license": "MIT" }, "node_modules/tmp": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", - "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.7.tgz", + "integrity": "sha512-e0votIpp4Uo2AJYSzVHV6xCcawuiez3DzqDAbrTc3YxBkplN6e+dM13ZeIcZnDg/QpSuU2zfZ3rzwY8ukEnaXw==", "license": "MIT", "engines": { "node": ">=14.14" @@ -5458,32 +5411,30 @@ "typescript": ">=4.8.4 <5.8.0" } }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, "node_modules/universal-analytics": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/universal-analytics/-/universal-analytics-0.5.3.tgz", - "integrity": "sha512-HXSMyIcf2XTvwZ6ZZQLfxfViRm/yTGoRgDeTbojtq6rezeyKB0sTBcKH2fhddnteAHRcHiKgr/ACpbgjGOC6RQ==", + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/universal-analytics/-/universal-analytics-0.5.4.tgz", + "integrity": "sha512-db38BYsx+oZEx0bc+PeGmIwG+YiYH5Xluhxf9EBnL39U4+DAXJtXQHLJ+zzTH36lx/N54/WKQQYnh0kQWJ74yg==", "license": "MIT", "dependencies": { "debug": "^4.3.1", - "uuid": "^8.0.0" + "uuid": "^14.0.0" }, "engines": { - "node": ">=12.18.2" - } - }, - "node_modules/universal-analytics/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" + "node": ">=22.0.0" } }, "node_modules/update-browserslist-db": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz", - "integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", "dev": true, "funding": [ { @@ -5517,6 +5468,7 @@ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "license": "BSD-2-Clause", + "peer": true, "dependencies": { "punycode": "^2.1.0" } @@ -5543,16 +5495,16 @@ "license": "MIT" }, "node_modules/uuid": { - "version": "11.0.5", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.0.5.tgz", - "integrity": "sha512-508e6IcKLrhxKdBbcA2b4KQZlLVp2+J5UwQ6F7Drckkc5N9ZJwFa4TgWtsww9UG8fGHbm6gbV19TdM5pQ4GaIA==", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.1.tgz", + "integrity": "sha512-6ZxzVpzDXDa3bJWaHilVayA+BH/1zmxCJoVgvmqJnid/gPoKHxUrS/aC/T6LGQtNHT+XHG9fXPJB4d+IrU30Ew==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], "license": "MIT", "bin": { - "uuid": "dist/esm/bin/uuid" + "uuid": "dist-node/bin/uuid" } }, "node_modules/vscode-jsonrpc": { @@ -5565,9 +5517,9 @@ } }, "node_modules/watchpack": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", - "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.1.tgz", + "integrity": "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==", "dev": true, "license": "MIT", "dependencies": { @@ -5579,35 +5531,37 @@ } }, "node_modules/webpack": { - "version": "5.97.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.97.1.tgz", - "integrity": "sha512-EksG6gFY3L1eFMROS/7Wzgrii5mBAFe4rIr3r2BTfo7bcc+DWwFZ4OJ/miOuHJO/A85HwyI4eQ0F6IKXesO7Fg==", + "version": "5.105.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.105.0.tgz", + "integrity": "sha512-gX/dMkRQc7QOMzgTe6KsYFM7DxeIONQSui1s0n/0xht36HvrgbxtM1xBlgx596NbpHuQU8P7QpKwrZYwUX48nw==", "dev": true, "license": "MIT", "dependencies": { "@types/eslint-scope": "^3.7.7", - "@types/estree": "^1.0.6", + "@types/estree": "^1.0.8", + "@types/json-schema": "^7.0.15", "@webassemblyjs/ast": "^1.14.1", "@webassemblyjs/wasm-edit": "^1.14.1", "@webassemblyjs/wasm-parser": "^1.14.1", - "acorn": "^8.14.0", - "browserslist": "^4.24.0", + "acorn": "^8.15.0", + "acorn-import-phases": "^1.0.3", + "browserslist": "^4.28.1", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.1", - "es-module-lexer": "^1.2.1", + "enhanced-resolve": "^5.19.0", + "es-module-lexer": "^2.0.0", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", + "loader-runner": "^4.3.1", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^3.2.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.10", - "watchpack": "^2.4.1", - "webpack-sources": "^3.2.3" + "schema-utils": "^4.3.3", + "tapable": "^2.3.0", + "terser-webpack-plugin": "^5.3.16", + "watchpack": "^2.5.1", + "webpack-sources": "^3.3.3" }, "bin": { "webpack": "bin/webpack.js" @@ -5694,9 +5648,9 @@ } }, "node_modules/webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", + "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", "dev": true, "license": "MIT", "engines": { @@ -5738,9 +5692,9 @@ } }, "node_modules/workerpool": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", - "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-9.3.4.tgz", + "integrity": "sha512-TmPRQYYSAnnDiEB0P/Ytip7bFGvqnSU6I2BcuSw7Hx+JSg/DsUi5ebYfc8GYaSdpuvOcEs6dXxPurOYpe9QFwg==", "dev": true, "license": "Apache-2.0" }, @@ -5856,32 +5810,32 @@ } }, "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "version": "17.7.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz", + "integrity": "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==", "dev": true, "license": "MIT", "dependencies": { - "cliui": "^7.0.2", + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "string-width": "^4.2.0", + "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "yargs-parser": "^21.1.1" }, "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, "license": "ISC", "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/yargs-unparser": { @@ -5917,16 +5871,6 @@ "dev": true, "license": "MIT" }, - "node_modules/yargs/node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, "node_modules/yargs/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", diff --git a/package.json b/package.json index 25231a1d..531e6e37 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "version": "1.13.0-pre6", + "version": "1.13.0-pre10", "preview": false, "activationEvents": [ "onDebugResolve:cortex-debug", @@ -389,11 +389,6 @@ "type": "object", "title": "Miscellaneous", "properties": { - "cortex-debug.enableTelemetry": { - "type": "boolean", - "default": true, - "description": "Enable Telemetry for the Cortex-Debug Extension. Reporting will also respect the global telemetry.enableTelemetry setting." - }, "cortex-debug.dbgServerLogfile": { "type": [ "string", @@ -628,6 +623,12 @@ "deprecated": true, "description": "Deprecated: Restart is now handled by VSCode and it is pretty much the same as Start" }, + "overridePreEndSessionCommands": { + "default": [], + "type": "array", + "items": "string", + "description": "Override the commands that are normally executed at the start of ending a debug session (e.g. when stopping debugging)." + }, "overrideGDBServerStartedRegex": { "description": "You can supply a regular expression (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions) in the configuration property to override the output from the GDB Server that is looked for to determine if the GDB Server has started. Under most circumstances this will not be necessary - but could be needed as a result of a change in the output of a GDB Server making it incompatible with cortex-debug. This property has no effect for bmp or external GDB Server types.", "type": "string", @@ -698,7 +699,7 @@ "type": "string" }, "symbolFiles": { - "description": "Array of ELF files to load symbols from instead of the executable file. Each item in the array cab be a string or an object. Program information is ignored (see `loadFiles`). Can be an empty list to specify none. If this property does not exist, then the executable is used for symbols", + "description": "Array of ELF files to load symbols from instead of the executable file. Each item in the array can be a string or an object. Program information is ignored (see `loadFiles`). Can be an empty list to specify none. If this property does not exist, then the executable is used for symbols", "type": "array", "items": { "type": [ @@ -754,6 +755,15 @@ }, "default": null }, + "gdbInterruptMode": { + "default": "exec-interrupt", + "description": "Whether GDB shall be interrupted using \"exec-interrupt\" (default) or by signaling \"SIGINT\"", + "type": "string", + "enum": [ + "exec-interrupt", + "SIGINT" + ] + }, "gdbTarget": { "default": null, "description": "For externally (servertype = \"external\") controlled GDB Servers you must specify the GDB target to connect to. This can either be a \"hostname:port\" combination or path to a serial port", @@ -785,6 +795,42 @@ "maximum": 9, "default": 0 }, + "hardwareBreakpoints": { + "description": "WARNING: Force only HW breakpoints to be used. By default GDB will use HW or SW breakpoints depending on memory type. Use this only in rare circumstances to work around issues in your gdb-server or hardware. This setting is NOT recommended for general use.", + "type": "object", + "properties": { + "require": { + "type": "boolean", + "default": false, + "description": "If true, forces the use of hardware breakpoints" + }, + "limit": { + "type": "number", + "minimum": 0, + "multipleOf": 1, + "default": 0, + "description": "If limit > 0, enforce a limit on the number of hardware breakpoints that can be used" + } + } + }, + "hardwareWatchpoints": { + "description": "WARNING: Force only HW watchpoints to be used. By default GDB will use HW or SW watchpoints depending on memory type. Use this only in rare circumstances", + "type": "object", + "properties": { + "require": { + "type": "boolean", + "default": false, + "description": "If true, forces the use of hardware watchpoints" + }, + "limit": { + "type": "number", + "minimum": 0, + "multipleOf": 1, + "default": 0, + "description": "If limit > 0, enforce a limit on the number of hardware watchpoints that can be used" + } + } + }, "liveWatch": { "description": "An object with parameters for Live Watch", "properties": { @@ -1752,6 +1798,12 @@ "items": "string", "description": "Additional GDB Commands to be executed at the end of the reset sequence" }, + "overridePreEndSessionCommands": { + "default": [], + "type": "array", + "items": "string", + "description": "Override the commands that are normally executed at the start of ending a debug session (e.g. when stopping debugging)." + }, "overrideGDBServerStartedRegex": { "description": "You can supply a regular expression (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions) in the configuration property to override the output from the GDB Server that is looked for to determine if the GDB Server has started. Under most circumstances this will not be necessary - but could be needed as a result of a change in the output of a GDB Server making it incompatible with cortex-debug. This property has no effect for bmp or external GDB Server types.", "type": "string", @@ -1827,7 +1879,7 @@ "default": null }, "symbolFiles": { - "description": "Array of ELF files to load symbols from instead of the executable file. Each item in the array cab be a string or an object. Program information is ignored (see `loadFiles`). Can be an empty list to specify none. If this property does not exist, then the executable is used for symbols", + "description": "Array of ELF files to load symbols from instead of the executable file. Each item in the array can be a string or an object. Program information is ignored (see `loadFiles`). Can be an empty list to specify none. If this property does not exist, then the executable is used for symbols", "type": "array", "items": { "type": [ @@ -1883,6 +1935,15 @@ }, "default": null }, + "gdbInterruptMode": { + "default": "exec-interrupt", + "description": "Whether GDB shall be interrupted using \"exec-interrupt\" (default) or by signaling \"SIGINT\"", + "type": "string", + "enum": [ + "exec-interrupt", + "SIGINT" + ] + }, "gdbTarget": { "default": null, "description": "For externally (servertype = \"external\") controlled GDB Servers you must specify the GDB target to connect to. This can either be a \"hostname:port\" combination or path to a serial port", @@ -1920,6 +1981,42 @@ "maximum": 9, "default": 0 }, + "hardwareBreakpoints": { + "description": "WARNING: Force only HW breakpoints to be used. By default GDB will use HW or SW breakpoints depending on memory type. Use this only in rare circumstances to work around issues in your gdb-server or hardware. This setting is NOT recommended for general use.", + "type": "object", + "properties": { + "require": { + "type": "boolean", + "default": false, + "description": "If true, forces the use of hardware breakpoints" + }, + "limit": { + "type": "number", + "minimum": 0, + "multipleOf": 1, + "default": 0, + "description": "If limit > 0, enforce a limit on the number of hardware breakpoints that can be used" + } + } + }, + "hardwareWatchpoints": { + "description": "WARNING: Force only HW watchpoints to be used. By default GDB will use HW or SW watchpoints depending on memory type. Use this only in rare circumstances", + "type": "object", + "properties": { + "require": { + "type": "boolean", + "default": false, + "description": "If true, forces the use of hardware watchpoints" + }, + "limit": { + "type": "number", + "minimum": 0, + "multipleOf": 1, + "default": 0, + "description": "If limit > 0, enforce a limit on the number of hardware watchpoints that can be used" + } + } + }, "liveWatch": { "description": "An object with parameters for Live Watch", "properties": { @@ -2516,7 +2613,7 @@ "swoPort": { "type": "string", "default": "", - "description": "When server is \"external\" && source is \"socket\", port to connect to. Format [host:]port. For BMP, specifies the regex match of the USB interface contianing raw SWO data." + "description": "When server is \"external\" && source is \"socket\", port to connect to. Format [host:]port. For BMP, specifies the regex match of the USB interface containing raw SWO data." }, "decoders": { "description": "SWO Decoder Configuration", @@ -3022,7 +3119,7 @@ "dependencies": { "@vscode/extension-telemetry": "^0.9.8", "@vscode/webview-ui-toolkit": "^1.4.0", - "binary-parser": "^2.2.1", + "binary-parser": "^2.3.0", "bindings": "^1.5.0", "command-exists": "^1.2.9", "commander": "^13.0.0", @@ -3037,17 +3134,17 @@ "safe-buffer": "^5.2.1", "serialport": "^13.0.0", "stream-json": "^1.9.1", - "tmp": "^0.2.3", - "universal-analytics": "^0.5.3", + "tmp": "^0.2.7", + "universal-analytics": "^0.5.4", "usb": "^2.14.0", - "uuid": "^11.0.5", + "uuid": "^14.0.1", "vscode-jsonrpc": "^8.2.1" }, "description": "ARM Cortex-M GDB Debugger support for VSCode", "devDependencies": { "@stylistic/eslint-plugin": "^2.13.0", "@types/mocha": "^10.0.10", - "@types/node": "16.x", + "@types/node": "22.x", "@types/vscode": "^1.69.0", "@vscode/debugadapter": "^1.68.0", "@vscode/debugprotocol": "^1.68.0", @@ -3057,7 +3154,7 @@ "ts-loader": "^9.5.2", "typescript": "^5.7.3", "typescript-eslint": "^8.20.0", - "webpack": "^5.97.1", + "webpack": "^5.105.0", "webpack-cli": "^6.0.1" }, "displayName": "Cortex-Debug", diff --git a/src/backend/backend.ts b/src/backend/backend.ts index b4b55e59..736b3555 100644 --- a/src/backend/backend.ts +++ b/src/backend/backend.ts @@ -6,14 +6,18 @@ import { hexFormat } from '../frontend/utils'; export interface OurSourceBreakpoint extends DebugProtocol.SourceBreakpoint { file?: string; raw?: string; // Used for function name as well and old style address breakpoints + isFunction?: boolean; + isTemporary?: boolean; // What we get from gdb below address?: string; number?: number; + hwOpt?: string; // The gdb MI argument to use for hardware breakpoint allocation } export interface OurInstructionBreakpoint extends DebugProtocol.InstructionBreakpoint { address: number; number: number; + htOpt?: string; // The gdb MI argument to use for hardware breakpoint allocation } export interface OurDataBreakpoint extends DebugProtocol.DataBreakpoint { diff --git a/src/backend/mi2/mi2.ts b/src/backend/mi2/mi2.ts index 5033cf6a..e750f9ad 100644 --- a/src/backend/mi2/mi2.ts +++ b/src/backend/mi2/mi2.ts @@ -1,5 +1,7 @@ -import { IBackend, Stack, Variable, VariableObject, MIError, - OurInstructionBreakpoint, OurDataBreakpoint, OurSourceBreakpoint } from '../backend'; +import { + IBackend, Stack, Variable, VariableObject, MIError, + OurInstructionBreakpoint, OurDataBreakpoint, OurSourceBreakpoint +} from '../backend'; import * as ChildProcess from 'child_process'; import { EventEmitter } from 'events'; import { parseMI, MINode } from '../mi_parse'; @@ -7,7 +9,7 @@ import { posix } from 'path'; import * as os from 'os'; import { ServerConsoleLog } from '../server'; import { hexFormat } from '../../frontend/utils'; -import { ADAPTER_DEBUG_MODE } from '../../common'; +import { ADAPTER_DEBUG_MODE, GDBInterruptMode } from '../../common'; const path = posix; export interface ReadMemResults { @@ -46,7 +48,8 @@ function couldBeOutput(line: string) { const trace = false; export class MI2 extends EventEmitter implements IBackend { - public debugOutput: ADAPTER_DEBUG_MODE; + public debugOutput: ADAPTER_DEBUG_MODE = ADAPTER_DEBUG_MODE.NONE; + public interruptMode: GDBInterruptMode = GDBInterruptMode.EXEC_INTERRUPT; public procEnv: any; protected currentToken: number = 1; protected nextTokenComing = 1; // This will be the next token output from gdb @@ -87,24 +90,40 @@ export class MI2 extends EventEmitter implements IBackend { }); if (!this.forLiveGdb) { - let timeout = setTimeout(() => { - this.gdbStartError(); - setTimeout(() => { - reject(new Error('Could not start gdb, no response from gdb')); - }, 10); - timeout = undefined; - }, 5000); + const maxSeconds = 60; + const start = Date.now(); + let msgTime = start; + let timeout = setInterval(() => { + const now = Date.now(); + if ((now - msgTime) > 5000) { + ServerConsoleLog(`Waiting for GDB process to start... (${Math.floor((now - start) / 1000)}s)`); + msgTime = now; + } + const elapsed = now - start; + if (elapsed > (maxSeconds * 1000)) { + clearInterval(timeout); + timeout = undefined; + reject(new Error(`GDB process failed to start within ${maxSeconds} seconds. Check your gdb installation by running ` + + `'${this.application} --version' in a terminal. If your gdb is very slow to start, you can try disabling antivirus ` + + 'software or switching to a faster gdb version.')); + } + }, 250); const swallOutput = this.debugOutput ? false : true; let v; try { v = await this.sendCommand('gdb-version', false, true, swallOutput); if (timeout) { - clearTimeout(timeout); + clearInterval(timeout); + timeout = undefined; } else { return; } } catch (e) { + if (timeout) { + clearInterval(timeout); + timeout = undefined; + } reject(e); return; } @@ -365,7 +384,9 @@ export class MI2 extends EventEmitter implements IBackend { fid = item[1]; // for future use, available for thread-selected } } - if (record.asyncClass === 'thread-created') { + if (record.asyncClass === 'breakpoint-deleted') { + this.emit('breakpoint-deleted', { bkptId: parseInt(tid) }); + } else if (record.asyncClass === 'thread-created') { this.emit('thread-created', { threadId: parseInt(tid), threadGroupId: gid }); } else if (record.asyncClass === 'thread-exited') { this.emit('thread-exited', { threadId: parseInt(tid), threadGroupId: gid }); @@ -402,10 +423,10 @@ export class MI2 extends EventEmitter implements IBackend { } } - // stop() can get called twice ... once by the disconnect sequence and once by the server existing because + // stop() can get called twice ... once by the disconnect sequence and once by the server exiting because // we called disconnect. And the sleeps don't help that cause private exiting = false; - public async stop() { + public async stop(doDisconnect = true) { if (trace) { this.log('stderr', 'stop'); } @@ -414,20 +435,28 @@ export class MI2 extends EventEmitter implements IBackend { // With JLink all of these catches, timeouts occur one time or the other. Two back to back runs don't produce // the same program flow. Sometimes, we get all the way to a proper gdb-exit without any timers expiring and // everything working. Very next run totally erratic. Openocd has its own issues - let timer; + let timer: NodeJS.Timeout | undefined = undefined; const startKillTimeout = (ms: number) => { - if (timer) { clearTimeout(timer); } - timer = setTimeout(() => { - if (timer && !this.exited) { - ServerConsoleLog('GDB Kill timer expired for a disconnect+exit, so forcing a kill', this.pid); + if (timer) { destroyTimer(); } + const now = Date.now(); + timer = setInterval(() => { + if (this.exited) { + destroyTimer(); + return; + } + const elapsed = Date.now() - now; + if (elapsed >= ms) { + destroyTimer(); + if (this.debugOutput) { + this.log('stderr', 'GDB kill or disconnect timer expired for a disconnect+exit, so forcing a kill'); + } this.tryKill(); } - timer = undefined; - }, ms); + }, 50); }; const destroyTimer = () => { if (timer) { - clearTimeout(timer); + clearInterval(timer); timer = undefined; } }; @@ -437,26 +466,32 @@ export class MI2 extends EventEmitter implements IBackend { // Disconnect first. Not doing so and exiting will cause an unwanted detach if the // program is in paused state try { - startKillTimeout(500); - await new Promise((res) => setTimeout(res, 100)); // For some people delay was needed. Doesn't hurt I guess - await this.sendCommand('target-disconnect'); // Yes, this can fail + if (doDisconnect && !this.exited) { + startKillTimeout(500); + await this.sendCommand('target-disconnect'); // Yes, this can fail + } } catch (e) { if (this.exited) { - ServerConsoleLog('GDB already exited during a target-disconnect', this.pid); + if (this.debugOutput) { + this.log('stderr', 'GDB already exited during a target-disconnect'); + } destroyTimer(); return; } - ServerConsoleLog(`target-disconnect failed with exception: ${e}. Proceeding to gdb-exit` + e, this.pid); + if (this.debugOutput) { + this.log('stderr', `target-disconnect failed with exception: ${e}. Proceeding to gdb-exit`); + } } - startKillTimeout(350); // Reset timer for a smaller timeout - await new Promise((res) => setTimeout(res, 250)); // For some people delay was needed. Doesn't hurt I guess + startKillTimeout(500); // Reset timer for a smaller timeout if (this.exited) { // This occurs sometimes after a successful disconnect. - ServerConsoleLog('gdb already exited before an exit was requested', this.pid); - return; + if (this.debugOutput) { + this.log('stderr', 'gdb already exited before an exit was requested?'); + } + } else { + this.sendRaw('-gdb-exit'); } - this.sendRaw('-gdb-exit'); } } @@ -466,7 +501,7 @@ export class MI2 extends EventEmitter implements IBackend { } let to = setTimeout(() => { if (to) { - ServerConsoleLog('target-detach hung: target probably running, thats okay, continue to stop()', this.pid); + this.log('stderr', 'target-detach hung: target probably running, continue to stop()'); to = null; this.stop(); } @@ -480,13 +515,13 @@ export class MI2 extends EventEmitter implements IBackend { clearTimeout(to); to = null; } - this.stop(); + this.stop(false); }, (e) => { if (to) { clearTimeout(to); to = null; } - ServerConsoleLog('target-detach failed: target probably running, thats okay, continue to stop()', this.pid); + this.log('stderr', 'target-detach failed: target probably running, continue to stop()'); this.stop(); }); } @@ -495,11 +530,21 @@ export class MI2 extends EventEmitter implements IBackend { if (trace) { this.log('stderr', 'interrupt ' + arg); } - return new Promise((resolve, reject) => { - this.sendCommand(`exec-interrupt ${arg}`).then((info) => { - resolve(info.resultRecords.resultClass === 'done'); - }, reject); - }); + if (this.interruptMode == GDBInterruptMode.EXEC_INTERRUPT) { + return new Promise((resolve, reject) => { + this.sendCommand(`exec-interrupt ${arg}`).then((info) => { + resolve(info.resultRecords.resultClass === 'done'); + }, reject); + }); + } else if (this.interruptMode == GDBInterruptMode.SIGINT) { + if (this.process.kill('SIGINT')) { + return Promise.resolve(true); + } else { + return Promise.reject(new Error('Could not send SIGINT to gdb')); + } + } else { + this.log('stderr', `WARNING: Invalid GDB interrupt mode '${this.interruptMode as string}'`); + } } public continue(threadId: number): Thenable { @@ -548,20 +593,6 @@ export class MI2 extends EventEmitter implements IBackend { }); } - public goto(filename: string, line: number): Thenable { - if (trace) { - this.log('stderr', 'goto'); - } - return new Promise((resolve, reject) => { - const target: string = '"' + (filename ? escape(filename) + ':' : '') + line.toString() + '"'; - this.sendCommand('break-insert -t ' + target).then(() => { - this.sendCommand('exec-jump ' + target).then((info) => { - resolve(info.resultRecords.resultClass === 'running'); - }, reject); - }, reject); - }); - } - public restart(commands: string[]): Thenable { if (trace) { this.log('stderr', 'restart'); @@ -634,10 +665,24 @@ export class MI2 extends EventEmitter implements IBackend { bkptArgs += `-c "${breakpoint.condition}" `; } - if (breakpoint.raw) { + if (breakpoint.isTemporary) { + bkptArgs += '-t '; + } + + if (breakpoint.isFunction) { + bkptArgs += '--function ' + '"' + escape(breakpoint.raw) + '" '; + } else if (breakpoint.raw) { bkptArgs += '*' + escape(breakpoint.raw); } else { - bkptArgs += '"' + escape(breakpoint.file) + ':' + breakpoint.line + '"'; + bkptArgs += '"' + escape(breakpoint.file) + ':' + breakpoint.line + '" '; + } + + if (breakpoint.hwOpt) { + if (breakpoint.logMessage) { + reject(new MIError('Hardware breakpoints not supported by gdb with logpoints (dprintf) ' + bkptArgs, 'internal')); + return; + } + bkptArgs = breakpoint.hwOpt + ' ' + bkptArgs; } const cmd = breakpoint.logMessage ? 'dprintf-insert' : 'break-insert'; @@ -680,7 +725,7 @@ export class MI2 extends EventEmitter implements IBackend { bkptArgs += '*' + hexFormat(breakpoint.address); - this.sendCommand(`break-insert ${bkptArgs}`).then((result) => { + this.sendCommand(`break-insert ${breakpoint.htOpt || ''} ${bkptArgs}`).then((result) => { if (result.resultRecords.resultClass === 'done') { const bkptNum = parseInt(result.result('bkpt.number')); breakpoint.number = bkptNum; @@ -739,16 +784,15 @@ export class MI2 extends EventEmitter implements IBackend { breakpoint.number = bkptNum; if (breakpoint.condition) { - this.setBreakPointCondition(bkptNum, breakpoint.condition).then((result) => { + Promise.resolve(this.setBreakPointCondition(bkptNum, breakpoint.condition)).then((result) => { if (result.resultRecords.resultClass === 'done') { resolve(breakpoint); } else { reject(new MIError(result.result('msg') || 'Internal error', 'Setting breakpoint condition')); } - }, - (reason) => { + }).catch((reason) => { // Just delete the breakpoint we just created as the condition creation failed - this.sendCommand(`break-delete ${bkptNum}`).then((x) => {}, (e) => {}); + this.sendCommand(`break-delete ${bkptNum}`).then((x) => { }, (e) => { }); reject(reason); // Use this reason as reason for failing to create the breakpoint }); } else { @@ -822,7 +866,7 @@ export class MI2 extends EventEmitter implements IBackend { ret.push({ address: addr, fileName: filename, - file: file, + file: file || filename, function: func || from, level: level, line: line @@ -955,14 +999,14 @@ export class MI2 extends EventEmitter implements IBackend { return omg; } - public static getThreadFrameStr(threadId: number, frameId: number): string { + public static getThreadFrameStr(threadId: number | undefined, frameId: number | undefined): string { const th = ((threadId !== undefined) && (threadId > 0)) ? `--thread ${threadId} ` : ''; const fr = ((frameId !== undefined) && (frameId >= 0)) ? `--frame ${frameId}` : ''; return th + fr; } // Pass negative threadId/frameId to specify no context or current context - public async varUpdate(name: string = '*', threadId: number, frameId: number): Promise { + public async varUpdate(name: string = '*', threadId: number | undefined, frameId: number | undefined): Promise { if (trace) { this.log('stderr', 'varUpdate'); } @@ -970,14 +1014,14 @@ export class MI2 extends EventEmitter implements IBackend { } // Pass negative threadId/frameId to specify no context or current context - public async varAssign(name: string, rawValue: string, threadId: number, frameId: number): Promise { + public async varAssign(name: string, rawValue: string, threadId: number | undefined, frameId: number | undefined): Promise { if (trace) { this.log('stderr', 'varAssign'); } return this.sendCommand(`var-assign ${MI2.getThreadFrameStr(threadId, frameId)} ${name} ${rawValue}`); } - public async exprAssign(expr: string, rawValue: string, threadId: number, frameId: number): Promise { + public async exprAssign(expr: string, rawValue: string, threadId: number | undefined, frameId: number | undefined): Promise { if (trace) { this.log('stderr', 'exprAssign'); } diff --git a/src/backend/server.ts b/src/backend/server.ts index db622148..c3cc72e8 100644 --- a/src/backend/server.ts +++ b/src/backend/server.ts @@ -9,10 +9,19 @@ import { quoteShellCmdLine } from '../common'; import { greenFormat } from '../frontend/ansi-helpers'; export let GdbPid = -1; + +let ServerLogFilePath: string | null = null; +export function getServerLogFilePath(): string { + if (!ServerLogFilePath) { + const tmpDirName = os.tmpdir(); + ServerLogFilePath = path.join(tmpDirName, 'cortex-debug-server.log'); + } + return ServerLogFilePath; +} + export function ServerConsoleLog(str: string, usePid?: number) { if (!str) { return; } try { - const tmpDirName = os.tmpdir(); const date = new Date(); if (usePid) { GdbPid = usePid; @@ -22,7 +31,7 @@ export function ServerConsoleLog(str: string, usePid?: number) { if (!str.endsWith('\n')) { str += '\n'; } - fs.appendFileSync(path.join(tmpDirName, 'cortex-debug-server-exiting.log'), str); + fs.appendFileSync(getServerLogFilePath(), str); } catch (e) { console.log(e ? e.toString() : 'unknown exception?'); } @@ -30,19 +39,19 @@ export function ServerConsoleLog(str: string, usePid?: number) { let currentServers: GDBServer[] = []; export class GDBServer extends EventEmitter { - private process: ChildProcess.ChildProcess; + private process: ChildProcess.ChildProcess | null = null; private outBuffer: string = ''; private errBuffer: string = ''; - protected consoleSocket: net.Socket = null; - private initResolve: (result: boolean) => void; - private initReject: (error: any) => void; - public static readonly SERVER_TIMEOUT = 10000; + protected consoleSocket: net.Socket | null = null; + private initResolve: ((result: boolean) => void) | null = null; + private initReject: ((error: any) => void) | null = null; + public static readonly SERVER_TIMEOUT = 10 * 60 * 1000; public static readonly LOCALHOST = '0.0.0.0'; - public pid: number = -1; + public pid: number | undefined = -1; constructor( - private cwd: string, private application: string, private args: string[], - private initMatch: RegExp, private port: number | undefined, private consolePort: number) { + private cwd: string | null, private application: string | null, private args: string[], + private initMatch: RegExp | null, private port: number | undefined, private consolePort: number) { super(); } @@ -57,11 +66,13 @@ export class GDBServer extends EventEmitter { ServerConsoleLog('GDBServer: Could not connect to console: ' + e); reject(e); } - this.process = ChildProcess.spawn(this.application, this.args, { cwd: this.cwd }); + this.process = ChildProcess.spawn(this.application, this.args, { cwd: this.cwd || undefined }); currentServers.push(this); this.pid = this.process.pid; - this.process.stdout.on('data', this.onStdout.bind(this)); - this.process.stderr.on('data', this.onStderr.bind(this)); + if (this.process.stdout && this.process.stderr) { + this.process.stdout.on('data', this.onStdout.bind(this)); + this.process.stderr.on('data', this.onStderr.bind(this)); + } this.process.on('exit', this.onExit.bind(this)); this.process.on('error', this.onError.bind(this)); @@ -100,7 +111,7 @@ export class GDBServer extends EventEmitter { return !!this.process; } - private exitTimeout: NodeJS.Timeout = null; + private exitTimeout: NodeJS.Timeout | null = null; private killInProgress = false; public exit(): void { if (this.process && !this.killInProgress) { @@ -114,7 +125,7 @@ export class GDBServer extends EventEmitter { } } - private onExit(code, signal) { + private onExit(code: any, signal: any) { if (this.exitTimeout) { clearTimeout(this.exitTimeout); this.exitTimeout = null; @@ -129,7 +140,7 @@ export class GDBServer extends EventEmitter { }, 10); } - private onError(err) { + private onError(err: any) { if (this.initReject) { this.initReject(err); this.initReject = null; @@ -139,7 +150,7 @@ export class GDBServer extends EventEmitter { this.emit('launcherror', err); } - private onStdout(data) { + private onStdout(data: any) { this.sendToConsole(data); // Send it without any processing or buffering if (this.initResolve) { if (typeof data === 'string') { @@ -163,7 +174,7 @@ export class GDBServer extends EventEmitter { } } - private onStderr(data) { + private onStderr(data: any) { this.sendToConsole(data); // Send it without any processing or buffering if (this.initResolve) { if (typeof data === 'string') { @@ -192,7 +203,9 @@ export class GDBServer extends EventEmitter { const socket = new net.Socket(); socket.on('data', (data) => { try { - this.process.stdin.write(data, 'utf8'); + if (this.process && this.process.stdin) { + this.process.stdin.write(data, 'utf8'); + } } catch (e) { console.error(`stdin write failed ${e}`); } @@ -218,7 +231,8 @@ export class GDBServer extends EventEmitter { // It is possible that the server is not ready socket.connect(this.consolePort, '127.0.0.1', () => { - socket.write(greenFormat(quoteShellCmdLine([this.application, ...this.args]) + '\n')); + const app = this.application || ''; + socket.write(greenFormat(quoteShellCmdLine([app, ...this.args]) + '\n')); this.consoleSocket = socket; resolve(); }); @@ -251,7 +265,7 @@ export class GDBServer extends EventEmitter { // are in server mode (as in when in debug) it does not do that because we are always running. // // See GDBDebugSession.disconnectRequest() -process.on('exit', (code, signal) => { +process.on('exit', (code: any, signal: any) => { if (currentServers.length > 0) { ServerConsoleLog(`Debug Adapter crashed or killed by VSCode? code=${code} signal=${signal}`); for (const p of [...currentServers]) { diff --git a/src/backend/symbols.ts b/src/backend/symbols.ts index 5bda19f6..ce3bf284 100644 --- a/src/backend/symbols.ts +++ b/src/backend/symbols.ts @@ -26,6 +26,25 @@ const SCOPE_MAP: { [id: string]: SymbolScope } = { '!': SymbolScope.Both }; +/** + * While parsing output of nm/objdump (both are line oriented), how you parse a line changes depending on where + * you are in the output. This context object helps keep track of that. The callback is the current line parser function + * which change as we progress through the output. This way, we have a simple state machine for parsing. Not every field + * is needed by every parser, but the most important is the callback. + */ +export class ObjectReaderContext { + public curObjFile: string | null = null; // Current object file being processed from nm/objdump + constructor(public reader: SpawnLineReader) { } + + public setCallback(cb: (line: string, err?: any) => boolean) { + this.reader.callback = cb; + } + + public getCallback() { + return this.reader.callback; + } +} + export class SymbolNode implements Interval { constructor( public readonly symbol: SymbolInformation, // Only functions and objects @@ -147,125 +166,13 @@ export class SymbolTable { } } - /* - private createSymtableSerializedFName(exeName: string) { - return this.createFileMapCacheFileName(exeName, '-syms') + '.gz'; - } - - private static CurrentVersion = 1; - private serializeSymbolTable(exeName: string) { - const fMap: {[key: string]: number} = {}; - const keys = this.allSymbols.length > 0 ? Object.keys(this.allSymbols[0]) : []; - this.fileTable = []; - const syms = []; - for (const sym of this.allSymbols) { - const fName: string = sym.file as string; - let id: number = fMap[fName]; - if (id === undefined) { - id = this.fileTable.length; - this.fileTable.push(fName); - fMap[fName] = id; - } - const tmp = sym.file; - sym.file = id; - syms.push(Object.values(sym)); - sym.file = tmp; - } - const serObj: ISymbolTableSerData = { - version: SymbolTable.CurrentVersion, - memoryRegions: this.memoryRegions, - fileTable: this.fileTable, - symbolKeys: keys, - allSymbols: syms - }; - - const fName = this.createSymtableSerializedFName(exeName); - const fStream = fs.createWriteStream(fName, { flags: 'w' }); - fStream.on('error', () => { - console.error('Saving symbol table failed!!!'); - }); - fStream.on('close', () => { - console.log('Saved symbol table'); - }); - const jsonStream = new JsonStreamStringify([serObj]); - jsonStream.on('error', () => { - console.error('Saving symbol table JsonStreamStringify() failed!!!'); - }); - jsonStream - .pipe(zlib.createGzip()) - .pipe(fStream) - .on('finish', () => { - console.log('Pipe ended'); - }); - } - - private deSerializeSymbolTable(exeName: string): Promise { - return new Promise((resolve) => { - const fName = this.createSymtableSerializedFName(exeName); - if (!fs.existsSync(fName)) { - resolve(false); - return; - } - const fStream = fs.createReadStream(fName); - fStream.on('error', () => { - resolve(false); - }); - - console.time('abc'); - const jsonStream = StreamArray.withParser(); - jsonStream.on('data', ({key, value}) => { - console.timeLog('abc', 'Parsed data:'); - fStream.close(); - reconstruct(value); - }); - fStream - .pipe(zlib.createGunzip()) - .pipe(jsonStream.input); - - const reconstruct = (data: any) => { - try { - const serObj: ISymbolTableSerData = data as ISymbolTableSerData; - if (!serObj || (serObj.version !== SymbolTable.CurrentVersion)) { - resolve(false); - return; - } - this.fileMap = {}; - for (const f of serObj.fileTable) { - if (f !== null) { // Yes, there one null in there - this.addPathVariations(f); - } - } - - this.allSymbols = []; - const keys = serObj.symbolKeys; - const n = keys.length; - for (const values of serObj.allSymbols) { - const sym: any = {}; - values.forEach((v, i) => sym[keys[i]] = v); - sym.file = serObj.fileTable[sym.file as number]; - this.addSymbol(sym/* as SymbolInformation* /); - } - this.memoryRegions = []; - for (const m of serObj.memoryRegions) { - this.memoryRegions.push(new MemoryRegion(m)); - } - console.timeEnd('abc'); - resolve(true); - } catch (e) { - resolve(false); - } - }; - }); - } - */ - /** * Problem statement: * We need a read the symbol table for multiple types of information and none of the tools so far * give all all we need * * 1. List of static variables by file - * 2. List og globals + * 2. List of globals * 3. Functions (global and static) with their addresses and lengths * * Things we tried: @@ -339,10 +246,7 @@ export class SymbolTable { add(this.symbolsByAddressOrig, sym.addressOrig); } - private objdumpReader: SpawnLineReader; - private currentObjDumpFile: string = null; - - private readObjdumpHeaderLine(symF: SymbolFile, line: string, err: any): boolean { + private readObjdumpHeaderLine(cxt: ObjectReaderContext, symF: SymbolFile, line: string, err: any): boolean { if (!line) { return line === '' ? true : false; } @@ -390,15 +294,15 @@ export class SymbolTable { }); this.memoryRegions.push(region); } else { - const memRegionsEnd = RegExp(/^SYMBOL TABLE:/); - if (memRegionsEnd.test(line)) { - this.objdumpReader.callback = this.readObjdumpSymbolLine.bind(this, symF); + if (line.startsWith('SYMBOL TABLE:')) { + // Switch the parser to symbol line parser mode + cxt.setCallback(this.readObjdumpSymbolLine.bind(this, cxt, symF)); } } return true; } - private readObjdumpSymbolLine(symF: SymbolFile, line: string, err: any): boolean { + private readObjdumpSymbolLine(cxt: ObjectReaderContext, symF: SymbolFile, line: string, err: any): boolean { if (!line) { return line === '' ? true : false; } @@ -406,12 +310,12 @@ export class SymbolTable { if (match) { if (match[7] === 'd' && match[8] === 'f') { if (match[11]) { - this.currentObjDumpFile = SymbolTable.NormalizePath(match[11].trim()); + cxt.curObjFile = SymbolTable.NormalizePath(match[11].trim()); } else { // This can happen with C++. Inline and template methods/variables/functions/etc. are listed with // an empty file association. So, symbols after this line can come from multiple compilation // units with no clear owner. These can be locals, globals or other. - this.currentObjDumpFile = null; + cxt.curObjFile = null; } // We don't really use the symbol except know that the symbol following this belong to this file return true; @@ -445,12 +349,12 @@ export class SymbolTable { addressOrig: addr, address: newaddr, name: name, - file: this.currentObjDumpFile, + file: cxt.curObjFile, type: type, scope: scope, section: secName, length: size, - isStatic: (scope === SymbolScope.Local) && this.currentObjDumpFile ? true : false, + isStatic: (scope === SymbolScope.Local) && cxt.curObjFile ? true : false, instructions: null, hidden: hidden }; @@ -472,82 +376,85 @@ export class SymbolTable { } try { const spawnOpts = { cwd: this.gdbSession.args.cwd }; - const objdumpStart = Date.now(); - const objDumpArgs = [ - '--syms', // Of course, we want symbols - '-C', // Demangle - '-h', // Want section headers - '-w', // Don't wrap lines (wide format) - executable]; - this.currentObjDumpFile = null; - this.objdumpReader = new SpawnLineReader(); - this.objdumpReader.on('error', (e) => { - rejected = true; - reject(e); - }); - this.objdumpReader.on('exit', (code, signal) => { - if (code !== 0) { - this.gdbSession.handleMsg('log', `'objdump' exited with a nonzero exit status ${code}, ${signal}\n`); - } - }); - this.objdumpReader.on('close', (code, signal) => { - this.objdumpReader = undefined; - this.currentObjDumpFile = null; + // eslint-disable-next-line no-constant-condition + if (true) { + const objdumpStart = Date.now(); + const objDumpArgs = [ + '--syms', // Of course, we want symbols + '-C', // Demangle + '-h', // Want section headers + '-w', // Don't wrap lines (wide format) + executable]; + const cxt = new ObjectReaderContext(new SpawnLineReader()); + cxt.setCallback(this.readObjdumpHeaderLine.bind(this, cxt, symbolFile)); + cxt.reader.on('error', (e) => { + rejected = true; + reject(e); + }); + cxt.reader.on('exit', (code, signal) => { + if (code !== 0) { + this.gdbSession.handleMsg('log', `'objdump' exited with a nonzero exit status ${code}, ${signal}. File: ${executable}\n`); + } + }); + cxt.reader.on('close', (code, signal) => { + if (trace || this.gdbSession.args.showDevDebugOutput) { + const ms = Date.now() - objdumpStart; + this.gdbSession.handleMsg('log', `Finished reading symbols from objdump: Time: ${ms} ms. File: ${executable}\n`); + } + }); + if (trace || this.gdbSession.args.showDevDebugOutput) { - const ms = Date.now() - objdumpStart; - this.gdbSession.handleMsg('log', `Finished reading symbols from objdump: Time: ${ms} ms\n`); + this.gdbSession.handleMsg('log', `Reading symbols from ${this.objdumpPath} ${objDumpArgs.join(' ')}\n`); } - }); - - if (trace || this.gdbSession.args.showDevDebugOutput) { - this.gdbSession.handleMsg('log', `Reading symbols from ${this.objdumpPath} ${objDumpArgs.join(' ')}\n`); + objdumpPromises.push({ + args: [this.objdumpPath, ...objDumpArgs], + promise: cxt.reader.startWithProgram( + this.objdumpPath, objDumpArgs, spawnOpts, cxt.getCallback()), + }); } - objdumpPromises.push({ - args: [this.objdumpPath, ...objDumpArgs], - promise: this.objdumpReader.startWithProgram( - this.objdumpPath, - objDumpArgs, - spawnOpts, - this.readObjdumpHeaderLine.bind(this, symbolFile) - ), - }); - const nmStart = Date.now(); - const nmProg = replaceProgInPath(this.objdumpPath, /objdump/i, 'nm'); - const nmArgs = [ - '--defined-only', - '-S', // Want size as well - '-l', // File/line info - '-C', // Demangle - '-p', // don't bother sorting - // Do not use posix format. It is inaccurate - executable - ]; - const nmReader = new SpawnLineReader(); - nmReader.on('error', (e) => { - this.gdbSession.handleMsg('log', `Error: ${nmProg} failed! statics/global/functions may not be properly classified: ${e.toString()}\n`); - this.gdbSession.handleMsg('log', ' Expecting `nm` next to `objdump`. If that is not the problem please report this.\n'); - this.nmPromises = []; - }); - nmReader.on('exit', (code, signal) => { - if (code !== 0) { - this.gdbSession.handleMsg('log', `'nm' exited with a nonzero exit status ${code}, ${signal}\n`); - } - }); - nmReader.on('close', () => { + // eslint-disable-next-line no-constant-condition + if (true) { + const nmStart = Date.now(); + const nmProg = replaceProgInPath(this.objdumpPath, /objdump/i, 'nm'); + const nmArgs = [ + '--defined-only', + '-S', // Want size as well + '-l', // File/line info + '-C', // Demangle + '-p', // don't bother sorting + // Do not use posix format. It is inaccurate + executable + ]; + const cxt = new ObjectReaderContext(new SpawnLineReader()); + cxt.setCallback(this.readNmSymbolLine.bind(this, cxt, symbolFile)); + cxt.reader.on('error', (e) => { + // eslint-disable-next-line @stylistic/max-len + this.gdbSession.handleMsg('log', `Error: ${nmProg} failed! statics/global/functions may not be properly classified: ${e.toString()}\n`); + this.gdbSession.handleMsg('log', ' Expecting `nm` next to `objdump`. If that is not the problem please report this.\n'); + this.nmPromises = []; + }); + cxt.reader.on('exit', (code, signal) => { + if (code !== 0) { + this.gdbSession.handleMsg('log', `'nm' exited with a nonzero exit status ${code}, ${signal}. File: ${executable}\n`); + } + }); + cxt.reader.on('close', () => { + if (trace || this.gdbSession.args.showDevDebugOutput) { + const ms = Date.now() - nmStart; + this.gdbSession.handleMsg('log', `Finished reading symbols from nm: Time: ${ms} ms. File: ${executable}\n`); + } + }); + if (trace || this.gdbSession.args.showDevDebugOutput) { - const ms = Date.now() - nmStart; - this.gdbSession.handleMsg('log', `Finished reading symbols from nm: Time: ${ms} ms\n`); + this.gdbSession.handleMsg('log', `Reading symbols from ${nmProg} ${nmArgs.join(' ')}\n`); } - }); - - if (trace || this.gdbSession.args.showDevDebugOutput) { - this.gdbSession.handleMsg('log', `Reading symbols from ${nmProg} ${nmArgs.join(' ')}\n`); + this.nmPromises.push({ + args: [nmProg, ...nmArgs], + promise: cxt.reader.startWithProgram( + nmProg, nmArgs, spawnOpts, cxt.getCallback()), + }); } - this.nmPromises.push({ - args: [nmProg, ...nmArgs], - promise: nmReader.startWithProgram(nmProg, nmArgs, spawnOpts, this.readNmSymbolLine.bind(this, symbolFile)) - }); } catch (e) { if (!rejected) { rejected = true; @@ -610,7 +517,7 @@ export class SymbolTable { } private addressToFileOrig: Map = new Map(); // These are addresses used before re-mapped via symbol-files - private readNmSymbolLine(symF: SymbolFile, line: string, err: any): boolean { + private readNmSymbolLine(cxt: ObjectReaderContext, symF: SymbolFile, line: string, err: any): boolean { const match = line && line.match(NM_SYMBOL_RE); if (match) { const offset = symF.offset || 0; diff --git a/src/bmp.ts b/src/bmp.ts index a0b7d74d..30b27339 100644 --- a/src/bmp.ts +++ b/src/bmp.ts @@ -90,7 +90,7 @@ export class BMPServerController extends EventEmitter implements GDBServerContro const encoding = this.args.swoConfig.swoEncoding === 'manchester' ? 1 : 2; if (this.args.swoConfig.source === 'probe') { - commands.push(encoding === 2 ? `monitor traceswo ${swoFrequency}` : 'monitor traceswo'); + commands.push(encoding === 2 ? `monitor traceswo enable ${swoFrequency}` : 'monitor traceswo enable'); } return commands.map((c) => `interpreter-exec console "${c}"`); diff --git a/src/common.ts b/src/common.ts index 22fdcf1e..86043f09 100644 --- a/src/common.ts +++ b/src/common.ts @@ -252,6 +252,16 @@ export function defSymbolFile(file: string): SymbolFile { return ret; } +export interface HWBreakpointInfo { + require: boolean; + limit?: number; +} + +export interface HWWatchpointInfo { + require: boolean; + limit?: number; +} + export interface ConfigurationArguments extends DebugProtocol.LaunchRequestArguments { name: string; request: string; @@ -262,6 +272,7 @@ export interface ConfigurationArguments extends DebugProtocol.LaunchRequestArgum serverpath: string; gdbPath: string; gdbServerConsolePort: number; + gdbInterruptMode: GDBInterruptMode; objdumpPath: string; serverArgs: string[]; serverCwd: string; @@ -269,6 +280,7 @@ export interface ConfigurationArguments extends DebugProtocol.LaunchRequestArgum loadFiles: string[]; symbolFiles: SymbolFile[]; debuggerArgs: string[]; + overridePreEndSessionCommands: null | string[]; preLaunchCommands: string[]; postLaunchCommands: string[]; overrideLaunchCommands: string[]; @@ -305,7 +317,8 @@ export interface ConfigurationArguments extends DebugProtocol.LaunchRequestArgum registerUseNaturalFormat: boolean; variableUseNaturalFormat: boolean; chainedConfigurations: ChainedConfigurations; - + hardwareBreakpoints: HWBreakpointInfo; + hardwareWatchpoints: HWWatchpointInfo; pvtIsReset: boolean; pvtPorts: { [name: string]: number }; pvtParent: ConfigurationArguments; @@ -365,6 +378,11 @@ export enum CTIAction { 'resume' } +export enum GDBInterruptMode { + EXEC_INTERRUPT = 'exec-interrupt', + SIGINT = 'SIGINT' +} + export interface GDBServerController extends EventEmitter { portsNeeded: string[]; name: string; diff --git a/src/frontend/configprovider.ts b/src/frontend/configprovider.ts index 0ae12977..61503f2b 100644 --- a/src/frontend/configprovider.ts +++ b/src/frontend/configprovider.ts @@ -130,6 +130,7 @@ export class CortexDebugConfigurationProvider implements vscode.DebugConfigurati if (!config.postAttachCommands) { config.postAttachCommands = []; } if (!config.preResetCommands) { config.preResetCommands = config.preRestartCommands || []; } if (!config.postResetCommands) { config.postResetCommands = config.postRestartCommands || []; } + if (config.overridePreEndSessionCommands === undefined) { config.overridePreEndSessionCommands = null; } if (!config.postResetSessionCommands) { config.postResetSessionCommands = config.postRestartSessionCommands || null; } if (config.runToEntryPoint) { config.runToEntryPoint = config.runToEntryPoint.trim(); } else if (config.runToMain) { config.runToEntryPoint = 'main'; diff --git a/src/frontend/extension.ts b/src/frontend/extension.ts index a1d66d0d..a49ba7b4 100644 --- a/src/frontend/extension.ts +++ b/src/frontend/extension.ts @@ -8,9 +8,9 @@ import { LiveWatchTreeProvider, LiveVariableNode } from './views/live-watch'; import { RTTCore, SWOCore } from './swo/core'; import { ConfigurationArguments, RTTCommonDecoderOpts, RTTConsoleDecoderOpts, - CortexDebugKeys, ChainedEvents, ADAPTER_DEBUG_MODE, ChainedConfig } from '../common'; + CortexDebugKeys, ChainedEvents, ADAPTER_DEBUG_MODE, ChainedConfig +} from '../common'; import { MemoryContentProvider } from './memory_content_provider'; -import Reporting from '../reporting'; import { CortexDebugConfigurationProvider } from './configprovider'; import { JLinkSocketRTTSource, SocketRTTSource, SocketSWOSource, PeMicroSocketSource } from './swo/sources/socket'; @@ -40,23 +40,21 @@ class ServerStartedPromise { export class CortexDebugExtension { private rttTerminals: RTTTerminal[] = []; - private gdbServerConsole: GDBServerConsole = null; + private gdbServerConsole: GDBServerConsole | null = null; private memoryProvider: MemoryContentProvider; private liveWatchProvider: LiveWatchTreeProvider; private liveWatchTreeView: vscode.TreeView; private SVDDirectory: SVDInfo[] = []; - private functionSymbols: SymbolInformation[] = null; - private serverStartedEvent: ServerStartedPromise; + private functionSymbols: SymbolInformation[] | null = null; + private serverStartedEvent: ServerStartedPromise | undefined; constructor(private context: vscode.ExtensionContext) { const config = vscode.workspace.getConfiguration('cortex-debug'); this.startServerConsole(context, config.get(CortexDebugKeys.SERVER_LOG_FILE_NAME, '')); // Make this the first thing we do to be ready for the session this.memoryProvider = new MemoryContentProvider(); - Reporting.activate(context); - this.liveWatchProvider = new LiveWatchTreeProvider(this.context); this.liveWatchTreeView = vscode.window.createTreeView('cortex-debug.liveWatch', { treeDataProvider: this.liveWatchProvider @@ -128,7 +126,7 @@ export class CortexDebugExtension { let session = CortexDebugExtension.getActiveCDSession(); if (session) { let mySession = CDebugSession.FindSession(session); - const parentConfig = mySession.config?.pvtParent; + const parentConfig = mySession?.config?.pvtParent; while (mySession && parentConfig) { // We have a parent. See if our life-cycle is managed by our parent, if so // send a reset to the parent instead @@ -155,7 +153,7 @@ export class CortexDebugExtension { this.gdbServerConsole.startServer().then(() => { resolve(); // All worked out }).catch((e) => { - this.gdbServerConsole.dispose(); + this.gdbServerConsole?.dispose(); this.gdbServerConsole = null; vscode.window.showErrorMessage(`Could not create gdb-server-console. Will use old style console. Please report this problem. ${e.toString()}`); }); @@ -193,7 +191,9 @@ export class CortexDebugExtension { if (e.affectsConfiguration(`cortex-debug.${CortexDebugKeys.SERVER_LOG_FILE_NAME}`)) { const config = vscode.workspace.getConfiguration('cortex-debug'); const fName = config.get(CortexDebugKeys.SERVER_LOG_FILE_NAME, ''); - this.gdbServerConsole.createLogFile(fName); + if (this.gdbServerConsole) { + this.gdbServerConsole.createLogFile(fName); + } } if (e.affectsConfiguration(`cortex-debug.${CortexDebugKeys.DEV_DEBUG_MODE}`)) { const config = vscode.workspace.getConfiguration('cortex-debug'); @@ -208,7 +208,7 @@ export class CortexDebugExtension { } } - private getSVDFile(device: string): string { + private getSVDFile(device: string): string | null { const entry = this.SVDDirectory.find((de) => de.expression.test(device)); return entry ? entry.path : null; } @@ -221,12 +221,11 @@ export class CortexDebugExtension { this.SVDDirectory.push({ expression: expression, path: path }); } - private activeEditorChanged(editor: vscode.TextEditor) { - const session = CortexDebugExtension.getActiveCDSession(); - if (editor !== undefined && session) { - const uri = editor.document.uri; - if (uri.scheme === 'file') { - // vscode.debug.activeDebugSession.customRequest('set-active-editor', { path: uri.path }); + private activeEditorChanged(editor: vscode.TextEditor | undefined) { + if (editor && editor.document.uri.scheme === 'file') { + const session = CortexDebugExtension.getActiveCDSession(); + if (session) { + // session.customRequest('set-active-editor', { path: editor.document.uri.fsPath }); } } } @@ -237,7 +236,7 @@ export class CortexDebugExtension { const installExt = 'Install MemoryView Extension'; vscode.window.showErrorMessage( `Unable to execute ${cmd}. Perhaps the MemoryView extension is not installed. ` - + 'Please install extension and try again. A restart may be needed', undefined, + + 'Please install extension and try again. A restart may be needed', {}, { title: installExt }, @@ -282,10 +281,10 @@ export class CortexDebugExtension { prompt: 'Memory Address' }).then( (address) => { + if (!address) { return; } address = address.trim(); if (!validateAddress(address)) { vscode.window.showErrorMessage('Invalid memory address entered'); - Reporting.sendEvent('Examine Memory', 'Invalid Address', address); return; } @@ -295,14 +294,13 @@ export class CortexDebugExtension { prompt: 'Length' }).then( (length) => { + if (!length) { return; } length = length.trim(); if (!validateValue(length)) { vscode.window.showErrorMessage('Invalid length entered'); - Reporting.sendEvent('Examine Memory', 'Invalid Length', length); return; } - Reporting.sendEvent('Examine Memory', 'Valid', `${address}-${length}`); const timestamp = new Date().getTime(); const addrEnc = encodeURIComponent(`${address}`); const uri = vscode.Uri.parse( @@ -314,10 +312,8 @@ export class CortexDebugExtension { .then((doc) => { this.memoryProvider.Register(doc); vscode.window.showTextDocument(doc, { viewColumn: 2, preview: false }); - Reporting.sendEvent('Examine Memory', 'Used'); }, (error) => { vscode.window.showErrorMessage(`Failed to examine memory: ${error}`); - Reporting.sendEvent('Examine Memory', 'Error', error.toString()); }); }, (error) => { @@ -344,7 +340,7 @@ export class CortexDebugExtension { for (const mapping of configurationTargetMapping) { const [inspectKeyPrefix, mappingTarget] = mapping; const inspectKey = inspectKeyPrefix + inspectKeySuffix; - if (info[inspectKey] !== undefined) + if (info && (info as any)[inspectKey] !== undefined) return [mappingTarget, inspectKeySuffix == 'LanguageValue']; } } @@ -408,8 +404,6 @@ export class CortexDebugExtension { svdfile = this.getSVDFile(args.device); } - Reporting.beginSession(session.id, args as ConfigurationArguments); - if (newSession.swoSource) { this.initializeSWO(session, args); } @@ -427,8 +421,6 @@ export class CortexDebugExtension { if (session.type !== 'cortex-debug') { return; } const mySession = CDebugSession.FindSession(session); try { - Reporting.endSession(session.id); - this.liveWatchProvider?.debugSessionTerminated(session); if (mySession?.swo) { mySession.swo.debugSessionTerminated(); @@ -441,12 +433,12 @@ export class CortexDebugExtension { } if (mySession?.rttPortMap) { for (const ch of Object.keys(mySession.rttPortMap)) { - mySession.rttPortMap[ch].dispose(); + mySession.rttPortMap[parseInt(ch)].dispose(); } mySession.rttPortMap = {}; } } catch (e) { - vscode.window.showInformationMessage(`Debug session did not terminate cleanly ${e}\n${e ? e.stackstrace : ''}. Please report this problem`); + vscode.window.showInformationMessage(`Debug session did not terminate cleanly ${e}\n${e ? (e as Error).stack : ''}. Please report this problem`); } finally { CDebugSession.RemoveSession(session); } @@ -570,14 +562,14 @@ export class CortexDebugExtension { if (launch && launch.detached && (count > 0)) { try { // tslint:disable-next-line: one-variable-per-declaration - let res: (value: vscode.DebugSessionCustomEvent) => void; - let rej: (reason?: any) => void; + let res!: (value: vscode.DebugSessionCustomEvent) => void; + let rej!: (reason?: any) => void; const prevStartedPromise = new Promise((resolve, reject) => { res = resolve; rej = reject; }); this.serverStartedEvent = new ServerStartedPromise(launch.name, prevStartedPromise, res, rej); - let to = setTimeout(() => { + let to: any = setTimeout(() => { if (this.serverStartedEvent) { this.serverStartedEvent.reject(new Error(`Timeout starting chained session: ${launch.name}`)); this.serverStartedEvent = undefined; @@ -599,7 +591,7 @@ export class CortexDebugExtension { private endChainedConfigs(e: vscode.DebugSessionCustomEvent) { const mySession = CDebugSession.FindSession(e.session); - if (mySession && mySession.hasChildren) { + if (mySession && mySession.hasChildren()) { // Note that we may not be the root, but we have children. Also we do not modify the tree while iterating it const deathList: CDebugSession[] = []; const orphanList: CDebugSession[] = []; @@ -615,11 +607,12 @@ export class CortexDebugExtension { // According to current scheme, there should not be any orphaned children. while (orphanList.length > 0) { const s = orphanList.pop(); - s.moveToRoot(); // Or should we move to our parent. TODO: fix for when we are going to have grand children + s?.moveToRoot(); // Or should we move to our parent. TODO: fix for when we are going to have grand children } while (deathList.length > 0) { const s = deathList.pop(); + if (!s) { continue; } // We cannot actually use the following API. We have to do this ourselves. Probably because we own // the lifetime management. // vscode.debug.stopDebugging(s.session); @@ -637,7 +630,7 @@ export class CortexDebugExtension { private resetOrResartChained(e: vscode.DebugSessionCustomEvent, type: 'reset' | 'restart') { const mySession = CDebugSession.FindSession(e.session); - if (mySession && mySession.hasChildren) { + if (mySession && mySession.hasChildren()) { mySession.broadcastDFS((s) => { if (s === mySession) { return; } if (s.config.pvtMyConfigFromParent.lifecycleManagedByParent) { @@ -649,7 +642,7 @@ export class CortexDebugExtension { } } - private getWsFolder(folder: string, def: vscode.WorkspaceFolder, childName): vscode.WorkspaceFolder { + private getWsFolder(folder: string, def: vscode.WorkspaceFolder | undefined, childName: string): vscode.WorkspaceFolder | undefined { if (folder) { const orig = folder; const normalize = (fsPath: string) => { @@ -662,62 +655,68 @@ export class CortexDebugExtension { }; // Folder is always a full path name folder = normalize(folder); - for (const f of vscode.workspace.workspaceFolders) { - const tmp = normalize(f.uri.fsPath); - if ((f.uri.fsPath === folder) || (f.name === folder) || (tmp === folder)) { - return f; + if (vscode.workspace.workspaceFolders) { + for (const f of vscode.workspace.workspaceFolders) { + const tmp = normalize(f.uri.fsPath); + if ((f.uri.fsPath === folder) || (f.name === folder) || (tmp === folder)) { + return f; + } } } vscode.window.showInformationMessage( `Chained configuration for '${childName}' specified folder is '${orig}' normalized path is '${folder}'` - + ' did not match any workspace folders. Using parents folder.'); + + ` but that folder is not open in the workspace. Using '${def ? def.name : 'root'}'`); + } else { + // No folder specified. Use the default one (parent's folder) + return def; } return def; } - private getCurrentArgs(session: vscode.DebugSession): ConfigurationArguments { - if (!session) { - session = vscode.debug.activeDebugSession; - if (!session || (session.type !== 'cortex-debug')) { - return undefined; - } + private getCurrentArgs(session: vscode.DebugSession): ConfigurationArguments | undefined { + const sess = session || vscode.debug.activeDebugSession; + if (!sess || (sess.type !== 'cortex-debug')) { + return undefined; } - const ourSession = CDebugSession.FindSession(session); + const ourSession = CDebugSession.FindSession(sess); if (ourSession) { return ourSession.config as ConfigurationArguments; } - return session.configuration as unknown as ConfigurationArguments; + return sess.configuration as unknown as ConfigurationArguments; } // Assuming 'session' valid and it a cortex-debug session private isDebugging(session: vscode.DebugSession) { - const { noDebug } = this.getCurrentArgs(session); - return (noDebug !== true); // If it is exactly equal to 'true' we are doing a 'run without debugging' + const args = this.getCurrentArgs(session); + return args && (args.noDebug !== true); // If it is exactly equal to 'true' we are doing a 'run without debugging' } private receivedStopEvent(e: vscode.DebugSessionCustomEvent) { const mySession = CDebugSession.FindSession(e.session); - mySession.status = 'stopped'; - this.liveWatchProvider?.debugStopped(e.session); - vscode.workspace.textDocuments.filter((td) => td.fileName.endsWith('.cdmem')).forEach((doc) => { - if (!doc.isClosed) { - this.memoryProvider.update(doc); - } - }); - if (mySession.swo) { mySession.swo.debugStopped(); } - if (mySession.rtt) { mySession.rtt.debugStopped(); } + if (mySession) { + mySession.status = 'stopped'; + this.liveWatchProvider?.debugStopped(e.session); + vscode.workspace.textDocuments.filter((td) => td.fileName.endsWith('.cdmem')).forEach((doc) => { + if (!doc.isClosed) { + this.memoryProvider.update(doc); + } + }); + if (mySession.swo) { mySession.swo.debugStopped(); } + if (mySession.rtt) { mySession.rtt.debugStopped(); } + } } private receivedContinuedEvent(e: vscode.DebugSessionCustomEvent) { const mySession = CDebugSession.FindSession(e.session); - mySession.status = 'running'; - this.liveWatchProvider?.debugContinued(e.session); - if (mySession.swo) { mySession.swo.debugContinued(); } - if (mySession.rtt) { mySession.rtt.debugContinued(); } + if (mySession) { + mySession.status = 'running'; + this.liveWatchProvider?.debugContinued(e.session); + if (mySession.swo) { mySession.swo.debugContinued(); } + if (mySession.rtt) { mySession.rtt.debugContinued(); } + } } - private receivedEvent(e) { - Reporting.sendEvent(e.body.category, e.body.action, e.body.label, e.body.parameters); + private receivedEvent(e: any) { } private receivedSWOConfigureEvent(e: vscode.DebugSessionCustomEvent) { @@ -737,20 +736,15 @@ export class CortexDebugExtension { }, (e) => { vscode.window.showErrorMessage(`Could not open SWO TCP port ${e.body.port} ${e} after ${src.nTries} tries`); }); - Reporting.sendEvent('SWO', 'Source', 'Socket'); return; } else if (e.body.type === 'fifo') { mySession.swoSource = new FifoSWOSource(e.body.path); - Reporting.sendEvent('SWO', 'Source', 'FIFO'); } else if (e.body.type === 'file') { mySession.swoSource = new FileSWOSource(e.body.path); - Reporting.sendEvent('SWO', 'Source', 'File'); } else if (e.body.type === 'serial') { mySession.swoSource = new SerialSWOSource(e.body.device, e.body.baudRate); - Reporting.sendEvent('SWO', 'Source', 'Serial'); } else if (e.body.type === 'usb') { mySession.swoSource = new UsbSWOSource(e.body.device, e.body.port); - Reporting.sendEvent('SWO', 'Source', 'USB'); } this.initializeSWO(e.session, e.body.args); @@ -760,10 +754,8 @@ export class CortexDebugExtension { if (e.body.type === 'socket') { const decoder: RTTCommonDecoderOpts = e.body.decoder; if ((decoder.type === 'console') || (decoder.type === 'binary')) { - Reporting.sendEvent('RTT', 'Source', 'Socket: Console'); this.rttCreateTerninal(e, decoder as RTTConsoleDecoderOpts); } else { - Reporting.sendEvent('RTT', 'Source', `Socket: ${decoder.type}`); if (!decoder.ports) { this.createRTTSource(e, decoder.tcpPort, decoder.port); } else { @@ -841,8 +833,9 @@ export class CortexDebugExtension { this.rttTerminals = this.rttTerminals.filter((t) => t.terminal !== terminal); } - private initializeSWO(session: vscode.DebugSession, args) { + private initializeSWO(session: vscode.DebugSession, args: any) { const mySession = CDebugSession.FindSession(session); + if (!mySession) { return; } if (!mySession.swoSource) { vscode.window.showErrorMessage('Tried to initialize SWO Decoding without a SWO data source'); return; @@ -853,8 +846,9 @@ export class CortexDebugExtension { } } - private initializeRTT(session: vscode.DebugSession, args) { + private initializeRTT(session: vscode.DebugSession, args: any) { const mySession = CDebugSession.FindSession(session); + if (!mySession) { return; } if (!mySession.rtt) { mySession.rtt = new RTTCore(mySession.rttPortMap, args, this.context.extensionPath); } @@ -866,7 +860,7 @@ export class CortexDebugExtension { ignoreFocusOut: true, prompt: 'Enter Live Watch Expression' }).then((v) => { - if (v) { + if (v && vscode.debug.activeDebugSession) { this.liveWatchProvider.addWatchExpr(v, vscode.debug.activeDebugSession); } }); @@ -888,7 +882,7 @@ export class CortexDebugExtension { mySession.session.customRequest('is-global-or-static', { varRef: varRef }).then((result) => { if (!result.success) { vscode.window.showErrorMessage(`Cannot add ${expr} to Live Watch. Must be a global or static variable`); - } else { + } else if (vscode.debug.activeDebugSession) { this.liveWatchProvider.addWatchExpr(expr, vscode.debug.activeDebugSession); } }, (e) => { @@ -923,4 +917,4 @@ export function activate(context: vscode.ExtensionContext) { return new CortexDebugExtension(context); } -export function deactivate() {} +export function deactivate() { } diff --git a/src/frontend/swo/sources/fifo.ts b/src/frontend/swo/sources/fifo.ts index c21309aa..3de58694 100644 --- a/src/frontend/swo/sources/fifo.ts +++ b/src/frontend/swo/sources/fifo.ts @@ -12,7 +12,7 @@ export class FifoSWOSource extends EventEmitter implements SWORTTSource { this.stream.on('data', (buffer) => { this.emit('data', buffer); }); - this.stream.on('close', (buffer) => { + this.stream.on('close', () => { this.emit('disconnected'); }); this.connected = true; diff --git a/src/gdb.ts b/src/gdb.ts index 6b61b84e..5a06b57d 100755 --- a/src/gdb.ts +++ b/src/gdb.ts @@ -18,7 +18,7 @@ import { createPortName, GenericCustomEvent, quoteShellCmdLine, toStringDecHexOctBin, ADAPTER_DEBUG_MODE, defSymbolFile, CTIAction, getPathRelative, SWOConfigureEvent, RTTCommonDecoderOpts } from './common'; -import { GDBServer, ServerConsoleLog } from './backend/server'; +import { GDBServer, getServerLogFilePath, ServerConsoleLog } from './backend/server'; import { MINode } from './backend/mi_parse'; import { expandValue, isExpandable } from './backend/gdb_expansion'; import { GdbDisassembler } from './backend/disasm'; @@ -44,7 +44,6 @@ import { SymbolTable } from './backend/symbols'; import { SymbolInformation, SymbolScope } from './symbols'; import { TcpPortScanner } from './tcpportscanner'; import { LiveWatchMonitor } from './live-watch-monitor'; -import { HandlerResult } from 'vscode-jsonrpc'; // returns [threadId, frameId] // We use 3 nibbles for frameId (max of 4K) and 2 nibbles for ThreadId (max of 256). @@ -58,18 +57,68 @@ export function encodeReference(threadId: number, frameId: number): number { return ((threadId << 12) | (frameId & 0xFFF)) & RegionSize; } +export type HWBreakpointType = 'src' | 'data' | 'instr' | 'function'; +export class HWBreakpointMgr { + private breakpointSet: Set = new Set(); + constructor( + private readonly maxHwBreakpoints: number = 0, + private readonly forceHwBreakpoints: boolean = false) { + } + + isHWForced(): boolean { + return this.forceHwBreakpoints; + } + + limitReached(): boolean { + if (this.maxHwBreakpoints <= 0) { + return false; + } + const count = this.breakpointSet.size; + return count >= this.maxHwBreakpoints; + } + + getLimit(): number { + return this.maxHwBreakpoints; + } + + addBreakpoint(breakpointId: number): void { + this.breakpointSet.add(breakpointId); + } + + removeBreakpoints(breakpointId: number | number[]): void { + if (typeof breakpointId === 'number') { + this.breakpointSet.delete(breakpointId); + } else { + for (const id of breakpointId) { + this.breakpointSet.delete(id); + } + } + } + + clearAllBreakpoints(): void { + this.breakpointSet.clear(); + } + + getGdbMiArg(bptType: HWBreakpointType): string { + if (this.forceHwBreakpoints) { + return (bptType === 'data') ? '' : '-h'; + } + return ''; + } +} + enum HandleRegions { - /* eslint-disable @stylistic/no-multi-spaces */ - GLOBAL_HANDLE_ID = 0xFFFFFFFF, - STACK_HANDLES_START = encodeReference(0x01, 0x000), - STACK_HANDLES_FINISH = encodeReference(0xFF, 0xFFF), - STATIC_HANDLES_START = STACK_HANDLES_FINISH + 1, + + GLOBAL_HANDLE_ID = 0xFFFFFFFF, + STACK_HANDLES_START = encodeReference(0x01, 0x000), + STACK_HANDLES_FINISH = encodeReference(0xFF, 0xFFF), + STATIC_HANDLES_START = STACK_HANDLES_FINISH + 1, STATIC_HANDLES_FINISH = STATIC_HANDLES_START + RegionSize, - REG_HANDLE_START = STATIC_HANDLES_FINISH + 1, - REG_HANDLE_FINISH = REG_HANDLE_START + RegionSize, - VAR_HANDLES_START = REG_HANDLE_FINISH + 1, + REG_HANDLE_START = STATIC_HANDLES_FINISH + 1, + REG_HANDLE_FINISH = REG_HANDLE_START + RegionSize, + VAR_HANDLES_START = REG_HANDLE_FINISH + 1, rest = 0xFFFFFFFF - VAR_HANDLES_START - /* eslint-enable */ + } const SERVER_TYPE_MAP = { @@ -93,7 +142,7 @@ enum SessionMode { const VarNotFoundMsg = 'Variable object not found'; export class ExtendedVariable { - constructor(public name, public options) { + constructor(public name: any, public options: any) { } } @@ -110,12 +159,12 @@ function COMMAND_MAP(c: string): string { let dbgResumeStopCounter = 0; class CustomStoppedEvent extends Event implements DebugProtocol.Event { - public readonly body: { + public readonly body!: { reason: string; threadID: number; }; - public readonly event: string; + public readonly event!: string; constructor(reason: string, threadID: number) { super('custom-stop', { reason: reason, threadID: threadID }); @@ -125,7 +174,7 @@ class CustomStoppedEvent extends Event implements DebugProtocol.Event { } class PendingContinue { - constructor(public shouldContinue: boolean, public haveMore?: () => boolean) {} + constructor(public shouldContinue: boolean, public haveMore?: () => boolean) { } } class VSCodeRequest { @@ -138,7 +187,7 @@ class VSCodeRequest { public resolve: any, public reject: any, public extra: any[] - ) {} + ) { } } /* @@ -156,11 +205,11 @@ export class RequestQueue { private queue: VSCodeRequest[] = []; private queueBusy = false; public pendedContinue = new PendingContinue(false, this.haveMore.bind(this)); - constructor(private alwaysResolve = true) {} + constructor(private alwaysResolve = true) { } public add( // For the varargs, extra can be any set of args but the first arg if used, is of type PendContinue functor: (response: RespType, args: ArgsType, ...extra: any[]) => Promise, - response: RespType, args: ArgsType, ...extra): Promise { + response: RespType, args: ArgsType, ...extra: any[]): Promise { return new Promise(async (resolve, reject) => { this.queue.push(new VSCodeRequest(functor, response, args, resolve, reject, extra)); while (!this.queueBusy && (this.queue.length > 0)) { @@ -188,13 +237,6 @@ export class RequestQueue { } class CustomContinuedEvent extends Event implements DebugProtocol.Event { - public readonly body: { - threadID: number; - allThreads: boolean; - }; - - public readonly event: string; - constructor(threadID: number, allThreads: boolean = true) { super('custom-continued', { threadID: threadID, allThreads: allThreads }); // console.log(`${dbgResumeStopCounter} **** Running thread:${threadID}`); @@ -204,29 +246,32 @@ class CustomContinuedEvent extends Event implements DebugProtocol.Event { const traceThreads = false; export class GDBDebugSession extends LoggingDebugSession { - private server: GDBServer; - public args: ConfigurationArguments; - private ports: { [name: string]: number }; - private serverController: GDBServerController; - public symbolTable: SymbolTable; + private server!: GDBServer; + public args!: ConfigurationArguments; + private ports!: { [name: string]: number }; + private serverController!: GDBServerController; + public symbolTable!: SymbolTable; private usingParentServer = false; private debugLogFd = -1; protected variableHandles = new Handles(HandleRegions.VAR_HANDLES_START); protected variableHandlesReverse = new Map(); - protected quit: boolean; - protected attached: boolean; - protected started: boolean; - protected debugReady: boolean; - public miDebugger: MI2; + protected quit!: boolean; + protected attached!: boolean; + protected started!: boolean; + protected debugReady!: boolean; + public miDebugger!: MI2; public miLiveGdb: LiveWatchMonitor | undefined; - protected activeEditorPath: string = null; - protected disassember: GdbDisassembler; + protected activeEditorPath: string | null = null; + protected disassember!: GdbDisassembler; // currentThreadId is the currently selected thread or where execution has stopped. It not very // meaningful since the current thread id in gdb can change in many ways (when you use a --thread // option on certain commands) protected currentThreadId: number = 0; protected activeThreadIds = new Set(); // Used for consistency check + protected hwBreakpointMgr!: HWBreakpointMgr; + protected hwWatchpointMgr!: HWBreakpointMgr; + protected configDone!: boolean; /** * If we are requested a major switch like restart/disconnect/detach we may have to interrupt the @@ -248,7 +293,7 @@ export class GDBDebugSession extends LoggingDebugSession { // can be made stricter and we can remove this variable public stoppedThreadId: number = 0; - protected functionBreakpoints = []; + protected functionBreakpoints: number[] = []; protected breakpointMap: Map = new Map(); protected breakpointById: Map = new Map(); protected instrBreakpointMap: Map = new Map(); @@ -256,7 +301,6 @@ export class GDBDebugSession extends LoggingDebugSession { protected fileExistsCache: Map = new Map(); protected onInternalEvents: EventEmitter = new EventEmitter(); - protected configDone: boolean; protected suppressRadixMsgs = false; @@ -276,7 +320,7 @@ export class GDBDebugSession extends LoggingDebugSession { TcpPortScanner.PortAllocated.on('allocated', this.tcpPortAllocatedListner); } - private tcpPortsAllocated(ports) { + private tcpPortsAllocated(ports: any) { this.sendEvent(new GenericCustomEvent('ports-allocated', ports)); } @@ -294,6 +338,7 @@ export class GDBDebugSession extends LoggingDebugSession { this.miDebugger.on('quit', this.quitEvent.bind(this)); this.miDebugger.on('exited-normally', this.quitEvent.bind(this)); this.miDebugger.on('stopped', this.stopEvent.bind(this)); + this.miDebugger.on('breakpoint-deleted', this.handleBreakpointDeleted.bind(this)); this.miDebugger.on('msg', this.handleMsg.bind(this)); this.miDebugger.on('breakpoint', this.handleBreakpoint.bind(this)); this.miDebugger.on('watchpoint', this.handleWatchpoint.bind(this, 'hit')); @@ -310,6 +355,7 @@ export class GDBDebugSession extends LoggingDebugSession { } protected initializeRequest(response: DebugProtocol.InitializeResponse, args: DebugProtocol.InitializeRequestArguments): void { + response.body = response.body || {}; response.body.supportsHitConditionalBreakpoints = true; response.body.supportsConfigurationDoneRequest = true; response.body.supportsConditionalBreakpoints = true; @@ -333,6 +379,20 @@ export class GDBDebugSession extends LoggingDebugSession { response.body.supportsInstructionBreakpoints = true; response.body.supportsReadMemoryRequest = true; response.body.supportsWriteMemoryRequest = true; + + const bptAppliesTo: DebugProtocol.BreakpointModeApplicability[] = ['source', /* 'exception' , */ 'data', 'instruction']; + response.body.breakpointModes = [ + { + mode: 'default', + label: 'Let GDB decide which breakpoint method (HW or SW) to chose', + appliesTo: [] + }, + { + mode: 'hardware', + label: 'Request GDB to set a hardware breakpoint', + appliesTo: [] + } + ]; this.sendResponse(response); } @@ -352,11 +412,16 @@ export class GDBDebugSession extends LoggingDebugSession { }); args.showDevDebugOutput = ADAPTER_DEBUG_MODE.RAW; } - this.args = this.normalizeArguments(args); + this.handleMsg('stdout', `Cortex-Debug: VSCode debugger extension version ${args.pvtVersion} git(${__COMMIT_HASH__}). ` + 'Usage info: https://github.com/Marus/cortex-debug#usage'); + if (this.args.showDevDebugOutput) { + this.handleMsg('stderr', `INFO: A log of gdb-servers, gdb, debug adapter start/stop/pid info can be found in '${getServerLogFilePath()}'.\n`); + } + + this.setHWBreakpointInfo(); if (this.args.showDevDebugOutput) { this.handleMsg('log', '"configuration": ' + JSON.stringify(args, undefined, 4) + '\n'); @@ -388,6 +453,23 @@ export class GDBDebugSession extends LoggingDebugSession { } } + private setHWBreakpointInfo() { + let forceHW = this.args.hardwareBreakpoints?.require || false; + let limit = this.args.hardwareBreakpoints?.limit || 0; + this.hwBreakpointMgr = new HWBreakpointMgr(limit, forceHW); + if (forceHW) { + const limitMsg = (limit > 0) ? `Limit of ${limit} breakpoints will be enforced by cortex-debug` : 'GDB enforces any limits you may have configured'; + this.handleMsg('stderr', `INFO: All breakpoints will be requested as hardware breakpoints. ${limitMsg}\n`); + } + forceHW = this.args.hardwareWatchpoints?.require || false; + limit = this.args.hardwareWatchpoints?.limit || 0; + this.hwWatchpointMgr = new HWBreakpointMgr(limit, forceHW); + if (forceHW && (limit > 0)) { + const limitMsg = `Limit of ${limit} watchpoints will be enforced by cortex-debug`; + this.handleMsg('stderr', `INFO: All watchpoints are done by GDB as hardware watchpoints (default). ${limitMsg}\n`); + } + } + public isDebugLoggingAvailable() { return (this.debugLogFd >= 0); } @@ -405,7 +487,7 @@ export class GDBDebugSession extends LoggingDebugSession { } } - private dbgSymbolTable: SymbolTable = null; + private dbgSymbolTable: SymbolTable | null = null; private loadSymbols(): Promise { return new Promise((resolve) => { // this.dbgSymbolStuff(args, '/Users/hdm/Downloads/XXX-01.elf', 'main', null); @@ -520,7 +602,7 @@ export class GDBDebugSession extends LoggingDebugSession { return args; } - private getTCPPorts(useParent): Thenable { + private getTCPPorts(useParent: boolean): Thenable { return new Promise((resolve, reject) => { const startPort = 50000; if (useParent) { @@ -534,9 +616,13 @@ export class GDBDebugSession extends LoggingDebugSession { const totalPortsNeeded = this.calculatePortsNeeded(); const portFinderOpts = { min: startPort, max: 52000, retrieve: totalPortsNeeded, consecutive: true }; TcpPortScanner.findFreePorts(portFinderOpts, GDBServer.LOCALHOST).then((ports) => { - this.createPortsMap(ports); - this.serverController.setPorts(this.ports); - resolve(); + if (ports) { + this.createPortsMap(ports); + this.serverController.setPorts(this.ports); + resolve(); + } else { + reject(new Error('Could not find free ports')); + } }, (e) => { reject(e); }); @@ -548,7 +634,7 @@ export class GDBDebugSession extends LoggingDebugSession { const doResolve = () => { if (resolve) { resolve(); - resolve = null; + resolve = undefined as any; } }; const haveSymFiles = this.args.symbolFiles && (this.args.symbolFiles.length > 0); @@ -557,7 +643,7 @@ export class GDBDebugSession extends LoggingDebugSession { return doResolve(); } - const ControllerClass = SERVER_TYPE_MAP[this.args.servertype]; + const ControllerClass = (SERVER_TYPE_MAP as any)[this.args.servertype]; this.serverController = new ControllerClass(); this.serverController.setArguments(this.args); this.serverController.on('event', this.serverControllerEvent.bind(this)); @@ -578,13 +664,23 @@ export class GDBDebugSession extends LoggingDebugSession { return doResolve(); } const symbolsPromise = this.loadSymbols(); // This is totally async and in most cases, done while gdb is starting - let gdbPromiseAsyncErr; + let gdbPromiseAsyncErr: any; const gdbPromise = this.startGdb(response); gdbPromise.catch((err) => { gdbPromiseAsyncErr = err; }); this.usingParentServer = this.args.pvtMyConfigFromParent && !this.args.pvtMyConfigFromParent.detached; this.getTCPPorts(this.usingParentServer).then(async () => { + function clearTimers() { + if (timeout) { + clearTimeout(timeout); + timeout = null; + } + if (feedbackTimer) { + clearInterval(feedbackTimer); + feedbackTimer = null; + } + } await this.serverController.allocateRTTPorts(); // Must be done before serverArguments() const executable = this.usingParentServer ? null : this.serverController.serverExecutable(); const args = this.usingParentServer ? [] : this.serverController.serverArguments(); @@ -630,7 +726,7 @@ export class GDBDebugSession extends LoggingDebugSession { doResolve(); }); - let timeout = setTimeout(() => { + let timeout: any = setTimeout(() => { this.server.exit(); this.sendEvent(new TelemetryEvent( 'Error', @@ -641,12 +737,16 @@ export class GDBDebugSession extends LoggingDebugSession { doResolve(); }, GDBServer.SERVER_TIMEOUT); + let elapsed = 0; + let feedbackTimer: any = setInterval(() => { + const svrName = this.serverController.name || this.args.servertype; + elapsed += 5; + this.handleMsg('stdout', `Still waiting for ${svrName} GDB Server to be ready, ${elapsed} seconds...looking for '${initMatch}'\n`); + }, 5 * 1000); + this.serverController.serverLaunchStarted(); this.server.init().then(async (started) => { - if (timeout) { - clearTimeout(timeout); - timeout = null; - } + clearTimers(); const commands = []; try { // This is where 4 things meet and they must all finish (in any order) before we can proceed @@ -655,8 +755,9 @@ export class GDBDebugSession extends LoggingDebugSession { // 3. Found free TCP ports and launched gdb-server // 4. Finished reading symbols from objdump and nm const showTimes = this.args.showDevDebugOutput && this.args.showDevDebugTimestamps; - if (gdbPromiseAsyncErr) + if (gdbPromiseAsyncErr) { throw gdbPromiseAsyncErr; + } await gdbPromise; if (showTimes) { this.handleMsg('log', 'Debug Time: GDB Ready...\n'); } @@ -697,7 +798,8 @@ export class GDBDebugSession extends LoggingDebugSession { if (err instanceof MIError) { msg = `Failed to initialize GDB: ${err.message}\n\nFailed on command:\n${err.source}`; } else { - msg = 'Failed to generate gdb commands: ' + err.toString() + '\n' + err.stack.toString(); + const e = err as Error; + msg = 'Failed to generate gdb commands: ' + e.toString() + '\n' + (e.stack || '').toString(); } this.sendEvent(new TelemetryEvent('Error', 'Launching GDB', msg)); this.launchErrorResponse(response, 104, msg); @@ -717,7 +819,10 @@ export class GDBDebugSession extends LoggingDebugSession { const mode = attach ? SessionMode.ATTACH : SessionMode.LAUNCH; this.started = true; this.serverController.debuggerLaunchCompleted(); - + if (!this.args.noDebug && (mode === SessionMode.LAUNCH) && this.args.runToEntryPoint) { + // Claim the first breakpoint to be the runToEntryPoint, don't wait on it though + this.setRunToEntryPoint(); + } this.sendEvent(new InitializedEvent()); // This is when we tell that the debugger has really started // After the above, VSCode will set various kinds of breakpoints, watchpoints, etc. When all those things // happen, it will finally send a configDone request and now everything should be stable @@ -759,10 +864,7 @@ export class GDBDebugSession extends LoggingDebugSession { } }); }, (error) => { - if (timeout) { - clearTimeout(timeout); - timeout = null; - } + clearTimers(); this.sendEvent(new TelemetryEvent( 'Error', 'Launching Server', @@ -799,12 +901,12 @@ export class GDBDebugSession extends LoggingDebugSession { // the server scripts (OpenOCD, JLink, etc.) live and changing cwd for all servers will break for other servers // that are not so quirky. // - private getServerCwd(serverExe: string) { + private getServerCwd(serverExe: string | null) { let serverCwd = this.args.cwd || process.cwd(); if (this.args.serverCwd) { serverCwd = this.args.serverCwd; } else if (this.args.servertype === 'stlink') { - serverCwd = path.dirname(serverExe) || '.'; + serverCwd = serverExe ? path.dirname(serverExe) : '.'; if (serverCwd !== '.') { this.handleMsg('log', `Setting GDB-Server CWD: ${serverCwd}\n`); } @@ -865,23 +967,33 @@ export class GDBDebugSession extends LoggingDebugSession { this.sendEvent(new GenericCustomEvent('popup', { type: 'error', message: msg })); } if (!this.args.noDebug && (mode !== SessionMode.ATTACH) && this.args.runToEntryPoint) { - this.miDebugger.sendCommand(`break-insert -t --function ${this.args.runToEntryPoint}`).then(() => { - this.miDebugger.once('generic-stopped', () => { - resolve(); - }); + const bptResult = await this.setRunToEntryPoint(); + this.runToEntryPointPromise = null; + if (!(bptResult instanceof MIError)) { + // There two main reasons for failure here: + // 1. Function does not exist + // 2. Function exists but no breakpoints can be set (e.g. out of hardware breakpoints) + resolve(); this.startCompleteForReset(mode, false); this.sendContinue(); - }, (err) => { + } else { // If failed to set the temporary breakpoint (e.g. function does not exist) // complete the launch as if the breakpoint had not being defined - this.handleMsg('log', `launch.json: Unable to set temporary breakpoint "runToEntryPoint":"${this.args.runToEntryPoint}".` - + 'Function may not exist or out of breakpoints? ' + err.toString() + '\n'); + const msg = `Unable to set temporary breakpoint "runToEntryPoint":"${this.args.runToEntryPoint}". ` + + 'Function may not exist or out of breakpoints?'; + this.handleMsg('log', msg + '\n'); + this.sendEvent(new GenericCustomEvent('popup', { type: 'warning', message: msg })); + if (mode === SessionMode.LAUNCH) { this.args.runToEntryPoint = ''; // Don't try again. It will likely to fail + resolve(); + this.startCompleteForReset(mode, false); + this.sendContinue(); + } else { + this.startComplete(mode); // Call this again to return actual stack trace + resolve(); } - this.startComplete(mode); // Call this again to return actual stack trace - resolve(); - }); + } } else { this.runPostStartSessionCommands(mode).then((didContinue) => { if (!didContinue) { @@ -897,7 +1009,7 @@ export class GDBDebugSession extends LoggingDebugSession { }); } - private getGdbPath(response: DebugProtocol.LaunchResponse): string { + private getGdbPath(response: DebugProtocol.LaunchResponse): string | null { let gdbExePath = os.platform() !== 'win32' ? `${this.args.toolchainPrefix}-gdb` : `${this.args.toolchainPrefix}-gdb.exe`; if (this.args.toolchainPath) { gdbExePath = path.normalize(path.join(this.args.toolchainPath, gdbExePath)); @@ -938,6 +1050,9 @@ export class GDBDebugSession extends LoggingDebugSession { this.miDebugger = new MI2(gdbExePath, gdbargs); this.miDebugger.debugOutput = this.args.showDevDebugOutput; + if (this.args.gdbInterruptMode) { + this.miDebugger.interruptMode = this.args.gdbInterruptMode; + } this.miDebugger.on('launcherror', (err) => { const msg = 'Could not start GDB process, does the program exist in filesystem?\n' + err.toString() + '\n'; this.launchErrorResponse(response, 103, msg); @@ -1001,6 +1116,9 @@ export class GDBDebugSession extends LoggingDebugSession { liveGdb.setupEvents(mi2); const commands = [...this.gdbInitCommands]; mi2.debugOutput = this.args.showDevDebugOutput; + if (this.args.gdbInterruptMode) { + mi2.interruptMode = this.args.gdbInterruptMode; + } commands.push('interpreter-exec console "set stack-cache off"'); commands.push('interpreter-exec console "set remote interrupt-on-connect off"'); if (this.serverController) { @@ -1139,8 +1257,8 @@ export class GDBDebugSession extends LoggingDebugSession { const r: DebugProtocol.EvaluateResponse = { ...response, body: { - result: undefined, - variablesReference: undefined + result: '', + variablesReference: 0 } }; await this.miLiveGdb.evaluateRequest(r, args); @@ -1328,7 +1446,10 @@ export class GDBDebugSession extends LoggingDebugSession { } const buf = Buffer.from(intAry); const b64Data = buf.toString('base64'); - response.body.data = b64Data; + response.body = { + address: args.memoryReference, + data: b64Data + }; this.sendResponse(response); }, (error) => { this.sendErrorResponse(response, 114, `Read memory error: ${error.toString()}`); @@ -1409,9 +1530,9 @@ export class GDBDebugSession extends LoggingDebugSession { this.miDebugger.sendCommand(`data-list-register-values ${fmt}`).then((node) => { if (node.resultRecords.resultClass === 'done') { const rv = node.resultRecords.results[0][1]; - response.body = rv.map((n) => { - const val = {}; - n.forEach((x) => { + response.body = rv.map((n: any[]) => { + const val: { [key: string]: any } = {}; + n.forEach((x: any[]) => { val[x[0]] = x[1]; }); return val; @@ -1463,19 +1584,19 @@ export class GDBDebugSession extends LoggingDebugSession { this.sendResponse(response); }, (error) => { response.body = { error: error }; - this.sendErrorResponse(response, 116, `Unable to read register list: ${error.toString()}`); + this.sendErrorResponse(response, 116, `Unable to read register list: ${(error).toString()}`); this.sendEvent(new TelemetryEvent('Error', 'Reading Register List', '')); }); } private waitForServerExitAndRespond(response: DebugProtocol.DisconnectResponse) { - if (!this.server.isExternal()) { + if (!this.server.isExternal() && this.server.isProcessRunning()) { let nTimes = 60; - let to = setInterval(() => { + let to: NodeJS.Timeout | null = setInterval(() => { if ((nTimes === 0) || this.quit) { // We waited long enough so try to nuke the server and send VSCode a response // This is a really bad situation to be in, but not sure what else to do. - clearInterval(to); + if (to) clearInterval(to); to = null; this.server.exit(); this.serverConsoleLog('disconnectRequest sendResponse 3'); @@ -1493,15 +1614,18 @@ export class GDBDebugSession extends LoggingDebugSession { } }); // Note: If gdb exits first, then we kill the server anyways - } else { + } else if (this.miDebugger.isRunning()) { this.miDebugger.once('quit', () => { this.serverConsoleLog('disconnectRequest sendResponse 1'); this.sendResponse(response); }); + } else { + this.serverConsoleLog('disconnectRequest sendResponse 3'); + this.sendResponse(response); } } - protected disconnectingPromise: Promise = undefined; + protected disconnectingPromise: Promise | undefined; protected async disconnectRequest(response: DebugProtocol.DisconnectResponse, args: DebugProtocol.DisconnectArguments): Promise { TcpPortScanner.PortAllocated.removeListener('allocated', this.tcpPortAllocatedListner); if (this.disconnectingPromise) { @@ -1537,9 +1661,11 @@ export class GDBDebugSession extends LoggingDebugSession { protected async tryDeleteBreakpoints(): Promise { try { await this.miDebugger.sendCommand('break-delete'); + this.hwBreakpointMgr.clearAllBreakpoints(); return true; } catch (e) { this.handleMsg('log', `Could not delete all breakpoints. ${e}\n`); + this.hwBreakpointMgr.clearAllBreakpoints(); return false; } } @@ -1547,6 +1673,9 @@ export class GDBDebugSession extends LoggingDebugSession { protected disconnectRequest2( response: DebugProtocol.DisconnectResponse | DebugProtocol.Response, args: DebugProtocol.DisconnectArguments): Promise { + if (this.args.showDevDebugOutput) { + this.handleMsg('stderr', `Client (vscode?) requested end of debug session: ${JSON.stringify(args)}\n`); + } this.disconnectingPromise = new Promise(async (resolve) => { this.serverConsoleLog('Begin disconnectRequest'); const doDisconnectProcessing = async () => { @@ -1557,6 +1686,16 @@ export class GDBDebugSession extends LoggingDebugSession { await this.tryDeleteBreakpoints(); this.disableSendStoppedEvents = false; this.attached = false; + if (this.args.overridePreEndSessionCommands) { + for (const cmd of this.args.overridePreEndSessionCommands) { + try { + await this.miDebugger.sendCommand(cmd); + } catch (e) { + this.handleMsg('log', 'GDB commands overridePreEndSessionCommands failed ' + (e ? e.toString() : 'Unknown error') + '\n'); + } + } + await new Promise(() => setTimeout(() => { }, 5)); + } this.waitForServerExitAndRespond(response); // Will wait asynchronously until the following actions are done if (args.terminateDebuggee || args.suspendDebuggee) { // There is no such thing as terminate for us. Hopefully, the gdb-server will @@ -1576,7 +1715,7 @@ export class GDBDebugSession extends LoggingDebugSession { // Many ways things can fail. See issue #561 // exec-interrupt can fail because gdb is wedged and does not respond with proper status ever // use a timeout and try to end session anyways. - let to = setTimeout(() => { + let to: NodeJS.Timeout | null = setTimeout(() => { if (to) { to = null; this.handleMsg('log', 'GDB never responded to an interrupt request. Trying to end session anyways\n'); @@ -1591,7 +1730,7 @@ export class GDBDebugSession extends LoggingDebugSession { } }); try { - await this.miDebugger.sendCommand('exec-interrupt'); + await this.miDebugger.interrupt(); } catch (e) { // The timeout will take care of it... this.handleMsg('log', `Could not interrupt program. Trying to end session anyways ${e}\n`); @@ -1675,7 +1814,7 @@ export class GDBDebugSession extends LoggingDebugSession { restartProcessing(); } else { this.miDebugger.once('generic-stopped', restartProcessing); - this.miDebugger.sendCommand('exec-interrupt'); + this.miDebugger.interrupt(); } }); } @@ -1927,6 +2066,12 @@ export class GDBDebugSession extends LoggingDebugSession { this.activeThreadIds.clear(); } + protected handleBreakpointDeleted(info: { bkptId: number }) { + // This event is sent when a breakpoint is deleted in gdb automatically (like a temporary breakpoint) + // It is not called when we delete breakpoints explicitly ising break-delete + this.hwBreakpointMgr.removeBreakpoints(info.bkptId); + } + protected stopEvent(info: MINode, reason: string = 'exception') { if (!this.quit) { this.continuing = false; @@ -2057,6 +2202,42 @@ export class GDBDebugSession extends LoggingDebugSession { } } + protected addBptSyncRunning = false; + protected addBptSyncQueue: { + func: () => Promise; + obj: any; + resolve: (value: any) => void; + }[] = []; + + protected async addBptSync(func: () => Promise, obj: any, isData: boolean = false): Promise { + return new Promise(async (resolve) => { + const mgr = isData ? this.hwWatchpointMgr : this.hwBreakpointMgr; + this.addBptSyncQueue.push({ func: func, obj: obj, resolve: resolve }); + while (this.addBptSyncRunning) { + await new Promise((resolve) => setTimeout(resolve, 0)); + } + this.addBptSyncRunning = true; + while (this.addBptSyncQueue.length > 0) { + const item = this.addBptSyncQueue.shift(); + if (mgr.limitReached()) { + item.resolve(this.reportHwBreakptLimit(obj)); + } else { + try { + const ret = await item.func() as T; + if (ret && !(ret instanceof MIError)) { + const brk = ret as unknown as { number: number }; + mgr.addBreakpoint(brk?.number || -1); + } + item.resolve(ret); + } catch (err) { + item.resolve(err as MIError); + } + } + } + this.addBptSyncRunning = false; + }); + } + // These should really by multiple pairs that are unique so you cannot mix up // the response and args private allBreakPointsQ = new RequestQueue< @@ -2069,6 +2250,23 @@ export class GDBDebugSession extends LoggingDebugSession { DebugProtocol.SetInstructionBreakpointsArguments | DebugProtocol.SetDataBreakpointsArguments>(); + protected runToEntryPointPromise: Promise | null = null; + protected setRunToEntryPoint(): Promise { + if (!this.runToEntryPointPromise) { + const brk: OurSourceBreakpoint = { + isFunction: true, + isTemporary: true, + raw: this.args.runToEntryPoint, + hwOpt: this.hwBreakpointMgr.getGdbMiArg('function'), + line: 0 + }; + this.runToEntryPointPromise = this.addBptSync(() => { + return this.miDebugger.addBreakPoint(brk); + }, brk); + } + return this.runToEntryPointPromise; + } + protected setFunctionBreakPointsRequest( r: DebugProtocol.SetFunctionBreakpointsResponse, a: DebugProtocol.SetFunctionBreakpointsArguments): Promise { @@ -2080,17 +2278,23 @@ export class GDBDebugSession extends LoggingDebugSession { const createBreakpoints = async () => { try { await this.miDebugger.removeBreakpoints(this.functionBreakpoints); + this.hwBreakpointMgr.removeBreakpoints(this.functionBreakpoints); this.functionBreakpoints = []; const all = new Array>(); + const hwOpt = this.hwBreakpointMgr.getGdbMiArg('function'); args.breakpoints.forEach((brk) => { const arg: OurSourceBreakpoint = { ...brk, raw: brk.name, + isFunction: true, + hwOpt: hwOpt, file: undefined, - line: undefined + line: 0 }; - all.push(this.miDebugger.addBreakPoint(arg).catch((err: MIError) => err)); + all.push(this.addBptSync(() => { + return this.miDebugger.addBreakPoint(arg); + }, arg)); }); const breakpoints = await Promise.all(all); @@ -2107,7 +2311,9 @@ export class GDBDebugSession extends LoggingDebugSession { }; } - this.functionBreakpoints.push(brkp.number); + if (brkp.number !== undefined) { + this.functionBreakpoints.push(brkp.number); + } return { source: { @@ -2127,7 +2333,7 @@ export class GDBDebugSession extends LoggingDebugSession { }; this.sendResponse(response); } catch (msg) { - this.sendErrorResponse(response, 10, msg.toString()); + this.sendErrorResponse(response, 10, (msg).toString()); } this.continueIfNoMore(pendContinue); @@ -2138,11 +2344,21 @@ export class GDBDebugSession extends LoggingDebugSession { }); }; - return this.allBreakPointsQ.add(doit, r, a); + return this.allBreakPointsQ.add(doit as any, r, a); } - private continueIfNoMore(pendContinue: PendingContinue) { - if (!pendContinue.haveMore() && pendContinue.shouldContinue) { + private reportHwBreakptLimit(brk: any): MIError { + const limit = this.hwBreakpointMgr.getLimit(); + const str = brk ? JSON.stringify(brk) : ''; + this.handleMsg('log', `Hardware breakpoint limit reached (${limit}) for breakpoint ${str}. Further breakpoints will not be set.\n`); + return new MIError( + `Hardware breakpoint limit reached (${limit}). Calculated by cortex-debug and not gdb.`, + 'internal' + ); + } + + private continueIfNoMore(pendContinue: PendingContinue | undefined) { + if (pendContinue && !pendContinue.haveMore?.() && pendContinue.shouldContinue) { this.disableSendStoppedEvents = false; pendContinue.shouldContinue = false; this.sendContinue(); @@ -2158,7 +2374,7 @@ export class GDBDebugSession extends LoggingDebugSession { this.miDebugger.once('generic-stopped', () => { createBreakpoints(); }); - this.miDebugger.sendCommand('exec-interrupt'); + this.miDebugger.interrupt(); } } @@ -2171,10 +2387,12 @@ export class GDBDebugSession extends LoggingDebugSession { pendContinue: PendingContinue): Promise => { return new Promise(async (resolve) => { const createBreakpoints = async () => { - const currentBreakpoints = (this.breakpointMap.get(args.source.path) || []).map((bp) => bp.number); + const currentBreakpoints = (this.breakpointMap.get(args.source.path) || []).map((bp) => bp.number).filter((n) => n !== undefined); + const hwOpt = this.hwBreakpointMgr.getGdbMiArg('src'); try { await this.miDebugger.removeBreakpoints(currentBreakpoints); + this.hwBreakpointMgr.removeBreakpoints(currentBreakpoints); for (const old of currentBreakpoints) { this.breakpointById.delete(old); } @@ -2182,53 +2400,16 @@ export class GDBDebugSession extends LoggingDebugSession { const all: Promise[] = []; const sourcepath = decodeURIComponent(args.source.path); - - if (sourcepath.startsWith('disassembly:/')) { - let sidx = 13; - if (sourcepath.startsWith('disassembly:///')) { sidx = 15; } - const path = sourcepath.substring(sidx, sourcepath.length - 6); // Account for protocol and extension - const parts = path.split(':::'); - let func: string; - let file: string; - - if (parts.length === 2) { - func = parts[1]; - file = parts[0]; - } else { - func = parts[0]; - } - - const symbol: SymbolInformation = await this.disassember.getDisassemblyForFunction(func, file); - - if (symbol) { - args.breakpoints.forEach((brk) => { - if (brk.line <= symbol.instructions.length) { - const line = symbol.instructions[brk.line - 1]; - const arg: OurSourceBreakpoint = { - ...brk, - file: args.source.path, - raw: line.address - }; - all.push(this.miDebugger.addBreakPoint(arg).catch((err: MIError) => err)); - } else { - all.push( - Promise.resolve( - new MIError( - `${func} only contains ${symbol.instructions.length} instructions`, - 'Set breakpoint' - ) - ) - ); - } - }); - } - } else { + if (args.breakpoints) { args.breakpoints.forEach((brk) => { const arg: OurSourceBreakpoint = { ...brk, - file: args.source.path + file: args.source.path, + hwOpt: hwOpt }; - all.push(this.miDebugger.addBreakPoint(arg).catch((err: MIError) => err)); + all.push(this.addBptSync(() => { + return this.miDebugger.addBreakPoint(arg); + }, arg)); }); } @@ -2264,7 +2445,7 @@ export class GDBDebugSession extends LoggingDebugSession { this.breakpointMap.set(args.source.path, bpts); this.sendResponse(response); } catch (msg) { - this.sendErrorResponse(response, 9, msg.toString()); + this.sendErrorResponse(response, 9, (msg).toString()); } this.continueIfNoMore(pendContinue); @@ -2275,7 +2456,7 @@ export class GDBDebugSession extends LoggingDebugSession { }); }; - return this.allBreakPointsQ.add(doit, r, a); + return this.allBreakPointsQ.add(doit as any, r, a); } protected setInstructionBreakpointsRequest( @@ -2292,12 +2473,16 @@ export class GDBDebugSession extends LoggingDebugSession { this.instrBreakpointMap.clear(); await this.miDebugger.removeBreakpoints(currentBreakpoints); + this.hwBreakpointMgr.removeBreakpoints(currentBreakpoints); const all: Promise[] = []; + const hwOpt = this.hwBreakpointMgr.getGdbMiArg('instr'); args.breakpoints.forEach((brk) => { - const addr = parseInt(brk.instructionReference) + brk.offset || 0; - const bpt: OurInstructionBreakpoint = { ...brk, number: -1, address: addr }; - all.push(this.miDebugger.addInstrBreakPoint(bpt).catch((err: MIError) => err)); + const addr = parseInt(brk.instructionReference) + (brk.offset || 0); + const bpt: OurInstructionBreakpoint = { ...brk, number: -1, address: addr, htOpt: hwOpt }; + all.push(this.addBptSync(() => { + return this.miDebugger.addInstrBreakPoint(bpt); + }, bpt)); }); const brkpoints = await Promise.all(all); @@ -2321,7 +2506,7 @@ export class GDBDebugSession extends LoggingDebugSession { this.sendResponse(response); } catch (msg) { - this.sendErrorResponse(response, 9, msg.toString()); + this.sendErrorResponse(response, 9, (msg).toString()); } this.continueIfNoMore(pendContinue); @@ -2332,7 +2517,7 @@ export class GDBDebugSession extends LoggingDebugSession { }); }; - return this.allBreakPointsQ.add(doit, r, a); + return this.allBreakPointsQ.add(doit as any, r, a); } protected isVarRefGlobalOrStatic(varRefNum: number, id: any): 'global' | 'static' | undefined { @@ -2374,8 +2559,8 @@ export class GDBDebugSession extends LoggingDebugSession { const ref = args.variablesReference; if ((ref !== undefined) && args.name && !((ref >= HandleRegions.REG_HANDLE_START) && (ref <= HandleRegions.REG_HANDLE_FINISH))) { - const id = this.variableHandles.get(args.variablesReference); - response.body.canPersist = !!this.isVarRefGlobalOrStatic(args.variablesReference, id); + const id = this.variableHandles.get(ref); + response.body.canPersist = !!this.isVarRefGlobalOrStatic(ref, id); const parentObj = id as VariableObject; const fullName = (parentObj ? (parentObj.fullExp || parentObj.exp) + '.' : '') + args.name; response.body.dataId = fullName; @@ -2397,15 +2582,23 @@ export class GDBDebugSession extends LoggingDebugSession { const createBreakpoints = async () => { try { const currentBreakpoints = Array.from(this.dataBreakpointMap.keys()); + this.hwWatchpointMgr.removeBreakpoints(currentBreakpoints); this.dataBreakpointMap.clear(); + // It is not clear how gdb implements. It has to use the DWT in the Cortex-M for hardware data + // breakpoints. So, we will assume that it counts as one hardware breakpoint per data breakpoint + // The docs don't say anything about it needing a '-h' to force HW data breakpoints + // TODO: Verify this assumption + await this.miDebugger.removeBreakpoints(currentBreakpoints); const all: Promise[] = []; args.breakpoints.forEach((brk) => { const bkp: OurDataBreakpoint = { ...brk }; - all.push(this.miDebugger.addDataBreakPoint(bkp).catch((err: MIError) => err)); + all.push(this.addBptSync(() => { + return this.miDebugger.addDataBreakPoint(bkp); + }, bkp, true)); }); const brkpoints = await Promise.all(all); @@ -2434,7 +2627,7 @@ export class GDBDebugSession extends LoggingDebugSession { this.sendResponse(response); } catch (msg) { - this.sendErrorResponse(response, 9, msg.toString()); + this.sendErrorResponse(response, 9, (msg).toString()); } this.continueIfNoMore(pendContinue); @@ -2445,7 +2638,7 @@ export class GDBDebugSession extends LoggingDebugSession { }); }; - return this.allBreakPointsQ.add(doit, r, a); + return this.allBreakPointsQ.add(doit as any, r, a); } protected threadsRequest(response: DebugProtocol.ThreadsResponse): Promise { @@ -2459,7 +2652,7 @@ export class GDBDebugSession extends LoggingDebugSession { if (this.args.showDevDebugOutput) { this.handleMsg('log', 'Returning dummy thread-id to workaround VSCode issue with pause button not working\n'); } - const useThread = this.currentThreadId || (this.activeThreadIds.size ? this.activeThreadIds.values[0] : 1); + const useThread = this.currentThreadId || (this.activeThreadIds.size ? Array.from(this.activeThreadIds.values())[0] : 1); response.body.threads = [new Thread(useThread, 'cortex-debug-dummy-thread')]; this.sendResponse(response); return Promise.resolve(); @@ -2468,7 +2661,7 @@ export class GDBDebugSession extends LoggingDebugSession { return new Promise(async (resolve) => { try { const threadIdNode = await this.miDebugger.sendCommand('thread-list-ids'); - const threadIds: number[] = threadIdNode.result('thread-ids').map((ti) => parseInt(ti[1])); + const threadIds: number[] = threadIdNode.result('thread-ids').map((ti: any) => parseInt(ti[1])); const currentThread = threadIdNode.result('current-thread-id'); if (!threadIds || (threadIds.length === 0)) { @@ -2570,7 +2763,7 @@ export class GDBDebugSession extends LoggingDebugSession { args.startFrame = args.startFrame ?? 0; args.levels = args.levels ?? Infinity; const createDummy = () => { - response.body.stackFrames = [new StackFrame(encodeReference(args.threadId, 0), 'cortex-debug-dummy', null, 0, 0)]; + response.body.stackFrames = [new StackFrame(encodeReference(args.threadId, 0), 'cortex-debug-dummy', undefined, 0, 0)]; response.body.totalFrames = 1; }; const isBusy = () => { @@ -2603,8 +2796,11 @@ export class GDBDebugSession extends LoggingDebugSession { const useMaxDepth = false; const defMaxDepth = 1000; const maxDepth = useMaxDepth ? await this.miDebugger.getStackDepth(args.threadId, defMaxDepth) : defMaxDepth; - const highFrame = Math.min(maxDepth, args.startFrame + args.levels) - 1; - const stack = await this.miDebugger.getStack(args.threadId, args.startFrame, highFrame); + const startFrame = args.startFrame || 0; + const levels = args.levels || 20; + + const highFrame = Math.min(maxDepth, startFrame + levels) - 1; + const stack = await this.miDebugger.getStack(args.threadId, startFrame, highFrame); const ret: StackFrame[] = []; for (const element of stack) { const stackId = encodeReference(args.threadId, element.level); @@ -2622,7 +2818,7 @@ export class GDBDebugSession extends LoggingDebugSession { resolve(); } catch (err) { if (isBusy()) { // Between the time we asked for a info, a continue occurred - this.sendErrorResponse(response, 12, `Failed to get Stack Trace: ${err.toString()}`); + this.sendErrorResponse(response, 12, `Failed to get Stack Trace: ${(err).toString()}`); } else { this.sendResponse(response); } @@ -2752,7 +2948,7 @@ export class GDBDebugSession extends LoggingDebugSession { throw new Error('Unable to parse response for reg. values'); } } catch (error) { - this.sendErrorResponse(response, 115, `Unable to read registers: ${error.toString()}`); + this.sendErrorResponse(response, 115, `Unable to read registers: ${(error).toString()}`); this.sendEvent(new TelemetryEvent('Error', 'Reading Registers', '')); return; } @@ -2764,10 +2960,10 @@ export class GDBDebugSession extends LoggingDebugSession { displayName: string | undefined, symOrExpr: string, gdbVarName: string, parentVarReference: number, threadId: number, frameId: number, isFloating: boolean): Promise { try { - let varObj: VariableObject; + let varObj: VariableObject | undefined; let varId = this.variableHandlesReverse.get(gdbVarName); let createNewVar = varId === undefined; - let updateError; + let updateError: any; if (!createNewVar) { try { const changes = await this.miDebugger.varUpdate(gdbVarName, threadId, frameId); @@ -2777,8 +2973,10 @@ export class GDBDebugSession extends LoggingDebugSession { if (inScope === 'true') { const name = MINode.valueOf(change, 'name'); const vId = this.variableHandlesReverse.get(name); - const v = this.variableHandles.get(vId) as any; - v.applyChanges(change); + if (vId !== undefined) { + const v = this.variableHandles.get(vId) as any; + v.applyChanges(change); + } } else { const msg = `${symOrExpr} currently not in scope`; await this.miDebugger.sendCommand(`var-delete ${gdbVarName}`); @@ -2789,7 +2987,9 @@ export class GDBDebugSession extends LoggingDebugSession { throw new Error(msg); } } - varObj = this.variableHandles.get(varId) as any; + if (varId !== undefined) { + varObj = this.variableHandles.get(varId) as any; + } } catch (err) { updateError = err; } @@ -2815,7 +3015,7 @@ export class GDBDebugSession extends LoggingDebugSession { this.handleMsg('stderr', `Could not create global/static variable ${symOrExpr}\n`); this.handleMsg('stderr', `Error: ${err}\n`); } - varObj = null; + throw err; } else { throw err; } @@ -2824,7 +3024,7 @@ export class GDBDebugSession extends LoggingDebugSession { if (isFloating && varObj) { this.putFloatingVariable(parentVarReference, symOrExpr, varObj); } - return varObj?.toProtocolVariable(displayName || varObj.name); + return varObj.toProtocolVariable(displayName || varObj.name); } catch (err) { const ret: DebugProtocol.Variable = { name: symOrExpr, @@ -2918,7 +3118,7 @@ export class GDBDebugSession extends LoggingDebugSession { } } - private createVariable(arg, options?): number { + private createVariable(arg: any, options?: any): number { if (options) { return this.variableHandles.create(new ExtendedVariable(arg, options)); } else { @@ -3093,7 +3293,7 @@ export class GDBDebugSession extends LoggingDebugSession { const varReq = id; if (varReq.options.arg) { - const strArr = []; + const strArr: DebugProtocol.Variable[] = []; let argsPart = true; let arrIndex = 0; const submit = () => { @@ -3272,19 +3472,19 @@ export class GDBDebugSession extends LoggingDebugSession { if (args.context !== 'repl') { try { - response.body = await this.evalExprInternal(args.expression, args.frameId, args.context, threadId, frameId); + response.body = await this.evalExprInternal(args.expression, args.frameId, args.context || 'hover', threadId, frameId); this.sendResponse(response); } catch (err) { if (this.isBusy()) { this.busyError(response, args); } else { response.body = { - result: (args.context === 'hover') ? null : `<${err.toString()}>`, + result: (args.context === 'hover') ? '' : `<${(err).toString()}>`, variablesReference: 0 }; this.sendResponse(response); if (this.args.showDevDebugOutput) { - this.handleMsg('stderr', args.context + ' ' + err.toString()); + this.handleMsg('stderr', args.context + ' ' + (err).toString()); } } // this.sendErrorResponse(response, 7, err.toString()); @@ -3301,25 +3501,14 @@ export class GDBDebugSession extends LoggingDebugSession { } try { this.miDebugger.sendUserInput(args.expression).then((output) => { - if (typeof output === 'undefined') { - response.body = { - result: '', - variablesReference: 0 - }; - } else { - response.body = { - result: JSON.stringify(output), - variablesReference: 0 - }; - } this.sendResponse(response); resolve(); }, (msg) => { - this.sendErrorResponse(response, 8, msg.toString()); + this.sendErrorResponse(response, 8, (msg).toString()); resolve(); }); } catch (e) { - this.sendErrorResponse(response, 8, e.toString()); + this.sendErrorResponse(response, 8, (e).toString()); resolve(); } } @@ -3331,12 +3520,12 @@ export class GDBDebugSession extends LoggingDebugSession { private async evalExprInternal( exp: string, frameRef: number | undefined, context: string, - threadId: number, frameId: number): Promise { + threadId: number | undefined, frameId: number | undefined): Promise { const varObjName = this.createVarNameFromExpr(exp, frameRef, context); - let varObj: VariableObject; + let varObj: VariableObject | undefined; let varId = this.variableHandlesReverse.get(varObjName); let createNewVar = varId === undefined; - let updateError; + let updateError: unknown; if (!createNewVar) { try { const changes = await this.miDebugger.varUpdate(varObjName, threadId, frameId); @@ -3346,8 +3535,10 @@ export class GDBDebugSession extends LoggingDebugSession { if (inScope === 'true') { const name = MINode.valueOf(change, 'name'); const vId = this.variableHandlesReverse.get(name); - const v = this.variableHandles.get(vId) as any; - v.applyChanges(change); + if (vId !== undefined) { + const v = this.variableHandles.get(vId) as any; + v.applyChanges(change); + } } else { const msg = `${exp} currently not in scope`; await this.miDebugger.sendCommand(`var-delete ${varObjName}`); @@ -3358,7 +3549,9 @@ export class GDBDebugSession extends LoggingDebugSession { throw new Error(msg); } } - varObj = this.variableHandles.get(varId) as any; + if (varId !== undefined) { + varObj = this.variableHandles.get(varId) as any; + } } catch (err) { updateError = err; } @@ -3395,14 +3588,26 @@ export class GDBDebugSession extends LoggingDebugSession { protected async gotoTargetsRequest(response: DebugProtocol.GotoTargetsResponse, args: DebugProtocol.GotoTargetsArguments): Promise { try { - const done = await this.miDebugger.goto(args.source.path, args.line); - if (!done) { + const brk: OurSourceBreakpoint = { + file: args.source.path, + line: args.line, + isTemporary: true, + hwOpt: this.hwBreakpointMgr.getGdbMiArg('src') + }; + + const result = await this.addBptSync(() => { + return this.miDebugger.addBreakPoint(brk); + }, brk); + + if (result instanceof MIError) { + this.sendErrorResponse(response, 16, `Could not jump to: ${result.message} ${args.source.path}:${args.line}`); + } else if (!result) { this.sendErrorResponse(response, 16, `Could not jump to: ${args.source.path}:${args.line}`); } else { response.body = { targets: [{ - id: 1, - label: args.source.name, + id: result.number || 0, + label: args.source.name || '', column: args.column, line: args.line }] @@ -3415,7 +3620,7 @@ export class GDBDebugSession extends LoggingDebugSession { } } -function prettyStringArray(strings): unknown { +function prettyStringArray(strings: any): unknown { if (typeof strings === 'object') { if (strings.length !== undefined) { return strings.join(', '); @@ -3425,8 +3630,8 @@ function prettyStringArray(strings): unknown { } else { return strings; } } -function initTwoCharsToIntMap(): object { - const obj = {}; +function initTwoCharsToIntMap(): any { + const obj: any = {}; for (let i = 0; i < 256; i++) { const key = i.toString(16).padStart(2, '0'); obj[key] = i; @@ -3436,4 +3641,23 @@ function initTwoCharsToIntMap(): object { const twoCharsToIntMap = initTwoCharsToIntMap(); -LoggingDebugSession.run(GDBDebugSession); +process.on('uncaughtException', (err) => { + const msg = err && err.stack ? err.stack : (err.message ? err.message : 'unknown error'); + console.error('cortex-debug: Caught exception:', msg); + ServerConsoleLog('Caught exception: ' + msg); + process.exit(1); // The process is in an unreliable state, so exit is recommended +}); + +process.on('unhandledRejection', (reason, promise) => { + const msg = 'cortex-debug: Unhandled Rejection: reason: ' + reason.toString() + ' promise: ' + promise.toString(); + console.error(msg); + ServerConsoleLog(msg); +}); + +try { + LoggingDebugSession.run(GDBDebugSession); +} catch (error) { + console.error('cortex-debug: Error occurred while running GDBDebugSession:', error); + ServerConsoleLog('cortex-debug: Caught exception: ' + error.toString()); + throw error; +} diff --git a/src/global.d.ts b/src/global.d.ts index 668a059c..a38b6832 100644 --- a/src/global.d.ts +++ b/src/global.d.ts @@ -1 +1,2 @@ declare const __COMMIT_HASH__: string; // Source: webpack plugin defined in webpack.config.js +declare module 'hasbin'; diff --git a/src/live-watch-monitor.ts b/src/live-watch-monitor.ts index 8c8108f9..9c4ac0a0 100644 --- a/src/live-watch-monitor.ts +++ b/src/live-watch-monitor.ts @@ -53,7 +53,7 @@ export class VariablesHandler { const v = this.variableHandles.get(vId) as any; v.applyChanges(change); } - }).finally (() => { + }).finally(() => { resolve(); }); } @@ -457,7 +457,7 @@ export class LiveWatchMonitor { try { if (!this.quitting) { this.quitting = true; - this.miDebugger.detach(); + this.miDebugger.stop(true); } } catch (e) { console.error('LiveWatchMonitor.quit', e); diff --git a/src/openocd.ts b/src/openocd.ts index e6ec15c8..f970d334 100644 --- a/src/openocd.ts +++ b/src/openocd.ts @@ -210,6 +210,10 @@ export class OpenOCDServerController extends EventEmitter implements GDBServerCo public serverArguments(): string[] { let serverargs: string[] = []; + // This should come before anything else so that gdb/tcl/telnet ports can be used in OpenoCD V12 + // without a warning and older versions will work fine as well + serverargs.push('-f', `${this.args.extensionPath}/support/openocd-helpers.tcl`); + // Regardless of the target processor, we will only supply the processor '0's port# // OpenOcd will increment and assign the right port-numer to the right processor serverargs.push('-c', `gdb_port ${this.ports['gdbPort']}`); @@ -228,7 +232,6 @@ export class OpenOCDServerController extends EventEmitter implements GDBServerCo serverargs.push('-c', cmd); } - serverargs.push('-f', `${this.args.extensionPath}/support/openocd-helpers.tcl`); this.args.configFiles.forEach((cf, idx) => { serverargs.push('-f', cf); }); diff --git a/src/pyocd.ts b/src/pyocd.ts index 4abb88ba..98e4b016 100644 --- a/src/pyocd.ts +++ b/src/pyocd.ts @@ -130,7 +130,7 @@ export class PyOCDServerController extends EventEmitter implements GDBServerCont } public initMatch(): RegExp { - return /GDB server started (at|on) port/; + return /GDB server (listening|started) (at|on) port/; } public serverLaunchStarted(): void {} diff --git a/src/remote/package-lock.json b/src/remote/package-lock.json index 6f051bec..299e6690 100644 --- a/src/remote/package-lock.json +++ b/src/remote/package-lock.json @@ -16,17 +16,17 @@ "@types/command-exists": "^1.2.0", "@types/glob": "^7.2.0", "@types/mocha": "^9.0.0", - "@types/node": "14.x", + "@types/node": "22.x", "@types/vscode": "^1.63.0", "@typescript-eslint/eslint-plugin": "^5.9.1", "@typescript-eslint/parser": "^5.9.1", - "@vscode/test-electron": "^2.0.3", + "@vscode/test-electron": "^2.5.2", "eslint": "^8.6.0", "glob": "^7.2.0", "mocha": "^11.1.0", "ts-loader": "^9.2.6", "typescript": "^4.5.4", - "webpack": "^5.94.0", + "webpack": "^5.105.0", "webpack-cli": "^4.9.1" }, "engines": { @@ -197,17 +197,14 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "dev": true, + "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" } }, "node_modules/@jridgewell/resolve-uri": { @@ -215,40 +212,35 @@ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/source-map": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", - "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25" } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -300,26 +292,40 @@ "node": ">=14" } }, - "node_modules/@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, "node_modules/@types/command-exists": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@types/command-exists/-/command-exists-1.2.0.tgz", "integrity": "sha512-ugsxEJfsCuqMLSuCD4PIJkp5Uk2z6TCMRCgYVuhRo5cYQY3+1xXTQkSlPtkpGHuvWMjS2KTeVQXxkXRACMbM6A==", "dev": true }, + "node_modules/@types/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" }, "node_modules/@types/glob": { "version": "7.2.0", @@ -332,10 +338,11 @@ } }, "node_modules/@types/json-schema": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", - "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", - "dev": true + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" }, "node_modules/@types/minimatch": { "version": "3.0.5", @@ -350,10 +357,14 @@ "dev": true }, "node_modules/@types/node": { - "version": "14.18.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.8.tgz", - "integrity": "sha512-TCYQllM94EyDe/EsfSPrddbTGzkwM46mGuQVyi+YiYSaAFsz9sYbtx4nXRc08sj856SWh2Nx3PmhutigSblkuw==", - "dev": true + "version": "22.19.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.18.tgz", + "integrity": "sha512-9v00a+dn2yWVsYDEunWC4g/TcRKVq3r8N5FuZp7u0SGrPvdN9c2yXI9bBuf5Fl0hNCb+QTIePTn5pJs2pwBOQQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } }, "node_modules/@types/vscode": { "version": "1.63.1", @@ -546,163 +557,180 @@ } }, "node_modules/@vscode/test-electron": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@vscode/test-electron/-/test-electron-2.1.0.tgz", - "integrity": "sha512-nE5ha/V+l4WnS0QS5wJhb2S75Ceamif30UOcURHYw+8FoJJHg2g1xM8/dSpvX2Xk4+04Rbl76/ui/tgI5qia+Q==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/@vscode/test-electron/-/test-electron-2.5.2.tgz", + "integrity": "sha512-8ukpxv4wYe0iWMRQU18jhzJOHkeGKbnw7xWRX3Zw1WJA4cEKbHcmmLPdPrPtL6rhDcrlCZN+xKRpv09n4gRHYg==", "dev": true, + "license": "MIT", "dependencies": { - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "rimraf": "^3.0.2", - "unzipper": "^0.10.11" + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.5", + "jszip": "^3.10.1", + "ora": "^8.1.0", + "semver": "^7.6.2" }, "engines": { - "node": ">=8.9.3" + "node": ">=16" } }, "node_modules/@webassemblyjs/ast": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", - "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" } }, "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", - "dev": true + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", - "dev": true + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", - "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", - "dev": true + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", - "dev": true + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", - "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.12.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" } }, "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", "dev": true, + "license": "MIT", "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "node_modules/@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", - "dev": true + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", - "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-opt": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1", - "@webassemblyjs/wast-printer": "1.12.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" } }, "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", - "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", - "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" } }, "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", - "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "node_modules/@webassemblyjs/wast-printer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", - "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/ast": "1.14.1", "@xtuc/long": "4.2.2" } }, @@ -746,19 +774,22 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/@xtuc/long": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -766,13 +797,17 @@ "node": ">=0.4.0" } }, - "node_modules/acorn-import-attributes": { - "version": "1.9.5", - "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", - "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "node_modules/acorn-import-phases": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", + "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + }, "peerDependencies": { - "acorn": "^8" + "acorn": "^8.14.0" } }, "node_modules/acorn-jsx": { @@ -785,15 +820,13 @@ } }, "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", "dev": true, - "dependencies": { - "debug": "4" - }, + "license": "MIT", "engines": { - "node": ">= 6.0.0" + "node": ">= 14" } }, "node_modules/ajv": { @@ -812,15 +845,48 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, "peerDependencies": { - "ajv": "^6.9.1" + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, "node_modules/ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", @@ -889,26 +955,14 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "node_modules/big-integer": { - "version": "1.6.51", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", - "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/binary": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", - "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=", + "node_modules/baseline-browser-mapping": { + "version": "2.9.19", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz", + "integrity": "sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==", "dev": true, - "dependencies": { - "buffers": "~0.1.1", - "chainsaw": "~0.1.0" - }, - "engines": { - "node": "*" + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" } }, "node_modules/binary-extensions": { @@ -920,12 +974,6 @@ "node": ">=8" } }, - "node_modules/bluebird": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", - "integrity": "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=", - "dev": true - }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -967,9 +1015,9 @@ "dev": true }, "node_modules/browserslist": { - "version": "4.23.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", - "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", "dev": true, "funding": [ { @@ -985,11 +1033,13 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001646", - "electron-to-chromium": "^1.5.4", - "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.0" + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" }, "bin": { "browserslist": "cli.js" @@ -1002,25 +1052,8 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/buffer-indexof-polyfill": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz", - "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/buffers": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", - "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=", "dev": true, - "engines": { - "node": ">=0.2.0" - } + "license": "MIT" }, "node_modules/callsites": { "version": "3.1.0", @@ -1044,9 +1077,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001655", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001655.tgz", - "integrity": "sha512-jRGVy3iSGO5Uutn2owlb5gR6qsGngTw9ZTb4ali9f3glshcNmJ2noam4Mo9zia5P9Dk3jNNydy7vQjuE5dQmfg==", + "version": "1.0.30001769", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001769.tgz", + "integrity": "sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg==", "dev": true, "funding": [ { @@ -1061,19 +1094,8 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] - }, - "node_modules/chainsaw": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", - "integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=", - "dev": true, - "dependencies": { - "traverse": ">=0.3.0 <0.4" - }, - "engines": { - "node": "*" - } + ], + "license": "CC-BY-4.0" }, "node_modules/chalk": { "version": "4.1.2", @@ -1127,6 +1149,35 @@ "node": ">=6.0" } }, + "node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", @@ -1189,7 +1240,8 @@ "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/concat-map": { "version": "0.0.1", @@ -1201,7 +1253,8 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cross-spawn": { "version": "7.0.3", @@ -1287,15 +1340,6 @@ "node": ">=6.0.0" } }, - "node_modules/duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", - "dev": true, - "dependencies": { - "readable-stream": "^2.0.2" - } - }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -1304,10 +1348,11 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.13", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.13.tgz", - "integrity": "sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q==", - "dev": true + "version": "1.5.286", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz", + "integrity": "sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==", + "dev": true, + "license": "ISC" }, "node_modules/emoji-regex": { "version": "8.0.0", @@ -1317,13 +1362,14 @@ "license": "MIT" }, "node_modules/enhanced-resolve": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz", - "integrity": "sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA==", + "version": "5.19.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz", + "integrity": "sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" + "tapable": "^2.3.0" }, "engines": { "node": ">=10.13.0" @@ -1342,10 +1388,11 @@ } }, "node_modules/es-module-lexer": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", - "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", - "dev": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", + "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", + "dev": true, + "license": "MIT" }, "node_modules/escalade": { "version": "3.2.0", @@ -1645,6 +1692,23 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, + "node_modules/fast-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", + "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/fastest-levenshtein": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", @@ -1711,10 +1775,11 @@ } }, "node_modules/flatted": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.4.tgz", - "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==", - "dev": true + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true, + "license": "ISC" }, "node_modules/foreground-child": { "version": "3.3.0", @@ -1766,35 +1831,6 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/fstream": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", - "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", - "deprecated": "This package is no longer supported.", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" - }, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/fstream/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -1817,6 +1853,19 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-east-asian-width": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.5.0.tgz", + "integrity": "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", @@ -1866,7 +1915,8 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true + "dev": true, + "license": "BSD-2-Clause" }, "node_modules/globals": { "version": "13.12.0", @@ -1904,10 +1954,11 @@ } }, "node_modules/graceful-fs": { - "version": "4.2.9", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", - "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", - "dev": true + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" }, "node_modules/has": { "version": "1.0.3", @@ -1940,30 +1991,31 @@ } }, "node_modules/http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", "dev": true, + "license": "MIT", "dependencies": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" + "agent-base": "^7.1.0", + "debug": "^4.3.4" }, "engines": { - "node": ">= 6" + "node": ">= 14" } }, "node_modules/https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", "dev": true, + "license": "MIT", "dependencies": { - "agent-base": "6", + "agent-base": "^7.1.2", "debug": "4" }, "engines": { - "node": ">= 6" + "node": ">= 14" } }, "node_modules/human-signals": { @@ -1984,6 +2036,13 @@ "node": ">= 4" } }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", + "dev": true, + "license": "MIT" + }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -2114,14 +2173,27 @@ "node": ">=0.10.0" } }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "node_modules/is-interactive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", + "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", "dev": true, + "license": "MIT", "engines": { - "node": ">=0.12.0" - } + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } }, "node_modules/is-plain-obj": { "version": "2.1.0", @@ -2171,8 +2243,9 @@ "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" }, "node_modules/isexe": { "version": "2.0.0", @@ -2210,6 +2283,7 @@ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", @@ -2224,6 +2298,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -2235,10 +2310,21 @@ } }, "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz", + "integrity": "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -2264,6 +2350,19 @@ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, + "node_modules/jszip": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", + "dev": true, + "license": "(MIT OR GPL-3.0-or-later)", + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + } + }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -2286,19 +2385,28 @@ "node": ">= 0.8.0" } }, - "node_modules/listenercount": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", - "integrity": "sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc=", - "dev": true + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "immediate": "~3.0.5" + } }, "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", + "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.11.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, "node_modules/locate-path": { @@ -2338,18 +2446,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -2408,11 +2504,25 @@ "node": ">=6" } }, + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -2420,12 +2530,6 @@ "node": "*" } }, - "node_modules/minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true - }, "node_modules/minipass": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", @@ -2436,18 +2540,6 @@ "node": ">=16 || 14 >=14.17" } }, - "node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, "node_modules/mocha": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.1.0.tgz", @@ -2485,9 +2577,9 @@ } }, "node_modules/mocha/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2516,13 +2608,13 @@ } }, "node_modules/mocha/node_modules/glob/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "dev": true, "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^2.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -2532,9 +2624,9 @@ } }, "node_modules/mocha/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", + "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", "dev": true, "license": "ISC", "dependencies": { @@ -2579,10 +2671,11 @@ "dev": true }, "node_modules/node-releases": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", - "dev": true + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "dev": true, + "license": "MIT" }, "node_modules/normalize-path": { "version": "3.0.0", @@ -2646,6 +2739,140 @@ "node": ">= 0.8.0" } }, + "node_modules/ora": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-8.2.0.tgz", + "integrity": "sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^5.3.0", + "cli-cursor": "^5.0.0", + "cli-spinners": "^2.9.2", + "is-interactive": "^2.0.0", + "is-unicode-supported": "^2.0.0", + "log-symbols": "^6.0.0", + "stdin-discarder": "^0.2.2", + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/ora/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, + "node_modules/ora/node_modules/is-unicode-supported": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/log-symbols": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz", + "integrity": "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^5.3.0", + "is-unicode-supported": "^1.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/log-symbols/node_modules/is-unicode-supported": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -2692,6 +2919,13 @@ "dev": true, "license": "BlueOak-1.0.0" }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true, + "license": "(MIT AND Zlib)" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -2771,16 +3005,18 @@ } }, "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" }, "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -2865,7 +3101,8 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/punycode": { "version": "2.1.1", @@ -2906,10 +3143,11 @@ } }, "node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, + "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -2966,6 +3204,16 @@ "node": ">=0.10.0" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/resolve": { "version": "1.21.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.21.0.tgz", @@ -3013,6 +3261,52 @@ "node": ">=4" } }, + "node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor/node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -3069,14 +3363,16 @@ "dev": true }, "node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", "dev": true, + "license": "MIT", "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" }, "engines": { "node": ">= 10.13.0" @@ -3086,14 +3382,49 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "node_modules/schema-utils/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, + "license": "MIT", "dependencies": { - "lru-cache": "^6.0.0" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/schema-utils/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/schema-utils/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -3114,8 +3445,9 @@ "node_modules/setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "dev": true, + "license": "MIT" }, "node_modules/shallow-clone": { "version": "3.0.1", @@ -3170,6 +3502,7 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -3179,16 +3512,31 @@ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, + "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, + "node_modules/stdin-discarder": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz", + "integrity": "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } @@ -3296,22 +3644,28 @@ } }, "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, "node_modules/terser": { - "version": "5.31.6", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.6.tgz", - "integrity": "sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==", + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz", + "integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", + "acorn": "^8.15.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, @@ -3323,16 +3677,17 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", - "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", + "version": "5.3.16", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz", + "integrity": "sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==", "dev": true, + "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.20", + "@jridgewell/trace-mapping": "^0.3.25", "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.26.0" + "schema-utils": "^4.3.0", + "serialize-javascript": "^6.0.2", + "terser": "^5.31.1" }, "engines": { "node": ">= 10.13.0" @@ -3356,18 +3711,6 @@ } } }, - "node_modules/terser/node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -3386,15 +3729,6 @@ "node": ">=8.0" } }, - "node_modules/traverse": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", - "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/ts-loader": { "version": "9.2.6", "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.2.6.tgz", @@ -3472,28 +3806,17 @@ "node": ">=4.2.0" } }, - "node_modules/unzipper": { - "version": "0.10.11", - "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.11.tgz", - "integrity": "sha512-+BrAq2oFqWod5IESRjL3S8baohbevGcVA+teAIOYWM3pDVdseogqbzhhvvmiyQrUNKFUnDMtELW3X8ykbyDCJw==", + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, - "dependencies": { - "big-integer": "^1.6.17", - "binary": "~0.3.0", - "bluebird": "~3.4.1", - "buffer-indexof-polyfill": "~1.0.0", - "duplexer2": "~0.1.4", - "fstream": "^1.0.12", - "graceful-fs": "^4.2.2", - "listenercount": "~1.0.1", - "readable-stream": "~2.3.6", - "setimmediate": "~1.0.4" - } + "license": "MIT" }, "node_modules/update-browserslist-db": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", - "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", "dev": true, "funding": [ { @@ -3509,9 +3832,10 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" + "escalade": "^3.2.0", + "picocolors": "^1.1.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -3532,8 +3856,9 @@ "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" }, "node_modules/v8-compile-cache": { "version": "2.3.0", @@ -3550,10 +3875,11 @@ } }, "node_modules/watchpack": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", - "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.1.tgz", + "integrity": "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==", "dev": true, + "license": "MIT", "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -3563,34 +3889,37 @@ } }, "node_modules/webpack": { - "version": "5.94.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz", - "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==", - "dev": true, - "dependencies": { - "@types/estree": "^1.0.5", - "@webassemblyjs/ast": "^1.12.1", - "@webassemblyjs/wasm-edit": "^1.12.1", - "@webassemblyjs/wasm-parser": "^1.12.1", - "acorn": "^8.7.1", - "acorn-import-attributes": "^1.9.5", - "browserslist": "^4.21.10", + "version": "5.105.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.105.0.tgz", + "integrity": "sha512-gX/dMkRQc7QOMzgTe6KsYFM7DxeIONQSui1s0n/0xht36HvrgbxtM1xBlgx596NbpHuQU8P7QpKwrZYwUX48nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.8", + "@types/json-schema": "^7.0.15", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.15.0", + "acorn-import-phases": "^1.0.3", + "browserslist": "^4.28.1", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.1", - "es-module-lexer": "^1.2.1", + "enhanced-resolve": "^5.19.0", + "es-module-lexer": "^2.0.0", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", + "loader-runner": "^4.3.1", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^3.2.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.10", - "watchpack": "^2.4.1", - "webpack-sources": "^3.2.3" + "schema-utils": "^4.3.3", + "tapable": "^2.3.0", + "terser-webpack-plugin": "^5.3.16", + "watchpack": "^2.5.1", + "webpack-sources": "^3.3.3" }, "bin": { "webpack": "bin/webpack.js" @@ -3674,45 +4003,15 @@ } }, "node_modules/webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", - "dev": true, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webpack/node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", + "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/webpack/node_modules/enhanced-resolve": { - "version": "5.17.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", - "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, + "license": "MIT", "engines": { "node": ">=10.13.0" } }, - "node_modules/webpack/node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -3803,12 +4102,6 @@ "node": ">=10" } }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", diff --git a/src/remote/package.json b/src/remote/package.json index a49f2454..1f7de989 100644 --- a/src/remote/package.json +++ b/src/remote/package.json @@ -10,8 +10,7 @@ "Other" ], "activationEvents": [ - "onDebugResolve:cortex-debug", - "onCommand:cortex-debug-remote.helloWorld" + "onDebugResolve:cortex-debug" ], "main": "./dist/extension.js", "publisher": "marus25", @@ -42,17 +41,17 @@ "@types/command-exists": "^1.2.0", "@types/glob": "^7.2.0", "@types/mocha": "^9.0.0", - "@types/node": "14.x", + "@types/node": "22.x", "@types/vscode": "^1.63.0", "@typescript-eslint/eslint-plugin": "^5.9.1", "@typescript-eslint/parser": "^5.9.1", - "@vscode/test-electron": "^2.0.3", + "@vscode/test-electron": "^2.5.2", "eslint": "^8.6.0", "glob": "^7.2.0", "mocha": "^11.1.0", "ts-loader": "^9.2.6", "typescript": "^4.5.4", - "webpack": "^5.94.0", + "webpack": "^5.105.0", "webpack-cli": "^4.9.1" }, "dependencies": { diff --git a/src/reporting.ts b/src/reporting.ts index 10743715..ef26e675 100644 --- a/src/reporting.ts +++ b/src/reporting.ts @@ -48,6 +48,7 @@ function getUUID(): string { } function telemetryEnabled(): boolean { + return false; // Disable telemetry for now, until we have a better understanding of what to send and how to use it. const telemetry = vscode.workspace.getConfiguration('telemetry'); const cortexDebug = vscode.workspace.getConfiguration('cortex-debug'); diff --git a/src/stlink.ts b/src/stlink.ts index 97923778..8a89d9c2 100755 --- a/src/stlink.ts +++ b/src/stlink.ts @@ -265,7 +265,7 @@ export class STLinkServerController extends EventEmitter implements GDBServerCon } serverargs.push('--halt'); // Need this for reset to work as expected (perform a halt) if (this.targetProcessor > 0) { - serverargs.push('-m', `this.targetProcessor`); + serverargs.push('-m', `${this.targetProcessor}`); } if (this.args.serverArgs) { diff --git a/support/openocd-helpers.tcl b/support/openocd-helpers.tcl index 51249d62..317c763e 100644 --- a/support/openocd-helpers.tcl +++ b/support/openocd-helpers.tcl @@ -6,8 +6,11 @@ # Note that this file simply defines a function for use later when it is time to configure # for SWO. # +# This file must be loaded before the `init` command is called and before gdb/tcl/telnet ports are set +# as it contains overrides for those commands to keep compatibility with older versions of OpenOCD +# set USE_SWO 0 -proc CDSWOConfigure { CDCPUFreqHz CDSWOFreqHz CDSWOOutput } { +proc CDSWOConfigure { CDCPUFreqHz CDSWOFreqHz CDSWOOutput } { # We don't create/configure the entire TPIU which requires advanced knowledge of the device # like which DAP/AP ports to use, what their bases addresses are, etc. That should already # be done by the config files from the Silicon Vendor @@ -64,3 +67,26 @@ proc CDLiveWatchSetup {} { puts stderr "[info script]: Error: Failed to increase gdb-max-connections for current target. Live variables will not work" } } + +# In version 12 of openocd they deprecated the gdb_port command. So, we create the old command and +# use it from the command-line so that we keep compatibility with older versions of openocd +if { [llength [info commands "gdb"] ] != 0 } { + proc gdb_port { port } { + puts "[info script]: Setting gdb port to $port" + gdb port $port + } +} + +if { [llength [info commands "tcl"] ] != 0 } { + proc tcl_port { port } { + puts "[info script]: Setting tcl port to $port" + tcl port $port + } +} + +if { [llength [info commands "telnet"] ] != 0 } { + proc telnet_port { port } { + puts "[info script]: Setting telnet port to $port" + telnet port $port + } +} diff --git a/tsconfig.json b/tsconfig.json index b660597d..6b6471c1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,8 +4,17 @@ "target": "es6", "outDir": "out", "lib": [ - "es6" + "es6", + "dom" ], + "skipLibCheck": true, + "strict": true, + "strictNullChecks": false, + "noImplicitAny": false, + "noImplicitThis": false, + "strictFunctionTypes": false, + "useUnknownInCatchVariables": false, + "forceConsistentCasingInFileNames": true, "sourceMap": true, "rootDir": ".", },