From 3c36f62545cf03fc531d88b4e5723f04091091c0 Mon Sep 17 00:00:00 2001 From: Till Schneidereit Date: Wed, 19 Feb 2025 19:46:02 -0600 Subject: [PATCH 1/6] Add a VSCode extension for debugging JS running in StarlingMonkey This commit introduces a substantial new feature: debugging support via the [Debug Adapter Protocol](https://microsoft.github.io/debug-adapter-protocol/). While for now the debugger is experimental and not quite ready for production use, it already covers a decent amount of functionality: it supports breakpoints, single-stepping into and over function calls, stack and (local and global) scope inspection, and modifying locals and object properties. Building on the platform support added in #218, the extension has two key components: 1. a DAP implementation as a Node.js script that starts StarlingMonkey, starts a server for the debug session, and translates between the messages StarlingMonkey sends/receives and the DAP 2. a VS Code extension providing launch configurations and settings for the debugger, and initiates the debug session --- debugger/vscode-dap-extension/.eslintrc.json | 22 + debugger/vscode-dap-extension/.gitignore | 8 + .../vscode-dap-extension/.vscode/launch.json | 55 + .../.vscode/settings.json | 9 + .../vscode-dap-extension/.vscode/tasks.json | 32 + debugger/vscode-dap-extension/.vscodeignore | 10 + debugger/vscode-dap-extension/LICENSE | 218 + debugger/vscode-dap-extension/README.md | 30 + .../images/starlingmonkey-logo.png | Bin 0 -> 3611 bytes .../vscode-dap-extension/package-lock.json | 5280 +++++++++++++++++ debugger/vscode-dap-extension/package.json | 216 + .../sampleWorkspace/.vscode/launch.json | 17 + .../sampleWorkspace/main.js | 23 + .../src/activateStarlingMonkeyDebugger.ts | 203 + .../vscode-dap-extension/src/debugAdapter.ts | 48 + .../vscode-dap-extension/src/extension.ts | 68 + debugger/vscode-dap-extension/src/signals.ts | 37 + .../src/starlingMonkeyDebugger.ts | 365 ++ .../src/starlingMonkeyRuntime.ts | 429 ++ .../starling-debugger/debugger.ts | 623 ++ debugger/vscode-dap-extension/tsconfig.json | 28 + 21 files changed, 7721 insertions(+) create mode 100644 debugger/vscode-dap-extension/.eslintrc.json create mode 100644 debugger/vscode-dap-extension/.gitignore create mode 100644 debugger/vscode-dap-extension/.vscode/launch.json create mode 100644 debugger/vscode-dap-extension/.vscode/settings.json create mode 100644 debugger/vscode-dap-extension/.vscode/tasks.json create mode 100644 debugger/vscode-dap-extension/.vscodeignore create mode 100644 debugger/vscode-dap-extension/LICENSE create mode 100644 debugger/vscode-dap-extension/README.md create mode 100644 debugger/vscode-dap-extension/images/starlingmonkey-logo.png create mode 100644 debugger/vscode-dap-extension/package-lock.json create mode 100644 debugger/vscode-dap-extension/package.json create mode 100644 debugger/vscode-dap-extension/sampleWorkspace/.vscode/launch.json create mode 100644 debugger/vscode-dap-extension/sampleWorkspace/main.js create mode 100644 debugger/vscode-dap-extension/src/activateStarlingMonkeyDebugger.ts create mode 100644 debugger/vscode-dap-extension/src/debugAdapter.ts create mode 100644 debugger/vscode-dap-extension/src/extension.ts create mode 100644 debugger/vscode-dap-extension/src/signals.ts create mode 100644 debugger/vscode-dap-extension/src/starlingMonkeyDebugger.ts create mode 100644 debugger/vscode-dap-extension/src/starlingMonkeyRuntime.ts create mode 100644 debugger/vscode-dap-extension/starling-debugger/debugger.ts create mode 100644 debugger/vscode-dap-extension/tsconfig.json diff --git a/debugger/vscode-dap-extension/.eslintrc.json b/debugger/vscode-dap-extension/.eslintrc.json new file mode 100644 index 00000000..971f15db --- /dev/null +++ b/debugger/vscode-dap-extension/.eslintrc.json @@ -0,0 +1,22 @@ +{ + "root": true, + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": 2022, + "sourceType": "module" + }, + "plugins": [ + "@typescript-eslint" + ], + "rules": { + "@typescript-eslint/naming-convention": "warn", + "@typescript-eslint/semi": "warn", + "curly": "warn", + "eqeqeq": "warn", + "no-throw-literal": "warn", + "semi": "off" + }, + "ignorePatterns": [ + "**/*.d.ts" + ] +} diff --git a/debugger/vscode-dap-extension/.gitignore b/debugger/vscode-dap-extension/.gitignore new file mode 100644 index 00000000..57cae8b6 --- /dev/null +++ b/debugger/vscode-dap-extension/.gitignore @@ -0,0 +1,8 @@ +out +dist +node_modules +.vscode-test/ +npm-debug.log +*.vsix +.DS_Store +sampleWorkspace/out diff --git a/debugger/vscode-dap-extension/.vscode/launch.json b/debugger/vscode-dap-extension/.vscode/launch.json new file mode 100644 index 00000000..2053f03a --- /dev/null +++ b/debugger/vscode-dap-extension/.vscode/launch.json @@ -0,0 +1,55 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Extension", + "type": "extensionHost", + "request": "launch", + "args": [ + "--extensionDevelopmentPath=${workspaceFolder}", + "${workspaceFolder}/sampleWorkspace" + ], + "outFiles": [ + "${workspaceFolder}/dist/**/*.js" + ], + "preLaunchTask": "npm: watch" + }, + { + "name": "Web Extension", + "type": "extensionHost", + "debugWebWorkerHost": true, + "request": "launch", + "args": [ + "--extensionDevelopmentPath=${workspaceFolder}", + "--extensionDevelopmentKind=web", + "${workspaceFolder}/sampleWorkspace" + ], + "outFiles": [ + "${workspaceFolder}/dist/**/*.js" + ], + "preLaunchTask": "npm: watch web" + }, + // TODO: enable the server configuration, once passing the required arguments is figured out + // { + // "name": "Server", + // "type": "node", + // "request": "launch", + // "cwd": "${workspaceFolder}", + // "program": "${workspaceFolder}/src/debugAdapter.ts", + // "args": [ + // "--server=9721", + // "${workspaceFolder}/sampleWorkspace" + // ], + // "outFiles": [ + // "${workspaceFolder}/out/**/*.js" + // ], + // "preLaunchTask": "npm: compile" + // } + ], + // "compounds": [ + // { + // "name": "Extension + Server", + // "configurations": [ "Extension", "Server" ] + // } + // ] +} diff --git a/debugger/vscode-dap-extension/.vscode/settings.json b/debugger/vscode-dap-extension/.vscode/settings.json new file mode 100644 index 00000000..fb2bfe12 --- /dev/null +++ b/debugger/vscode-dap-extension/.vscode/settings.json @@ -0,0 +1,9 @@ +{ + "search.exclude": { + "out": true + }, + "typescript.tsc.autoDetect": "off", + + "git.branchProtection": ["main"], + "git.branchProtectionPrompt": "alwaysCommitToNewBranch" +} diff --git a/debugger/vscode-dap-extension/.vscode/tasks.json b/debugger/vscode-dap-extension/.vscode/tasks.json new file mode 100644 index 00000000..6bedf41a --- /dev/null +++ b/debugger/vscode-dap-extension/.vscode/tasks.json @@ -0,0 +1,32 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "type": "npm", + "script": "build", + "isBackground": false, + "group": { + "isDefault": true, + "kind": "build" + }, + "problemMatcher": "$esbuild", + "label": "npm: build" + }, + { + "type": "npm", + "script": "watch", + "group": "build", + "problemMatcher": "$esbuild-watch", + "isBackground": true, + "label": "npm: watch" + }, + { + "type": "npm", + "script": "watch-web", + "group": "build", + "problemMatcher": "$esbuild-watch", + "isBackground": true, + "label": "npm: watch web" + } + ] +} \ No newline at end of file diff --git a/debugger/vscode-dap-extension/.vscodeignore b/debugger/vscode-dap-extension/.vscodeignore new file mode 100644 index 00000000..fa7114d2 --- /dev/null +++ b/debugger/vscode-dap-extension/.vscodeignore @@ -0,0 +1,10 @@ +.vscode/**/* +.gitignore +**/*.js.map +build +sampleWorkspace +sampleWorkspace/out +node_modules +tsconfig.json +out +src diff --git a/debugger/vscode-dap-extension/LICENSE b/debugger/vscode-dap-extension/LICENSE new file mode 100644 index 00000000..fecea6ac --- /dev/null +++ b/debugger/vscode-dap-extension/LICENSE @@ -0,0 +1,218 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2020 Fastly, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +--- LLVM Exceptions to the Apache 2.0 License ---- + +As an exception, if, as a result of your compiling your source code, portions +of this Software are embedded into an Object form of such source code, you +may redistribute such embedded portions in such Object form without complying +with the conditions of Sections 4(a), 4(b) and 4(d) of the License. + +In addition, if you combine or link compiled forms of this Software with +software that is licensed under the GPLv2 ("Combined Software") and if a +court of competent jurisdiction determines that the patent provision (Section +3), the indemnity provision (Section 9) or other Section of the License +conflicts with the conditions of the GPLv2, you may retroactively and +prospectively choose to deem waived or otherwise exclude such Section(s) of +the License, but only in their entirety and only with respect to the Combined +Software. diff --git a/debugger/vscode-dap-extension/README.md b/debugger/vscode-dap-extension/README.md new file mode 100644 index 00000000..ca83472a --- /dev/null +++ b/debugger/vscode-dap-extension/README.md @@ -0,0 +1,30 @@ +# StarlingMonkey Debugger for VS Code + +This extension adds support for debugging JavaScript code running in the [StarlingMonkey](https://github.com/bytecodealliance/StarlingMonkey/) JS runtime inside a [WebAssembly Component](https://component-model.bytecodealliance.org/). + +**NOTE:** This extension is experimental for now, and will break in surprising and not always enjoyable ways. + +## Using The StarlingMonkey Debugger + +The extension is currently experimental and can't be installed directly. Instead, follow the instructions below for building it: + +## Building and Running + +* Install a recent version of the [Wasmtime](https://wasmtime.dev/) WebAssembly runtime and ensure that it's available in your path[^1] +* Clone the [StarlingMonkey project](https://github.com/bytecodealliance/StarlingMonkey/) +* Ensure that you have a branch checked out that contains the debugger +* Open the contained folder `debugger/vscode-dap-extension` in VS Code +* Ensure that a build of StarlingMonkey is available with the path `debugger/vscode-dap-extension/out/main.wasm`. This is configurable via the `component` property of the launch configuration in `launch.json`[^2] +* Open the "Run and Debug" sidebar and ensure that the `Extension` launch configuration is active +* Press `F5` to build the extension and launch another VS Code window with it installed +* In the explorer view of the new window open `main.js` +* Set some breakpoints +* Press `F5` to start debugging the file +* invoke the component. For HTTP server components, this would be done by sending an HTTP request to the address the component is served at. By default, that would be `http://localhost:8080/` + +## Configuration + +The extension adds a `StarlingMonkey Debugger` section to VS Code's configuration. Open the VS Code settings and search for `StarlingMonkey` to see the available options. + +[^1]: Alternatively, you can use another WebAssembly Components runtime, as long as it supports outgoing TCP socket connections, and passing environment variables to the guest. In that case, you'll have to update the [configuration](#configuration) to ensure the right options are passed to the runtime. +[^2]: The currently easiest way to get this file is to build StarlingMonkey itself using the CMake target `starling`, and then copying the resulting `starling.wasm` file from the CMake build folder. See the repository's top-level `README` for details on the build process diff --git a/debugger/vscode-dap-extension/images/starlingmonkey-logo.png b/debugger/vscode-dap-extension/images/starlingmonkey-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..7113927168bb380ffea4efc37c578ff5a3f4acf0 GIT binary patch literal 3611 zcmeHKX*d-8*Zz$$Mha8b2V(|*lD(csvNXoNBuz|+2w9S)Y@skC*|YD-lCm^e##YHT zMLmqHlVvcr>`NrF4u9{*_v8Eh{c!GcUFW{e`EY-@&p9zTQv*&8Ar1flr;(wq*>NWR zPq4EcV=Km?^SC~3q^pGwv|F`3QOoz`bkk*S{1^o`#>b}{V?35AcwRv(Bf9ScTIdy9 zVnG3`GFn<1!KwxG4$G3zf&^&ueu6#FxeifzH+cquKTZKppT`{&;~764e;zT&=D zvM7kO-4$Ihx^_(wIbNRrFF!!P7getgv$8QYptb(};;Xx5_j#IVrzn`|i{5HIs73M? zB?6_q(22qqcZx4(C>c<6ZdY%^163sUseXu$LC~U**1B8U)0IYMuqO)w>e! zR{6VJ+=^-9(zD;)xIw#ny~a}CMRK7C*H|x7VsWvhOyo|w&#AWn`<8;UhN)%rJD9y+ zh-KRq$yE_#rg~R%f?W|Eok94Kyz?!OO9y<+I|5*ac224ME5{3J?ImG#kiSjCn2@xTiT>?70N$by~ zAjH*g0kXuHZMh_WKt@MPNnHY2fjulYkLf3O9iKq|pZdS3(Zvde#|@xcp%9A_40-LB z{eJ$b?<4*-`-B}KM~003WoGb^Bzea+`pa5xPXp!1@vy6XWIt^6(SzyUSUnn%bD5`8 z07efz3sHV|wb+&M9?^;Up2BzpA$M`DC+zV&7*n=?EK=cYf=ERr1sz51?084tA0Xhz z)Mxd{E&-CFiJBuUj)za%Hkv0N)+H~S+M60q*BDJobbn77mw`+o_g%?z+hBC1)cL7G zYKx3Xldz-34(hZr8)cb^wrkc4Fb)eYyDl4;iOIAwD27n1IU@o-*TuvSo#yrZ`Xo_R zF=>Do_$(3{04KLP!c7{o%m-?!+Q*DJ3D(GU{S;ffek}4K^hVjhNyPThCGQWZ{AmL ze|1FYuQFLVDF(;kz5Hr`ZQQh6SDE&dT%phw&>DI}FL2EskOJB*^2exq!tynbr@!Q& z`5Wz$UOq#oo}IJhl55mj2{|?V$rUKSpU^(rQUYnC_E4cj!H%ryr^DGHQ_9MnVurTa z$9D3*mkTo(8gbAR&v9--x==Dr8G~BMdP`Z#U-FIZIUBC2O~K);ZHOXL1i1XHCbK}u zhql(_J`Nq7xAHtx`nm$_M{|>wU*^A^zt0^RI2CEd<@op_M7>THc_5|Tcyz7E<2k?~ zFUekY*=Hm#ztdLLL`JRvba7ws2rl{;(myyU%Rm53zopyb3u46;Xx%&wce^5x-lv;5 zG(|gPGYBUB$r5RM)lhIja*!W;MU${@HH)d(#Ic4efSnwuSkNm&xqKJ~k5qaSUU#VO z#QC4JK{{WvL+qi1uw5t{-tO#ujqUS52`<{eZS({LR#5u=U zYmqi9ckcc(Il!uZz>-e#K(aIm&xNn@GrdHes{*(jY1K%&>^^u*Y~ zzS?QIO`T5GDEsNKuGSSZZkl)RN@ZuJSxRYr|7(+SFka8SU$UiJdk?bHCM@QnnQEwE zXea;<)eoOLQ)|nEeN9*;gu=n|DFHD$23Drk$|^!(NV)IiB!ZYkccBJ0orOO0tt?K_H29i$$S# zki<#sDZ#n?@(cXemh)jZ`7ZcIfE@H?d;*u61R5tcpQZI|)3f&knhh$Jee9zi8QWYq z0qC%0TV_W8hv8G26-7G3l8DW=rKF1>qY-|H@Rv4+R}Jl&7cG%%$udmYeZgHaPYARA z=S087bpurkDG0heMNgzsURh_btmvN$3gNdZ{ILa`L}%3XwcDxM_8)sW%;$*<&cRN; znn>H2cN6jbEw>Fin?{5k`#mGPy=;W7W=JG-4OrJg`);S5i8mMf4uc;3>xS10mQS%2 z2C{Qu+^XM(zF2dYoU(0Lz&7`xri&`l1N|O}?Xg8&c2sIiRf~x0`;)%bRIl7@4WR_c ztyY%JB7X3{i4~oz+=>V+GAO0hL9m%7I}AAA=3V}}jgWvhc`lh-=N*(8;-wiDe~odcVToPeM%z5+80v8Qk2dZu31+uNJn_a#KFN*0;L093Aw4*N=!VCM-I}G}@ab zlbHO785^k_t zJ7D!>S+V#{ShW`{X}`FUr6TpExt?WSslVn5TG69DPS~vyR72?vGHQJ@iAJc}XcC&g zv*pITD-s;60i5Cst362DOrAcr_gp7GQl>JpBf(Yzu$BR{+d?XjchtGD8ZEPYLGBRp zIYf2qeCu_<#0N94W0=)P`D$@~F)jXzZBM%+L8%Y>SZUY(4_0#Ir^)_2R7e9hw6$QQ z3}_`Jqpa8OAGKd=Y*&2DI=1jDMR)LGrwH3&c-z> z-Z&T}ST;cr3zUI4u|YF<0s=2rsBQ9@k5LL z51n=lqzk2PRUO!r_kgNGQb(C@og5!%(@67rewgT9deC5As_b>L_mm$Z=V(hIn`u5a zIKYN&7wbhe{5kwisaN{rabq+UiuK6!;!TR+qg!q>#EaNG!P6N?Ec8EaKIv_F2h4yq>H7(J=|dw{(g%IiwOGcb^Mr5Jk$B$!blFxQ}~hMYo@1>|Se-*J1O zbPQp3j1pc&5MC#wk{3<^x{{tmp433WTWL&bC$vrxj-HIuJEk$ z?n^fP5H{nz(CiHxVs-bYheHj!atm`wSzGuSa%gKzrn%`=x$Kum4zZk<5kDj@Q>$pM z1!p^s*zxlBO3RGXPN#M8sco;(^0Saa@2Qm$qf;XuR#PA;{!+R}1{aX@^}NWd4xA)R zC3A|P*p6E{oL{&AJ=(m(Wf9;m47uo3L9rL7@zpogK-#xDI&S5Ew;rMP6Z~z)e*3*W Qe)@oso~dqyw*8a;0`Ntk>i_@% literal 0 HcmV?d00001 diff --git a/debugger/vscode-dap-extension/package-lock.json b/debugger/vscode-dap-extension/package-lock.json new file mode 100644 index 00000000..6c5bf504 --- /dev/null +++ b/debugger/vscode-dap-extension/package-lock.json @@ -0,0 +1,5280 @@ +{ + "name": "starlingmonkey-debugger", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "starlingmonkey-debugger", + "version": "0.1.0", + "license": "Apache-2.0 WITH LLVM-exception", + "devDependencies": { + "@types/glob": "8.1.0", + "@types/mocha": "10.0.10", + "@types/node": "22.10.0", + "@types/path-browserify": "^1.0.3", + "@types/vscode": "^1.95.0", + "@typescript-eslint/eslint-plugin": "8.16.0", + "@typescript-eslint/parser": "8.16.0", + "@vscode/debugadapter": "^1.68.0", + "@vscode/debugadapter-testsupport": "^1.68.0", + "@vscode/vsce": "^3.2.1", + "esbuild": "0.24.0", + "eslint": "9.15.0", + "events": "^3.3.0", + "glob": "11.0.0", + "mocha": "11.0.0", + "path-browserify": "^1.0.1", + "rimraf": "6.0.1", + "typescript": "5.7.2" + }, + "engines": { + "vscode": "^1.95.0" + } + }, + "node_modules/@azure/abort-controller": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz", + "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-auth": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.9.0.tgz", + "integrity": "sha512-FPwHpZywuyasDSLMqJ6fhbOK3TqUdviZNF8OqRGA4W5Ewib2lEEZ+pBsYcBa88B2NGO/SEnYPGhyBqNlE8ilSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "@azure/core-util": "^1.11.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-client": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.9.2.tgz", + "integrity": "sha512-kRdry/rav3fUKHl/aDLd/pDLcB+4pOFwPPTVEExuMyaI5r+JBbMWqRbCY1pn5BniDaU3lRxO9eaQ1AmSMehl/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "@azure/core-auth": "^1.4.0", + "@azure/core-rest-pipeline": "^1.9.1", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.6.1", + "@azure/logger": "^1.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-rest-pipeline": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.18.0.tgz", + "integrity": "sha512-QSoGUp4Eq/gohEFNJaUOwTN7BCc2nHTjjbm75JT0aD7W65PWM1H/tItz0GsABn22uaKyGxiMhWQLt2r+FGU89Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "@azure/core-auth": "^1.8.0", + "@azure/core-tracing": "^1.0.1", + "@azure/core-util": "^1.11.0", + "@azure/logger": "^1.0.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-tracing": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.2.0.tgz", + "integrity": "sha512-UKTiEJPkWcESPYJz3X5uKRYyOcJD+4nYph+KpfdPRnQJVrZfk0KJgdnaAWKfhsBBtAf/D58Az4AvCJEmWgIBAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-util": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.11.0.tgz", + "integrity": "sha512-DxOSLua+NdpWoSqULhjDyAZTXFdP/LKkqtYuxxz1SCN289zk3OG8UOpnCQAz/tygyACBtWp/BoO72ptK7msY8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/identity": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-4.5.0.tgz", + "integrity": "sha512-EknvVmtBuSIic47xkOqyNabAme0RYTw52BTMz8eBgU1ysTyMrD1uOoM+JdS0J/4Yfp98IBT3osqq3BfwSaNaGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "@azure/core-auth": "^1.9.0", + "@azure/core-client": "^1.9.2", + "@azure/core-rest-pipeline": "^1.17.0", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.11.0", + "@azure/logger": "^1.0.0", + "@azure/msal-browser": "^3.26.1", + "@azure/msal-node": "^2.15.0", + "events": "^3.0.0", + "jws": "^4.0.0", + "open": "^8.0.0", + "stoppable": "^1.1.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/logger": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.1.4.tgz", + "integrity": "sha512-4IXXzcCdLdlXuCG+8UKEwLA1T1NHqUfanhXYHiQTn+6sfWCZXduqbtXDGceg3Ce5QxTGo7EqmbV6Bi+aqKuClQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/msal-browser": { + "version": "3.27.0", + "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-3.27.0.tgz", + "integrity": "sha512-+b4ZKSD8+vslCtVRVetkegEhOFMLP3rxDWJY212ct+2r6jVg6OSQKc1Qz3kCoXo0FgwaXkb+76TMZfpHp8QtgA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@azure/msal-common": "14.16.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@azure/msal-common": { + "version": "14.16.0", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-14.16.0.tgz", + "integrity": "sha512-1KOZj9IpcDSwpNiQNjt0jDYZpQvNZay7QAEi/5DLubay40iGYtLzya/jbjRPLyOTZhEKyL1MzPuw2HqBCjceYA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@azure/msal-node": { + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-2.16.2.tgz", + "integrity": "sha512-An7l1hEr0w1HMMh1LU+rtDtqL7/jw74ORlc9Wnh06v7TU/xpG39/Zdr1ZJu3QpjUfKJ+E0/OXMW8DRSWTlh7qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@azure/msal-common": "14.16.0", + "jsonwebtoken": "^9.0.0", + "uuid": "^8.3.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.0.tgz", + "integrity": "sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.0.tgz", + "integrity": "sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.0.tgz", + "integrity": "sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.0.tgz", + "integrity": "sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.0.tgz", + "integrity": "sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.0.tgz", + "integrity": "sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.0.tgz", + "integrity": "sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.0.tgz", + "integrity": "sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.0.tgz", + "integrity": "sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.0.tgz", + "integrity": "sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.0.tgz", + "integrity": "sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.0.tgz", + "integrity": "sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.0.tgz", + "integrity": "sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.0.tgz", + "integrity": "sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.0.tgz", + "integrity": "sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.0.tgz", + "integrity": "sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.0.tgz", + "integrity": "sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.0.tgz", + "integrity": "sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.0.tgz", + "integrity": "sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.0.tgz", + "integrity": "sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.0.tgz", + "integrity": "sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.0.tgz", + "integrity": "sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.0.tgz", + "integrity": "sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.0.tgz", + "integrity": "sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.0.tgz", + "integrity": "sha512-zdHg2FPIFNKPdcHWtiNT+jEFCHYVplAXRDlQDyqy0zGx/q2parwh7brGJSiTxRk/TSMkbM//zt/f5CHgyTyaSQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.4", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.9.0.tgz", + "integrity": "sha512-7ATR9F0e4W85D/0w7cU0SNj7qkAexMG+bAHEZOjo9akvGuhHE2m7umzWzfnpa0XAg5Kxc1BWmtPMV67jJ+9VUg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "9.15.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.15.0.tgz", + "integrity": "sha512-tMTqrY+EzbXmKJR5ToI8lxu7jaN5EdmrBFJpQk5JmSlyLsx6o4t27r883K5xsLuCYCpfKBCGswMSWXsM+jB7lg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", + "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.3.tgz", + "integrity": "sha512-2b/g5hRmpbb1o4GnTZax9N9m0FXzz9OV42ZzI4rDDMDuHUqigAiQCEWChBWCY4ztAGVRjoWT19v0yMmc5/L5kA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz", + "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/minimatch": "^5.1.2", + "@types/node": "*" + } + }, + "node_modules/@types/json-schema": { + "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": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mocha": { + "version": "10.0.10", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz", + "integrity": "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz", + "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "node_modules/@types/path-browserify": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/path-browserify/-/path-browserify-1.0.3.tgz", + "integrity": "sha512-ZmHivEbNCBtAfcrFeBCiTjdIc2dey0l7oCGNGpSuRTy8jP6UVND7oUowlvDujBy8r2Hoa8bfFUOCiPWfmtkfxw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/vscode": { + "version": "1.95.0", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.95.0.tgz", + "integrity": "sha512-0LBD8TEiNbet3NvWsmn59zLzOFu/txSlGxnv5yAFHCrhG9WvAnR3IvfHzMOs2aeWqgvNjq9pO99IUw8d3n+unw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.16.0.tgz", + "integrity": "sha512-5YTHKV8MYlyMI6BaEG7crQ9BhSc8RxzshOReKwZwRWN0+XvvTOm+L/UYLCYxFpfwYuAAqhxiq4yae0CMFwbL7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.16.0", + "@typescript-eslint/type-utils": "8.16.0", + "@typescript-eslint/utils": "8.16.0", + "@typescript-eslint/visitor-keys": "8.16.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.16.0.tgz", + "integrity": "sha512-D7DbgGFtsqIPIFMPJwCad9Gfi/hC0PWErRRHFnaCWoEDYi5tQUDiJCTmGUbBiLzjqAck4KcXt9Ayj0CNlIrF+w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/scope-manager": "8.16.0", + "@typescript-eslint/types": "8.16.0", + "@typescript-eslint/typescript-estree": "8.16.0", + "@typescript-eslint/visitor-keys": "8.16.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.16.0.tgz", + "integrity": "sha512-mwsZWubQvBki2t5565uxF0EYvG+FwdFb8bMtDuGQLdCCnGPrDEDvm1gtfynuKlnpzeBRqdFCkMf9jg1fnAK8sg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.16.0", + "@typescript-eslint/visitor-keys": "8.16.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.16.0.tgz", + "integrity": "sha512-IqZHGG+g1XCWX9NyqnI/0CX5LL8/18awQqmkZSl2ynn8F76j579dByc0jhfVSnSnhf7zv76mKBQv9HQFKvDCgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "8.16.0", + "@typescript-eslint/utils": "8.16.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.16.0.tgz", + "integrity": "sha512-NzrHj6thBAOSE4d9bsuRNMvk+BvaQvmY4dDglgkgGC0EW/tB3Kelnp3tAKH87GEwzoxgeQn9fNGRyFJM/xd+GQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.16.0.tgz", + "integrity": "sha512-E2+9IzzXMc1iaBy9zmo+UYvluE3TW7bCGWSF41hVWUE01o8nzr1rvOQYSxelxr6StUvRcTMe633eY8mXASMaNw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "8.16.0", + "@typescript-eslint/visitor-keys": "8.16.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "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==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.16.0.tgz", + "integrity": "sha512-C1zRy/mOL8Pj157GiX4kaw7iyRLKfJXBR3L82hk5kS/GyHcOFmy4YUq/zfZti72I9wnuQtA/+xzft4wCC8PJdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.16.0", + "@typescript-eslint/types": "8.16.0", + "@typescript-eslint/typescript-estree": "8.16.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.16.0.tgz", + "integrity": "sha512-pq19gbaMOmFE3CbL0ZB8J8BFCo2ckfHBfaIsaOZgBIF4EoISJIdLX5xRhd0FGB0LlHReNRuzoJoMGpTjq8F2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.16.0", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/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==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@vscode/debugadapter": { + "version": "1.68.0", + "resolved": "https://registry.npmjs.org/@vscode/debugadapter/-/debugadapter-1.68.0.tgz", + "integrity": "sha512-D6gk5Fw2y4FV8oYmltoXpj+VAZexxJFopN/mcZ6YcgzQE9dgq2L45Aj3GLxScJOD6GeLILcxJIaA8l3v11esGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vscode/debugprotocol": "1.68.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@vscode/debugadapter-testsupport": { + "version": "1.68.0", + "resolved": "https://registry.npmjs.org/@vscode/debugadapter-testsupport/-/debugadapter-testsupport-1.68.0.tgz", + "integrity": "sha512-UpbaPsCGMKyjIvJFtqFKDD1MVvME50xuOtRBPrqY1WdhAOLjWQN7FcKEoHv3X85twfNL21jW2M54FYwEdEQv4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vscode/debugprotocol": "1.68.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@vscode/debugprotocol": { + "version": "1.68.0", + "resolved": "https://registry.npmjs.org/@vscode/debugprotocol/-/debugprotocol-1.68.0.tgz", + "integrity": "sha512-2J27dysaXmvnfuhFGhfeuxfHRXunqNPxtBoR3koiTOA9rdxWNDTa1zIFLCFMSHJ9MPTPKFcBeblsyaCJCIlQxg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vscode/vsce": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@vscode/vsce/-/vsce-3.2.1.tgz", + "integrity": "sha512-AY9vBjwExakK1c0cI/3NN2Ey0EgiKLBye/fxl/ue+o4q6RZ7N+xzd1jAD6eI6eBeMVANi617+V2rxIAkDPco2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@azure/identity": "^4.1.0", + "@vscode/vsce-sign": "^2.0.0", + "azure-devops-node-api": "^12.5.0", + "chalk": "^2.4.2", + "cheerio": "^1.0.0-rc.9", + "cockatiel": "^3.1.2", + "commander": "^6.2.1", + "form-data": "^4.0.0", + "glob": "^11.0.0", + "hosted-git-info": "^4.0.2", + "jsonc-parser": "^3.2.0", + "leven": "^3.1.0", + "markdown-it": "^14.1.0", + "mime": "^1.3.4", + "minimatch": "^3.0.3", + "parse-semver": "^1.1.1", + "read": "^1.0.7", + "semver": "^7.5.2", + "tmp": "^0.2.3", + "typed-rest-client": "^1.8.4", + "url-join": "^4.0.1", + "xml2js": "^0.5.0", + "yauzl": "^2.3.1", + "yazl": "^2.2.2" + }, + "bin": { + "vsce": "vsce" + }, + "engines": { + "node": ">= 20" + }, + "optionalDependencies": { + "keytar": "^7.7.0" + } + }, + "node_modules/@vscode/vsce-sign": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign/-/vsce-sign-2.0.5.tgz", + "integrity": "sha512-GfYWrsT/vypTMDMgWDm75iDmAOMe7F71sZECJ+Ws6/xyIfmB3ELVnVN+LwMFAvmXY+e6eWhR2EzNGF/zAhWY3Q==", + "dev": true, + "hasInstallScript": true, + "license": "SEE LICENSE IN LICENSE.txt", + "optionalDependencies": { + "@vscode/vsce-sign-alpine-arm64": "2.0.2", + "@vscode/vsce-sign-alpine-x64": "2.0.2", + "@vscode/vsce-sign-darwin-arm64": "2.0.2", + "@vscode/vsce-sign-darwin-x64": "2.0.2", + "@vscode/vsce-sign-linux-arm": "2.0.2", + "@vscode/vsce-sign-linux-arm64": "2.0.2", + "@vscode/vsce-sign-linux-x64": "2.0.2", + "@vscode/vsce-sign-win32-arm64": "2.0.2", + "@vscode/vsce-sign-win32-x64": "2.0.2" + } + }, + "node_modules/@vscode/vsce-sign-alpine-arm64": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-alpine-arm64/-/vsce-sign-alpine-arm64-2.0.2.tgz", + "integrity": "sha512-E80YvqhtZCLUv3YAf9+tIbbqoinWLCO/B3j03yQPbjT3ZIHCliKZlsy1peNc4XNZ5uIb87Jn0HWx/ZbPXviuAQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "SEE LICENSE IN LICENSE.txt", + "optional": true, + "os": [ + "alpine" + ] + }, + "node_modules/@vscode/vsce-sign-alpine-x64": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-alpine-x64/-/vsce-sign-alpine-x64-2.0.2.tgz", + "integrity": "sha512-n1WC15MSMvTaeJ5KjWCzo0nzjydwxLyoHiMJHu1Ov0VWTZiddasmOQHekA47tFRycnt4FsQrlkSCTdgHppn6bw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "SEE LICENSE IN LICENSE.txt", + "optional": true, + "os": [ + "alpine" + ] + }, + "node_modules/@vscode/vsce-sign-darwin-arm64": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-darwin-arm64/-/vsce-sign-darwin-arm64-2.0.2.tgz", + "integrity": "sha512-rz8F4pMcxPj8fjKAJIfkUT8ycG9CjIp888VY/6pq6cuI2qEzQ0+b5p3xb74CJnBbSC0p2eRVoe+WgNCAxCLtzQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "SEE LICENSE IN LICENSE.txt", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@vscode/vsce-sign-darwin-x64": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-darwin-x64/-/vsce-sign-darwin-x64-2.0.2.tgz", + "integrity": "sha512-MCjPrQ5MY/QVoZ6n0D92jcRb7eYvxAujG/AH2yM6lI0BspvJQxp0o9s5oiAM9r32r9tkLpiy5s2icsbwefAQIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "SEE LICENSE IN LICENSE.txt", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@vscode/vsce-sign-linux-arm": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-arm/-/vsce-sign-linux-arm-2.0.2.tgz", + "integrity": "sha512-Fkb5jpbfhZKVw3xwR6t7WYfwKZktVGNXdg1m08uEx1anO0oUPUkoQRsNm4QniL3hmfw0ijg00YA6TrxCRkPVOQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "SEE LICENSE IN LICENSE.txt", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@vscode/vsce-sign-linux-arm64": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-arm64/-/vsce-sign-linux-arm64-2.0.2.tgz", + "integrity": "sha512-Ybeu7cA6+/koxszsORXX0OJk9N0GgfHq70Wqi4vv2iJCZvBrOWwcIrxKjvFtwyDgdeQzgPheH5nhLVl5eQy7WA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "SEE LICENSE IN LICENSE.txt", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@vscode/vsce-sign-linux-x64": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-x64/-/vsce-sign-linux-x64-2.0.2.tgz", + "integrity": "sha512-NsPPFVtLaTlVJKOiTnO8Cl78LZNWy0Q8iAg+LlBiCDEgC12Gt4WXOSs2pmcIjDYzj2kY4NwdeN1mBTaujYZaPg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "SEE LICENSE IN LICENSE.txt", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@vscode/vsce-sign-win32-arm64": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-win32-arm64/-/vsce-sign-win32-arm64-2.0.2.tgz", + "integrity": "sha512-wPs848ymZ3Ny+Y1Qlyi7mcT6VSigG89FWQnp2qRYCyMhdJxOpA4lDwxzlpL8fG6xC8GjQjGDkwbkWUcCobvksQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "SEE LICENSE IN LICENSE.txt", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@vscode/vsce-sign-win32-x64": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-win32-x64/-/vsce-sign-win32-x64-2.0.2.tgz", + "integrity": "sha512-pAiRN6qSAhDM5SVOIxgx+2xnoVUePHbRNC7OD2aOR3WltTKxxF25OfpK8h8UQ7A0BuRkSgREbB59DBlFk4iAeg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "SEE LICENSE IN LICENSE.txt", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/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": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "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", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/azure-devops-node-api": { + "version": "12.5.0", + "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-12.5.0.tgz", + "integrity": "sha512-R5eFskGvOm3U/GzeAuxRkUsAl0hrAwGgWn6zAd2KrZmrEhWZVqLew4OOupbQlXUuojUzpGtq62SmdhJ06N88og==", + "dev": true, + "license": "MIT", + "dependencies": { + "tunnel": "0.0.6", + "typed-rest-client": "^1.8.4" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true, + "license": "ISC" + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true, + "license": "ISC" + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cheerio": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz", + "integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "encoding-sniffer": "^0.2.0", + "htmlparser2": "^9.1.0", + "parse5": "^7.1.2", + "parse5-htmlparser2-tree-adapter": "^7.0.0", + "parse5-parser-stream": "^7.1.2", + "undici": "^6.19.5", + "whatwg-mimetype": "^4.0.0" + }, + "engines": { + "node": ">=18.17" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true, + "license": "ISC", + "optional": true + }, + "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==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/cockatiel": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/cockatiel/-/cockatiel-3.2.1.tgz", + "integrity": "sha512-gfrHV6ZPkquExvMh9IOkKsBzNDk6sDuZ6DdBGUBkvFnTCqCxzpuq48RySgP0AnaqQkw2zynOFj9yly6T1Q2G5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/encoding-sniffer": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz", + "integrity": "sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.3", + "whatwg-encoding": "^3.1.1" + }, + "funding": { + "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.0.tgz", + "integrity": "sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.24.0", + "@esbuild/android-arm": "0.24.0", + "@esbuild/android-arm64": "0.24.0", + "@esbuild/android-x64": "0.24.0", + "@esbuild/darwin-arm64": "0.24.0", + "@esbuild/darwin-x64": "0.24.0", + "@esbuild/freebsd-arm64": "0.24.0", + "@esbuild/freebsd-x64": "0.24.0", + "@esbuild/linux-arm": "0.24.0", + "@esbuild/linux-arm64": "0.24.0", + "@esbuild/linux-ia32": "0.24.0", + "@esbuild/linux-loong64": "0.24.0", + "@esbuild/linux-mips64el": "0.24.0", + "@esbuild/linux-ppc64": "0.24.0", + "@esbuild/linux-riscv64": "0.24.0", + "@esbuild/linux-s390x": "0.24.0", + "@esbuild/linux-x64": "0.24.0", + "@esbuild/netbsd-x64": "0.24.0", + "@esbuild/openbsd-arm64": "0.24.0", + "@esbuild/openbsd-x64": "0.24.0", + "@esbuild/sunos-x64": "0.24.0", + "@esbuild/win32-arm64": "0.24.0", + "@esbuild/win32-ia32": "0.24.0", + "@esbuild/win32-x64": "0.24.0" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint": { + "version": "9.15.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.15.0.tgz", + "integrity": "sha512-7CrWySmIibCgT1Os28lUU6upBshZ+GxybLOrmRzi08kS8MBuO8QA7pXEgYgY5W8vK3e74xv0lpjo9DbaGU9Rkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.19.0", + "@eslint/core": "^0.9.0", + "@eslint/eslintrc": "^3.2.0", + "@eslint/js": "9.15.0", + "@eslint/plugin-kit": "^0.2.3", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.1", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.5", + "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", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", + "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/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==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/espree": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.14.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree/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==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "dev": true, + "license": "(MIT OR WTFPL)", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "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" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "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==", + "dev": true, + "license": "ISC" + }, + "node_modules/foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/form-data": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "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", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "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/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/glob": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.0.tgz", + "integrity": "sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^4.0.1", + "minimatch": "^10.0.0", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", + "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/htmlparser2": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", + "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "entities": "^4.5.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause", + "optional": true + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC", + "optional": true + }, + "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-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/jackspeak": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.2.tgz", + "integrity": "sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsonwebtoken": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jsonwebtoken/node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jsonwebtoken/node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "dev": true, + "license": "MIT", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jwa": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/keytar": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/keytar/-/keytar-7.9.0.tgz", + "integrity": "sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-addon-api": "^4.3.0", + "prebuild-install": "^7.0.1" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "uc.micro": "^2.0.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/log-symbols/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-symbols/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/log-symbols/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/markdown-it": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, + "node_modules/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "dev": true, + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=10" + }, + "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==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "optional": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/mocha": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.0.0.tgz", + "integrity": "sha512-9VQaK0N4YQ2F89Vy4wTIEyTm/Ggcv1PejfVeI82wOw0vBO6BjFyBGHCiNbl+wyHmgWDyFmHb2Yw1QlLaWzaEoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.3", + "browser-stdout": "^1.3.1", + "chokidar": "^3.5.3", + "debug": "^4.3.5", + "diff": "^5.2.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^8.1.0", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^5.1.6", + "ms": "^2.1.3", + "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", + "yargs-unparser": "^2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/mocha/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/mocha/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true, + "license": "ISC" + }, + "node_modules/napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-abi": { + "version": "3.71.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.71.0.tgz", + "integrity": "sha512-SZ40vRiy/+wRTf21hxkkEjPJZpARzUMVcJoQse2EF8qkUWbbO2z7vd5oA/H6bVH6SZQ5STGcu0KRDS7biNRfxw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-addon-api": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", + "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==", + "dev": true, + "license": "MIT", + "optional": true + }, + "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/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/object-inspect": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", + "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-semver": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/parse-semver/-/parse-semver-1.1.1.tgz", + "integrity": "sha512-Eg1OuNntBMH0ojvEKSrvDSnwLmvVuUOSdylH/pSCPNMIspLlweJyIWXCE+k/5hm3cj/EBUYwmWkjhBALNP4LXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^5.1.0" + } + }, + "node_modules/parse-semver/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/parse5": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", + "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^4.5.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", + "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "domhandler": "^5.0.3", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-parser-stream": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", + "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", + "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.2.tgz", + "integrity": "sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true, + "license": "MIT" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/prebuild-install": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz", + "integrity": "sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/pump": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", + "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.1.tgz", + "integrity": "sha512-EJPeIn0CYrGu+hli1xilKAPXODtJ12T0sP63Ijx2/khC2JtuaN3JyNIpvmnkmaEtha9ocbG4A4cMcr+TvqvwQg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "optional": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", + "integrity": "sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "mute-stream": "~0.0.4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.0.1.tgz", + "integrity": "sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^11.0.0", + "package-json-from-dist": "^1.0.0" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/sax": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", + "dev": true, + "license": "ISC" + }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true + }, + "node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/stoppable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz", + "integrity": "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4", + "npm": ">=6" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tmp": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.14" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-api-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.0.tgz", + "integrity": "sha512-032cPxaEKwM+GT3vA5JXNzIaizx388rhsSW79vGRNGXfRRAdEAn2mvk36PvK5HnOchyWZ7afLEXqYCvPCrzuzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, + "node_modules/tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6.11 <=0.7.0 || >=0.7.3" + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/typed-rest-client": { + "version": "1.8.11", + "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.11.tgz", + "integrity": "sha512-5UvfMpd1oelmUPRbbaVnq+rHP7ng2cE4qoQkQeAqxRL6PklkxsM0g32/HL0yfvruK6ojQ5x8EE+HF4YV6DtuCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "qs": "^6.9.1", + "tunnel": "0.0.6", + "underscore": "^1.12.1" + } + }, + "node_modules/typescript": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", + "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "dev": true, + "license": "MIT" + }, + "node_modules/underscore": { + "version": "1.13.7", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.7.tgz", + "integrity": "sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==", + "dev": true, + "license": "MIT" + }, + "node_modules/undici": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.0.tgz", + "integrity": "sha512-BUgJXc752Kou3oOIuU1i+yZZypyZRqNPW0vqoMPl8VaoalSfeR0D8/t4iAS3yirs79SSMTxTag+ZC86uswv+Cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, + "node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true, + "license": "MIT" + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", + "dev": true, + "license": "MIT" + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT", + "optional": true + }, + "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==", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/workerpool": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/xml2js": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", + "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "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==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yazl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", + "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/debugger/vscode-dap-extension/package.json b/debugger/vscode-dap-extension/package.json new file mode 100644 index 00000000..15bafc30 --- /dev/null +++ b/debugger/vscode-dap-extension/package.json @@ -0,0 +1,216 @@ +{ + "name": "starlingmonkey-debugger", + "displayName": "StarlingMonkey Debugger", + "version": "0.1.0", + "publisher": "bytecodealliance", + "description": "Debugger for the StarlingMonkey JS runtime", + "author": { + "name": "The Bytecode Alliance Contributors" + }, + "license": "Apache-2.0 WITH LLVM-exception", + "keywords": [ + "multi-root ready" + ], + "engines": { + "vscode": "^1.95.0" + }, + "icon": "images/starlingmonkey-logo.png", + "categories": [ + "Debuggers" + ], + "private": false, + "repository": { + "type": "git", + "url": "https://github.com/BytecodeAlliance/StarlingMonkey.git" + }, + "bugs": { + "url": "https://github.com/BytecodeAlliance/StarlingMonkey/issues" + }, + "scripts": { + "compile": "tsc -p ./", + "lint": "eslint src starling-debugger --ext ts", + "typecheck": "tsc -p tsconfig.json --noEmit", + "esbuild-extension": "esbuild ./src/extension.ts --bundle --tsconfig=./tsconfig.json --external:vscode --format=cjs --platform=node --outfile=dist/extension.js", + "esbuild-debugger": "esbuild ./starling-debugger/debugger.ts --bundle --tsconfig=./tsconfig.json --format=cjs --platform=node --outfile=dist/debugger.js", + "esbuild-all": "npm run esbuild-extension && npm run esbuild-debugger", + "watch": "npm run -S esbuild-all -- --sourcemap --sources-content=false --watch", + "build": "npm run -S esbuild-all -- --sourcemap --sources-content=false", + "package": "vsce package", + "publish": "vsce publish", + "publish-pre-release": "vsce publish --pre-release", + "vscode:prepublish": "rimraf dist && npm run -S esbuild-all -- --minify", + "test": "npm run typecheck" + }, + "devDependencies": { + "@types/glob": "8.1.0", + "@types/mocha": "10.0.10", + "@types/node": "22.10.0", + "@types/path-browserify": "^1.0.3", + "@types/vscode": "^1.95.0", + "@typescript-eslint/eslint-plugin": "8.16.0", + "@typescript-eslint/parser": "8.16.0", + "@vscode/debugadapter": "^1.68.0", + "@vscode/debugadapter-testsupport": "^1.68.0", + "@vscode/vsce": "^3.2.1", + "esbuild": "0.24.0", + "eslint": "9.15.0", + "events": "^3.3.0", + "glob": "11.0.0", + "mocha": "11.0.0", + "path-browserify": "^1.0.1", + "rimraf": "6.0.1", + "typescript": "5.7.2" + }, + "main": "./dist/extension.js", + "activationEvents": [ + "onDebugResolve:starlingmonkey", + "onDebugDynamicConfigurations:starlingmonkey", + "onCommand:extension.starlingmonkey-debugger.getProgramName", + "onCommand:extension.starlingmonkey-debugger.getComponent" + ], + "workspaceTrust": { + "request": "never" + }, + "contributes": { + "menus": { + "editor/title/run": [ + { + "command": "extension.starlingmonkey-debugger.runEditorContents", + "when": "resourceLangId == javascript", + "group": "navigation@1" + }, + { + "command": "extension.starlingmonkey-debugger.debugEditorContents", + "when": "resourceLangId == javascript", + "group": "navigation@2" + } + ], + "commandPalette": [ + { + "command": "extension.starlingmonkey-debugger.debugEditorContents", + "when": "resourceLangId == javascript" + }, + { + "command": "extension.starlingmonkey-debugger.runEditorContents", + "when": "resourceLangId == javascript" + } + ] + }, + "commands": [ + { + "command": "extension.starlingmonkey-debugger.debugEditorContents", + "title": "Debug File", + "category": "StarlingMonkey Debugger", + "enablement": "!inDebugMode", + "icon": "$(debug-alt)" + }, + { + "command": "extension.starlingmonkey-debugger.runEditorContents", + "title": "Run File", + "category": "StarlingMonkey Debugger", + "enablement": "!inDebugMode", + "icon": "$(play)" + } + ], + "breakpoints": [ + { + "language": "javascript" + } + ], + "debuggers": [ + { + "type": "starlingmonkey", + "languages": [ + "javascript" + ], + "label": "StarlingMonkey Debugger", + "configurationAttributes": { + "launch": { + "required": [ + "program", + "component" + ], + "properties": { + "program": { + "type": "string", + "description": "Absolute path to a JS file to debug.", + "default": "${workspaceFolder}/${command:AskForProgramName}" + }, + "component": { + "type": "string", + "description": "Absolute path to a StarlingMonkey component to use for debugging.", + "default": "${workspaceFolder}/${command:AskForComponent}" + }, + "stopOnEntry": { + "type": "boolean", + "description": "Automatically stop after launch.", + "default": true + }, + "trace": { + "type": "boolean", + "description": "Enable logging of the Debug Adapter Protocol.", + "default": false + } + } + } + }, + "initialConfigurations": [ + { + "type": "starlingmonkey", + "request": "launch", + "name": "Ask for file name", + "program": "${workspaceFolder}/${command:AskForProgramName}", + "component": "${workspaceFolder}/${command:AskForComponent}", + "stopOnEntry": true + } + ], + "configurationSnippets": [ + { + "label": "StarlingMonkey Debugger: Launch", + "description": "A new configuration for debugging JS code running in StarlingMonkey.", + "body": { + "type": "starlingmonkey", + "request": "launch", + "name": "Ask for file name", + "program": "^\"\\${workspaceFolder}/\\${command:AskForProgramName}\"", + "component": "^\"\\${workspaceFolder}/\\${command:AskForComponent}\"", + "stopOnEntry": true + } + } + ], + "variables": { + "AskForProgramName": "extension.starlingmonkey-debugger.getProgramName", + "AskForComponent": "extension.starlingmonkey-debugger.getComponent" + } + } + ], + "configuration": [ + { + "title": "StarlingMonkey Debugger", + "properties": { + "starlingmonkey.componentRuntime.executable": { + "type": "string", + "default": "wasmtime", + "scope": "machine-overridable", + "description": "The runtime to use for debugging StarlingMonkey components." + }, + "starlingmonkey.componentRuntime.options": { + "type": "array", + "items": { + "type": "string" + }, + "default": ["serve", "-S", "cli,tcp,inherit-network", "--env", "STARLINGMONKEY_CONFIG=--verbose -d", "--dir", "${workspaceFolder}::/", "--addr", "0.0.0.0:8080"], + "scope": "machine-overridable", + "description": "CLI options to pass to the component runtime. The component to debug will always be appended to this list, and `${workspaceFolder}` will be replaced with the path to the workspace folder." + }, + "starlingmonkey.componentRuntime.envOption": { + "type": "string", + "default": "--env", + "scope": "machine-overridable", + "description": "Name of the CLI option to use for setting environment variables in the component runtime. This option might be passed multiple times, with the variables provided in the format =." + } + } + } + ] + } +} diff --git a/debugger/vscode-dap-extension/sampleWorkspace/.vscode/launch.json b/debugger/vscode-dap-extension/sampleWorkspace/.vscode/launch.json new file mode 100644 index 00000000..46601e10 --- /dev/null +++ b/debugger/vscode-dap-extension/sampleWorkspace/.vscode/launch.json @@ -0,0 +1,17 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "starlingmonkey", + "request": "launch", + "name": "Debug main.js", + "program": "${workspaceFolder}/main.js", + "component": "${workspaceFolder}/out/main.wasm", + "stopOnEntry": false, + "trace": true + } + ] +} diff --git a/debugger/vscode-dap-extension/sampleWorkspace/main.js b/debugger/vscode-dap-extension/sampleWorkspace/main.js new file mode 100644 index 00000000..16cc041c --- /dev/null +++ b/debugger/vscode-dap-extension/sampleWorkspace/main.js @@ -0,0 +1,23 @@ +var v = "bar"; +console.log("hello."); +addEventListener('fetch', (event) => { + foo(event); +}); + +function foo(ev) { + let arr = [1, 2, 3]; + let obj = { + a: 1, + b: 2, + c: 3 + }; + let re = /a/; + bar(ev); + console.log("hello from foo"); +} + +function bar(evt) { + let body = 'Hello from content!'; + let resp = new Response(body); + evt.respondWith(resp); +} diff --git a/debugger/vscode-dap-extension/src/activateStarlingMonkeyDebugger.ts b/debugger/vscode-dap-extension/src/activateStarlingMonkeyDebugger.ts new file mode 100644 index 00000000..8e44ea85 --- /dev/null +++ b/debugger/vscode-dap-extension/src/activateStarlingMonkeyDebugger.ts @@ -0,0 +1,203 @@ +import { + WorkspaceFolder, + DebugConfiguration, + ProviderResult, + CancellationToken, + commands, + debug, + DebugAdapterDescriptor, + DebugAdapterDescriptorFactory, + DebugAdapterInlineImplementation, + DebugConfigurationProvider, + DebugConfigurationProviderTriggerKind, + DebugSession, + ExtensionContext, + Uri, + window, + workspace, +} from "vscode"; +import { StarlingMonkeyDebugSession } from "./starlingMonkeyDebugger.js"; +import { FileAccessor, IStarlingMonkeyRuntimeConfig } from "./starlingMonkeyRuntime.js"; + +export function activateStarlingMonkeyDebug( + context: ExtensionContext, + factory?: DebugAdapterDescriptorFactory +) { + context.subscriptions.push( + commands.registerCommand( + "extension.starlingmonkey-debugger.runEditorContents", + (resource: Uri) => { + let targetResource = resource; + if (!targetResource && window.activeTextEditor) { + targetResource = window.activeTextEditor.document.uri; + } + if (targetResource) { + debug.startDebugging( + undefined, + { + type: "starlingmonkey", + name: "Run File", + request: "launch", + program: targetResource.fsPath, + component: "${workspaceFolder}/${command:AskForComponent}", + }, + { noDebug: true } + ); + } + } + ), + commands.registerCommand( + "extension.starlingmonkey-debugger.debugEditorContents", + (resource: Uri) => { + let targetResource = resource; + if (!targetResource && window.activeTextEditor) { + targetResource = window.activeTextEditor.document.uri; + } + if (targetResource) { + debug.startDebugging(undefined, { + type: "starlingmonkey", + name: "Debug File", + request: "launch", + program: targetResource.fsPath, + component: "${workspaceFolder}/${command:AskForComponent}", + stopOnEntry: true, + }); + } + } + ) + ); + + context.subscriptions.push( + commands.registerCommand( + "extension.starlingmonkey-debugger.getProgramName", + (config) => { + return window.showInputBox({ + placeHolder: + "Please enter the name of a JS file in the workspace folder", + value: "index.js", + }); + } + ) + ); + + context.subscriptions.push( + commands.registerCommand( + "extension.starlingmonkey-debugger.getComponent", + (config) => { + return window.showInputBox({ + placeHolder: + "StarlingMonkey component in the workspace folder to use for debugging (e.g. 'starling.wasm')", + }); + } + ) + ); + + const provider = new StarlingMonkeyConfigurationProvider(); + context.subscriptions.push( + debug.registerDebugConfigurationProvider("starlingmonkey", provider) + ); + + context.subscriptions.push( + debug.registerDebugConfigurationProvider( + "starlingmonkey", + { + provideDebugConfigurations( + folder: WorkspaceFolder | undefined + ): ProviderResult { + return [ + { + name: "StarlingMonkey Launch", + request: "launch", + type: "starlingmonkey", + program: "${file}", + component: "${workspaceFolder}/${command:AskForComponent}", + }, + ]; + }, + }, + DebugConfigurationProviderTriggerKind.Dynamic + ) + ); + + if (!factory) { + factory = new InlineDebugAdapterFactory(); + } + context.subscriptions.push( + debug.registerDebugAdapterDescriptorFactory("starlingmonkey", factory) + ); + if ("dispose" in factory) { + context.subscriptions.push(<{ dispose(): any }>factory); + } +} + +class StarlingMonkeyConfigurationProvider + implements DebugConfigurationProvider +{ + resolveDebugConfiguration( + folder: WorkspaceFolder | undefined, + config: DebugConfiguration, + token?: CancellationToken + ): ProviderResult { + if (!config.type && !config.request && !config.name) { + const editor = window.activeTextEditor; + if (editor && editor.document.languageId === "javascript") { + config.type = "starlingmonkey"; + config.name = "Launch"; + config.request = "launch"; + config.program = "${file}"; + config.component = "${file}"; + config.stopOnEntry = true; + } + } + + if (!config.program) { + return window + .showInformationMessage("Cannot find a program to debug") + .then((_) => { + return undefined; + }); + } + + return config; + } +} + +export const workspaceFileAccessor: FileAccessor = { + isWindows: typeof process !== "undefined" && process.platform === "win32", + async readFile(path: string): Promise { + let uri: Uri; + try { + uri = pathToUri(path); + } catch (e) { + return new TextEncoder().encode(`cannot read '${path}'`); + } + + return await workspace.fs.readFile(uri); + }, + async writeFile(path: string, contents: Uint8Array) { + await workspace.fs.writeFile(pathToUri(path), contents); + }, +}; + +function pathToUri(path: string) { + try { + return Uri.file(path); + } catch (e) { + return Uri.parse(path); + } +} + +class InlineDebugAdapterFactory implements DebugAdapterDescriptorFactory { + createDebugAdapterDescriptor( + session: DebugSession + ): ProviderResult { + let config = workspace.getConfiguration("starlingmonkey"); + return new DebugAdapterInlineImplementation( + new StarlingMonkeyDebugSession( + workspaceFileAccessor, + session.workspaceFolder ? session.workspaceFolder.uri.fsPath : '/', + config + ) + ); + } +} diff --git a/debugger/vscode-dap-extension/src/debugAdapter.ts b/debugger/vscode-dap-extension/src/debugAdapter.ts new file mode 100644 index 00000000..7f1da56c --- /dev/null +++ b/debugger/vscode-dap-extension/src/debugAdapter.ts @@ -0,0 +1,48 @@ +import { StarlingMonkeyDebugSession } from "./starlingMonkeyDebugger.js"; +import { promises as fs } from "fs"; +import * as Net from "net"; +import { FileAccessor } from "./starlingMonkeyRuntime.js"; + +const fsAccessor: FileAccessor = { + isWindows: process.platform === "win32", + readFile(path: string): Promise { + return fs.readFile(path); + }, + writeFile(path: string, contents: Uint8Array): Promise { + return fs.writeFile(path, contents); + }, +}; + +const args = process.argv.slice(2); +if (args.length < 1) { + console.error("Usage: node debugAdapter.js [--server=] "); + process.exit(1); +} +const workspace = args.pop(); +let port = 0; +args.forEach(function (val) { + const portMatch = /^--server=(\d{4,5})$/.exec(val); + if (portMatch) { + port = parseInt(portMatch[1], 10); + } +}); + +// TODO: actually start the debug session once passing the correct configuration has been implemented. +// if (port > 0) { +// console.error(`waiting for debug protocol on port ${port}`); +// Net.createServer((socket) => { +// console.error(">> accepted connection from client"); +// socket.on("end", () => { +// console.error(">> client connection closed\n"); +// }); +// const session = new StarlingMonkeyDebugSession(fsAccessor, workspace); +// session.setRunAsServer(true); +// session.start(socket, socket); +// }).listen(port); +// } else { +// const session = new StarlingMonkeyDebugSession(fsAccessor, workspace); +// process.on("SIGTERM", () => { +// session.shutdown(); +// }); +// session.start(process.stdin, process.stdout); +// } diff --git a/debugger/vscode-dap-extension/src/extension.ts b/debugger/vscode-dap-extension/src/extension.ts new file mode 100644 index 00000000..89b4b4a2 --- /dev/null +++ b/debugger/vscode-dap-extension/src/extension.ts @@ -0,0 +1,68 @@ +import { Server, createServer, AddressInfo } from "net"; +import { + ExtensionContext, + DebugAdapterDescriptorFactory, + DebugSession, + DebugAdapterExecutable, + ProviderResult, + DebugAdapterDescriptor, + DebugAdapterServer, + workspace, +} from "vscode"; +import { StarlingMonkeyDebugSession } from "./starlingMonkeyDebugger.js"; +import { + activateStarlingMonkeyDebug, + workspaceFileAccessor, +} from "./activateStarlingMonkeyDebugger.js"; +import { IStarlingMonkeyRuntimeConfig } from "./starlingMonkeyRuntime.js"; + +const runMode: "server" | "inline" = "inline"; + +export function activate(context: ExtensionContext) { + switch (runMode) { + case "server": + activateStarlingMonkeyDebug( + context, + new StarlingMonkeyDebugAdapterServerDescriptorFactory() + ); + break; + + case "inline": + activateStarlingMonkeyDebug(context); + break; + } +} + +export function deactivate() {} + +class StarlingMonkeyDebugAdapterServerDescriptorFactory + implements DebugAdapterDescriptorFactory +{ + private server?: Server; + + createDebugAdapterDescriptor( + session: DebugSession, + executable: DebugAdapterExecutable | undefined + ): ProviderResult { + if (!this.server) { + this.server = createServer((socket) => { + let config = workspace.getConfiguration("starlingmonkey"); + const debugSession = new StarlingMonkeyDebugSession( + workspaceFileAccessor, + session.workspaceFolder ? session.workspaceFolder.uri.fsPath : "/", + config + ); + debugSession.setRunAsServer(true); + debugSession.start(socket as NodeJS.ReadableStream, socket); + }).listen(0); + } + + return new DebugAdapterServer((this.server.address() as AddressInfo).port); + } + + dispose() { + if (this.server) { + this.server.close(); + } + } +} diff --git a/debugger/vscode-dap-extension/src/signals.ts b/debugger/vscode-dap-extension/src/signals.ts new file mode 100644 index 00000000..a7fdc587 --- /dev/null +++ b/debugger/vscode-dap-extension/src/signals.ts @@ -0,0 +1,37 @@ +export class Signal { + private _promise!: Promise; + private _resolve!: (val: Val) => void; + private _reject!: (err: Err) => void; + private _handled = false; + + constructor() { + this.setPromise(); + } + + wait(): Promise { + this._handled = true; + return this._promise; + } + + resolve(value: Val) { + this._resolve(value); + this.setPromise(); + } + + reject(err: Err) { + this._reject(err); + this.setPromise(); + } + + get handled() { + return this._handled; + } + + private setPromise() { + this._handled = false; + this._promise = new Promise((resolve, reject) => { + this._resolve = resolve; + this._reject = reject; + }); + } +} \ No newline at end of file diff --git a/debugger/vscode-dap-extension/src/starlingMonkeyDebugger.ts b/debugger/vscode-dap-extension/src/starlingMonkeyDebugger.ts new file mode 100644 index 00000000..b49d6320 --- /dev/null +++ b/debugger/vscode-dap-extension/src/starlingMonkeyDebugger.ts @@ -0,0 +1,365 @@ +import { + Logger, + logger, + LoggingDebugSession, + InitializedEvent, + TerminatedEvent, + StoppedEvent, + OutputEvent, + Thread, + StackFrame, + Source, +} from "@vscode/debugadapter"; +import { DebugProtocol } from "@vscode/debugprotocol"; +import { basename } from "path-browserify"; +import { + IStarlingMonkeyRuntimeConfig, + StarlingMonkeyRuntime, + FileAccessor, +} from "./starlingMonkeyRuntime.js"; + +interface ILaunchRequestArguments extends DebugProtocol.LaunchRequestArguments { + program: string; + component: string; + stopOnEntry?: boolean; + trace?: boolean; + noDebug?: boolean; +} + +interface IAttachRequestArguments extends ILaunchRequestArguments {} + +export class StarlingMonkeyDebugSession extends LoggingDebugSession { + private static threadID = 1; + private _runtime: StarlingMonkeyRuntime; + private _initialized = false; + + public constructor(fileAccessor: FileAccessor, workspace: string, configuration: IStarlingMonkeyRuntimeConfig) { + super(); + + this.setDebuggerLinesStartAt1(true); + this.setDebuggerColumnsStartAt1(true); + + this._runtime = new StarlingMonkeyRuntime(workspace, fileAccessor, configuration); + + // setup event handlers + this._runtime.on("programLoaded", () => { + this._initialized = true; + this.sendEvent(new InitializedEvent()); + }); + this._runtime.on("stopOnEntry", () => { + this.sendEvent( + new StoppedEvent("entry", StarlingMonkeyDebugSession.threadID) + ); + }); + this._runtime.on("stopOnStep", () => { + this.sendEvent( + new StoppedEvent("step", StarlingMonkeyDebugSession.threadID) + ); + }); + this._runtime.on("stopOnBreakpoint", () => { + this.sendEvent( + new StoppedEvent("breakpoint", StarlingMonkeyDebugSession.threadID) + ); + }); + this._runtime.on("stopOnDataBreakpoint", () => { + this.sendEvent( + new StoppedEvent("data breakpoint", StarlingMonkeyDebugSession.threadID) + ); + }); + this._runtime.on("stopOnInstructionBreakpoint", () => { + this.sendEvent( + new StoppedEvent( + "instruction breakpoint", + StarlingMonkeyDebugSession.threadID + ) + ); + }); + this._runtime.on("stopOnException", (exception) => { + if (exception) { + this.sendEvent( + new StoppedEvent( + `exception(${exception})`, + StarlingMonkeyDebugSession.threadID + ) + ); + } else { + this.sendEvent( + new StoppedEvent("exception", StarlingMonkeyDebugSession.threadID) + ); + } + }); + this._runtime.on("output", (type, text, filePath, line, column) => { + let category: string; + switch (type) { + case "prio": + category = "important"; + break; + case "out": + category = "stdout"; + break; + case "err": + category = "stderr"; + break; + default: + category = "console"; + break; + } + const e: DebugProtocol.OutputEvent = new OutputEvent( + `${text}\n`, + category + ); + + if (text === "start" || text === "startCollapsed" || text === "end") { + e.body.group = text; + e.body.output = `group-${text}\n`; + } + + e.body.source = this.createSource(filePath); + e.body.line = this.convertDebuggerLineToClient(line); + e.body.column = this.convertDebuggerColumnToClient(column); + this.sendEvent(e); + }); + this._runtime.on("end", () => { + this.sendEvent(new TerminatedEvent()); + }); + } + + protected initializeRequest( + response: DebugProtocol.InitializeResponse, + args: DebugProtocol.InitializeRequestArguments + ): void { + response.body = { + ...response.body, + supportsSetVariable: true, + supportsConfigurationDoneRequest: true, + supportsBreakpointLocationsRequest: true, + }; + + this.sendResponse(response); + } + + protected configurationDoneRequest( + response: DebugProtocol.ConfigurationDoneResponse, + args: DebugProtocol.ConfigurationDoneArguments + ): void { + super.configurationDoneRequest(response, args); + this._runtime.run(); + } + + protected disconnectRequest( + response: DebugProtocol.DisconnectResponse, + args: DebugProtocol.DisconnectArguments, + request?: DebugProtocol.Request + ): void { + console.log( + `disconnectRequest suspend: ${args.suspendDebuggee}, terminate: ${args.terminateDebuggee}` + ); + } + + protected async attachRequest( + response: DebugProtocol.AttachResponse, + args: IAttachRequestArguments + ) { + return this.launchRequest(response, args); + } + + protected async launchRequest( + response: DebugProtocol.LaunchResponse, + args: ILaunchRequestArguments + ) { + logger.setup( + args.trace ? Logger.LogLevel.Verbose : Logger.LogLevel.Stop, + false + ); + this._runtime.start(args.program, args.component, !!args.stopOnEntry, !args.noDebug); + this.sendResponse(response); + } + + protected setFunctionBreakPointsRequest( + response: DebugProtocol.SetFunctionBreakpointsResponse, + args: DebugProtocol.SetFunctionBreakpointsArguments, + request?: DebugProtocol.Request + ): void { + this.sendResponse(response); + } + + protected async setBreakPointsRequest( + response: DebugProtocol.SetBreakpointsResponse, + args: DebugProtocol.SetBreakpointsArguments + ): Promise { + const path = args.source.path as string; + response.body = { breakpoints: [] }; + const breakpoints = response.body.breakpoints; + if (args.breakpoints) { + for (const bp of args.breakpoints) { + let line = this.convertClientLineToDebugger(bp.line); + let column = bp.column + ? this.convertClientColumnToDebugger(bp.column) + : undefined; + const result = await this._runtime.setBreakPoint(path, line, column); + if (result.id === -1) { + breakpoints.push({ + verified: false, + line: bp.line, + column: bp.column, + message: "Failed to set breakpoint", + }); + } else { + breakpoints.push({ + verified: true, + id: result.id, + line: result.line, + column: result.column, + }); + } + } + } + this.sendResponse(response); + } + + protected async breakpointLocationsRequest( + response: DebugProtocol.BreakpointLocationsResponse, + args: DebugProtocol.BreakpointLocationsArguments, + request?: DebugProtocol.Request + ): Promise { + // VSCode apparently sends this request before the `Initialized` event is sent. + // In that case, we can't answer it yet and instead ignore it. + if (!this._initialized) { + return; + } + if (args.source.path) { + const bps = await this._runtime.getBreakpointLocations( + args.source.path, + this.convertClientLineToDebugger(args.line) + ); + response.body = { + breakpoints: bps.map(({ line, column }) => { + return { + line: this.convertDebuggerColumnToClient(line), + column: this.convertDebuggerColumnToClient(column), + }; + }), + }; + } else { + response.body = { + breakpoints: [], + }; + } + this.sendResponse(response); + } + + protected threadsRequest(response: DebugProtocol.ThreadsResponse): void { + response.body = { + threads: [new Thread(StarlingMonkeyDebugSession.threadID, "Main")], + }; + this.sendResponse(response); + } + + protected stackTraceRequest( + response: DebugProtocol.StackTraceResponse, + args: DebugProtocol.StackTraceArguments + ): void { + const startFrame = + typeof args.startFrame === "number" ? args.startFrame : 0; + const maxLevels = typeof args.levels === "number" ? args.levels : 1000; + + this._runtime.stack(startFrame, maxLevels).then((stk) => { + response.body = { + stackFrames: stk.frames.map((f, ix) => { + const sf: DebugProtocol.StackFrame = new StackFrame( + f.index, + f.name, + this.createSource(f.file), + this.convertDebuggerLineToClient(f.line) + ); + if (typeof f.column === "number") { + sf.column = this.convertDebuggerColumnToClient(f.column); + } + + return sf; + }), + // 4 options for 'totalFrames': + //omit totalFrames property: // VS Code has to probe/guess. Should result in a max. of two requests + totalFrames: stk.count, // stk.count is the correct size, should result in a max. of two requests + //totalFrames: 1000000 // not the correct size, should result in a max. of two requests + //totalFrames: endFrame + 20 // dynamically increases the size with every requested chunk, results in paging + }; + this.sendResponse(response); + }); + } + + protected async scopesRequest( + response: DebugProtocol.ScopesResponse, + args: DebugProtocol.ScopesArguments + ): Promise { + let scopes = await this._runtime.getScopes(args.frameId); + response.body = { scopes }; + this.sendResponse(response); + } + + protected async variablesRequest( + response: DebugProtocol.VariablesResponse, + args: DebugProtocol.VariablesArguments, + request?: DebugProtocol.Request + ): Promise { + let variables = await this._runtime.getVariables(args.variablesReference); + response.body = { variables }; + this.sendResponse(response); + } + + protected async setVariableRequest( + response: DebugProtocol.SetVariableResponse, + args: DebugProtocol.SetVariableArguments + ): Promise { + // TODO: implement + let message = await this._runtime.setVariable( + args.variablesReference, + args.name, + args.value + ); + response.body = { value: message.value, type: message.type, variablesReference: message.variablesReference }; + this.sendResponse(response); + } + + protected continueRequest( + response: DebugProtocol.ContinueResponse, + args: DebugProtocol.ContinueArguments + ): void { + this.sendResponse(response); + this._runtime.continue(); + } + + protected nextRequest( + response: DebugProtocol.NextResponse, + args: DebugProtocol.NextArguments + ): void { + this.sendResponse(response); + this._runtime.next(args.granularity ?? "statement"); + } + + protected stepInRequest( + response: DebugProtocol.StepInResponse, + args: DebugProtocol.StepInArguments + ): void { + this._runtime.stepIn(args.targetId); + this.sendResponse(response); + } + + protected stepOutRequest( + response: DebugProtocol.StepOutResponse, + args: DebugProtocol.StepOutArguments + ): void { + this._runtime.stepOut(); + this.sendResponse(response); + } + + private createSource(filePath: string): Source { + return new Source( + basename(filePath), + this.convertDebuggerPathToClient(filePath), + undefined, + undefined, + "starlingmonkey-adapter-data" + ); + } +} diff --git a/debugger/vscode-dap-extension/src/starlingMonkeyRuntime.ts b/debugger/vscode-dap-extension/src/starlingMonkeyRuntime.ts new file mode 100644 index 00000000..88b788c3 --- /dev/null +++ b/debugger/vscode-dap-extension/src/starlingMonkeyRuntime.ts @@ -0,0 +1,429 @@ +import { Scope } from "@vscode/debugadapter"; +import { ChildProcessWithoutNullStreams, spawn } from "child_process"; +import { EventEmitter } from "events"; +import * as Net from "net"; +import { Signal } from "./signals.js"; +import { assert } from "console"; + +export interface FileAccessor { + isWindows: boolean; + readFile(path: string): Promise; + writeFile(path: string, contents: Uint8Array): Promise; +} + +export interface IRuntimeBreakpoint { + id: number; + line: number; + column: number; +} + +interface IRuntimeStackFrame { + index: number; + name: string; + file: string; + line: number; + column?: number; + instruction?: number; +} + +interface IRuntimeStack { + count: number; + frames: IRuntimeStackFrame[]; +} + +interface IRuntimeMessage { + type: string; + value: any; +} + +interface IRuntimeVariable { + name: string; + value: string; + type: string; + variablesReference: number; +} + +export interface IComponentRuntimeConfig { + executable: string; + options: string[]; + envOption: string; +} +export interface IStarlingMonkeyRuntimeConfig { + componentRuntime: IComponentRuntimeConfig; +} + +class ComponentRuntimeInstance { + private static _componentRuntime: ChildProcessWithoutNullStreams; + static running: boolean; + static workspaceFolder: string; + static _server: Net.Server; + static _nextSessionPort: number | undefined; + + static setNextSessionPort(port: number) { + this._nextSessionPort = port; + } + + static async start(workspaceFolder: string, component: string, config: IComponentRuntimeConfig) { + assert(!this.running, "ComponentRuntime is already running"); + this.running = true; + this.workspaceFolder = workspaceFolder; + + this._server = Net.createServer((socket) => { + socket.on("data", (data) => { + assert( + data.toString() === "get-session-port", + `expected "get-session-port" message, got "${data.toString()}"` + ); + console.debug("StarlingMonkey sent a get-session-port request"); + if (!this._nextSessionPort) { + console.debug( + "No debugging session active, telling runtime to continue" + ); + socket.write("no-session"); + } else { + console.debug( + `Starting debug session on port ${this._nextSessionPort}` + ); + socket.write(this._nextSessionPort.toString()); + this._nextSessionPort = undefined; + } + }); + }).listen(); + let port = (this._server.address()).port; + console.info(`waiting for debug protocol on port ${port}`); + + // Start componentRuntime as a new process + let args = Array.from(config.options).map(opt => opt.replace("${workspaceFolder}", workspaceFolder)); + args.push(config.envOption); + args.push(`DEBUGGER_PORT=${port}`); + args.push(component); + // console.debug(`${config.executable} ${args.join(" ")}`); + this._componentRuntime = spawn(config.executable, args); + + this._componentRuntime.stdout.on("data", (data) => { + console.log(`componentRuntime ${data}`); + }); + + this._componentRuntime.stderr.on("data", (data) => { + console.error(`componentRuntime ${data}`); + }); + + this._componentRuntime.on("close", (code) => { + console.info(`child process exited with code ${code}`); + this.running = false; + }); + } +} + +export class StarlingMonkeyRuntime extends EventEmitter { + private _debug!: boolean; + private _stopOnEntry!: boolean; + public get fileAccessor(): FileAccessor { + return this._fileAccessor; + } + public set fileAccessor(value: FileAccessor) { + this._fileAccessor = value; + } + + private _server!: Net.Server; + private _socket!: Net.Socket; + + private _messageReceived = new Signal(); + + private _sourceFile!: string; + public get sourceFile() { + return this._sourceFile; + } + + constructor( + private _workspaceDir: string, + private _fileAccessor: FileAccessor, + private _config: IStarlingMonkeyRuntimeConfig + ) { + super(); + } + + public async start(program: string, component: string, stopOnEntry: boolean, debug: boolean ): Promise { + await this.startComponentRuntime(component); + this.startSessionServer(); + // TODO: tell StarlingMonkey not to debug if this is false. + this._debug = debug; + this._stopOnEntry = stopOnEntry; + this._sourceFile = this.normalizePath(program); + let message = await this._messageReceived.wait(); + assert( + message.type === "connect", + `expected "connect" message, got "${message.type}"` + ); + this.sendMessage("startDebugLogging"); + message = await this.sendAndReceiveMessage("loadProgram", this._sourceFile); + assert( + message.type === "programLoaded", + `expected "programLoaded" message, got "${message.type}"` + ); + this.emit("programLoaded"); + } + + /** + * Starts a server that creates a new session for every connection request. + * + * The server listens for incoming connections and handles data received from the client. + * It attempts to parse the received data as JSON and resolves the `_messageReceived` promise + * with the parsed message. If the data cannot be parsed, it is stored in `partialMessage` + * for the next data event. + * + * When the connection ends, the server emits an "end" event. + * + * The server listens on a dynamically assigned port, which is then set as the next session port + * in the `ComponentRuntimeInstance`. + */ + startSessionServer(): void { + let debuggerScriptSent = false; + let partialMessage = ""; + let expectedLength = 0; + let eol = -1; + let lengthReceived = false; + + async function resetMessageState() { + partialMessage = partialMessage.slice(expectedLength); + expectedLength = 0; + lengthReceived = false; + eol = -1; + if (partialMessage.length > 0) { + await 1; // Ensure that the current message is processed before the next data event. + handleData(""); + } + } + + const handleData = async (data: string) => { + if (!debuggerScriptSent) { + if (data.toString() !== "get-debugger") { + console.warn( + `expected "get-debugger" message, got "${data.toString()}". Ignoring ...` + ); + return; + } + let extensionDir = `${__dirname}/../`; + let debuggerScript = await this._fileAccessor.readFile(`${extensionDir}/dist/debugger.js`); + this._socket.write(`${debuggerScript.length}\n${debuggerScript}`); + debuggerScriptSent = true; + return; + } + + partialMessage += data; + + if (!lengthReceived) { + eol = partialMessage.indexOf("\n"); + if (eol === -1) { + return; + } + lengthReceived = true; + expectedLength = parseInt(partialMessage.slice(0, eol), 10); + if (isNaN(expectedLength)) { + console.warn(`expected message length, got "${partialMessage}"`); + resetMessageState(); + return; + } + partialMessage = partialMessage.slice(eol + 1); + lengthReceived = true; + } + if (partialMessage.length < expectedLength) { + return; + } + let message = partialMessage.slice(0, expectedLength); + try { + let parsed = JSON.parse(message); + console.debug(`received message ${partialMessage}`); + resetMessageState(); + this._messageReceived.resolve(parsed); + } catch (e) { + console.warn(`Illformed message received. Error: ${e}, message: ${partialMessage}`); + resetMessageState(); + } + } + + this._server = Net.createServer(socket => { + this._socket = socket; + console.debug("Debug session server accepted connection from client"); + socket.on("data", handleData); + socket.on("end", () => this.emit("end")); + }).listen(); + let port = (this._server.address()).port; + ComponentRuntimeInstance.setNextSessionPort(port); + } + + private async startComponentRuntime(component: string) { + if (ComponentRuntimeInstance.running) { + assert( + ComponentRuntimeInstance.workspaceFolder === this._workspaceDir, + "ComponentRuntime is already running in a different workspace" + ); + return; + } + await ComponentRuntimeInstance.start(this._workspaceDir, component, this._config.componentRuntime); + } + + private sendMessage(type: string, value?: any, useRawValue = false) { + let message: string; + if (useRawValue) { + message = `{"type": "${type}", "value": ${value}}`; + } else { + message = JSON.stringify({ type, value }); + } + console.debug(`sending message to runtime: ${message}`); + this._socket.write(`${message.length}\n`); + this._socket.write(message); + } + + private sendAndReceiveMessage( + type: string, + value?: any, + useRawValue = false + ): Promise { + this.sendMessage(type, value, useRawValue); + return this._messageReceived.wait(); + } + + public async run() { + if (this._debug && this._stopOnEntry) { + this.emit("stopOnEntry"); + } else { + this.continue(); + } + } + + public async continue() { + let message = await this.sendAndReceiveMessage("continue"); + // TODO: handle other results, such as run to completion + assert( + message.type === "breakpointHit", + `expected "breakpointHit" message, got "${message.type}"` + ); + this.emit("stopOnBreakpoint"); + } + + public next(granularity: "statement" | "line" | "instruction") { + this.handleStep("next"); + } + + public stepIn(targetId: number | undefined) { + this.handleStep("stepIn"); + } + + public stepOut() { + this.handleStep("stepOut"); + } + + private async handleStep(type: "next" | "stepIn" | "stepOut") { + let message = await this.sendAndReceiveMessage(type); + // TODO: handle other results, such as run to completion + assert( + message.type === "stopOnStep", + `expected "stopOnStep" message, got "${message.type}"` + ); + this.emit("stopOnStep"); + } + + public async stack(index: number, count: number): Promise { + let message = await this.sendAndReceiveMessage("getStack", { + index, + count, + }); + assert( + message.type === "stack", + `expected "stack" message, got "${message.type}"` + ); + let stack = message.value; + for (let frame of stack) { + frame.file = this.qualifyPath(frame.file); + } + return { + count: stack.length, + frames: stack, + }; + } + + async getScopes(frameId: number): Promise { + let message = await this.sendAndReceiveMessage("getScopes", frameId); + assert( + message.type === "scopes", + `expected "scopes" message, got "${message.type}"` + ); + return message.value; + } + + public async getBreakpointLocations( + path: string, + line: number + ): Promise<{ line: number; column: number }[]> { + // TODO: support the full set of query params from BreakpointLocationsArguments + path = this.normalizePath(path); + let message = await this.sendAndReceiveMessage("getBreakpointsForLine", { + path, + line, + }); + assert( + message.type === "breakpointsForLine", + `expected "breakpointsForLine" message, got "${message.type}"` + ); + return message.value; + } + + public async setBreakPoint( + path: string, + line: number, + column?: number + ): Promise { + path = this.normalizePath(path); + let response = await this.sendAndReceiveMessage("setBreakpoint", { + path, + line, + column, + }); + assert( + response.type === "breakpointSet", + `expected "breakpointSet" message, got "${response.type}"` + ); + return response.value; + } + + public async getVariables(reference: number): Promise { + let message = await this.sendAndReceiveMessage("getVariables", reference); + assert( + message.type === "variables", + `expected "variables" message, got "${message.type}"` + ); + return message.value; + } + + public async setVariable( + variablesReference: number, + name: string, + value: string + ): Promise { + // Manually encode the value so that it'll be decoded as raw values by the runtime, instead of everything becoming a string. + let rawValue = `{"variablesReference": ${variablesReference}, "name": "${name}", "value": ${value}}`; + let message = await this.sendAndReceiveMessage( + "setVariable", + rawValue, + true + ); + assert( + message.type === "variableSet", + `expected "variableSet" message, got "${message.type}"` + ); + return message.value; + } + + // private methods + private normalizePath(path: string) { + path = path.replace(/\\/g, "/"); + return path.startsWith(this._workspaceDir) + ? path.substring(this._workspaceDir.length + 1) + : path; + } + + private qualifyPath(path: string) { + return `${this._workspaceDir}/${path}`; + } +} diff --git a/debugger/vscode-dap-extension/starling-debugger/debugger.ts b/debugger/vscode-dap-extension/starling-debugger/debugger.ts new file mode 100644 index 00000000..b507f0d8 --- /dev/null +++ b/debugger/vscode-dap-extension/starling-debugger/debugger.ts @@ -0,0 +1,623 @@ +// Type definitions for SpiderMonkey Debugger API +declare class Debugger { + static Object: any; + static Script: any; + static Environment: any; + static Frame: any; + constructor(); + addAllGlobalsAsDebuggees(): void; + findScripts(): Debugger.Script[]; + onNewScript: ((script: Debugger.Script, global?: any) => void) | undefined; + onEnterFrame: ((frame: Debugger.Frame) => void) | undefined; +} + +declare namespace Debugger { + interface Script { + url: string; + startLine: number; + startColumn: number; + lineCount: number; + global: Object; + getOffsetMetadata(offset: number): { lineNumber: number; columnNumber: number }; + getPossibleBreakpointOffsets(options: { line: number }): number[]; + getChildScripts(): Script[]; + setBreakpoint(offset: number, handler: BreakpointHandler): void; + } + + interface Frame { + script: Script; + offset: number; + this?: Object; + type: string; + older?: Frame; + olderSavedFrame?: Frame; + callee?: { name: string }; + environment: Environment; + onStep: (() => void) | undefined; + onPop: (() => void) | undefined; + } + + interface Environment { + names(): string[]; + getVariable(name: string): any; + setVariable(name: string, value: any): void; + } + + interface Object { + class?: string; + getOwnPropertyNames(): string[]; + getOwnPropertyDescriptor(name: string): PropertyDescriptor; + setProperty(name: string, value: any): void; + } + + interface PropertyDescriptor { + value?: any; + get?: Object; + set?: Object; + } + + interface BreakpointHandler { + hit(frame: Frame): void; + } +} + +declare const socket: { + send(data: string): void; + receive(bytes: number): string; +}; + +declare function print(message: string): void; +declare function assert(condition: any, message?: string): asserts condition; +declare function setContentPath(path: string): void; + +let LOG = false; + +try { + let dbg = new Debugger(); + dbg.addAllGlobalsAsDebuggees(); + + let scripts = new Map>(); + let currentFrame: Debugger.Frame | undefined; + let lastLine = 0; + let lastColumn = 0; + // Reserve the first 0xFFF for stack frames. + const MAX_FRAMES = 0xfff; + const GLOBAL_OBJECT_REF = MAX_FRAMES + 1; + const OBJECT_REFS_START = GLOBAL_OBJECT_REF + 1; + let varRefsIndex = OBJECT_REFS_START; + let objectToId = new Map(); + let idToObject = new Map(); + + function addScript(script: Debugger.Script): void { + let urlScripts = scripts.get(script.url); + if (!urlScripts) { + urlScripts = new Set(); + scripts.set(script.url, urlScripts); + } + urlScripts.add(script); + } + + dbg.onNewScript = function (script: Debugger.Script, _global?: any): void { + if (scripts.has(script.url)) { + LOG && print(`Warning: script with url ${script.url} already loaded`); + } + addScript(script); + }; + + dbg.onEnterFrame = function (frame: Debugger.Frame): void { + dbg.onEnterFrame = undefined; + for (let script of dbg.findScripts()) { + addScript(script); + } + sendMessage("programLoaded"); + return handlePausedFrame(frame); + }; + + function handlePausedFrame(frame: Debugger.Frame): void { + try { + dbg.onEnterFrame = undefined; + if (currentFrame) { + currentFrame.onStep = undefined; + currentFrame.onPop = undefined; + } + currentFrame = frame; + idToObject.set(GLOBAL_OBJECT_REF, frame.script.global); + objectToId.set(frame.script.global, GLOBAL_OBJECT_REF); + varRefsIndex = OBJECT_REFS_START; + setCurrentPosition(); + waitForSocket(); + objectToId.clear(); + idToObject.clear(); + } catch (e) { + assert(e instanceof Error); + LOG && print( + `Exception during paused frame handling: ${e}. Stack:\n${e.stack}` + ); + } + } + + interface Message { + type: string; + value?: any; + } + + function waitForSocket(): void { + while (true) { + try { + let message = receiveMessage(); + LOG && print(`received message ${JSON.stringify(message)}`); + switch (message.type) { + case "loadProgram": + setContentPath(message.value); + return; + case "getBreakpointsForLine": + getBreakpointsForLine(message.value); + break; + case "setBreakpoint": + setBreakpoint(message.value); + break; + case "getStack": + getStack(message.value.index, message.value.count); + break; + case "getScopes": + getScopes(message.value); + break; + case "getVariables": + getVariables(message.value); + break; + case "setVariable": + setVariable(message.value); + break; + case "next": + currentFrame!.onStep = handleNext; + return; + case "stepIn": + currentFrame!.onStep = handleNext; + dbg.onEnterFrame = handleStepIn; + return; + case "stepOut": + currentFrame!.onPop = handleStepOut; + return; + case "continue": + currentFrame = undefined; + return; + case "startDebugLogging": + LOG = true; + break; + case "stopDebugLogging": + LOG = false; + break; + default: + LOG && print( + `Invalid message received, continuing execution. Message: ${message.type}` + ); + currentFrame = undefined; + return; + } + } catch (e) { + assert(e instanceof Error); + LOG && print(`Exception during paused frame loop: ${e}. Stack:\n${e.stack}`); + } + } + } + + function setCurrentPosition(): void { + if (!currentFrame) { + lastLine = 0; + lastColumn = 0; + return; + } + let offsetMeta = currentFrame.script.getOffsetMetadata(currentFrame.offset); + lastLine = offsetMeta.lineNumber; + lastColumn = offsetMeta.columnNumber; + } + + function positionChanged(frame: Debugger.Frame): boolean { + let offsetMeta = frame.script.getOffsetMetadata(frame.offset); + return ( + offsetMeta.lineNumber !== lastLine || + offsetMeta.columnNumber !== lastColumn + ); + } + + function handleNext(this: Debugger.Frame): void { + if (!positionChanged(this)) { + return; + } + sendMessage("stopOnStep"); + handlePausedFrame(this); + } + + function handleStepIn(frame: Debugger.Frame): void { + dbg.onEnterFrame = undefined; + sendMessage("stopOnStep"); + handlePausedFrame(frame); + } + + function handleStepOut(this: Debugger.Frame): void { + this.onPop = undefined; + if (this.older) { + this.older.onStep = handleNext; + } else { + dbg.onEnterFrame = handleStepIn; + } + } + + const breakpointHandler: Debugger.BreakpointHandler = { + hit(frame: Debugger.Frame): void { + sendMessage("breakpointHit", frame.offset); + return handlePausedFrame(frame); + }, + }; + + interface BreakpointLocation { + script: Debugger.Script; + offsets: number[]; + } + + function getPossibleBreakpointsInScripts( + scripts: Set | undefined, + line: number + ): BreakpointLocation | null { + if (!scripts) { + return null; + } + for (let script of scripts) { + let result = getPossibleBreakpointsInScriptRecursive(script, line); + if (result) { + return result; + } + } + return null; + } + + function getPossibleBreakpointsInScriptRecursive( + script: Debugger.Script, + line: number + ): BreakpointLocation | null { + let offsets = script.getPossibleBreakpointOffsets({ line }); + if (offsets.length) { + return { script, offsets }; + } + + for (let child of script.getChildScripts()) { + let result = getPossibleBreakpointsInScriptRecursive(child, line); + if (result) { + return result; + } + } + return null; + } + + function getBreakpointsForLine({ + path, + line, + }: { + path: string; + line: number; + }): void { + let fileScripts = scripts.get(path); + let { script, offsets } = + getPossibleBreakpointsInScripts(fileScripts, line) || {}; + let locations: { line: number; column: number }[] = []; + if (offsets) { + locations = offsets.map((offset) => { + let meta = script!.getOffsetMetadata(offset); + return { + line: meta.lineNumber, + column: meta.columnNumber, + }; + }); + } + sendMessage("breakpointsForLine", locations); + } + + function setBreakpoint({ + path, + line, + column, + }: { + path: string; + line: number; + column: number; + }): void { + let fileScripts = scripts.get(path); + if (!fileScripts) { + LOG && print(`Can't set breakpoint: no scripts found for file ${path}`); + sendMessage("breakpointSet", { id: -1, line, column }); + return; + } + let { script, offsets } = + getPossibleBreakpointsInScripts(fileScripts, line) || {}; + let offset = -1; + if (offsets) { + for (offset of offsets) { + let meta = script!.getOffsetMetadata(offset); + assert( + meta.lineNumber === line, + `Line number mismatch, should be ${line}, got ${meta.lineNumber}` + ); + if (meta.columnNumber === column) { + break; + } + } + script!.setBreakpoint(offset, breakpointHandler); + } + sendMessage("breakpointSet", { id: offset, line, column }); + } + + interface IRuntimeStackFrame { + index: number; + name?: string; + file?: string; + line?: number; + column?: number; + instruction?: number; + } + function getStack(index: number, count: number): void { + let stack: IRuntimeStackFrame[] = []; + assert(currentFrame); + let frame = findFrame(currentFrame, index); + + while (stack.length < count) { + let entry: IRuntimeStackFrame = { + index: stack.length, + }; + if (frame.script) { + const offsetMeta = frame.script.getOffsetMetadata(frame.offset); + entry.file = frame.script.url; + entry.line = offsetMeta.lineNumber; + entry.column = offsetMeta.columnNumber; + } + + if (frame.callee) { + entry.name = frame.callee.name; + } else { + entry.name = frame.type; + } + stack.push(entry); + let nextFrame = frame.older || frame.olderSavedFrame; + if (!nextFrame) { + break; + } + frame = nextFrame; + } + sendMessage("stack", stack); + } + + interface Scope { + name: string; + presentationHint?: 'arguments' | 'locals' | 'registers' | string; + variablesReference: number; + namedVariables?: number; + indexedVariables?: number; + expensive: boolean; + // source?: Source; TODO: support + line?: number; + column?: number; + endLine?: number; + endColumn?: number; + } + + function getScopes(index: number): void { + assert(currentFrame); + let frame = findFrame(currentFrame, index); + let script = frame.script; + let scopes: Scope[] = [{ + name: "Locals", + presentationHint: "locals", + variablesReference: index + 1, + expensive: false, + line: script.startLine, + column: script.startColumn, + endLine: script.startLine + script.lineCount, + }, + { + name: "Globals", + presentationHint: "globals", + variablesReference: GLOBAL_OBJECT_REF, + expensive: true, + }]; + + sendMessage("scopes", scopes); + } + + function getVariables(reference: number): void { + if (reference > MAX_FRAMES) { + let object = idToObject.get(reference); + let locals = getMembers(object!); + sendMessage("variables", locals); + return; + } + + assert(currentFrame); + let frame = findFrame(currentFrame, reference - 1); + let locals = []; + + for (let name of frame.environment.names()) { + let value = frame.environment.getVariable(name); + locals.push({ name, ...formatValue(value) }); + } + + if (frame.this) { + let { value, type, variablesReference } = formatValue(frame.this); + locals.push({ + name: "", + value, + type, + variablesReference, + }); + } + + sendMessage("variables", locals); + } + + function setVariable({ + variablesReference, + name, + value, + }: { + variablesReference: number; + name: string; + value: any; + }): void { + let newValue; + if (variablesReference > MAX_FRAMES) { + let object = idToObject.get(variablesReference); + assert(object); + object.setProperty(name, value); + newValue = getMember(object, name); + } else { + assert(currentFrame); + let frame = findFrame(currentFrame, variablesReference - 1); + frame.environment.setVariable(name, value); + newValue = formatValue(frame.environment.getVariable(name)); + } + sendMessage("variableSet", newValue); + } + + function getMembers(object: Debugger.Object): any[] { + let names = object.getOwnPropertyNames(); + let members = []; + for (let name of names) { + members.push(getMember(object, name)); + } + return members; + } + + function getMember(object: Debugger.Object, name: string): any { + let descriptor = object.getOwnPropertyDescriptor(name); + return { name, ...formatDescriptor(descriptor) }; + } + + function formatValue(value: any): { + value: string; + type: string; + variablesReference: number; + } { + let formatted; + let type: string = typeof value; + let structured = false; + type = type[0].toUpperCase() + type.slice(1); + if (type === "Object") { + if (value === null) { + formatted = "null"; + type = "Null"; + } else if (!(value instanceof Debugger.Object) && value.uninitialized) { + formatted = ""; + type = "Uninitialized Binding"; + } else { + type = value.class ?? "Object"; + formatted = `[object ${type}]`; + structured = true; + } + } else if (type === "String") { + formatted = `"${value}"`; + } else { + formatted = `${value}`; + } + let variablesReference = 0; + if (structured) { + if (!objectToId.has(value)) { + variablesReference = varRefsIndex++; + idToObject.set(variablesReference, value); + objectToId.set(value, variablesReference); + } + } + return { value: formatted, type, variablesReference }; + } + + function formatDescriptor(descriptor: Debugger.PropertyDescriptor): { + value: string; + type: string; + variablesReference: number; + } { + if (descriptor.value) { + return formatValue(descriptor.value); + } + + let formatted; + if (descriptor.get) { + formatted = formatValue(descriptor.get); + } + + if (descriptor.set) { + let setter = formatValue(descriptor.set); + if (formatted) { + formatted += `, ${setter}`; + } else { + formatted = setter; + } + } + + return { value: formatted, type: "Accessor", variablesReference: 0 }; + } + + function findFrame( + start: Debugger.Frame, + index: number + ): Debugger.Frame { + let frame = start; + for (let i = 0; i < index && frame; i++) { + let nextFrame = frame.older || frame.olderSavedFrame; + frame = nextFrame!; + assert(frame, `Frame with index ${index} not found`); + } + return frame; + } + + function sendMessage(type, value?) { + const messageStr = JSON.stringify({ type, value }); + LOG && print(`sending message: ${messageStr}`); + socket.send(`${messageStr.length}\n${messageStr}`); + } + + function receiveMessage(): Message { + LOG && print("Debugger listening for incoming message ..."); + let partialMessage = ""; + let eol = -1; + while (true) { + partialMessage += socket.receive(10); + eol = partialMessage.indexOf("\n"); + if (eol >= 0) { + break; + } + } + + let length = parseInt(partialMessage.slice(0, eol), 10); + if (isNaN(length)) { + LOG && print( + `WARN: Received message ${partialMessage} not of the format '[length]\\n[JSON encoded message with length {length}]', discarding` + ); + return receiveMessage(); + } + partialMessage = partialMessage.slice(eol + 1); + + while (partialMessage.length < length) { + partialMessage += socket.receive(length - partialMessage.length); + } + + if (partialMessage.length > length) { + LOG && print( + `WARN: Received message ${ + partialMessage.length - length + } bytes longer than advertised, ignoring everything beyond the first ${length} bytes` + ); + partialMessage = partialMessage.slice(0, length); + } + + try { + return JSON.parse(partialMessage); + } catch (e) { + assert(e instanceof Error); + LOG && print(`WARN: Ill-formed message received, discarding: ${e}, ${e.stack}`); + return receiveMessage(); + } + } + + sendMessage("connect"); + waitForSocket(); +} catch (e) { + assert(e instanceof Error); + LOG && print(`Setting up connection to debugger failed with exception: ${e},\nstack:\n${e.stack}`); +} diff --git a/debugger/vscode-dap-extension/tsconfig.json b/debugger/vscode-dap-extension/tsconfig.json new file mode 100644 index 00000000..30330d29 --- /dev/null +++ b/debugger/vscode-dap-extension/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "outDir": "out", + "lib": [ + "WebWorker", + "ES2022" + ], + "sourceMap": true, + "rootDir": "src", + "strict": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "noImplicitAny": false, + "removeComments": false, + "noUnusedLocals": true, + "noImplicitThis": true, + "inlineSourceMap": false, + "preserveConstEnums": true, + "strictNullChecks": true, + "noUnusedParameters": false + }, + "exclude": [ + "node_modules" + ] +} From f5ccdab4d3a97340ab89c4848ed72d98f0cbaeb0 Mon Sep 17 00:00:00 2001 From: Till Schneidereit Date: Wed, 19 Mar 2025 18:26:42 +0100 Subject: [PATCH 2/6] More configuration options for debugging runtime --- debugger/vscode-dap-extension/package.json | 13 +- .../sampleWorkspace/world.wit | 1860 +++++++++++++++++ .../src/starlingMonkeyRuntime.ts | 35 +- 3 files changed, 1895 insertions(+), 13 deletions(-) create mode 100644 debugger/vscode-dap-extension/sampleWorkspace/world.wit diff --git a/debugger/vscode-dap-extension/package.json b/debugger/vscode-dap-extension/package.json index 15bafc30..e2284252 100644 --- a/debugger/vscode-dap-extension/package.json +++ b/debugger/vscode-dap-extension/package.json @@ -188,6 +188,15 @@ { "title": "StarlingMonkey Debugger", "properties": { + "starlingmonkey.jsRuntimeOptions": { + "type": "array", + "items": { + "type": "string" + }, + "default": ["--verbose", "-d"], + "scope": "machine-overridable", + "description": "CLI options to pass to StarlingMonkey." + }, "starlingmonkey.componentRuntime.executable": { "type": "string", "default": "wasmtime", @@ -199,9 +208,9 @@ "items": { "type": "string" }, - "default": ["serve", "-S", "cli,tcp,inherit-network", "--env", "STARLINGMONKEY_CONFIG=--verbose -d", "--dir", "${workspaceFolder}::/", "--addr", "0.0.0.0:8080"], + "default": ["serve", "-S", "cli,tcp,inherit-network", "--dir", "${workspaceFolder}::/", "--addr", "0.0.0.0:8080", "${component}"], "scope": "machine-overridable", - "description": "CLI options to pass to the component runtime. The component to debug will always be appended to this list, and `${workspaceFolder}` will be replaced with the path to the workspace folder." + "description": "CLI options to pass to the component runtime. `${component} will be replaced with the path to the component to debug, and `${workspaceFolder}` will be replaced with the path to the workspace folder." }, "starlingmonkey.componentRuntime.envOption": { "type": "string", diff --git a/debugger/vscode-dap-extension/sampleWorkspace/world.wit b/debugger/vscode-dap-extension/sampleWorkspace/world.wit new file mode 100644 index 00000000..a5500ccb --- /dev/null +++ b/debugger/vscode-dap-extension/sampleWorkspace/world.wit @@ -0,0 +1,1860 @@ +package local:combined-wit; + +world combined { + import wasi:io/poll@0.2.3; + import wasi:clocks/monotonic-clock@0.2.3; + import wasi:io/error@0.2.3; + import wasi:io/streams@0.2.3; + import wasi:http/types@0.2.3; + import wasi:http/outgoing-handler@0.2.3; + import wasi:cli/environment@0.2.3; + import wasi:sockets/network@0.2.3; + import wasi:sockets/instance-network@0.2.3; + import wasi:sockets/tcp@0.2.3; + import wasi:sockets/tcp-create-socket@0.2.3; + + export wasi:http/incoming-handler@0.2.3; +} +package fermyon:spin { + interface redis-types { + enum error { + success, + error, + } + + type payload = list; + + variant redis-parameter { + int64(s64), + binary(payload), + } + + variant redis-result { + nil, + status(string), + int64(s64), + binary(payload), + } + } + interface inbound-redis { + use redis-types.{payload, error}; + + handle-message: func(message: payload) -> result<_, error>; + } +} + + +package wasi:io@0.2.3 { + @since(version = 0.2.0) + interface error { + @since(version = 0.2.0) + resource error { + @since(version = 0.2.0) + to-debug-string: func() -> string; + } + } + @since(version = 0.2.0) + interface poll { + @since(version = 0.2.0) + resource pollable { + @since(version = 0.2.0) + ready: func() -> bool; + @since(version = 0.2.0) + block: func(); + } + + @since(version = 0.2.0) + poll: func(in: list>) -> list; + } + @since(version = 0.2.0) + interface streams { + @since(version = 0.2.0) + use error.{error}; + @since(version = 0.2.0) + use poll.{pollable}; + + @since(version = 0.2.0) + variant stream-error { + last-operation-failed(error), + closed, + } + + @since(version = 0.2.0) + resource input-stream { + @since(version = 0.2.0) + read: func(len: u64) -> result, stream-error>; + @since(version = 0.2.0) + blocking-read: func(len: u64) -> result, stream-error>; + @since(version = 0.2.0) + skip: func(len: u64) -> result; + @since(version = 0.2.0) + blocking-skip: func(len: u64) -> result; + @since(version = 0.2.0) + subscribe: func() -> pollable; + } + + @since(version = 0.2.0) + resource output-stream { + @since(version = 0.2.0) + check-write: func() -> result; + @since(version = 0.2.0) + write: func(contents: list) -> result<_, stream-error>; + @since(version = 0.2.0) + blocking-write-and-flush: func(contents: list) -> result<_, stream-error>; + @since(version = 0.2.0) + flush: func() -> result<_, stream-error>; + @since(version = 0.2.0) + blocking-flush: func() -> result<_, stream-error>; + @since(version = 0.2.0) + subscribe: func() -> pollable; + @since(version = 0.2.0) + write-zeroes: func(len: u64) -> result<_, stream-error>; + @since(version = 0.2.0) + blocking-write-zeroes-and-flush: func(len: u64) -> result<_, stream-error>; + @since(version = 0.2.0) + splice: func(src: borrow, len: u64) -> result; + @since(version = 0.2.0) + blocking-splice: func(src: borrow, len: u64) -> result; + } + } + @since(version = 0.2.0) + world imports { + @since(version = 0.2.0) + import error; + @since(version = 0.2.0) + import poll; + @since(version = 0.2.0) + import streams; + } +} + + +package wasi:clocks@0.2.3 { + @since(version = 0.2.0) + interface monotonic-clock { + @since(version = 0.2.0) + use wasi:io/poll@0.2.3.{pollable}; + + @since(version = 0.2.0) + type instant = u64; + + @since(version = 0.2.0) + type duration = u64; + + @since(version = 0.2.0) + now: func() -> instant; + + @since(version = 0.2.0) + resolution: func() -> duration; + + @since(version = 0.2.0) + subscribe-instant: func(when: instant) -> pollable; + + @since(version = 0.2.0) + subscribe-duration: func(when: duration) -> pollable; + } + @since(version = 0.2.0) + interface wall-clock { + @since(version = 0.2.0) + record datetime { + seconds: u64, + nanoseconds: u32, + } + + @since(version = 0.2.0) + now: func() -> datetime; + + @since(version = 0.2.0) + resolution: func() -> datetime; + } + @since(version = 0.2.0) + world imports { + @since(version = 0.2.0) + import wasi:io/poll@0.2.3; + @since(version = 0.2.0) + import monotonic-clock; + @since(version = 0.2.0) + import wall-clock; + } +} + + +package wasi:random@0.2.3 { + @since(version = 0.2.0) + interface insecure-seed { + @since(version = 0.2.0) + insecure-seed: func() -> tuple; + } + @since(version = 0.2.0) + interface insecure { + @since(version = 0.2.0) + get-insecure-random-bytes: func(len: u64) -> list; + + @since(version = 0.2.0) + get-insecure-random-u64: func() -> u64; + } + @since(version = 0.2.0) + interface random { + @since(version = 0.2.0) + get-random-bytes: func(len: u64) -> list; + + @since(version = 0.2.0) + get-random-u64: func() -> u64; + } + @since(version = 0.2.0) + world imports { + @since(version = 0.2.0) + import random; + @since(version = 0.2.0) + import insecure; + @since(version = 0.2.0) + import insecure-seed; + } +} + + +package wasi:filesystem@0.2.3 { + @since(version = 0.2.0) + interface types { + @since(version = 0.2.0) + use wasi:io/streams@0.2.3.{input-stream, output-stream, error}; + @since(version = 0.2.0) + use wasi:clocks/wall-clock@0.2.3.{datetime}; + + @since(version = 0.2.0) + type filesize = u64; + + @since(version = 0.2.0) + enum descriptor-type { + unknown, + block-device, + character-device, + directory, + fifo, + symbolic-link, + regular-file, + socket, + } + + @since(version = 0.2.0) + flags descriptor-flags { + read, + write, + file-integrity-sync, + data-integrity-sync, + requested-write-sync, + mutate-directory, + } + + @since(version = 0.2.0) + flags path-flags { + symlink-follow, + } + + @since(version = 0.2.0) + flags open-flags { + create, + directory, + exclusive, + truncate, + } + + @since(version = 0.2.0) + type link-count = u64; + + @since(version = 0.2.0) + record descriptor-stat { + %type: descriptor-type, + link-count: link-count, + size: filesize, + data-access-timestamp: option, + data-modification-timestamp: option, + status-change-timestamp: option, + } + + @since(version = 0.2.0) + variant new-timestamp { + no-change, + now, + timestamp(datetime), + } + + record directory-entry { + %type: descriptor-type, + name: string, + } + + enum error-code { + access, + would-block, + already, + bad-descriptor, + busy, + deadlock, + quota, + exist, + file-too-large, + illegal-byte-sequence, + in-progress, + interrupted, + invalid, + io, + is-directory, + loop, + too-many-links, + message-size, + name-too-long, + no-device, + no-entry, + no-lock, + insufficient-memory, + insufficient-space, + not-directory, + not-empty, + not-recoverable, + unsupported, + no-tty, + no-such-device, + overflow, + not-permitted, + pipe, + read-only, + invalid-seek, + text-file-busy, + cross-device, + } + + @since(version = 0.2.0) + enum advice { + normal, + sequential, + random, + will-need, + dont-need, + no-reuse, + } + + @since(version = 0.2.0) + record metadata-hash-value { + lower: u64, + upper: u64, + } + + @since(version = 0.2.0) + resource descriptor { + @since(version = 0.2.0) + read-via-stream: func(offset: filesize) -> result; + @since(version = 0.2.0) + write-via-stream: func(offset: filesize) -> result; + @since(version = 0.2.0) + append-via-stream: func() -> result; + @since(version = 0.2.0) + advise: func(offset: filesize, length: filesize, advice: advice) -> result<_, error-code>; + @since(version = 0.2.0) + sync-data: func() -> result<_, error-code>; + @since(version = 0.2.0) + get-flags: func() -> result; + @since(version = 0.2.0) + get-type: func() -> result; + @since(version = 0.2.0) + set-size: func(size: filesize) -> result<_, error-code>; + @since(version = 0.2.0) + set-times: func(data-access-timestamp: new-timestamp, data-modification-timestamp: new-timestamp) -> result<_, error-code>; + @since(version = 0.2.0) + read: func(length: filesize, offset: filesize) -> result, bool>, error-code>; + @since(version = 0.2.0) + write: func(buffer: list, offset: filesize) -> result; + @since(version = 0.2.0) + read-directory: func() -> result; + @since(version = 0.2.0) + sync: func() -> result<_, error-code>; + @since(version = 0.2.0) + create-directory-at: func(path: string) -> result<_, error-code>; + @since(version = 0.2.0) + stat: func() -> result; + @since(version = 0.2.0) + stat-at: func(path-flags: path-flags, path: string) -> result; + @since(version = 0.2.0) + set-times-at: func(path-flags: path-flags, path: string, data-access-timestamp: new-timestamp, data-modification-timestamp: new-timestamp) -> result<_, error-code>; + @since(version = 0.2.0) + link-at: func(old-path-flags: path-flags, old-path: string, new-descriptor: borrow, new-path: string) -> result<_, error-code>; + @since(version = 0.2.0) + open-at: func(path-flags: path-flags, path: string, open-flags: open-flags, %flags: descriptor-flags) -> result; + @since(version = 0.2.0) + readlink-at: func(path: string) -> result; + @since(version = 0.2.0) + remove-directory-at: func(path: string) -> result<_, error-code>; + @since(version = 0.2.0) + rename-at: func(old-path: string, new-descriptor: borrow, new-path: string) -> result<_, error-code>; + @since(version = 0.2.0) + symlink-at: func(old-path: string, new-path: string) -> result<_, error-code>; + @since(version = 0.2.0) + unlink-file-at: func(path: string) -> result<_, error-code>; + @since(version = 0.2.0) + is-same-object: func(other: borrow) -> bool; + @since(version = 0.2.0) + metadata-hash: func() -> result; + @since(version = 0.2.0) + metadata-hash-at: func(path-flags: path-flags, path: string) -> result; + } + + @since(version = 0.2.0) + resource directory-entry-stream { + @since(version = 0.2.0) + read-directory-entry: func() -> result, error-code>; + } + + @since(version = 0.2.0) + filesystem-error-code: func(err: borrow) -> option; + } + @since(version = 0.2.0) + interface preopens { + @since(version = 0.2.0) + use types.{descriptor}; + + @since(version = 0.2.0) + get-directories: func() -> list>; + } + @since(version = 0.2.0) + world imports { + @since(version = 0.2.0) + import wasi:io/error@0.2.3; + @since(version = 0.2.0) + import wasi:io/poll@0.2.3; + @since(version = 0.2.0) + import wasi:io/streams@0.2.3; + @since(version = 0.2.0) + import wasi:clocks/wall-clock@0.2.3; + @since(version = 0.2.0) + import types; + @since(version = 0.2.0) + import preopens; + } +} + + +package wasi:sockets@0.2.3 { + @since(version = 0.2.0) + interface network { + @since(version = 0.2.0) + resource network; + + @since(version = 0.2.0) + enum error-code { + unknown, + access-denied, + not-supported, + invalid-argument, + out-of-memory, + timeout, + concurrency-conflict, + not-in-progress, + would-block, + invalid-state, + new-socket-limit, + address-not-bindable, + address-in-use, + remote-unreachable, + connection-refused, + connection-reset, + connection-aborted, + datagram-too-large, + name-unresolvable, + temporary-resolver-failure, + permanent-resolver-failure, + } + + @since(version = 0.2.0) + enum ip-address-family { + ipv4, + ipv6, + } + + @since(version = 0.2.0) + type ipv4-address = tuple; + + @since(version = 0.2.0) + type ipv6-address = tuple; + + @since(version = 0.2.0) + variant ip-address { + ipv4(ipv4-address), + ipv6(ipv6-address), + } + + @since(version = 0.2.0) + record ipv4-socket-address { + port: u16, + address: ipv4-address, + } + + @since(version = 0.2.0) + record ipv6-socket-address { + port: u16, + flow-info: u32, + address: ipv6-address, + scope-id: u32, + } + + @since(version = 0.2.0) + variant ip-socket-address { + ipv4(ipv4-socket-address), + ipv6(ipv6-socket-address), + } + } + @since(version = 0.2.0) + interface instance-network { + @since(version = 0.2.0) + use network.{network}; + + @since(version = 0.2.0) + instance-network: func() -> network; + } + @since(version = 0.2.0) + interface ip-name-lookup { + @since(version = 0.2.0) + use wasi:io/poll@0.2.3.{pollable}; + @since(version = 0.2.0) + use network.{network, error-code, ip-address}; + + @since(version = 0.2.0) + resource resolve-address-stream { + @since(version = 0.2.0) + resolve-next-address: func() -> result, error-code>; + @since(version = 0.2.0) + subscribe: func() -> pollable; + } + + @since(version = 0.2.0) + resolve-addresses: func(network: borrow, name: string) -> result; + } + @since(version = 0.2.0) + interface tcp { + @since(version = 0.2.0) + use wasi:io/streams@0.2.3.{input-stream, output-stream}; + @since(version = 0.2.0) + use wasi:io/poll@0.2.3.{pollable}; + @since(version = 0.2.0) + use wasi:clocks/monotonic-clock@0.2.3.{duration}; + @since(version = 0.2.0) + use network.{network, error-code, ip-socket-address, ip-address-family}; + + @since(version = 0.2.0) + enum shutdown-type { + receive, + send, + both, + } + + @since(version = 0.2.0) + resource tcp-socket { + @since(version = 0.2.0) + start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; + @since(version = 0.2.0) + finish-bind: func() -> result<_, error-code>; + @since(version = 0.2.0) + start-connect: func(network: borrow, remote-address: ip-socket-address) -> result<_, error-code>; + @since(version = 0.2.0) + finish-connect: func() -> result, error-code>; + @since(version = 0.2.0) + start-listen: func() -> result<_, error-code>; + @since(version = 0.2.0) + finish-listen: func() -> result<_, error-code>; + @since(version = 0.2.0) + accept: func() -> result, error-code>; + @since(version = 0.2.0) + local-address: func() -> result; + @since(version = 0.2.0) + remote-address: func() -> result; + @since(version = 0.2.0) + is-listening: func() -> bool; + @since(version = 0.2.0) + address-family: func() -> ip-address-family; + @since(version = 0.2.0) + set-listen-backlog-size: func(value: u64) -> result<_, error-code>; + @since(version = 0.2.0) + keep-alive-enabled: func() -> result; + @since(version = 0.2.0) + set-keep-alive-enabled: func(value: bool) -> result<_, error-code>; + @since(version = 0.2.0) + keep-alive-idle-time: func() -> result; + @since(version = 0.2.0) + set-keep-alive-idle-time: func(value: duration) -> result<_, error-code>; + @since(version = 0.2.0) + keep-alive-interval: func() -> result; + @since(version = 0.2.0) + set-keep-alive-interval: func(value: duration) -> result<_, error-code>; + @since(version = 0.2.0) + keep-alive-count: func() -> result; + @since(version = 0.2.0) + set-keep-alive-count: func(value: u32) -> result<_, error-code>; + @since(version = 0.2.0) + hop-limit: func() -> result; + @since(version = 0.2.0) + set-hop-limit: func(value: u8) -> result<_, error-code>; + @since(version = 0.2.0) + receive-buffer-size: func() -> result; + @since(version = 0.2.0) + set-receive-buffer-size: func(value: u64) -> result<_, error-code>; + @since(version = 0.2.0) + send-buffer-size: func() -> result; + @since(version = 0.2.0) + set-send-buffer-size: func(value: u64) -> result<_, error-code>; + @since(version = 0.2.0) + subscribe: func() -> pollable; + @since(version = 0.2.0) + shutdown: func(shutdown-type: shutdown-type) -> result<_, error-code>; + } + } + @since(version = 0.2.0) + interface tcp-create-socket { + @since(version = 0.2.0) + use network.{network, error-code, ip-address-family}; + @since(version = 0.2.0) + use tcp.{tcp-socket}; + + @since(version = 0.2.0) + create-tcp-socket: func(address-family: ip-address-family) -> result; + } + @since(version = 0.2.0) + interface udp { + @since(version = 0.2.0) + use wasi:io/poll@0.2.3.{pollable}; + @since(version = 0.2.0) + use network.{network, error-code, ip-socket-address, ip-address-family}; + + @since(version = 0.2.0) + record incoming-datagram { + data: list, + remote-address: ip-socket-address, + } + + @since(version = 0.2.0) + record outgoing-datagram { + data: list, + remote-address: option, + } + + @since(version = 0.2.0) + resource udp-socket { + @since(version = 0.2.0) + start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; + @since(version = 0.2.0) + finish-bind: func() -> result<_, error-code>; + @since(version = 0.2.0) + %stream: func(remote-address: option) -> result, error-code>; + @since(version = 0.2.0) + local-address: func() -> result; + @since(version = 0.2.0) + remote-address: func() -> result; + @since(version = 0.2.0) + address-family: func() -> ip-address-family; + @since(version = 0.2.0) + unicast-hop-limit: func() -> result; + @since(version = 0.2.0) + set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; + @since(version = 0.2.0) + receive-buffer-size: func() -> result; + @since(version = 0.2.0) + set-receive-buffer-size: func(value: u64) -> result<_, error-code>; + @since(version = 0.2.0) + send-buffer-size: func() -> result; + @since(version = 0.2.0) + set-send-buffer-size: func(value: u64) -> result<_, error-code>; + @since(version = 0.2.0) + subscribe: func() -> pollable; + } + + @since(version = 0.2.0) + resource incoming-datagram-stream { + @since(version = 0.2.0) + receive: func(max-results: u64) -> result, error-code>; + @since(version = 0.2.0) + subscribe: func() -> pollable; + } + + @since(version = 0.2.0) + resource outgoing-datagram-stream { + check-send: func() -> result; + @since(version = 0.2.0) + send: func(datagrams: list) -> result; + @since(version = 0.2.0) + subscribe: func() -> pollable; + } + } + @since(version = 0.2.0) + interface udp-create-socket { + @since(version = 0.2.0) + use network.{network, error-code, ip-address-family}; + @since(version = 0.2.0) + use udp.{udp-socket}; + + @since(version = 0.2.0) + create-udp-socket: func(address-family: ip-address-family) -> result; + } + @since(version = 0.2.0) + world imports { + @since(version = 0.2.0) + import network; + @since(version = 0.2.0) + import instance-network; + @since(version = 0.2.0) + import wasi:io/poll@0.2.3; + @since(version = 0.2.0) + import udp; + @since(version = 0.2.0) + import udp-create-socket; + @since(version = 0.2.0) + import wasi:io/error@0.2.3; + @since(version = 0.2.0) + import wasi:io/streams@0.2.3; + @since(version = 0.2.0) + import wasi:clocks/monotonic-clock@0.2.3; + @since(version = 0.2.0) + import tcp; + @since(version = 0.2.0) + import tcp-create-socket; + @since(version = 0.2.0) + import ip-name-lookup; + } +} + + +package wasi:cli@0.2.3 { + @since(version = 0.2.0) + interface environment { + @since(version = 0.2.0) + get-environment: func() -> list>; + + @since(version = 0.2.0) + get-arguments: func() -> list; + + @since(version = 0.2.0) + initial-cwd: func() -> option; + } + @since(version = 0.2.0) + interface exit { + @since(version = 0.2.0) + exit: func(status: result); + } + @since(version = 0.2.0) + interface run { + @since(version = 0.2.0) + run: func() -> result; + } + @since(version = 0.2.0) + interface stdin { + @since(version = 0.2.0) + use wasi:io/streams@0.2.3.{input-stream}; + + @since(version = 0.2.0) + get-stdin: func() -> input-stream; + } + @since(version = 0.2.0) + interface stdout { + @since(version = 0.2.0) + use wasi:io/streams@0.2.3.{output-stream}; + + @since(version = 0.2.0) + get-stdout: func() -> output-stream; + } + @since(version = 0.2.0) + interface stderr { + @since(version = 0.2.0) + use wasi:io/streams@0.2.3.{output-stream}; + + @since(version = 0.2.0) + get-stderr: func() -> output-stream; + } + @since(version = 0.2.0) + interface terminal-input { + @since(version = 0.2.0) + resource terminal-input; + } + @since(version = 0.2.0) + interface terminal-output { + @since(version = 0.2.0) + resource terminal-output; + } + @since(version = 0.2.0) + interface terminal-stdin { + @since(version = 0.2.0) + use terminal-input.{terminal-input}; + + @since(version = 0.2.0) + get-terminal-stdin: func() -> option; + } + @since(version = 0.2.0) + interface terminal-stdout { + @since(version = 0.2.0) + use terminal-output.{terminal-output}; + + @since(version = 0.2.0) + get-terminal-stdout: func() -> option; + } + @since(version = 0.2.0) + interface terminal-stderr { + @since(version = 0.2.0) + use terminal-output.{terminal-output}; + + @since(version = 0.2.0) + get-terminal-stderr: func() -> option; + } + @since(version = 0.2.0) + world imports { + @since(version = 0.2.0) + import environment; + @since(version = 0.2.0) + import exit; + @since(version = 0.2.0) + import wasi:io/error@0.2.3; + @since(version = 0.2.0) + import wasi:io/poll@0.2.3; + @since(version = 0.2.0) + import wasi:io/streams@0.2.3; + @since(version = 0.2.0) + import stdin; + @since(version = 0.2.0) + import stdout; + @since(version = 0.2.0) + import stderr; + @since(version = 0.2.0) + import terminal-input; + @since(version = 0.2.0) + import terminal-output; + @since(version = 0.2.0) + import terminal-stdin; + @since(version = 0.2.0) + import terminal-stdout; + @since(version = 0.2.0) + import terminal-stderr; + @since(version = 0.2.0) + import wasi:clocks/monotonic-clock@0.2.3; + @since(version = 0.2.0) + import wasi:clocks/wall-clock@0.2.3; + @since(version = 0.2.0) + import wasi:filesystem/types@0.2.3; + @since(version = 0.2.0) + import wasi:filesystem/preopens@0.2.3; + @since(version = 0.2.0) + import wasi:sockets/network@0.2.3; + @since(version = 0.2.0) + import wasi:sockets/instance-network@0.2.3; + @since(version = 0.2.0) + import wasi:sockets/udp@0.2.3; + @since(version = 0.2.0) + import wasi:sockets/udp-create-socket@0.2.3; + @since(version = 0.2.0) + import wasi:sockets/tcp@0.2.3; + @since(version = 0.2.0) + import wasi:sockets/tcp-create-socket@0.2.3; + @since(version = 0.2.0) + import wasi:sockets/ip-name-lookup@0.2.3; + @since(version = 0.2.0) + import wasi:random/random@0.2.3; + @since(version = 0.2.0) + import wasi:random/insecure@0.2.3; + @since(version = 0.2.0) + import wasi:random/insecure-seed@0.2.3; + } + @since(version = 0.2.0) + world command { + @since(version = 0.2.0) + import environment; + @since(version = 0.2.0) + import exit; + @since(version = 0.2.0) + import wasi:io/error@0.2.3; + @since(version = 0.2.0) + import wasi:io/poll@0.2.3; + @since(version = 0.2.0) + import wasi:io/streams@0.2.3; + @since(version = 0.2.0) + import stdin; + @since(version = 0.2.0) + import stdout; + @since(version = 0.2.0) + import stderr; + @since(version = 0.2.0) + import terminal-input; + @since(version = 0.2.0) + import terminal-output; + @since(version = 0.2.0) + import terminal-stdin; + @since(version = 0.2.0) + import terminal-stdout; + @since(version = 0.2.0) + import terminal-stderr; + @since(version = 0.2.0) + import wasi:clocks/monotonic-clock@0.2.3; + @since(version = 0.2.0) + import wasi:clocks/wall-clock@0.2.3; + @since(version = 0.2.0) + import wasi:filesystem/types@0.2.3; + @since(version = 0.2.0) + import wasi:filesystem/preopens@0.2.3; + @since(version = 0.2.0) + import wasi:sockets/network@0.2.3; + @since(version = 0.2.0) + import wasi:sockets/instance-network@0.2.3; + @since(version = 0.2.0) + import wasi:sockets/udp@0.2.3; + @since(version = 0.2.0) + import wasi:sockets/udp-create-socket@0.2.3; + @since(version = 0.2.0) + import wasi:sockets/tcp@0.2.3; + @since(version = 0.2.0) + import wasi:sockets/tcp-create-socket@0.2.3; + @since(version = 0.2.0) + import wasi:sockets/ip-name-lookup@0.2.3; + @since(version = 0.2.0) + import wasi:random/random@0.2.3; + @since(version = 0.2.0) + import wasi:random/insecure@0.2.3; + @since(version = 0.2.0) + import wasi:random/insecure-seed@0.2.3; + + @since(version = 0.2.0) + export run; + } +} + + +package wasi:http@0.2.3 { + @since(version = 0.2.0) + interface types { + @since(version = 0.2.0) + use wasi:clocks/monotonic-clock@0.2.3.{duration}; + @since(version = 0.2.0) + use wasi:io/streams@0.2.3.{input-stream, output-stream}; + @since(version = 0.2.0) + use wasi:io/error@0.2.3.{error as io-error}; + @since(version = 0.2.0) + use wasi:io/poll@0.2.3.{pollable}; + + @since(version = 0.2.0) + variant method { + get, + head, + post, + put, + delete, + connect, + options, + trace, + patch, + other(string), + } + + @since(version = 0.2.0) + variant scheme { + HTTP, + HTTPS, + other(string), + } + + @since(version = 0.2.0) + record DNS-error-payload { + rcode: option, + info-code: option, + } + + @since(version = 0.2.0) + record TLS-alert-received-payload { + alert-id: option, + alert-message: option, + } + + @since(version = 0.2.0) + record field-size-payload { + field-name: option, + field-size: option, + } + + @since(version = 0.2.0) + variant error-code { + DNS-timeout, + DNS-error(DNS-error-payload), + destination-not-found, + destination-unavailable, + destination-IP-prohibited, + destination-IP-unroutable, + connection-refused, + connection-terminated, + connection-timeout, + connection-read-timeout, + connection-write-timeout, + connection-limit-reached, + TLS-protocol-error, + TLS-certificate-error, + TLS-alert-received(TLS-alert-received-payload), + HTTP-request-denied, + HTTP-request-length-required, + HTTP-request-body-size(option), + HTTP-request-method-invalid, + HTTP-request-URI-invalid, + HTTP-request-URI-too-long, + HTTP-request-header-section-size(option), + HTTP-request-header-size(option), + HTTP-request-trailer-section-size(option), + HTTP-request-trailer-size(field-size-payload), + HTTP-response-incomplete, + HTTP-response-header-section-size(option), + HTTP-response-header-size(field-size-payload), + HTTP-response-body-size(option), + HTTP-response-trailer-section-size(option), + HTTP-response-trailer-size(field-size-payload), + HTTP-response-transfer-coding(option), + HTTP-response-content-coding(option), + HTTP-response-timeout, + HTTP-upgrade-failed, + HTTP-protocol-error, + loop-detected, + configuration-error, + internal-error(option), + } + + @since(version = 0.2.0) + variant header-error { + invalid-syntax, + forbidden, + immutable, + } + + @since(version = 0.2.0) + @deprecated(version = 0.2.2) + type field-key = string; + + @since(version = 0.2.1) + type field-name = field-key; + + @since(version = 0.2.0) + type field-value = list; + + @since(version = 0.2.0) + resource fields { + @since(version = 0.2.0) + constructor(); + @since(version = 0.2.0) + from-list: static func(entries: list>) -> result; + @since(version = 0.2.0) + get: func(name: field-name) -> list; + @since(version = 0.2.0) + has: func(name: field-name) -> bool; + @since(version = 0.2.0) + set: func(name: field-name, value: list) -> result<_, header-error>; + @since(version = 0.2.0) + delete: func(name: field-name) -> result<_, header-error>; + @since(version = 0.2.0) + append: func(name: field-name, value: field-value) -> result<_, header-error>; + @since(version = 0.2.0) + entries: func() -> list>; + @since(version = 0.2.0) + clone: func() -> fields; + } + + @since(version = 0.2.0) + type headers = fields; + + @since(version = 0.2.0) + type trailers = fields; + + @since(version = 0.2.0) + resource incoming-request { + @since(version = 0.2.0) + method: func() -> method; + @since(version = 0.2.0) + path-with-query: func() -> option; + @since(version = 0.2.0) + scheme: func() -> option; + @since(version = 0.2.0) + authority: func() -> option; + @since(version = 0.2.0) + headers: func() -> headers; + @since(version = 0.2.0) + consume: func() -> result; + } + + @since(version = 0.2.0) + resource outgoing-request { + @since(version = 0.2.0) + constructor(headers: headers); + @since(version = 0.2.0) + body: func() -> result; + @since(version = 0.2.0) + method: func() -> method; + @since(version = 0.2.0) + set-method: func(method: method) -> result; + @since(version = 0.2.0) + path-with-query: func() -> option; + @since(version = 0.2.0) + set-path-with-query: func(path-with-query: option) -> result; + @since(version = 0.2.0) + scheme: func() -> option; + @since(version = 0.2.0) + set-scheme: func(scheme: option) -> result; + @since(version = 0.2.0) + authority: func() -> option; + @since(version = 0.2.0) + set-authority: func(authority: option) -> result; + @since(version = 0.2.0) + headers: func() -> headers; + } + + @since(version = 0.2.0) + resource request-options { + @since(version = 0.2.0) + constructor(); + @since(version = 0.2.0) + connect-timeout: func() -> option; + @since(version = 0.2.0) + set-connect-timeout: func(duration: option) -> result; + @since(version = 0.2.0) + first-byte-timeout: func() -> option; + @since(version = 0.2.0) + set-first-byte-timeout: func(duration: option) -> result; + @since(version = 0.2.0) + between-bytes-timeout: func() -> option; + @since(version = 0.2.0) + set-between-bytes-timeout: func(duration: option) -> result; + } + + @since(version = 0.2.0) + resource response-outparam { + @since(version = 0.2.0) + set: static func(param: response-outparam, response: result); + } + + @since(version = 0.2.0) + type status-code = u16; + + @since(version = 0.2.0) + resource incoming-response { + @since(version = 0.2.0) + status: func() -> status-code; + @since(version = 0.2.0) + headers: func() -> headers; + @since(version = 0.2.0) + consume: func() -> result; + } + + @since(version = 0.2.0) + resource incoming-body { + @since(version = 0.2.0) + %stream: func() -> result; + @since(version = 0.2.0) + finish: static func(this: incoming-body) -> future-trailers; + } + + @since(version = 0.2.0) + resource future-trailers { + @since(version = 0.2.0) + subscribe: func() -> pollable; + @since(version = 0.2.0) + get: func() -> option, error-code>>>; + } + + @since(version = 0.2.0) + resource outgoing-response { + @since(version = 0.2.0) + constructor(headers: headers); + @since(version = 0.2.0) + status-code: func() -> status-code; + @since(version = 0.2.0) + set-status-code: func(status-code: status-code) -> result; + @since(version = 0.2.0) + headers: func() -> headers; + @since(version = 0.2.0) + body: func() -> result; + } + + @since(version = 0.2.0) + resource outgoing-body { + @since(version = 0.2.0) + write: func() -> result; + @since(version = 0.2.0) + finish: static func(this: outgoing-body, trailers: option) -> result<_, error-code>; + } + + @since(version = 0.2.0) + resource future-incoming-response { + @since(version = 0.2.0) + subscribe: func() -> pollable; + @since(version = 0.2.0) + get: func() -> option>>; + } + + @since(version = 0.2.0) + http-error-code: func(err: borrow) -> option; + } + @since(version = 0.2.0) + interface incoming-handler { + @since(version = 0.2.0) + use types.{incoming-request, response-outparam}; + + @since(version = 0.2.0) + handle: func(request: incoming-request, response-out: response-outparam); + } + @since(version = 0.2.0) + interface outgoing-handler { + @since(version = 0.2.0) + use types.{outgoing-request, request-options, future-incoming-response, error-code}; + + @since(version = 0.2.0) + handle: func(request: outgoing-request, options: option) -> result; + } + @since(version = 0.2.0) + world imports { + @since(version = 0.2.0) + import wasi:io/poll@0.2.3; + @since(version = 0.2.0) + import wasi:clocks/monotonic-clock@0.2.3; + @since(version = 0.2.0) + import wasi:clocks/wall-clock@0.2.3; + @since(version = 0.2.0) + import wasi:random/random@0.2.3; + @since(version = 0.2.0) + import wasi:io/error@0.2.3; + @since(version = 0.2.0) + import wasi:io/streams@0.2.3; + @since(version = 0.2.0) + import wasi:cli/stdout@0.2.3; + @since(version = 0.2.0) + import wasi:cli/stderr@0.2.3; + @since(version = 0.2.0) + import wasi:cli/stdin@0.2.3; + @since(version = 0.2.0) + import types; + @since(version = 0.2.0) + import outgoing-handler; + } + @since(version = 0.2.0) + world proxy { + @since(version = 0.2.0) + import wasi:io/poll@0.2.3; + @since(version = 0.2.0) + import wasi:clocks/monotonic-clock@0.2.3; + @since(version = 0.2.0) + import wasi:clocks/wall-clock@0.2.3; + @since(version = 0.2.0) + import wasi:random/random@0.2.3; + @since(version = 0.2.0) + import wasi:io/error@0.2.3; + @since(version = 0.2.0) + import wasi:io/streams@0.2.3; + @since(version = 0.2.0) + import wasi:cli/stdout@0.2.3; + @since(version = 0.2.0) + import wasi:cli/stderr@0.2.3; + @since(version = 0.2.0) + import wasi:cli/stdin@0.2.3; + @since(version = 0.2.0) + import types; + @since(version = 0.2.0) + import outgoing-handler; + + @since(version = 0.2.0) + export incoming-handler; + } +} + + +package fermyon:spin@2.0.0 { + interface key-value { + resource store { + open: static func(label: string) -> result; + get: func(key: string) -> result>, error>; + set: func(key: string, value: list) -> result<_, error>; + delete: func(key: string) -> result<_, error>; + exists: func(key: string) -> result; + get-keys: func() -> result, error>; + } + + variant error { + store-table-full, + no-such-store, + access-denied, + other(string), + } + } + interface llm { + type inferencing-model = string; + + record inferencing-params { + max-tokens: u32, + repeat-penalty: f32, + repeat-penalty-last-n-token-count: u32, + temperature: f32, + top-k: u32, + top-p: f32, + } + + variant error { + model-not-supported, + runtime-error(string), + invalid-input(string), + } + + record inferencing-usage { + prompt-token-count: u32, + generated-token-count: u32, + } + + record inferencing-result { + text: string, + usage: inferencing-usage, + } + + type embedding-model = string; + + record embeddings-usage { + prompt-token-count: u32, + } + + record embeddings-result { + embeddings: list>, + usage: embeddings-usage, + } + + infer: func(model: inferencing-model, prompt: string, params: option) -> result; + + generate-embeddings: func(model: embedding-model, text: list) -> result; + } + interface mqtt { + variant error { + invalid-address, + too-many-connections, + connection-failed(string), + other(string), + } + + enum qos { + at-most-once, + at-least-once, + exactly-once, + } + + resource connection { + open: static func(address: string, username: string, password: string, keep-alive-interval-in-secs: u64) -> result; + publish: func(topic: string, payload: payload, qos: qos) -> result<_, error>; + } + + type payload = list; + } + interface rdbms-types { + variant error { + connection-failed(string), + bad-parameter(string), + query-failed(string), + value-conversion-failed(string), + other(string), + } + + enum db-data-type { + boolean, + int8, + int16, + int32, + int64, + uint8, + uint16, + uint32, + uint64, + floating32, + floating64, + str, + binary, + other, + } + + variant db-value { + boolean(bool), + int8(s8), + int16(s16), + int32(s32), + int64(s64), + uint8(u8), + uint16(u16), + uint32(u32), + uint64(u64), + floating32(f32), + floating64(f64), + str(string), + binary(list), + db-null, + unsupported, + } + + variant parameter-value { + boolean(bool), + int8(s8), + int16(s16), + int32(s32), + int64(s64), + uint8(u8), + uint16(u16), + uint32(u32), + uint64(u64), + floating32(f32), + floating64(f64), + str(string), + binary(list), + db-null, + } + + record column { + name: string, + data-type: db-data-type, + } + + type row = list; + + record row-set { + columns: list, + rows: list, + } + } + interface mysql { + use rdbms-types.{parameter-value, row-set, error}; + + resource connection { + open: static func(address: string) -> result; + query: func(statement: string, params: list) -> result; + execute: func(statement: string, params: list) -> result<_, error>; + } + } + interface postgres { + use rdbms-types.{parameter-value, row-set, error}; + + resource connection { + open: static func(address: string) -> result; + query: func(statement: string, params: list) -> result; + execute: func(statement: string, params: list) -> result; + } + } + interface redis { + variant error { + invalid-address, + too-many-connections, + type-error, + other(string), + } + + resource connection { + open: static func(address: string) -> result; + publish: func(channel: string, payload: payload) -> result<_, error>; + get: func(key: string) -> result, error>; + set: func(key: string, value: payload) -> result<_, error>; + incr: func(key: string) -> result; + del: func(keys: list) -> result; + sadd: func(key: string, values: list) -> result; + smembers: func(key: string) -> result, error>; + srem: func(key: string, values: list) -> result; + execute: func(command: string, arguments: list) -> result, error>; + } + + type payload = list; + + variant redis-parameter { + int64(s64), + binary(payload), + } + + variant redis-result { + nil, + status(string), + int64(s64), + binary(payload), + } + } + interface sqlite { + resource connection { + open: static func(database: string) -> result; + execute: func(statement: string, parameters: list) -> result; + } + + variant error { + no-such-database, + access-denied, + invalid-connection, + database-full, + io(string), + } + + variant value { + integer(s64), + real(f64), + text(string), + blob(list), + null, + } + + record row-result { + values: list, + } + + record query-result { + columns: list, + rows: list, + } + } + interface variables { + variant error { + invalid-name(string), + undefined(string), + provider(string), + other(string), + } + + get: func(name: string) -> result; + } + world spin-imports { + import wasi:io/poll@0.2.3; + import wasi:clocks/monotonic-clock@0.2.3; + import wasi:io/error@0.2.3; + import wasi:io/streams@0.2.3; + import wasi:http/types@0.2.3; + import wasi:http/outgoing-handler@0.2.3; + import llm; + import redis; + import rdbms-types; + import postgres; + import mysql; + import mqtt; + import sqlite; + import key-value; + import variables; + } + world spin-redis { + import wasi:io/poll@0.2.3; + import wasi:clocks/monotonic-clock@0.2.3; + import wasi:io/error@0.2.3; + import wasi:io/streams@0.2.3; + import wasi:http/types@0.2.3; + import wasi:http/outgoing-handler@0.2.3; + import llm; + import redis; + import rdbms-types; + import postgres; + import mysql; + import mqtt; + import sqlite; + import key-value; + import variables; + import fermyon:spin/redis-types; + + export fermyon:spin/inbound-redis; + } + world spin-http { + import wasi:io/poll@0.2.3; + import wasi:clocks/monotonic-clock@0.2.3; + import wasi:io/error@0.2.3; + import wasi:io/streams@0.2.3; + import wasi:http/types@0.2.3; + import wasi:http/outgoing-handler@0.2.3; + import llm; + import redis; + import rdbms-types; + import postgres; + import mysql; + import mqtt; + import sqlite; + import key-value; + import variables; + + export wasi:http/incoming-handler@0.2.3; + } + world spin-all { + import wasi:io/poll@0.2.3; + import wasi:clocks/monotonic-clock@0.2.3; + import wasi:io/error@0.2.3; + import wasi:io/streams@0.2.3; + import wasi:http/types@0.2.3; + import wasi:http/outgoing-handler@0.2.3; + import llm; + import redis; + import rdbms-types; + import postgres; + import mysql; + import mqtt; + import sqlite; + import key-value; + import variables; + import fermyon:spin/redis-types; + + export fermyon:spin/inbound-redis; + export wasi:http/incoming-handler@0.2.3; + } +} + + +package wasi:keyvalue@0.2.0-draft2 { + interface store { + variant error { + no-such-store, + access-denied, + other(string), + } + + record key-response { + keys: list, + cursor: option, + } + + resource bucket { + get: func(key: string) -> result>, error>; + set: func(key: string, value: list) -> result<_, error>; + delete: func(key: string) -> result<_, error>; + exists: func(key: string) -> result; + list-keys: func(cursor: option) -> result; + } + + open: func(identifier: string) -> result; + } + interface atomics { + use store.{bucket, error}; + + resource cas { + new: static func(bucket: borrow, key: string) -> result; + current: func() -> result>, error>; + } + + variant cas-error { + store-error(error), + cas-failed(cas), + } + + increment: func(bucket: borrow, key: string, delta: s64) -> result; + + swap: func(cas: cas, value: list) -> result<_, cas-error>; + } + interface batch { + use store.{bucket, error}; + + get-many: func(bucket: borrow, keys: list) -> result>>>, error>; + + set-many: func(bucket: borrow, key-values: list>>) -> result<_, error>; + + delete-many: func(bucket: borrow, keys: list) -> result<_, error>; + } + interface watcher { + use store.{bucket}; + + on-set: func(bucket: bucket, key: string, value: list); + + on-delete: func(bucket: bucket, key: string); + } + world imports { + import store; + import atomics; + import batch; + } + world watch-service { + import store; + import atomics; + import batch; + + export watcher; + } +} + + +package spin:postgres@3.0.0 { + interface postgres { + variant error { + connection-failed(string), + bad-parameter(string), + query-failed(string), + value-conversion-failed(string), + other(string), + } + + enum db-data-type { + boolean, + int8, + int16, + int32, + int64, + floating32, + floating64, + str, + binary, + date, + time, + datetime, + timestamp, + other, + } + + variant db-value { + boolean(bool), + int8(s8), + int16(s16), + int32(s32), + int64(s64), + floating32(f32), + floating64(f64), + str(string), + binary(list), + date(tuple), + time(tuple), + datetime(tuple), + timestamp(s64), + db-null, + unsupported, + } + + variant parameter-value { + boolean(bool), + int8(s8), + int16(s16), + int32(s32), + int64(s64), + floating32(f32), + floating64(f64), + str(string), + binary(list), + date(tuple), + time(tuple), + datetime(tuple), + timestamp(s64), + db-null, + } + + record column { + name: string, + data-type: db-data-type, + } + + type row = list; + + record row-set { + columns: list, + rows: list, + } + + resource connection { + open: static func(address: string) -> result; + query: func(statement: string, params: list) -> result; + execute: func(statement: string, params: list) -> result; + } + } +} + + +package wasi:config@0.2.0-draft-2024-09-27 { + interface store { + variant error { + upstream(string), + io(string), + } + + get: func(key: string) -> result, error>; + + get-all: func() -> result>, error>; + } + world imports { + import store; + } +} + + +package fermyon:spin@3.0.0 { + world spin3-imports { + import spin:postgres/postgres@3.0.0; + import wasi:config/store@0.2.0-draft-2024-09-27; + import wasi:io/poll@0.2.3; + import wasi:clocks/monotonic-clock@0.2.3; + import wasi:io/error@0.2.3; + import wasi:io/streams@0.2.3; + import wasi:http/types@0.2.3; + import wasi:http/outgoing-handler@0.2.3; + import fermyon:spin/llm@2.0.0; + import fermyon:spin/redis@2.0.0; + import fermyon:spin/rdbms-types@2.0.0; + import fermyon:spin/postgres@2.0.0; + import fermyon:spin/mysql@2.0.0; + import fermyon:spin/mqtt@2.0.0; + import fermyon:spin/sqlite@2.0.0; + import fermyon:spin/key-value@2.0.0; + import fermyon:spin/variables@2.0.0; + import wasi:keyvalue/store@0.2.0-draft2; + import wasi:keyvalue/atomics@0.2.0-draft2; + import wasi:keyvalue/batch@0.2.0-draft2; + } + world spin3-redis { + import spin:postgres/postgres@3.0.0; + import wasi:config/store@0.2.0-draft-2024-09-27; + import wasi:io/poll@0.2.3; + import wasi:clocks/monotonic-clock@0.2.3; + import wasi:io/error@0.2.3; + import wasi:io/streams@0.2.3; + import wasi:http/types@0.2.3; + import wasi:http/outgoing-handler@0.2.3; + import fermyon:spin/llm@2.0.0; + import fermyon:spin/redis@2.0.0; + import fermyon:spin/rdbms-types@2.0.0; + import fermyon:spin/postgres@2.0.0; + import fermyon:spin/mysql@2.0.0; + import fermyon:spin/mqtt@2.0.0; + import fermyon:spin/sqlite@2.0.0; + import fermyon:spin/key-value@2.0.0; + import fermyon:spin/variables@2.0.0; + import wasi:keyvalue/store@0.2.0-draft2; + import wasi:keyvalue/atomics@0.2.0-draft2; + import wasi:keyvalue/batch@0.2.0-draft2; + import fermyon:spin/redis-types; + + export fermyon:spin/inbound-redis; + } + world spin3-http { + import spin:postgres/postgres@3.0.0; + import wasi:config/store@0.2.0-draft-2024-09-27; + import wasi:io/poll@0.2.3; + import wasi:clocks/monotonic-clock@0.2.3; + import wasi:io/error@0.2.3; + import wasi:io/streams@0.2.3; + import wasi:http/types@0.2.3; + import wasi:http/outgoing-handler@0.2.3; + import fermyon:spin/llm@2.0.0; + import fermyon:spin/redis@2.0.0; + import fermyon:spin/rdbms-types@2.0.0; + import fermyon:spin/postgres@2.0.0; + import fermyon:spin/mysql@2.0.0; + import fermyon:spin/mqtt@2.0.0; + import fermyon:spin/sqlite@2.0.0; + import fermyon:spin/key-value@2.0.0; + import fermyon:spin/variables@2.0.0; + import wasi:keyvalue/store@0.2.0-draft2; + import wasi:keyvalue/atomics@0.2.0-draft2; + import wasi:keyvalue/batch@0.2.0-draft2; + + export wasi:http/incoming-handler@0.2.3; + } + world spin3-all { + import spin:postgres/postgres@3.0.0; + import wasi:config/store@0.2.0-draft-2024-09-27; + import wasi:io/poll@0.2.3; + import wasi:clocks/monotonic-clock@0.2.3; + import wasi:io/error@0.2.3; + import wasi:io/streams@0.2.3; + import wasi:http/types@0.2.3; + import wasi:http/outgoing-handler@0.2.3; + import fermyon:spin/llm@2.0.0; + import fermyon:spin/redis@2.0.0; + import fermyon:spin/rdbms-types@2.0.0; + import fermyon:spin/postgres@2.0.0; + import fermyon:spin/mysql@2.0.0; + import fermyon:spin/mqtt@2.0.0; + import fermyon:spin/sqlite@2.0.0; + import fermyon:spin/key-value@2.0.0; + import fermyon:spin/variables@2.0.0; + import wasi:keyvalue/store@0.2.0-draft2; + import wasi:keyvalue/atomics@0.2.0-draft2; + import wasi:keyvalue/batch@0.2.0-draft2; + import fermyon:spin/redis-types; + + export fermyon:spin/inbound-redis; + export wasi:http/incoming-handler@0.2.3; + } +} diff --git a/debugger/vscode-dap-extension/src/starlingMonkeyRuntime.ts b/debugger/vscode-dap-extension/src/starlingMonkeyRuntime.ts index 88b788c3..45c5252e 100644 --- a/debugger/vscode-dap-extension/src/starlingMonkeyRuntime.ts +++ b/debugger/vscode-dap-extension/src/starlingMonkeyRuntime.ts @@ -49,6 +49,7 @@ export interface IComponentRuntimeConfig { envOption: string; } export interface IStarlingMonkeyRuntimeConfig { + jsRuntimeOptions: string[]; componentRuntime: IComponentRuntimeConfig; } @@ -63,7 +64,7 @@ class ComponentRuntimeInstance { this._nextSessionPort = port; } - static async start(workspaceFolder: string, component: string, config: IComponentRuntimeConfig) { + static async start(workspaceFolder: string, component: string, config: IStarlingMonkeyRuntimeConfig) { assert(!this.running, "ComponentRuntime is already running"); this.running = true; this.workspaceFolder = workspaceFolder; @@ -84,7 +85,7 @@ class ComponentRuntimeInstance { console.debug( `Starting debug session on port ${this._nextSessionPort}` ); - socket.write(this._nextSessionPort.toString()); + socket.write(`${this._nextSessionPort}`); this._nextSessionPort = undefined; } }); @@ -93,12 +94,25 @@ class ComponentRuntimeInstance { console.info(`waiting for debug protocol on port ${port}`); // Start componentRuntime as a new process - let args = Array.from(config.options).map(opt => opt.replace("${workspaceFolder}", workspaceFolder)); - args.push(config.envOption); - args.push(`DEBUGGER_PORT=${port}`); - args.push(component); - // console.debug(`${config.executable} ${args.join(" ")}`); - this._componentRuntime = spawn(config.executable, args); + let componentRuntimeArgs = Array.from(config.componentRuntime.options).map(opt => { + return opt + .replace("${workspaceFolder}", workspaceFolder) + .replace("${component}", component); + }); + componentRuntimeArgs.push(config.componentRuntime.envOption); + componentRuntimeArgs.push( + `STARLINGMONKEY_CONFIG="${config.jsRuntimeOptions.join(" ")}"` + ); + componentRuntimeArgs.push(config.componentRuntime.envOption); + componentRuntimeArgs.push(`DEBUGGER_PORT=${port}`); + console.debug( + `${config.componentRuntime.executable} ${componentRuntimeArgs.join(" ")}` + ); + this._componentRuntime = spawn( + config.componentRuntime.executable, + componentRuntimeArgs, + { cwd: workspaceFolder } + ); this._componentRuntime.stdout.on("data", (data) => { console.log(`componentRuntime ${data}`); @@ -260,7 +274,7 @@ export class StarlingMonkeyRuntime extends EventEmitter { ); return; } - await ComponentRuntimeInstance.start(this._workspaceDir, component, this._config.componentRuntime); + await ComponentRuntimeInstance.start(this._workspaceDir, component, this._config); } private sendMessage(type: string, value?: any, useRawValue = false) { @@ -271,8 +285,7 @@ export class StarlingMonkeyRuntime extends EventEmitter { message = JSON.stringify({ type, value }); } console.debug(`sending message to runtime: ${message}`); - this._socket.write(`${message.length}\n`); - this._socket.write(message); + this._socket.write(`${message.length}\n${message}`); } private sendAndReceiveMessage( From b597681996c808d2d30e1bdcc0cb41e2e1755838 Mon Sep 17 00:00:00 2001 From: Till Schneidereit Date: Wed, 19 Mar 2025 20:10:38 +0100 Subject: [PATCH 3/6] Bugfixes --- .../vscode-dap-extension/sampleWorkspace/.vscode/launch.json | 2 +- debugger/vscode-dap-extension/sampleWorkspace/{ => src}/main.js | 0 debugger/vscode-dap-extension/src/starlingMonkeyRuntime.ts | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename debugger/vscode-dap-extension/sampleWorkspace/{ => src}/main.js (100%) diff --git a/debugger/vscode-dap-extension/sampleWorkspace/.vscode/launch.json b/debugger/vscode-dap-extension/sampleWorkspace/.vscode/launch.json index 46601e10..b7abff76 100644 --- a/debugger/vscode-dap-extension/sampleWorkspace/.vscode/launch.json +++ b/debugger/vscode-dap-extension/sampleWorkspace/.vscode/launch.json @@ -8,7 +8,7 @@ "type": "starlingmonkey", "request": "launch", "name": "Debug main.js", - "program": "${workspaceFolder}/main.js", + "program": "${workspaceFolder}/src/main.js", "component": "${workspaceFolder}/out/main.wasm", "stopOnEntry": false, "trace": true diff --git a/debugger/vscode-dap-extension/sampleWorkspace/main.js b/debugger/vscode-dap-extension/sampleWorkspace/src/main.js similarity index 100% rename from debugger/vscode-dap-extension/sampleWorkspace/main.js rename to debugger/vscode-dap-extension/sampleWorkspace/src/main.js diff --git a/debugger/vscode-dap-extension/src/starlingMonkeyRuntime.ts b/debugger/vscode-dap-extension/src/starlingMonkeyRuntime.ts index 45c5252e..3e947362 100644 --- a/debugger/vscode-dap-extension/src/starlingMonkeyRuntime.ts +++ b/debugger/vscode-dap-extension/src/starlingMonkeyRuntime.ts @@ -85,7 +85,7 @@ class ComponentRuntimeInstance { console.debug( `Starting debug session on port ${this._nextSessionPort}` ); - socket.write(`${this._nextSessionPort}`); + socket.write(`${this._nextSessionPort}\n`); this._nextSessionPort = undefined; } }); From 44471f68e6341a42c41456e169fcd705e739ab1a Mon Sep 17 00:00:00 2001 From: Till Schneidereit Date: Sat, 22 Mar 2025 12:51:46 +0100 Subject: [PATCH 4/6] Address some warnings and build system issues in the VSCode debugging extension --- .../vscode-dap-extension/package-lock.json | 203 ++++++++++++++++++ debugger/vscode-dap-extension/package.json | 29 ++- .../starling-debugger/debugger.ts | 13 +- debugger/vscode-dap-extension/tsconfig.json | 2 - 4 files changed, 235 insertions(+), 12 deletions(-) diff --git a/debugger/vscode-dap-extension/package-lock.json b/debugger/vscode-dap-extension/package-lock.json index 6c5bf504..28073245 100644 --- a/debugger/vscode-dap-extension/package-lock.json +++ b/debugger/vscode-dap-extension/package-lock.json @@ -19,6 +19,7 @@ "@vscode/debugadapter": "^1.68.0", "@vscode/debugadapter-testsupport": "^1.68.0", "@vscode/vsce": "^3.2.1", + "concurrently": "^9.1.2", "esbuild": "0.24.0", "eslint": "9.15.0", "events": "^3.3.0", @@ -1930,6 +1931,168 @@ "dev": true, "license": "MIT" }, + "node_modules/concurrently": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.1.2.tgz", + "integrity": "sha512-H9MWcoPsYddwbOGM6difjVwVZHl63nwMEwDJG/L7VGtuaJhb12h2caPG2tVPWs7emuYix252iGfqOyrz1GczTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "lodash": "^4.17.21", + "rxjs": "^7.8.1", + "shell-quote": "^1.8.1", + "supports-color": "^8.1.1", + "tree-kill": "^1.2.2", + "yargs": "^17.7.2" + }, + "bin": { + "conc": "dist/bin/concurrently.js", + "concurrently": "dist/bin/concurrently.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" + } + }, + "node_modules/concurrently/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/concurrently/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/concurrently/node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/concurrently/node_modules/cliui": { + "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.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/concurrently/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/concurrently/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/concurrently/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/concurrently/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/concurrently/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/concurrently/node_modules/yargs-parser": { + "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": ">=12" + } + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -3491,6 +3654,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.includes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", @@ -4494,6 +4664,16 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -4593,6 +4773,19 @@ "node": ">=8" } }, + "node_modules/shell-quote": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz", + "integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/side-channel": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", @@ -4835,6 +5028,16 @@ "node": ">=8.0" } }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, "node_modules/ts-api-utils": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.0.tgz", diff --git a/debugger/vscode-dap-extension/package.json b/debugger/vscode-dap-extension/package.json index e2284252..a02ed85e 100644 --- a/debugger/vscode-dap-extension/package.json +++ b/debugger/vscode-dap-extension/package.json @@ -30,15 +30,17 @@ "compile": "tsc -p ./", "lint": "eslint src starling-debugger --ext ts", "typecheck": "tsc -p tsconfig.json --noEmit", - "esbuild-extension": "esbuild ./src/extension.ts --bundle --tsconfig=./tsconfig.json --external:vscode --format=cjs --platform=node --outfile=dist/extension.js", - "esbuild-debugger": "esbuild ./starling-debugger/debugger.ts --bundle --tsconfig=./tsconfig.json --format=cjs --platform=node --outfile=dist/debugger.js", + "esbuild-extension": "esbuild ./src/extension.ts --bundle --tsconfig=./tsconfig.json --external:vscode --format=cjs --platform=node --outfile=dist/extension.js --sourcemap --sources-content=false", + "esbuild-debugger": "esbuild ./starling-debugger/debugger.ts --bundle --tsconfig=./tsconfig.json --platform=neutral --outfile=dist/debugger.js", "esbuild-all": "npm run esbuild-extension && npm run esbuild-debugger", - "watch": "npm run -S esbuild-all -- --sourcemap --sources-content=false --watch", - "build": "npm run -S esbuild-all -- --sourcemap --sources-content=false", + "watch-extension": "esbuild ./src/extension.ts --bundle --tsconfig=./tsconfig.json --external:vscode --format=cjs --platform=node --outfile=dist/extension.js --sourcemap --sources-content=false --watch", + "watch-debugger": "esbuild ./starling-debugger/debugger.ts --bundle --tsconfig=./tsconfig.json --platform=neutral --outfile=dist/debugger.js --watch", + "watch": "concurrently \"npm run watch-extension\" \"npm run watch-debugger\"", + "build": "npm run -S esbuild-all", "package": "vsce package", "publish": "vsce publish", "publish-pre-release": "vsce publish --pre-release", - "vscode:prepublish": "rimraf dist && npm run -S esbuild-all -- --minify", + "vscode:prepublish": "rimraf dist && npm run -S esbuild-all", "test": "npm run typecheck" }, "devDependencies": { @@ -52,6 +54,7 @@ "@vscode/debugadapter": "^1.68.0", "@vscode/debugadapter-testsupport": "^1.68.0", "@vscode/vsce": "^3.2.1", + "concurrently": "^9.1.2", "esbuild": "0.24.0", "eslint": "9.15.0", "events": "^3.3.0", @@ -193,7 +196,10 @@ "items": { "type": "string" }, - "default": ["--verbose", "-d"], + "default": [ + "--verbose", + "-d" + ], "scope": "machine-overridable", "description": "CLI options to pass to StarlingMonkey." }, @@ -208,7 +214,16 @@ "items": { "type": "string" }, - "default": ["serve", "-S", "cli,tcp,inherit-network", "--dir", "${workspaceFolder}::/", "--addr", "0.0.0.0:8080", "${component}"], + "default": [ + "serve", + "-S", + "cli,tcp,inherit-network", + "--dir", + "${workspaceFolder}::/", + "--addr", + "0.0.0.0:8080", + "${component}" + ], "scope": "machine-overridable", "description": "CLI options to pass to the component runtime. `${component} will be replaced with the path to the component to debug, and `${workspaceFolder}` will be replaced with the path to the workspace folder." }, diff --git a/debugger/vscode-dap-extension/starling-debugger/debugger.ts b/debugger/vscode-dap-extension/starling-debugger/debugger.ts index b507f0d8..1b378de5 100644 --- a/debugger/vscode-dap-extension/starling-debugger/debugger.ts +++ b/debugger/vscode-dap-extension/starling-debugger/debugger.ts @@ -422,6 +422,13 @@ try { sendMessage("scopes", scopes); } + interface IVariable { + name: string; + value: string; + type: string; + variablesReference: number; + } + function getVariables(reference: number): void { if (reference > MAX_FRAMES) { let object = idToObject.get(reference); @@ -432,7 +439,7 @@ try { assert(currentFrame); let frame = findFrame(currentFrame, reference - 1); - let locals = []; + let locals: IVariable[] = []; for (let name of frame.environment.names()) { let value = frame.environment.getVariable(name); @@ -478,14 +485,14 @@ try { function getMembers(object: Debugger.Object): any[] { let names = object.getOwnPropertyNames(); - let members = []; + let members: IVariable[] = []; for (let name of names) { members.push(getMember(object, name)); } return members; } - function getMember(object: Debugger.Object, name: string): any { + function getMember(object: Debugger.Object, name: string): IVariable { let descriptor = object.getOwnPropertyDescriptor(name); return { name, ...formatDescriptor(descriptor) }; } diff --git a/debugger/vscode-dap-extension/tsconfig.json b/debugger/vscode-dap-extension/tsconfig.json index 30330d29..b9e3eaa5 100644 --- a/debugger/vscode-dap-extension/tsconfig.json +++ b/debugger/vscode-dap-extension/tsconfig.json @@ -5,11 +5,9 @@ "moduleResolution": "NodeNext", "outDir": "out", "lib": [ - "WebWorker", "ES2022" ], "sourceMap": true, - "rootDir": "src", "strict": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, From 3b7954fe2133557e4b43a191daccc11e8e45ab20 Mon Sep 17 00:00:00 2001 From: Till Schneidereit Date: Sat, 22 Mar 2025 15:28:13 +0100 Subject: [PATCH 5/6] Make handling of component host runtime and debugging server more robust --- .../src/starlingMonkeyRuntime.ts | 148 +++++++++++++----- 1 file changed, 106 insertions(+), 42 deletions(-) diff --git a/debugger/vscode-dap-extension/src/starlingMonkeyRuntime.ts b/debugger/vscode-dap-extension/src/starlingMonkeyRuntime.ts index 3e947362..23af9977 100644 --- a/debugger/vscode-dap-extension/src/starlingMonkeyRuntime.ts +++ b/debugger/vscode-dap-extension/src/starlingMonkeyRuntime.ts @@ -1,9 +1,9 @@ import { Scope } from "@vscode/debugadapter"; -import { ChildProcessWithoutNullStreams, spawn } from "child_process"; import { EventEmitter } from "events"; import * as Net from "net"; import { Signal } from "./signals.js"; import { assert } from "console"; +import { Terminal, TerminalShellExecution, window } from "vscode"; export interface FileAccessor { isWindows: boolean; @@ -54,21 +54,45 @@ export interface IStarlingMonkeyRuntimeConfig { } class ComponentRuntimeInstance { - private static _componentRuntime: ChildProcessWithoutNullStreams; - static running: boolean; - static workspaceFolder: string; - static _server: Net.Server; - static _nextSessionPort: number | undefined; + private static _workspaceFolder?: string; + private static _component?: string; + private static _server?: Net.Server; + private static _terminal?: Terminal; + private static _nextSessionPort?: number; + private static _runtimeExecution?: TerminalShellExecution; static setNextSessionPort(port: number) { this._nextSessionPort = port; } static async start(workspaceFolder: string, component: string, config: IStarlingMonkeyRuntimeConfig) { - assert(!this.running, "ComponentRuntime is already running"); - this.running = true; - this.workspaceFolder = workspaceFolder; + if (this._workspaceFolder && this._workspaceFolder !== workspaceFolder || + this._component && this._component !== component + ) { + this.reset(); + } + + this._workspaceFolder = workspaceFolder; + this._component = component; + + this.ensureServer(); + this.ensureHostRuntime(config, workspaceFolder, component); + } + static reset() { + this._workspaceFolder = undefined; + this._component = undefined; + this._nextSessionPort = undefined; + this._server?.close(); + this._server = undefined; + this._terminal?.dispose(); + this._terminal = undefined; + this._runtimeExecution = undefined; + } + static ensureServer() { + if (this._server) { + return; + } this._server = Net.createServer((socket) => { socket.on("data", (data) => { assert( @@ -89,11 +113,21 @@ class ComponentRuntimeInstance { this._nextSessionPort = undefined; } }); + socket.on("close", () => { + console.debug("ComponentRuntime disconnected"); + }); }).listen(); - let port = (this._server.address()).port; - console.info(`waiting for debug protocol on port ${port}`); + } + + private static serverPort() { + return (this._server!.address()).port; + } + + private static async ensureHostRuntime(config: IStarlingMonkeyRuntimeConfig, workspaceFolder: string, component: string) { + if (this._runtimeExecution) { + return; + } - // Start componentRuntime as a new process let componentRuntimeArgs = Array.from(config.componentRuntime.options).map(opt => { return opt .replace("${workspaceFolder}", workspaceFolder) @@ -104,28 +138,69 @@ class ComponentRuntimeInstance { `STARLINGMONKEY_CONFIG="${config.jsRuntimeOptions.join(" ")}"` ); componentRuntimeArgs.push(config.componentRuntime.envOption); - componentRuntimeArgs.push(`DEBUGGER_PORT=${port}`); + componentRuntimeArgs.push(`DEBUGGER_PORT=${this.serverPort()}`); + console.debug( `${config.componentRuntime.executable} ${componentRuntimeArgs.join(" ")}` ); - this._componentRuntime = spawn( - config.componentRuntime.executable, - componentRuntimeArgs, - { cwd: workspaceFolder } - ); - this._componentRuntime.stdout.on("data", (data) => { - console.log(`componentRuntime ${data}`); - }); + await this.ensureTerminal(); - this._componentRuntime.stderr.on("data", (data) => { - console.error(`componentRuntime ${data}`); - }); + if (this._terminal!.shellIntegration) { + this._runtimeExecution = this._terminal!.shellIntegration.executeCommand( + config.componentRuntime.executable, + componentRuntimeArgs + ); + let disposable = window.onDidEndTerminalShellExecution((event) => { + if (event.execution === this._runtimeExecution) { + this._runtimeExecution = undefined; + disposable.dispose(); + console.log(`Component host runtime exited with code ${event.exitCode}`); + } + }); + } else { + // Fallback to sendText if there is no shell integration. + // Send Ctrl+C to kill any existing component runtime first. + this._terminal!.sendText('\x03', false); + this._terminal!.sendText( + `${config.componentRuntime.executable} ${componentRuntimeArgs.join(" ")}`, + true + ); + } + } - this._componentRuntime.on("close", (code) => { - console.info(`child process exited with code ${code}`); - this.running = false; + private static async ensureTerminal() { + if (this._terminal && this._terminal.exitStatus === undefined) { + return; + } + + let signal = new Signal(); + this._terminal = window.createTerminal(); + let terminalCloseDisposable = window.onDidCloseTerminal((terminal) => { + if (terminal === this._terminal) { + signal.resolve(); + this._terminal = undefined; + this._runtimeExecution = undefined; + terminalCloseDisposable.dispose(); + } }); + + let shellIntegrationDisposable = window.onDidChangeTerminalShellIntegration( + async ({ terminal }) => { + if (terminal === this._terminal) { + clearTimeout(timeout); + shellIntegrationDisposable.dispose(); + signal.resolve(); + } + } + ); + // Fallback to sendText if there is no shell integration within 3 seconds of launching + let timeout = setTimeout(() => { + shellIntegrationDisposable.dispose(); + signal.resolve(); + }, 3000); + + await signal.wait(); } } @@ -158,7 +233,7 @@ export class StarlingMonkeyRuntime extends EventEmitter { } public async start(program: string, component: string, stopOnEntry: boolean, debug: boolean ): Promise { - await this.startComponentRuntime(component); + await ComponentRuntimeInstance.start(this._workspaceDir, component, this._config); this.startSessionServer(); // TODO: tell StarlingMonkey not to debug if this is false. this._debug = debug; @@ -169,7 +244,7 @@ export class StarlingMonkeyRuntime extends EventEmitter { message.type === "connect", `expected "connect" message, got "${message.type}"` ); - this.sendMessage("startDebugLogging"); + // this.sendMessage("startDebugLogging"); message = await this.sendAndReceiveMessage("loadProgram", this._sourceFile); assert( message.type === "programLoaded", @@ -247,7 +322,7 @@ export class StarlingMonkeyRuntime extends EventEmitter { let message = partialMessage.slice(0, expectedLength); try { let parsed = JSON.parse(message); - console.debug(`received message ${partialMessage}`); + // console.debug(`received message ${partialMessage}`); resetMessageState(); this._messageReceived.resolve(parsed); } catch (e) { @@ -266,17 +341,6 @@ export class StarlingMonkeyRuntime extends EventEmitter { ComponentRuntimeInstance.setNextSessionPort(port); } - private async startComponentRuntime(component: string) { - if (ComponentRuntimeInstance.running) { - assert( - ComponentRuntimeInstance.workspaceFolder === this._workspaceDir, - "ComponentRuntime is already running in a different workspace" - ); - return; - } - await ComponentRuntimeInstance.start(this._workspaceDir, component, this._config); - } - private sendMessage(type: string, value?: any, useRawValue = false) { let message: string; if (useRawValue) { @@ -284,7 +348,7 @@ export class StarlingMonkeyRuntime extends EventEmitter { } else { message = JSON.stringify({ type, value }); } - console.debug(`sending message to runtime: ${message}`); + // console.debug(`sending message to runtime: ${message}`); this._socket.write(`${message.length}\n${message}`); } From be44ec356918001830720003c2ab5a1ac4133098 Mon Sep 17 00:00:00 2001 From: Till Schneidereit Date: Fri, 28 Mar 2025 10:13:49 +0100 Subject: [PATCH 6/6] Update README and launch configs for debugger Signed-off-by: Till Schneidereit --- debugger/vscode-dap-extension/README.md | 41 +++++++++++-------- debugger/vscode-dap-extension/package.json | 10 ++--- .../sampleWorkspace/.vscode/launch.json | 5 +-- 3 files changed, 31 insertions(+), 25 deletions(-) diff --git a/debugger/vscode-dap-extension/README.md b/debugger/vscode-dap-extension/README.md index ca83472a..9ad3fc33 100644 --- a/debugger/vscode-dap-extension/README.md +++ b/debugger/vscode-dap-extension/README.md @@ -6,25 +6,34 @@ This extension adds support for debugging JavaScript code running in the [Starli ## Using The StarlingMonkey Debugger -The extension is currently experimental and can't be installed directly. Instead, follow the instructions below for building it: - -## Building and Running - -* Install a recent version of the [Wasmtime](https://wasmtime.dev/) WebAssembly runtime and ensure that it's available in your path[^1] -* Clone the [StarlingMonkey project](https://github.com/bytecodealliance/StarlingMonkey/) -* Ensure that you have a branch checked out that contains the debugger -* Open the contained folder `debugger/vscode-dap-extension` in VS Code -* Ensure that a build of StarlingMonkey is available with the path `debugger/vscode-dap-extension/out/main.wasm`. This is configurable via the `component` property of the launch configuration in `launch.json`[^2] -* Open the "Run and Debug" sidebar and ensure that the `Extension` launch configuration is active -* Press `F5` to build the extension and launch another VS Code window with it installed -* In the explorer view of the new window open `main.js` -* Set some breakpoints -* Press `F5` to start debugging the file -* invoke the component. For HTTP server components, this would be done by sending an HTTP request to the address the component is served at. By default, that would be `http://localhost:8080/` +The extension works for content built with a recent (`0.18` and up) version of [ComponentizeJS](https://www.npmjs.com/package/@bytecodealliance/componentize-js), provided some requirements are met. + +### Building Content + +The content needs to be invoked via the `wasi:http/incoming-handler@0.2.*/handle` function. In other words, it needs to target the `wasi:http/proxy@0.2` world. + +Additionally, it needs to import a few additionally interfaces, which you can add to your `*.wit` by adding these lines: + +```wit + import wasi:cli/environment@0.2.3; + import wasi:sockets/network@0.2.3; + import wasi:sockets/instance-network@0.2.3; + import wasi:sockets/tcp@0.2.3; + import wasi:sockets/tcp-create-socket@0.2.3; +``` + +And finally, when invoking `componentize-js`, the arguments `--runtime-args "--enable-script-debugging"` need to be passed. + +### Running Content + +To debug content, you need to create a launch config of the type `starlingmonkey`. By default, this will start the [Wasmtime](https://wasmtime.dev/) WebAssembly runtime with the provided component. + +Once `wasmtime` is running, sending a request to the host/port it's running on will cause StarlingMonkey to connect to the debugger. ## Configuration The extension adds a `StarlingMonkey Debugger` section to VS Code's configuration. Open the VS Code settings and search for `StarlingMonkey` to see the available options. +Additionally, all settings in this section can be overridden in the launch configuration. + [^1]: Alternatively, you can use another WebAssembly Components runtime, as long as it supports outgoing TCP socket connections, and passing environment variables to the guest. In that case, you'll have to update the [configuration](#configuration) to ensure the right options are passed to the runtime. -[^2]: The currently easiest way to get this file is to build StarlingMonkey itself using the CMake target `starling`, and then copying the resulting `starling.wasm` file from the CMake build folder. See the repository's top-level `README` for details on the build process diff --git a/debugger/vscode-dap-extension/package.json b/debugger/vscode-dap-extension/package.json index a02ed85e..f1a41f49 100644 --- a/debugger/vscode-dap-extension/package.json +++ b/debugger/vscode-dap-extension/package.json @@ -1,7 +1,8 @@ { "name": "starlingmonkey-debugger", "displayName": "StarlingMonkey Debugger", - "version": "0.1.0", + "version": "0.1.1", + "preview": true, "publisher": "bytecodealliance", "description": "Debugger for the StarlingMonkey JS runtime", "author": { @@ -130,7 +131,6 @@ "configurationAttributes": { "launch": { "required": [ - "program", "component" ], "properties": { @@ -161,8 +161,7 @@ { "type": "starlingmonkey", "request": "launch", - "name": "Ask for file name", - "program": "${workspaceFolder}/${command:AskForProgramName}", + "name": "Debug StarlingMonkey component", "component": "${workspaceFolder}/${command:AskForComponent}", "stopOnEntry": true } @@ -174,8 +173,7 @@ "body": { "type": "starlingmonkey", "request": "launch", - "name": "Ask for file name", - "program": "^\"\\${workspaceFolder}/\\${command:AskForProgramName}\"", + "name": "Debug StarlingMonkey component", "component": "^\"\\${workspaceFolder}/\\${command:AskForComponent}\"", "stopOnEntry": true } diff --git a/debugger/vscode-dap-extension/sampleWorkspace/.vscode/launch.json b/debugger/vscode-dap-extension/sampleWorkspace/.vscode/launch.json index b7abff76..192918b5 100644 --- a/debugger/vscode-dap-extension/sampleWorkspace/.vscode/launch.json +++ b/debugger/vscode-dap-extension/sampleWorkspace/.vscode/launch.json @@ -7,10 +7,9 @@ { "type": "starlingmonkey", "request": "launch", - "name": "Debug main.js", - "program": "${workspaceFolder}/src/main.js", + "name": "Debug StarlingMonkey component", "component": "${workspaceFolder}/out/main.wasm", - "stopOnEntry": false, + "stopOnEntry": true, "trace": true } ]