From 30136a209650b9ae67d2238e0b8b5e8901d0d07f Mon Sep 17 00:00:00 2001 From: Joschua Becker Date: Fri, 25 Oct 2024 20:17:05 +0200 Subject: [PATCH] init --- .gitignore | 5 + .prettierrc | 6 + LICENSE | 59 + README.md | 24 + eslint.config.mjs | 12 + package.json | 60 + pnpm-lock.yaml | 4239 ++++++++++++++++++++++++++++++++++ src/PluginManager.ts | 222 ++ src/TypeHelper.ts | 10 + src/handler/StatusHandler.ts | 14 + src/handler/WsHandler.ts | 128 + src/index.ts | 64 + src/tools/IpFinder.ts | 51 + src/tools/LogoProvider.ts | 407 ++++ src/tools/PortFinder.ts | 34 + tsconfig.json | 12 + 16 files changed, 5347 insertions(+) create mode 100644 .gitignore create mode 100644 .prettierrc create mode 100644 LICENSE create mode 100644 README.md create mode 100644 eslint.config.mjs create mode 100644 package.json create mode 100644 pnpm-lock.yaml create mode 100644 src/PluginManager.ts create mode 100644 src/TypeHelper.ts create mode 100644 src/handler/StatusHandler.ts create mode 100644 src/handler/WsHandler.ts create mode 100644 src/index.ts create mode 100644 src/tools/IpFinder.ts create mode 100644 src/tools/LogoProvider.ts create mode 100644 src/tools/PortFinder.ts create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d769278 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +dist/ +node_modules/ +.parcel-cache/ +plugins/ +config/ diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..fa51da2 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,6 @@ +{ + "trailingComma": "es5", + "tabWidth": 2, + "semi": false, + "singleQuote": true +} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..7ace406 --- /dev/null +++ b/LICENSE @@ -0,0 +1,59 @@ +Non-Profit Open Software License ("Non-Profit OSL") 3.0 + +This Non-Profit Open Software License ("Non-Profit OSL") version 3.0 (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following licensing notice adjacent to the copyright notice for the Original Work: + +Licensed under the Non-Profit Open Software License version 3.0 + +1) Grant of Copyright License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, for the duration of the copyright, to do the following: + +a) to reproduce the Original Work in copies, either alone or as part of a collective work; + +b) to translate, adapt, alter, transform, modify, or arrange the Original Work, thereby creating derivative works ("Derivative Works") based upon the Original Work; + +c) to distribute or communicate copies of the Original Work and Derivative Works to the public, with the proviso that copies of Original Work or Derivative Works that You distribute or communicate shall be licensed under this Non-Profit Open Software License or as provided in section 17(d); + +d) to perform the Original Work publicly; and + +e) to display the Original Work publicly. + +2) Grant of Patent License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, for the duration of the patents, to make, use, sell, offer for sale, have made, and import the Original Work and Derivative Works. + +3) Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work. + +4) Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior permission of the Licensor. Except as expressly stated herein, nothing in this License grants any license to Licensor's trademarks, copyrights, patents, trade secrets or any other intellectual property. No patent license is granted to make, use, sell, offer for sale, have made, or import embodiments of any patent claims other than the licensed claims defined in Section 2. No license is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under terms different from this License any Original Work that Licensor otherwise would have a right to license. + +5) External Deployment. The term "External Deployment" means the use, distribution, or communication of the Original Work or Derivative Works in any way such that the Original Work or Derivative Works may be used by anyone other than You, whether those works are distributed or communicated to those persons or made available as an application intended for use over a network. As an express condition for the grants of license hereunder, You must treat any External Deployment by You of the Original Work or a Derivative Work as a distribution under section 1(c). + +6) Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent, or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work. + +7) Warranty of Provenance and Disclaimer of Warranty. The Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of non-infringement, merchantability or fitness for a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to the Original Work is granted by this License except under this disclaimer. + +8) Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to anyone for any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to the extent applicable law prohibits such limitation. + +9) Acceptance and Termination. If, at any time, You expressly assented to this License, that assent indicates your clear and irrevocable acceptance of this License and all of its terms and conditions. If You distribute or communicate copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. This License conditions your rights to undertake the activities listed in Section 1, including your right to create Derivative Works based upon the Original Work, and doing so without honoring these terms and conditions is prohibited by copyright law and international treaty. Nothing in this License is intended to affect copyright exceptions and limitations (including "fair use" or "fair dealing"). This License shall terminate immediately and You may no longer exercise any of the rights granted to You by this License upon your failure to honor the conditions in Section 1(c). + +10) Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware. + +11) Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of copyright or patent law in the appropriate jurisdiction. This section shall survive the termination of this License. + +12) Attorneys' Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License. + +13) Miscellaneous. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. + +14) Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (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. + +15) Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You. + +16) Modification of This License. This License is Copyright © 2005 Lawrence Rosen. Permission is granted to copy, distribute, or communicate this License without modification. Nothing in this License permits You to modify this License as applied to the Original Work or to Derivative Works. However, You may modify the text of this License and copy, distribute or communicate your modified version (the "Modified License") and apply it to other original works of authorship subject to the following conditions: (i) You may not indicate in any way that your Modified License is the "Open Software License" or "OSL" and you may not use those names in the name of your Modified License; (ii) You must replace the notice specified in the first paragraph above with the notice "Licensed under " or with a notice of your own that is not confusingly similar to the notice in this License; and (iii) You may not claim that your original works are open source software unless your Modified License has been approved by Open Source Initiative (OSI) and You comply with its license review and certification process. + +17) Non-Profit Amendment. The name of this amended version of the Open Software License ("OSL 3.0") is "Non-Profit Open Software License 3.0". The original OSL 3.0 license has been amended as follows: + +(a) Licensor represents and declares that it is a not-for-profit organization that derives no revenue whatsoever from the distribution of the Original Work or Derivative Works thereof, or from support or services relating thereto. + +(b) The first sentence of Section 7 ["Warranty of Provenance"] of OSL 3.0 has been stricken. For Original Works licensed under this Non-Profit OSL 3.0, LICENSOR OFFERS NO WARRANTIES WHATSOEVER. + +(c) In the first sentence of Section 8 ["Limitation of Liability"] of this Non-Profit OSL 3.0, the list of damages for which LIABILITY IS LIMITED now includes "direct" damages. + +(d) The proviso in Section 1(c) of this License now refers to this "Non-Profit Open Software License" rather than the "Open Software License". You may distribute or communicate the Original Work or Derivative Works thereof under this Non-Profit OSL 3.0 license only if You make the representation and declaration in paragraph (a) of this Section 17. Otherwise, You shall distribute or communicate the Original Work or Derivative Works thereof only under the OSL 3.0 license and You shall publish clear licensing notices so stating. Also by way of clarification, this License does not authorize You to distribute or communicate works under this Non-Profit OSL 3.0 if You received them under the original OSL 3.0 license. + +(e) Original Works licensed under this license shall reference "Non-Profit OSL 3.0" in licensing notices to distinguish them from works licensed under the original OSL 3.0 license. diff --git a/README.md b/README.md new file mode 100644 index 0000000..f95b44c --- /dev/null +++ b/README.md @@ -0,0 +1,24 @@ +# @board-bound/server + +wip + +## License + +This project is licensed under the **Non-Profit Open Software License 3.0**. + +### About + +NPOSL-3.0 + +A variant of the Open Software License 3.0, this license requires that the organization using it is a non-profit and that no revenue is generated from sale of the software, support or services. + +### What you can do + +| Can | Cannot | Must | +|---------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +|
🟢 SublicenseDescribes the ability for you to grant/extend a license to the software.
|
🔴 Commercial UseCannot use the software for commercial purposes or generate revenue from its sale or support.
|
🔵 Disclose SourceDescribes whether you must disclose your source code when you communicate the software (i.e. even through cloud distribution).
| +|
🟢 ModifyDescribes the ability to modify the software and create derivatives.
|
🔴 Use TrademarkDescribes the allowance of using contributors' names, trademarks or logos.
|
🔵 Include CopyrightDescribes whether the original copyright must be retained.
| +|
🟢 DistributeDescribes the ability to distribute original or modified (derivative) works.
|
🔴 Hold LiabilityDescribes the warranty and if the software/license owner can be charged for damages.
|
🔵 Include LicenseIncluding the full text of license in modified software.
| + +*Information provided by https://tldrlegal.com/license/non-profit-open-software-license-3.0-(nposl-3.0), +this is not legal advice. See the LICENSE file for more information.* diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..70fd805 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,12 @@ +import globals from "globals"; +import pluginJs from "@eslint/js"; +import tseslint from "typescript-eslint"; + + +export default [ + {files: ["**/*.{js,mjs,cjs,ts}"]}, + {languageOptions: { globals: globals.node }}, + pluginJs.configs.recommended, + ...tseslint.configs.recommended, + {rules: {"no-console": "error"}}, +]; diff --git a/package.json b/package.json new file mode 100644 index 0000000..fbf70f4 --- /dev/null +++ b/package.json @@ -0,0 +1,60 @@ +{ + "name": "server", + "version": "1.0.0", + "source": "src/index.ts", + "main": "dist/index.cjs", + "module": "dist/index.mjs", + "types": "dist/index.d.ts", + "license": "NPOSL-3.0", + "scripts": { + "build": "parcel build", + "dev": "concurrently npm:dev:build npm:dev:run", + "dev:build": "parcel watch --no-hmr", + "dev:run": "sleep 5 && nodemon --delay 2 --watch dist --exec npm run dev:start", + "dev:start": "PLUGIN_WATCH=true PLUGIN_LOAD_DIRECT=\"../example/dist/index.cjs\" LOG_LEVEL=debug PORT=3000 node dist/index.cjs | pino-pretty", + "start": "node dist/index.cjs", + "lint": "eslint src", + "lint:fix": "eslint --fix src", + "prettier": "prettier --write src/**/*.ts" + }, + "dependencies": { + "@board-bound/sdk": "^0.1.0", + "axios": "^1.7.7", + "chokidar": "^4.0.1", + "express": "^4.21.1", + "express-ws": "^5.0.2", + "pino": "^9.5.0", + "semver": "^7.6.3", + "uuid": "^10.0.0" + }, + "devDependencies": { + "@eslint/js": "^9.13.0", + "@parcel/packager-ts": "2.12.0", + "@parcel/transformer-typescript-types": "2.12.0", + "@types/express": "^5.0.0", + "@types/express-ws": "^3.0.5", + "@types/node": "^22.7.7", + "@types/semver": "^7.5.8", + "@types/uuid": "^10.0.0", + "@types/ws": "^8.5.12", + "concurrently": "^9.0.1", + "eslint": "^9.13.0", + "globals": "^15.11.0", + "nodemon": "^3.1.7", + "parcel": "^2.12.0", + "pino": "^9.5.0", + "pino-pretty": "^11.3.0", + "prettier": "^3.3.3", + "typescript": ">=3.0.0", + "typescript-eslint": "^8.10.0" + }, + "engines": { + "node": ">=12" + }, + "targets": { + "main": { + "includeNodeModules": true, + "optimize": true + } + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..638bb91 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,4239 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@board-bound/sdk': + specifier: ^0.1.0 + version: 0.1.0 + axios: + specifier: ^1.7.7 + version: 1.7.7 + chokidar: + specifier: ^4.0.1 + version: 4.0.1 + express: + specifier: ^4.21.1 + version: 4.21.1 + express-ws: + specifier: ^5.0.2 + version: 5.0.2(express@4.21.1) + pino: + specifier: ^9.5.0 + version: 9.5.0 + semver: + specifier: ^7.6.3 + version: 7.6.3 + uuid: + specifier: ^10.0.0 + version: 10.0.0 + devDependencies: + '@eslint/js': + specifier: ^9.13.0 + version: 9.13.0 + '@parcel/packager-ts': + specifier: 2.12.0 + version: 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/transformer-typescript-types': + specifier: 2.12.0 + version: 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))(typescript@5.6.3) + '@types/express': + specifier: ^5.0.0 + version: 5.0.0 + '@types/express-ws': + specifier: ^3.0.5 + version: 3.0.5 + '@types/node': + specifier: ^22.7.7 + version: 22.7.7 + '@types/semver': + specifier: ^7.5.8 + version: 7.5.8 + '@types/uuid': + specifier: ^10.0.0 + version: 10.0.0 + '@types/ws': + specifier: ^8.5.12 + version: 8.5.12 + concurrently: + specifier: ^9.0.1 + version: 9.0.1 + eslint: + specifier: ^9.13.0 + version: 9.13.0 + globals: + specifier: ^15.11.0 + version: 15.11.0 + nodemon: + specifier: ^3.1.7 + version: 3.1.7 + parcel: + specifier: ^2.12.0 + version: 2.12.0(@swc/helpers@0.5.13)(typescript@5.6.3) + pino-pretty: + specifier: ^11.3.0 + version: 11.3.0 + prettier: + specifier: ^3.3.3 + version: 3.3.3 + typescript: + specifier: '>=3.0.0' + version: 5.6.3 + typescript-eslint: + specifier: ^8.10.0 + version: 8.10.0(eslint@9.13.0)(typescript@5.6.3) + +packages: + + '@babel/code-frame@7.25.7': + resolution: {integrity: sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.25.7': + resolution: {integrity: sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==} + engines: {node: '>=6.9.0'} + + '@babel/highlight@7.25.7': + resolution: {integrity: sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==} + engines: {node: '>=6.9.0'} + + '@board-bound/sdk@0.1.0': + resolution: {integrity: sha512-quFep718zgLNK3YUQNsuGDMGUdLWutuIYM3vWaJsyBAXIrwxOdiIT/2ZQX64DHYBUGpB9Wn7YPojWbXF1zZIEw==} + engines: {node: '>=12'} + + '@eslint-community/eslint-utils@4.4.0': + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.11.1': + resolution: {integrity: sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.18.0': + resolution: {integrity: sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.7.0': + resolution: {integrity: sha512-xp5Jirz5DyPYlPiKat8jaq0EmYvDXKKpzTbxXMpT9eqlRJkRKIz9AGMdlvYjih+im+QlhWrpvVjl8IPC/lHlUw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.1.0': + resolution: {integrity: sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.13.0': + resolution: {integrity: sha512-IFLyoY4d72Z5y/6o/BazFBezupzI/taV8sGumxTAVw3lXG9A6md1Dc34T9s1FoD/an9pJH8RHbAxsaEbBed9lA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.4': + resolution: {integrity: sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.2.1': + resolution: {integrity: sha512-HFZ4Mp26nbWk9d/BpvP0YNL6W4UoZF0VFcTw/aPPA8RpOxeFQgK+ClABGgAUXs9Y/RGX/l1vOmrqz1MQt9MNuw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@humanfs/core@0.19.0': + resolution: {integrity: sha512-2cbWIHbZVEweE853g8jymffCA+NCMiuqeECeBBLm8dg2oFdjuGJhgN4UAbI+6v0CKbbhvtXA4qV8YR5Ji86nmw==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.5': + resolution: {integrity: sha512-KSPA4umqSG4LHYRodq31VDwKAvaTF4xmVlzM8Aeh4PlU1JQ3IG0wiA8C25d3RQ9nJyM3mBHyI53K06VVL/oFFg==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.3.1': + resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} + engines: {node: '>=18.18'} + + '@lezer/common@1.2.3': + resolution: {integrity: sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA==} + + '@lezer/lr@1.4.2': + resolution: {integrity: sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==} + + '@lmdb/lmdb-darwin-arm64@2.8.5': + resolution: {integrity: sha512-KPDeVScZgA1oq0CiPBcOa3kHIqU+pTOwRFDIhxvmf8CTNvqdZQYp5cCKW0bUk69VygB2PuTiINFWbY78aR2pQw==} + cpu: [arm64] + os: [darwin] + + '@lmdb/lmdb-darwin-x64@2.8.5': + resolution: {integrity: sha512-w/sLhN4T7MW1nB3R/U8WK5BgQLz904wh+/SmA2jD8NnF7BLLoUgflCNxOeSPOWp8geP6nP/+VjWzZVip7rZ1ug==} + cpu: [x64] + os: [darwin] + + '@lmdb/lmdb-linux-arm64@2.8.5': + resolution: {integrity: sha512-vtbZRHH5UDlL01TT5jB576Zox3+hdyogvpcbvVJlmU5PdL3c5V7cj1EODdh1CHPksRl+cws/58ugEHi8bcj4Ww==} + cpu: [arm64] + os: [linux] + + '@lmdb/lmdb-linux-arm@2.8.5': + resolution: {integrity: sha512-c0TGMbm2M55pwTDIfkDLB6BpIsgxV4PjYck2HiOX+cy/JWiBXz32lYbarPqejKs9Flm7YVAKSILUducU9g2RVg==} + cpu: [arm] + os: [linux] + + '@lmdb/lmdb-linux-x64@2.8.5': + resolution: {integrity: sha512-Xkc8IUx9aEhP0zvgeKy7IQ3ReX2N8N1L0WPcQwnZweWmOuKfwpS3GRIYqLtK5za/w3E60zhFfNdS+3pBZPytqQ==} + cpu: [x64] + os: [linux] + + '@lmdb/lmdb-win32-x64@2.8.5': + resolution: {integrity: sha512-4wvrf5BgnR8RpogHhtpCPJMKBmvyZPhhUtEwMJbXh0ni2BucpfF07jlmyM11zRqQ2XIq6PbC2j7W7UCCcm1rRQ==} + cpu: [x64] + os: [win32] + + '@mischnic/json-sourcemap@0.1.1': + resolution: {integrity: sha512-iA7+tyVqfrATAIsIRWQG+a7ZLLD0VaOCKV2Wd/v4mqIU3J9c4jx9p7S0nw1XH3gJCKNBOOwACOPYYSUu9pgT+w==} + engines: {node: '>=12.0.0'} + + '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3': + resolution: {integrity: sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==} + cpu: [arm64] + os: [darwin] + + '@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.3': + resolution: {integrity: sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==} + cpu: [x64] + os: [darwin] + + '@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.3': + resolution: {integrity: sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==} + cpu: [arm64] + os: [linux] + + '@msgpackr-extract/msgpackr-extract-linux-arm@3.0.3': + resolution: {integrity: sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==} + cpu: [arm] + os: [linux] + + '@msgpackr-extract/msgpackr-extract-linux-x64@3.0.3': + resolution: {integrity: sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==} + cpu: [x64] + os: [linux] + + '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3': + resolution: {integrity: sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==} + cpu: [x64] + os: [win32] + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@parcel/bundler-default@2.12.0': + resolution: {integrity: sha512-3ybN74oYNMKyjD6V20c9Gerdbh7teeNvVMwIoHIQMzuIFT6IGX53PyOLlOKRLbjxMc0TMimQQxIt2eQqxR5LsA==} + engines: {node: '>= 12.0.0', parcel: ^2.12.0} + + '@parcel/cache@2.12.0': + resolution: {integrity: sha512-FX5ZpTEkxvq/yvWklRHDESVRz+c7sLTXgFuzz6uEnBcXV38j6dMSikflNpHA6q/L4GKkCqRywm9R6XQwhwIMyw==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@parcel/core': ^2.12.0 + + '@parcel/codeframe@2.12.0': + resolution: {integrity: sha512-v2VmneILFiHZJTxPiR7GEF1wey1/IXPdZMcUlNXBiPZyWDfcuNgGGVQkx/xW561rULLIvDPharOMdxz5oHOKQg==} + engines: {node: '>= 12.0.0'} + + '@parcel/compressor-raw@2.12.0': + resolution: {integrity: sha512-h41Q3X7ZAQ9wbQ2csP8QGrwepasLZdXiuEdpUryDce6rF9ZiHoJ97MRpdLxOhOPyASTw/xDgE1xyaPQr0Q3f5A==} + engines: {node: '>= 12.0.0', parcel: ^2.12.0} + + '@parcel/config-default@2.12.0': + resolution: {integrity: sha512-dPNe2n9eEsKRc1soWIY0yToMUPirPIa2QhxcCB3Z5RjpDGIXm0pds+BaiqY6uGLEEzsjhRO0ujd4v2Rmm0vuFg==} + peerDependencies: + '@parcel/core': ^2.12.0 + + '@parcel/core@2.12.0': + resolution: {integrity: sha512-s+6pwEj+GfKf7vqGUzN9iSEPueUssCCQrCBUlcAfKrJe0a22hTUCjewpB0I7lNrCIULt8dkndD+sMdOrXsRl6Q==} + engines: {node: '>= 12.0.0'} + + '@parcel/diagnostic@2.12.0': + resolution: {integrity: sha512-8f1NOsSFK+F4AwFCKynyIu9Kr/uWHC+SywAv4oS6Bv3Acig0gtwUjugk0C9UaB8ztBZiW5TQZhw+uPZn9T/lJA==} + engines: {node: '>= 12.0.0'} + + '@parcel/events@2.12.0': + resolution: {integrity: sha512-nmAAEIKLjW1kB2cUbCYSmZOGbnGj8wCzhqnK727zCCWaA25ogzAtt657GPOeFyqW77KyosU728Tl63Fc8hphIA==} + engines: {node: '>= 12.0.0'} + + '@parcel/fs@2.12.0': + resolution: {integrity: sha512-NnFkuvou1YBtPOhTdZr44WN7I60cGyly2wpHzqRl62yhObyi1KvW0SjwOMa0QGNcBOIzp4G0CapoZ93hD0RG5Q==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@parcel/core': ^2.12.0 + + '@parcel/graph@3.2.0': + resolution: {integrity: sha512-xlrmCPqy58D4Fg5umV7bpwDx5Vyt7MlnQPxW68vae5+BA4GSWetfZt+Cs5dtotMG2oCHzZxhIPt7YZ7NRyQzLA==} + engines: {node: '>= 12.0.0'} + + '@parcel/logger@2.12.0': + resolution: {integrity: sha512-cJ7Paqa7/9VJ7C+KwgJlwMqTQBOjjn71FbKk0G07hydUEBISU2aDfmc/52o60ErL9l+vXB26zTrIBanbxS8rVg==} + engines: {node: '>= 12.0.0'} + + '@parcel/markdown-ansi@2.12.0': + resolution: {integrity: sha512-WZz3rzL8k0H3WR4qTHX6Ic8DlEs17keO9gtD4MNGyMNQbqQEvQ61lWJaIH0nAtgEetu0SOITiVqdZrb8zx/M7w==} + engines: {node: '>= 12.0.0'} + + '@parcel/namer-default@2.12.0': + resolution: {integrity: sha512-9DNKPDHWgMnMtqqZIMiEj/R9PNWW16lpnlHjwK3ciRlMPgjPJ8+UNc255teZODhX0T17GOzPdGbU/O/xbxVPzA==} + engines: {node: '>= 12.0.0', parcel: ^2.12.0} + + '@parcel/node-resolver-core@3.3.0': + resolution: {integrity: sha512-rhPW9DYPEIqQBSlYzz3S0AjXxjN6Ub2yS6tzzsW/4S3Gpsgk/uEq4ZfxPvoPf/6TgZndVxmKwpmxaKtGMmf3cA==} + engines: {node: '>= 12.0.0'} + + '@parcel/optimizer-css@2.12.0': + resolution: {integrity: sha512-ifbcC97fRzpruTjaa8axIFeX4MjjSIlQfem3EJug3L2AVqQUXnM1XO8L0NaXGNLTW2qnh1ZjIJ7vXT/QhsphsA==} + engines: {node: '>= 12.0.0', parcel: ^2.12.0} + + '@parcel/optimizer-htmlnano@2.12.0': + resolution: {integrity: sha512-MfPMeCrT8FYiOrpFHVR+NcZQlXAptK2r4nGJjfT+ndPBhEEZp4yyL7n1y7HfX9geg5altc4WTb4Gug7rCoW8VQ==} + engines: {node: '>= 12.0.0', parcel: ^2.12.0} + + '@parcel/optimizer-image@2.12.0': + resolution: {integrity: sha512-bo1O7raeAIbRU5nmNVtx8divLW9Xqn0c57GVNGeAK4mygnQoqHqRZ0mR9uboh64pxv6ijXZHPhKvU9HEpjPjBQ==} + engines: {node: '>= 12.0.0', parcel: ^2.12.0} + peerDependencies: + '@parcel/core': ^2.12.0 + + '@parcel/optimizer-svgo@2.12.0': + resolution: {integrity: sha512-Kyli+ZZXnoonnbeRQdoWwee9Bk2jm/49xvnfb+2OO8NN0d41lblBoRhOyFiScRnJrw7eVl1Xrz7NTkXCIO7XFQ==} + engines: {node: '>= 12.0.0', parcel: ^2.12.0} + + '@parcel/optimizer-swc@2.12.0': + resolution: {integrity: sha512-iBi6LZB3lm6WmbXfzi8J3DCVPmn4FN2lw7DGXxUXu7MouDPVWfTsM6U/5TkSHJRNRogZ2gqy5q9g34NPxHbJcw==} + engines: {node: '>= 12.0.0', parcel: ^2.12.0} + + '@parcel/package-manager@2.12.0': + resolution: {integrity: sha512-0nvAezcjPx9FT+hIL+LS1jb0aohwLZXct7jAh7i0MLMtehOi0z1Sau+QpgMlA9rfEZZ1LIeFdnZZwqSy7Ccspw==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@parcel/core': ^2.12.0 + + '@parcel/packager-css@2.12.0': + resolution: {integrity: sha512-j3a/ODciaNKD19IYdWJT+TP+tnhhn5koBGBWWtrKSu0UxWpnezIGZetit3eE+Y9+NTePalMkvpIlit2eDhvfJA==} + engines: {node: '>= 12.0.0', parcel: ^2.12.0} + + '@parcel/packager-html@2.12.0': + resolution: {integrity: sha512-PpvGB9hFFe+19NXGz2ApvPrkA9GwEqaDAninT+3pJD57OVBaxB8U+HN4a5LICKxjUppPPqmrLb6YPbD65IX4RA==} + engines: {node: '>= 12.0.0', parcel: ^2.12.0} + + '@parcel/packager-js@2.12.0': + resolution: {integrity: sha512-viMF+FszITRRr8+2iJyk+4ruGiL27Y6AF7hQ3xbJfzqnmbOhGFtLTQwuwhOLqN/mWR2VKdgbLpZSarWaO3yAMg==} + engines: {node: '>= 12.0.0', parcel: ^2.12.0} + + '@parcel/packager-raw@2.12.0': + resolution: {integrity: sha512-tJZqFbHqP24aq1F+OojFbQIc09P/u8HAW5xfndCrFnXpW4wTgM3p03P0xfw3gnNq+TtxHJ8c3UFE5LnXNNKhYA==} + engines: {node: '>= 12.0.0', parcel: ^2.12.0} + + '@parcel/packager-svg@2.12.0': + resolution: {integrity: sha512-ldaGiacGb2lLqcXas97k8JiZRbAnNREmcvoY2W2dvW4loVuDT9B9fU777mbV6zODpcgcHWsLL3lYbJ5Lt3y9cg==} + engines: {node: '>= 12.0.0', parcel: ^2.12.0} + + '@parcel/packager-ts@2.12.0': + resolution: {integrity: sha512-8wR0BNN2NBD+IIU0tjioK+lRD4p2Qi/fKxDH5ixEW912tRV+Vd4kE8k++U6YQIpSlK4FRnjFod5zYYhNSLuiXg==} + engines: {node: '>= 12.0.0', parcel: ^2.12.0} + + '@parcel/packager-wasm@2.12.0': + resolution: {integrity: sha512-fYqZzIqO9fGYveeImzF8ll6KRo2LrOXfD+2Y5U3BiX/wp9wv17dz50QLDQm9hmTcKGWxK4yWqKQh+Evp/fae7A==} + engines: {node: '>=12.0.0', parcel: ^2.12.0} + + '@parcel/plugin@2.12.0': + resolution: {integrity: sha512-nc/uRA8DiMoe4neBbzV6kDndh/58a4wQuGKw5oEoIwBCHUvE2W8ZFSu7ollSXUGRzfacTt4NdY8TwS73ScWZ+g==} + engines: {node: '>= 12.0.0'} + + '@parcel/profiler@2.12.0': + resolution: {integrity: sha512-q53fvl5LDcFYzMUtSusUBZSjQrKjMlLEBgKeQHFwkimwR1mgoseaDBDuNz0XvmzDzF1UelJ02TUKCGacU8W2qA==} + engines: {node: '>= 12.0.0'} + + '@parcel/reporter-cli@2.12.0': + resolution: {integrity: sha512-TqKsH4GVOLPSCanZ6tcTPj+rdVHERnt5y4bwTM82cajM21bCX1Ruwp8xOKU+03091oV2pv5ieB18pJyRF7IpIw==} + engines: {node: '>= 12.0.0', parcel: ^2.12.0} + + '@parcel/reporter-dev-server@2.12.0': + resolution: {integrity: sha512-tIcDqRvAPAttRlTV28dHcbWT5K2r/MBFks7nM4nrEDHWtnrCwimkDmZTc1kD8QOCCjGVwRHcQybpHvxfwol6GA==} + engines: {node: '>= 12.0.0', parcel: ^2.12.0} + + '@parcel/reporter-tracer@2.12.0': + resolution: {integrity: sha512-g8rlu9GxB8Ut/F8WGx4zidIPQ4pcYFjU9bZO+fyRIPrSUFH2bKijCnbZcr4ntqzDGx74hwD6cCG4DBoleq2UlQ==} + engines: {node: '>= 12.0.0', parcel: ^2.12.0} + + '@parcel/resolver-default@2.12.0': + resolution: {integrity: sha512-uuhbajTax37TwCxu7V98JtRLiT6hzE4VYSu5B7Qkauy14/WFt2dz6GOUXPgVsED569/hkxebPx3KCMtZW6cHHA==} + engines: {node: '>= 12.0.0', parcel: ^2.12.0} + + '@parcel/runtime-browser-hmr@2.12.0': + resolution: {integrity: sha512-4ZLp2FWyD32r0GlTulO3+jxgsA3oO1P1b5oO2IWuWilfhcJH5LTiazpL5YdusUjtNn9PGN6QLAWfxmzRIfM+Ow==} + engines: {node: '>= 12.0.0', parcel: ^2.12.0} + + '@parcel/runtime-js@2.12.0': + resolution: {integrity: sha512-sBerP32Z1crX5PfLNGDSXSdqzlllM++GVnVQVeM7DgMKS8JIFG3VLi28YkX+dYYGtPypm01JoIHCkvwiZEcQJg==} + engines: {node: '>= 12.0.0', parcel: ^2.12.0} + + '@parcel/runtime-react-refresh@2.12.0': + resolution: {integrity: sha512-SCHkcczJIDFTFdLTzrHTkQ0aTrX3xH6jrA4UsCBL6ji61+w+ohy4jEEe9qCgJVXhnJfGLE43HNXek+0MStX+Mw==} + engines: {node: '>= 12.0.0', parcel: ^2.12.0} + + '@parcel/runtime-service-worker@2.12.0': + resolution: {integrity: sha512-BXuMBsfiwpIEnssn+jqfC3jkgbS8oxeo3C7xhSQsuSv+AF2FwY3O3AO1c1RBskEW3XrBLNINOJujroNw80VTKA==} + engines: {node: '>= 12.0.0', parcel: ^2.12.0} + + '@parcel/rust@2.12.0': + resolution: {integrity: sha512-005cldMdFZFDPOjbDVEXcINQ3wT4vrxvSavRWI3Az0e3E18exO/x/mW9f648KtXugOXMAqCEqhFHcXECL9nmMw==} + engines: {node: '>= 12.0.0'} + + '@parcel/source-map@2.1.1': + resolution: {integrity: sha512-Ejx1P/mj+kMjQb8/y5XxDUn4reGdr+WyKYloBljpppUy8gs42T+BNoEOuRYqDVdgPc6NxduzIDoJS9pOFfV5Ew==} + engines: {node: ^12.18.3 || >=14} + + '@parcel/transformer-babel@2.12.0': + resolution: {integrity: sha512-zQaBfOnf/l8rPxYGnsk/ufh/0EuqvmnxafjBIpKZ//j6rGylw5JCqXSb1QvvAqRYruKeccxGv7+HrxpqKU6V4A==} + engines: {node: '>= 12.0.0', parcel: ^2.12.0} + + '@parcel/transformer-css@2.12.0': + resolution: {integrity: sha512-vXhOqoAlQGATYyQ433Z1DXKmiKmzOAUmKysbYH3FD+LKEKLMEl/pA14goqp00TW+A/EjtSKKyeMyHlMIIUqj4Q==} + engines: {node: '>= 12.0.0', parcel: ^2.12.0} + + '@parcel/transformer-html@2.12.0': + resolution: {integrity: sha512-5jW4dFFBlYBvIQk4nrH62rfA/G/KzVzEDa6S+Nne0xXhglLjkm64Ci9b/d4tKZfuGWUbpm2ASAq8skti/nfpXw==} + engines: {node: '>= 12.0.0', parcel: ^2.12.0} + + '@parcel/transformer-image@2.12.0': + resolution: {integrity: sha512-8hXrGm2IRII49R7lZ0RpmNk27EhcsH+uNKsvxuMpXPuEnWgC/ha/IrjaI29xCng1uGur74bJF43NUSQhR4aTdw==} + engines: {node: '>= 12.0.0', parcel: ^2.12.0} + peerDependencies: + '@parcel/core': ^2.12.0 + + '@parcel/transformer-js@2.12.0': + resolution: {integrity: sha512-OSZpOu+FGDbC/xivu24v092D9w6EGytB3vidwbdiJ2FaPgfV7rxS0WIUjH4I0OcvHAcitArRXL0a3+HrNTdQQw==} + engines: {node: '>= 12.0.0', parcel: ^2.12.0} + peerDependencies: + '@parcel/core': ^2.12.0 + + '@parcel/transformer-json@2.12.0': + resolution: {integrity: sha512-Utv64GLRCQILK5r0KFs4o7I41ixMPllwOLOhkdjJKvf1hZmN6WqfOmB1YLbWS/y5Zb/iB52DU2pWZm96vLFQZQ==} + engines: {node: '>= 12.0.0', parcel: ^2.12.0} + + '@parcel/transformer-postcss@2.12.0': + resolution: {integrity: sha512-FZqn+oUtiLfPOn67EZxPpBkfdFiTnF4iwiXPqvst3XI8H+iC+yNgzmtJkunOOuylpYY6NOU5jT8d7saqWSDv2Q==} + engines: {node: '>= 12.0.0', parcel: ^2.12.0} + + '@parcel/transformer-posthtml@2.12.0': + resolution: {integrity: sha512-z6Z7rav/pcaWdeD+2sDUcd0mmNZRUvtHaUGa50Y2mr+poxrKilpsnFMSiWBT+oOqPt7j71jzDvrdnAF4XkCljg==} + engines: {node: '>= 12.0.0', parcel: ^2.12.0} + + '@parcel/transformer-raw@2.12.0': + resolution: {integrity: sha512-Ht1fQvXxix0NncdnmnXZsa6hra20RXYh1VqhBYZLsDfkvGGFnXIgO03Jqn4Z8MkKoa0tiNbDhpKIeTjyclbBxQ==} + engines: {node: '>= 12.0.0', parcel: ^2.12.0} + + '@parcel/transformer-react-refresh-wrap@2.12.0': + resolution: {integrity: sha512-GE8gmP2AZtkpBIV5vSCVhewgOFRhqwdM5Q9jNPOY5PKcM3/Ff0qCqDiTzzGLhk0/VMBrdjssrfZkVx6S/lHdJw==} + engines: {node: '>= 12.0.0', parcel: ^2.12.0} + + '@parcel/transformer-svg@2.12.0': + resolution: {integrity: sha512-cZJqGRJ4JNdYcb+vj94J7PdOuTnwyy45dM9xqbIMH+HSiiIkfrMsdEwYft0GTyFTdsnf+hdHn3tau7Qa5hhX+A==} + engines: {node: '>= 12.0.0', parcel: ^2.12.0} + + '@parcel/transformer-typescript-types@2.12.0': + resolution: {integrity: sha512-uxF4UBMYvbjiV3zHTWMrZX8cFD92VUvD3ArcGi5WEtuVROUm9Sc47o0mOzxKfMFlJu2KOfZVHYlzK9f/UKA2kQ==} + engines: {node: '>= 12.0.0', parcel: ^2.12.0} + peerDependencies: + typescript: '>=3.0.0' + + '@parcel/ts-utils@2.12.0': + resolution: {integrity: sha512-zou+W6dcqnXXUOfN5zGM+ePIWbYOhGp8bVB2jICoNkoKmNAHd4l4zeHl5yQXnbZfynVw88cZVqxtXS8tYebelg==} + engines: {node: '>= 12.0.0'} + peerDependencies: + typescript: '>=3.0.0' + + '@parcel/types@2.12.0': + resolution: {integrity: sha512-8zAFiYNCwNTQcglIObyNwKfRYQK5ELlL13GuBOrSMxueUiI5ylgsGbTS1N7J3dAGZixHO8KhHGv5a71FILn9rQ==} + + '@parcel/utils@2.12.0': + resolution: {integrity: sha512-z1JhLuZ8QmDaYoEIuUCVZlhcFrS7LMfHrb2OCRui5SQFntRWBH2fNM6H/fXXUkT9SkxcuFP2DUA6/m4+Gkz72g==} + engines: {node: '>= 12.0.0'} + + '@parcel/watcher-android-arm64@2.4.1': + resolution: {integrity: sha512-LOi/WTbbh3aTn2RYddrO8pnapixAziFl6SMxHM69r3tvdSm94JtCenaKgk1GRg5FJ5wpMCpHeW+7yqPlvZv7kg==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [android] + + '@parcel/watcher-darwin-arm64@2.4.1': + resolution: {integrity: sha512-ln41eihm5YXIY043vBrrHfn94SIBlqOWmoROhsMVTSXGh0QahKGy77tfEywQ7v3NywyxBBkGIfrWRHm0hsKtzA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [darwin] + + '@parcel/watcher-darwin-x64@2.4.1': + resolution: {integrity: sha512-yrw81BRLjjtHyDu7J61oPuSoeYWR3lDElcPGJyOvIXmor6DEo7/G2u1o7I38cwlcoBHQFULqF6nesIX3tsEXMg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [darwin] + + '@parcel/watcher-freebsd-x64@2.4.1': + resolution: {integrity: sha512-TJa3Pex/gX3CWIx/Co8k+ykNdDCLx+TuZj3f3h7eOjgpdKM+Mnix37RYsYU4LHhiYJz3DK5nFCCra81p6g050w==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [freebsd] + + '@parcel/watcher-linux-arm-glibc@2.4.1': + resolution: {integrity: sha512-4rVYDlsMEYfa537BRXxJ5UF4ddNwnr2/1O4MHM5PjI9cvV2qymvhwZSFgXqbS8YoTk5i/JR0L0JDs69BUn45YA==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + + '@parcel/watcher-linux-arm64-glibc@2.4.1': + resolution: {integrity: sha512-BJ7mH985OADVLpbrzCLgrJ3TOpiZggE9FMblfO65PlOCdG++xJpKUJ0Aol74ZUIYfb8WsRlUdgrZxKkz3zXWYA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + + '@parcel/watcher-linux-arm64-musl@2.4.1': + resolution: {integrity: sha512-p4Xb7JGq3MLgAfYhslU2SjoV9G0kI0Xry0kuxeG/41UfpjHGOhv7UoUDAz/jb1u2elbhazy4rRBL8PegPJFBhA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + + '@parcel/watcher-linux-x64-glibc@2.4.1': + resolution: {integrity: sha512-s9O3fByZ/2pyYDPoLM6zt92yu6P4E39a03zvO0qCHOTjxmt3GHRMLuRZEWhWLASTMSrrnVNWdVI/+pUElJBBBg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + + '@parcel/watcher-linux-x64-musl@2.4.1': + resolution: {integrity: sha512-L2nZTYR1myLNST0O632g0Dx9LyMNHrn6TOt76sYxWLdff3cB22/GZX2UPtJnaqQPdCRoszoY5rcOj4oMTtp5fQ==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + + '@parcel/watcher-win32-arm64@2.4.1': + resolution: {integrity: sha512-Uq2BPp5GWhrq/lcuItCHoqxjULU1QYEcyjSO5jqqOK8RNFDBQnenMMx4gAl3v8GiWa59E9+uDM7yZ6LxwUIfRg==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [win32] + + '@parcel/watcher-win32-ia32@2.4.1': + resolution: {integrity: sha512-maNRit5QQV2kgHFSYwftmPBxiuK5u4DXjbXx7q6eKjq5dsLXZ4FJiVvlcw35QXzk0KrUecJmuVFbj4uV9oYrcw==} + engines: {node: '>= 10.0.0'} + cpu: [ia32] + os: [win32] + + '@parcel/watcher-win32-x64@2.4.1': + resolution: {integrity: sha512-+DvS92F9ezicfswqrvIRM2njcYJbd5mb9CUgtrHCHmvn7pPPa+nMDRu1o1bYYz/l5IB2NVGNJWiH7h1E58IF2A==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [win32] + + '@parcel/watcher@2.4.1': + resolution: {integrity: sha512-HNjmfLQEVRZmHRET336f20H/8kOozUGwk7yajvsonjNxbj2wBTK1WsQuHkD5yYh9RxFGL2EyDHryOihOwUoKDA==} + engines: {node: '>= 10.0.0'} + + '@parcel/workers@2.12.0': + resolution: {integrity: sha512-zv5We5Jmb+ZWXlU6A+AufyjY4oZckkxsZ8J4dvyWL0W8IQvGO1JB4FGeryyttzQv3RM3OxcN/BpTGPiDG6keBw==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@parcel/core': ^2.12.0 + + '@swc/core-darwin-arm64@1.7.36': + resolution: {integrity: sha512-8vDczXzCgv3ceTPhEivlpGprN44YlrCK1nbfU9g2TrhV/Aiqi09W/eM5zLesdoM1Z3mJl492gc/8nlTkpDdusw==} + engines: {node: '>=10'} + cpu: [arm64] + os: [darwin] + + '@swc/core-darwin-x64@1.7.36': + resolution: {integrity: sha512-Pa2Gao7+Wf5m3SsK4abKRtd48AtoUnJInvaC3d077swBfgZjbjUbQvcpdc2dOeQtWwo49rFqUZJonMsL0jnPgQ==} + engines: {node: '>=10'} + cpu: [x64] + os: [darwin] + + '@swc/core-linux-arm-gnueabihf@1.7.36': + resolution: {integrity: sha512-3YsMWd7V+WZEjbfBnLkkz/olcRBa8nyoK0iIOnNARJBMcYaJxjkJSMZpmSojCnIVwvjA1N83CPAbUL+W+fCnHg==} + engines: {node: '>=10'} + cpu: [arm] + os: [linux] + + '@swc/core-linux-arm64-gnu@1.7.36': + resolution: {integrity: sha512-lqM3aBB7kJazJYOwHeA5OGNLqXoQPZ/76b3dV+XcjN1GhD0CcXz6mW5PRYVin6OSN1eKrKBKJjtDA1mqADDEvw==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + + '@swc/core-linux-arm64-musl@1.7.36': + resolution: {integrity: sha512-bqei2YDzvUfG0pth5W2xJaj0eG4XWYk0d/NJ75vBX6bkIzK6dC8iuKQ41jOfUWonnrAs7rTDDJW0sTn/evvRdw==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + + '@swc/core-linux-x64-gnu@1.7.36': + resolution: {integrity: sha512-03maXTUyaBjeCxlDltmdzHje1ryQt1C4OWmmNgSSRXjLb+GNnAenwOJMSrcvHP/aNClD2pwsFCnYKDGy+sYE6w==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + + '@swc/core-linux-x64-musl@1.7.36': + resolution: {integrity: sha512-XXysqLkvjtQnXm1zHqLhy00UYPv/gk5OtwR732X+piNisnEbcJBqI8Qp9O7YvLWllRcoP8IMBGDWLGdGLSpViA==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + + '@swc/core-win32-arm64-msvc@1.7.36': + resolution: {integrity: sha512-k7+dmb13a/zPw+E4XYfPmLZFWJgcOcBRKIjYl9nQErtYsgsg3Ji6TBbsvJVETy23lNHyewZ17V5Vq6NzaG0hzg==} + engines: {node: '>=10'} + cpu: [arm64] + os: [win32] + + '@swc/core-win32-ia32-msvc@1.7.36': + resolution: {integrity: sha512-ridD3ay6YM2PEYHZXXFN+edYEv0FOynaqOBP+NSnGNHA35azItIjoIe+KNi4WltGtAjpKCHSpjGCNfna12wdYQ==} + engines: {node: '>=10'} + cpu: [ia32] + os: [win32] + + '@swc/core-win32-x64-msvc@1.7.36': + resolution: {integrity: sha512-j1z2Z1Ln9d0E3dHsPkC1K9XDh0ojhRPwV+GfRTu4D61PE+aYhYLvbJC6xPvL4/204QrStRS7eDu3m+BcDp3rgQ==} + engines: {node: '>=10'} + cpu: [x64] + os: [win32] + + '@swc/core@1.7.36': + resolution: {integrity: sha512-bu7ymMX+LCJOSSrKank25Jaq66ymLVA9fOUuy4ck3/6rbXdLw+pIJPnIDKQ9uNcxww8KDxOuJk9Ui9pqR+aGFw==} + engines: {node: '>=10'} + peerDependencies: + '@swc/helpers': '*' + peerDependenciesMeta: + '@swc/helpers': + optional: true + + '@swc/counter@0.1.3': + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + + '@swc/helpers@0.5.13': + resolution: {integrity: sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w==} + + '@swc/types@0.1.13': + resolution: {integrity: sha512-JL7eeCk6zWCbiYQg2xQSdLXQJl8Qoc9rXmG2cEKvHe3CKwMHwHGpfOb8frzNLmbycOo6I51qxnLnn9ESf4I20Q==} + + '@trysound/sax@0.2.0': + resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} + engines: {node: '>=10.13.0'} + + '@types/body-parser@1.19.5': + resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} + + '@types/connect@3.4.38': + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + + '@types/estree@1.0.6': + resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + + '@types/express-serve-static-core@5.0.0': + resolution: {integrity: sha512-AbXMTZGt40T+KON9/Fdxx0B2WK5hsgxcfXJLr5bFpZ7b4JCex2WyQPTEKdXqfHiY5nKKBScZ7yCoO6Pvgxfvnw==} + + '@types/express-ws@3.0.5': + resolution: {integrity: sha512-lbWMjoHrm/v85j81UCmb/GNZFO3genxRYBW1Ob7rjRI+zxUBR+4tcFuOpKKsYQ1LYTYiy3356epLeYi/5zxUwA==} + + '@types/express@5.0.0': + resolution: {integrity: sha512-DvZriSMehGHL1ZNLzi6MidnsDhUZM/x2pRdDIKdwbUNqqwHxMlRdkxtn6/EPKyqKpHqTl/4nRZsRNLpZxZRpPQ==} + + '@types/http-errors@2.0.4': + resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/mime@1.3.5': + resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} + + '@types/node@22.7.7': + resolution: {integrity: sha512-SRxCrrg9CL/y54aiMCG3edPKdprgMVGDXjA3gB8UmmBW5TcXzRUYAh8EWzTnSJFAd1rgImPELza+A3bJ+qxz8Q==} + + '@types/qs@6.9.16': + resolution: {integrity: sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A==} + + '@types/range-parser@1.2.7': + resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} + + '@types/semver@7.5.8': + resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} + + '@types/send@0.17.4': + resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} + + '@types/serve-static@1.15.7': + resolution: {integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==} + + '@types/uuid@10.0.0': + resolution: {integrity: sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==} + + '@types/ws@8.5.12': + resolution: {integrity: sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==} + + '@typescript-eslint/eslint-plugin@8.10.0': + resolution: {integrity: sha512-phuB3hoP7FFKbRXxjl+DRlQDuJqhpOnm5MmtROXyWi3uS/Xg2ZXqiQfcG2BJHiN4QKyzdOJi3NEn/qTnjUlkmQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/parser@8.10.0': + resolution: {integrity: sha512-E24l90SxuJhytWJ0pTQydFT46Nk0Z+bsLKo/L8rtQSL93rQ6byd1V/QbDpHUTdLPOMsBCcYXZweADNCfOCmOAg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/scope-manager@8.10.0': + resolution: {integrity: sha512-AgCaEjhfql9MDKjMUxWvH7HjLeBqMCBfIaBbzzIcBbQPZE7CPh1m6FF+L75NUMJFMLYhCywJXIDEMa3//1A0dw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/type-utils@8.10.0': + resolution: {integrity: sha512-PCpUOpyQSpxBn230yIcK+LeCQaXuxrgCm2Zk1S+PTIRJsEfU6nJ0TtwyH8pIwPK/vJoA+7TZtzyAJSGBz+s/dg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/types@8.10.0': + resolution: {integrity: sha512-k/E48uzsfJCRRbGLapdZgrX52csmWJ2rcowwPvOZ8lwPUv3xW6CcFeJAXgx4uJm+Ge4+a4tFOkdYvSpxhRhg1w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.10.0': + resolution: {integrity: sha512-3OE0nlcOHaMvQ8Xu5gAfME3/tWVDpb/HxtpUZ1WeOAksZ/h/gwrBzCklaGzwZT97/lBbbxJ16dMA98JMEngW4w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/utils@8.10.0': + resolution: {integrity: sha512-Oq4uZ7JFr9d1ZunE/QKy5egcDRXT/FrS2z/nlxzPua2VHFtmMvFNDvpq1m/hq0ra+T52aUezfcjGRIB7vNJF9w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + + '@typescript-eslint/visitor-keys@8.10.0': + resolution: {integrity: sha512-k8nekgqwr7FadWk548Lfph6V3r9OVqjzAIVskE7orMZR23cGJjAOVazsZSJW+ElyjfTM4wx/1g88Mi70DDtG9A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + abort-controller@3.0.0: + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} + engines: {node: '>=6.5'} + + abortcontroller-polyfill@1.7.5: + resolution: {integrity: sha512-JMJ5soJWP18htbbxJjG7bG6yuI6pRhgJ0scHHTfkUjf6wjP912xZWvM+A4sJK3gqd9E8fcPbDnOefbA9Th/FIQ==} + + accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.13.0: + resolution: {integrity: sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==} + engines: {node: '>=0.4.0'} + hasBin: true + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + array-flatten@1.1.1: + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + atomic-sleep@1.0.0: + resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} + engines: {node: '>=8.0.0'} + + axios@1.7.7: + resolution: {integrity: sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + base-x@3.0.10: + resolution: {integrity: sha512-7d0s06rR9rYaIWHkpfLIFICM/tkSVdoPC9qYAQRpxn9DdKNWNsKC0uk++akckyLq16Tx2WIinnZ6WRriAt6njQ==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + body-parser@1.20.3: + resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.24.0: + resolution: {integrity: sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + caniuse-lite@1.0.30001669: + resolution: {integrity: sha512-DlWzFDJqstqtIVx1zeSpIMLjunf5SmwOw0N2Ck/QSQdS8PLS4+9HrLaYei4w8BIAL7IB/UEDu889d8vhCTPA0w==} + + chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + chokidar@4.0.1: + resolution: {integrity: sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==} + engines: {node: '>= 14.16.0'} + + chrome-trace-event@1.0.4: + resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} + engines: {node: '>=6.0'} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + clone@2.1.2: + resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} + engines: {node: '>=0.8'} + + color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + commander@7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + concurrently@9.0.1: + resolution: {integrity: sha512-wYKvCd/f54sTXJMSfV6Ln/B8UrfLBKOYa+lzc6CHay3Qek+LorVSBdMVfyewFhRbH0Rbabsk4D+3PL/VjQ5gzg==} + engines: {node: '>=18'} + hasBin: true + + content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + cookie-signature@1.0.6: + resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + + cookie@0.7.1: + resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} + engines: {node: '>= 0.6'} + + cosmiconfig@9.0.0: + resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + + cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + + css-select@4.3.0: + resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==} + + css-tree@1.1.3: + resolution: {integrity: sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==} + engines: {node: '>=8.0.0'} + + css-what@6.1.0: + resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} + engines: {node: '>= 6'} + + csso@4.2.0: + resolution: {integrity: sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==} + engines: {node: '>=8.0.0'} + + dateformat@4.6.3: + resolution: {integrity: sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==} + + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + detect-libc@1.0.3: + resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==} + engines: {node: '>=0.10'} + hasBin: true + + detect-libc@2.0.3: + resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} + engines: {node: '>=8'} + + dom-serializer@1.4.1: + resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@4.3.1: + resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==} + engines: {node: '>= 4'} + + domutils@2.8.0: + resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} + + dotenv-expand@5.1.0: + resolution: {integrity: sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==} + + dotenv@7.0.0: + resolution: {integrity: sha512-M3NhsLbV1i6HuGzBUH8vXrtxOk+tWmzWKDMbAVSUp3Zsjm7ywFeuwrUXhmhQyRK1q5B5GGy7hcXPbj3bnfZg2g==} + engines: {node: '>=6'} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + electron-to-chromium@1.5.41: + resolution: {integrity: sha512-dfdv/2xNjX0P8Vzme4cfzHqnPm5xsZXwsolTYr0eyW18IUmNyG08vL+fttvinTfhKfIKdRoqkDIC9e9iWQCNYQ==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + encodeurl@1.0.2: + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} + engines: {node: '>= 0.8'} + + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + + end-of-stream@1.4.4: + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + + entities@2.2.0: + resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} + + entities@3.0.1: + resolution: {integrity: sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==} + engines: {node: '>=0.12'} + + env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + + error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + + es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-scope@8.1.0: + resolution: {integrity: sha512-14dSvlhaVhKKsa9Fx1l8A17s7ah7Ef7wCakJ10LYk6+GYmP9yDti2oq2SEwcyndt6knfcZyhyxwY3i9yL78EQw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.1.0: + resolution: {integrity: sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint@9.13.0: + resolution: {integrity: sha512-EYZK6SX6zjFHST/HRytOdA/zE72Cq/bfw45LSyuwrdvcclb/gqV8RRQxywOBEWO2+WDpva6UZa4CcDeJKzUCFA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.2.0: + resolution: {integrity: sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + event-target-shim@5.0.1: + resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} + engines: {node: '>=6'} + + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + + express-ws@5.0.2: + resolution: {integrity: sha512-0uvmuk61O9HXgLhGl3QhNSEtRsQevtmbL94/eILaliEADZBHZOQUAiHFrGPrgsjikohyrmSG5g+sCfASTt0lkQ==} + engines: {node: '>=4.5.0'} + peerDependencies: + express: ^4.0.0 || ^5.0.0-alpha.1 + + express@4.21.1: + resolution: {integrity: sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==} + engines: {node: '>= 0.10.0'} + + fast-copy@3.0.2: + resolution: {integrity: sha512-dl0O9Vhju8IrcLndv2eU4ldt1ftXMqqfgN4H1cpmGV7P6jeB9FwpN9a2c8DPGE1Ys88rNUJVYDHq73CGAGOPfQ==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fast-redact@3.5.0: + resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==} + engines: {node: '>=6'} + + fast-safe-stringify@2.1.1: + resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} + + fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + finalhandler@1.3.1: + resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==} + engines: {node: '>= 0.8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.3.1: + resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + + follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + form-data@4.0.1: + resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==} + engines: {node: '>= 6'} + + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + + get-port@4.2.0: + resolution: {integrity: sha512-/b3jarXkH8KJoOMQc3uVGHASwGLPq3gSFJ7tgJm2diza+bydJPTGOibin2steecKeOylE8oY2JERlVWkAJO6yw==} + engines: {node: '>=6'} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + globals@13.24.0: + resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} + engines: {node: '>=8'} + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globals@15.11.0: + resolution: {integrity: sha512-yeyNSjdbyVaWurlwCpcA6XNBrHTMIeDdj0/hnvX/OLJ9ekOXYbLsLinH/MucQyGvNnXhidTdNhTtJaffL2sMfw==} + engines: {node: '>=18'} + + gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + + has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + help-me@5.0.0: + resolution: {integrity: sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==} + + htmlnano@2.1.1: + resolution: {integrity: sha512-kAERyg/LuNZYmdqgCdYvugyLWNFAm8MWXpQMz1pLpetmCbFwoMxvkSoaAMlFrOC4OKTWI4KlZGT/RsNxg4ghOw==} + peerDependencies: + cssnano: ^7.0.0 + postcss: ^8.3.11 + purgecss: ^6.0.0 + relateurl: ^0.2.7 + srcset: 5.0.1 + svgo: ^3.0.2 + terser: ^5.10.0 + uncss: ^0.17.3 + peerDependenciesMeta: + cssnano: + optional: true + postcss: + optional: true + purgecss: + optional: true + relateurl: + optional: true + srcset: + optional: true + svgo: + optional: true + terser: + optional: true + uncss: + optional: true + + htmlparser2@7.2.0: + resolution: {integrity: sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==} + + http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} + + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + ignore-by-default@1.0.1: + resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-json@2.0.1: + resolution: {integrity: sha512-6BEnpVn1rcf3ngfmViLM6vjUjGErbdrL4rwlv+u1NO1XO8kqT4YGL8+19Q+Z/bas8tY90BTWMk2+fW1g6hQjbA==} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + joycon@3.1.1: + resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} + engines: {node: '>=10'} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lightningcss-darwin-arm64@1.27.0: + resolution: {integrity: sha512-Gl/lqIXY+d+ySmMbgDf0pgaWSqrWYxVHoc88q+Vhf2YNzZ8DwoRzGt5NZDVqqIW5ScpSnmmjcgXP87Dn2ylSSQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.27.0: + resolution: {integrity: sha512-0+mZa54IlcNAoQS9E0+niovhyjjQWEMrwW0p2sSdLRhLDc8LMQ/b67z7+B5q4VmjYCMSfnFi3djAAQFIDuj/Tg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.27.0: + resolution: {integrity: sha512-n1sEf85fePoU2aDN2PzYjoI8gbBqnmLGEhKq7q0DKLj0UTVmOTwDC7PtLcy/zFxzASTSBlVQYJUhwIStQMIpRA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.27.0: + resolution: {integrity: sha512-MUMRmtdRkOkd5z3h986HOuNBD1c2lq2BSQA1Jg88d9I7bmPGx08bwGcnB75dvr17CwxjxD6XPi3Qh8ArmKFqCA==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.27.0: + resolution: {integrity: sha512-cPsxo1QEWq2sfKkSq2Bq5feQDHdUEwgtA9KaB27J5AX22+l4l0ptgjMZZtYtUnteBofjee+0oW1wQ1guv04a7A==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-arm64-musl@1.27.0: + resolution: {integrity: sha512-rCGBm2ax7kQ9pBSeITfCW9XSVF69VX+fm5DIpvDZQl4NnQoMQyRwhZQm9pd59m8leZ1IesRqWk2v/DntMo26lg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-x64-gnu@1.27.0: + resolution: {integrity: sha512-Dk/jovSI7qqhJDiUibvaikNKI2x6kWPN79AQiD/E/KeQWMjdGe9kw51RAgoWFDi0coP4jinaH14Nrt/J8z3U4A==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-linux-x64-musl@1.27.0: + resolution: {integrity: sha512-QKjTxXm8A9s6v9Tg3Fk0gscCQA1t/HMoF7Woy1u68wCk5kS4fR+q3vXa1p3++REW784cRAtkYKrPy6JKibrEZA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-win32-arm64-msvc@1.27.0: + resolution: {integrity: sha512-/wXegPS1hnhkeG4OXQKEMQeJd48RDC3qdh+OA8pCuOPCyvnm/yEayrJdJVqzBsqpy1aJklRCVxscpFur80o6iQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.27.0: + resolution: {integrity: sha512-/OJLj94Zm/waZShL8nB5jsNj3CfNATLCTyFxZyouilfTmSoLDX7VlVAmhPHoZWVFp4vdmoiEbPEYC8HID3m6yw==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.27.0: + resolution: {integrity: sha512-8f7aNmS1+etYSLHht0fQApPc2kNO8qGRutifN5rVIc6Xo6ABsEbqOr758UwI7ALVbTt4x1fllKt0PYgzD9S3yQ==} + engines: {node: '>= 12.0.0'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + lmdb@2.8.5: + resolution: {integrity: sha512-9bMdFfc80S+vSldBmG3HOuLVHnxRdNTlpzR6QDnzqCQtCzGUEAGTzBKYMeIM+I/sU4oZfgbcbS7X7F65/z/oxQ==} + hasBin: true + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + mdn-data@2.0.14: + resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==} + + media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + + merge-descriptors@1.0.3: + resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + msgpackr-extract@3.0.3: + resolution: {integrity: sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==} + hasBin: true + + msgpackr@1.11.0: + resolution: {integrity: sha512-I8qXuuALqJe5laEBYoFykChhSXLikZmUhccjGsPuSJ/7uPip2TJ7lwdIQwWSAi0jGZDXv4WOP8Qg65QZRuXxXw==} + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + + node-addon-api@6.1.0: + resolution: {integrity: sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==} + + node-addon-api@7.1.1: + resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} + + node-gyp-build-optional-packages@5.1.1: + resolution: {integrity: sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw==} + hasBin: true + + node-gyp-build-optional-packages@5.2.2: + resolution: {integrity: sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==} + hasBin: true + + node-releases@2.0.18: + resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} + + nodemon@3.1.7: + resolution: {integrity: sha512-hLj7fuMow6f0lbB0cD14Lz2xNjwsyruH251Pk4t/yIitCFJbmY1myuLlHm/q06aST4jg6EgAh74PIBBrRqpVAQ==} + engines: {node: '>=10'} + hasBin: true + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + nullthrows@1.1.1: + resolution: {integrity: sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==} + + object-inspect@1.13.2: + resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==} + engines: {node: '>= 0.4'} + + on-exit-leak-free@2.1.2: + resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} + engines: {node: '>=14.0.0'} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + ordered-binary@1.5.2: + resolution: {integrity: sha512-JTo+4+4Fw7FreyAvlSLjb1BBVaxEQAacmjD3jjuyPZclpbEghTvQZbXBb2qPd2LeIMxiHwXBZUcpmG2Gl/mDEA==} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + parcel@2.12.0: + resolution: {integrity: sha512-W+gxAq7aQ9dJIg/XLKGcRT0cvnStFAQHPaI0pvD0U2l6IVLueUAm3nwN7lkY62zZNmlvNx6jNtE4wlbS+CyqSg==} + engines: {node: '>= 12.0.0'} + hasBin: true + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-to-regexp@0.1.10: + resolution: {integrity: sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + pino-abstract-transport@2.0.0: + resolution: {integrity: sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==} + + pino-pretty@11.3.0: + resolution: {integrity: sha512-oXwn7ICywaZPHmu3epHGU2oJX4nPmKvHvB/bwrJHlGcbEWaVcotkpyVHMKLKmiVryWYByNp0jpgAcXpFJDXJzA==} + hasBin: true + + pino-std-serializers@7.0.0: + resolution: {integrity: sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==} + + pino@9.5.0: + resolution: {integrity: sha512-xSEmD4pLnV54t0NOUN16yCl7RIB1c5UUOse5HSyEXtBp+FgFQyPeDutc+Q2ZO7/22vImV7VfEjH/1zV2QuqvYw==} + hasBin: true + + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + posthtml-parser@0.10.2: + resolution: {integrity: sha512-PId6zZ/2lyJi9LiKfe+i2xv57oEjJgWbsHGGANwos5AvdQp98i6AtamAl8gzSVFGfQ43Glb5D614cvZf012VKg==} + engines: {node: '>=12'} + + posthtml-parser@0.11.0: + resolution: {integrity: sha512-QecJtfLekJbWVo/dMAA+OSwY79wpRmbqS5TeXvXSX+f0c6pW4/SE6inzZ2qkU7oAMCPqIDkZDvd/bQsSFUnKyw==} + engines: {node: '>=12'} + + posthtml-render@3.0.0: + resolution: {integrity: sha512-z+16RoxK3fUPgwaIgH9NGnK1HKY9XIDpydky5eQGgAFVXTCSezalv9U2jQuNV+Z9qV1fDWNzldcw4eK0SSbqKA==} + engines: {node: '>=12'} + + posthtml@0.16.6: + resolution: {integrity: sha512-JcEmHlyLK/o0uGAlj65vgg+7LIms0xKXe60lcDOTU7oVX/3LuEuLwrQpW3VJ7de5TaFKiW4kWkaIpJL42FEgxQ==} + engines: {node: '>=12.0.0'} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier@3.3.3: + resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} + engines: {node: '>=14'} + hasBin: true + + process-warning@4.0.0: + resolution: {integrity: sha512-/MyYDxttz7DfGMMHiysAsFE4qF+pQYAA8ziO/3NcRVrQ5fSk+Mns4QZA/oRPFzvcqNoVJXQNWNAsdwBXLUkQKw==} + + process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + pstree.remy@1.1.8: + resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==} + + pump@3.0.2: + resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + qs@6.13.0: + resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} + engines: {node: '>=0.6'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + quick-format-unescaped@4.0.4: + resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@2.5.2: + resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} + engines: {node: '>= 0.8'} + + react-error-overlay@6.0.9: + resolution: {integrity: sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew==} + + react-refresh@0.9.0: + resolution: {integrity: sha512-Gvzk7OZpiqKSkxsQvO/mbTN1poglhmAV7gR/DdIrRrSMXraRQQlfikRJOr3Nb9GTMPC5kof948Zy6jJZIFtDvQ==} + engines: {node: '>=0.10.0'} + + readable-stream@4.5.2: + resolution: {integrity: sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + readdirp@4.0.2: + resolution: {integrity: sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==} + engines: {node: '>= 14.16.0'} + + real-require@0.2.0: + resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} + engines: {node: '>= 12.13.0'} + + regenerator-runtime@0.13.11: + resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + rxjs@7.8.1: + resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safe-stable-stringify@2.5.0: + resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} + engines: {node: '>=10'} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + secure-json-parse@2.7.0: + resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==} + + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + engines: {node: '>=10'} + hasBin: true + + send@0.19.0: + resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==} + engines: {node: '>= 0.8.0'} + + serve-static@1.16.2: + resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==} + engines: {node: '>= 0.8.0'} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shell-quote@1.8.1: + resolution: {integrity: sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==} + + side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} + + simple-update-notifier@2.0.0: + resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} + engines: {node: '>=10'} + + sonic-boom@4.2.0: + resolution: {integrity: sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + + srcset@4.0.0: + resolution: {integrity: sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw==} + engines: {node: '>=12'} + + stable@0.1.8: + resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==} + deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility' + + statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + + svgo@2.8.0: + resolution: {integrity: sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==} + engines: {node: '>=10.13.0'} + hasBin: true + + term-size@2.2.1: + resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} + engines: {node: '>=8'} + + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + + thread-stream@3.1.0: + resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==} + + timsort@0.3.0: + resolution: {integrity: sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A==} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + touch@3.1.1: + resolution: {integrity: sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==} + hasBin: true + + tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + + ts-api-utils@1.3.0: + resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} + engines: {node: '>=16'} + peerDependencies: + typescript: '>=4.2.0' + + tslib@2.8.0: + resolution: {integrity: sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + + type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + + typescript-eslint@8.10.0: + resolution: {integrity: sha512-YIu230PeN7z9zpu/EtqCIuRVHPs4iSlqW6TEvjbyDAE3MZsSl2RXBo+5ag+lbABCG8sFM1WVKEXhlQ8Ml8A3Fw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + typescript@5.6.3: + resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} + engines: {node: '>=14.17'} + hasBin: true + + undefsafe@2.0.5: + resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==} + + undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + update-browserslist-db@1.1.1: + resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + utility-types@3.11.0: + resolution: {integrity: sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==} + engines: {node: '>= 4'} + + utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + + uuid@10.0.0: + resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==} + hasBin: true + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + weak-lru-cache@1.2.2: + resolution: {integrity: sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + ws@7.5.10: + resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + +snapshots: + + '@babel/code-frame@7.25.7': + dependencies: + '@babel/highlight': 7.25.7 + picocolors: 1.1.1 + + '@babel/helper-validator-identifier@7.25.7': {} + + '@babel/highlight@7.25.7': + dependencies: + '@babel/helper-validator-identifier': 7.25.7 + chalk: 2.4.2 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@board-bound/sdk@0.1.0': {} + + '@eslint-community/eslint-utils@4.4.0(eslint@9.13.0)': + dependencies: + eslint: 9.13.0 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.11.1': {} + + '@eslint/config-array@0.18.0': + dependencies: + '@eslint/object-schema': 2.1.4 + debug: 4.3.7(supports-color@5.5.0) + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@eslint/core@0.7.0': {} + + '@eslint/eslintrc@3.1.0': + dependencies: + ajv: 6.12.6 + debug: 4.3.7(supports-color@5.5.0) + espree: 10.2.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.13.0': {} + + '@eslint/object-schema@2.1.4': {} + + '@eslint/plugin-kit@0.2.1': + dependencies: + levn: 0.4.1 + + '@humanfs/core@0.19.0': {} + + '@humanfs/node@0.16.5': + dependencies: + '@humanfs/core': 0.19.0 + '@humanwhocodes/retry': 0.3.1 + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.3.1': {} + + '@lezer/common@1.2.3': {} + + '@lezer/lr@1.4.2': + dependencies: + '@lezer/common': 1.2.3 + + '@lmdb/lmdb-darwin-arm64@2.8.5': + optional: true + + '@lmdb/lmdb-darwin-x64@2.8.5': + optional: true + + '@lmdb/lmdb-linux-arm64@2.8.5': + optional: true + + '@lmdb/lmdb-linux-arm@2.8.5': + optional: true + + '@lmdb/lmdb-linux-x64@2.8.5': + optional: true + + '@lmdb/lmdb-win32-x64@2.8.5': + optional: true + + '@mischnic/json-sourcemap@0.1.1': + dependencies: + '@lezer/common': 1.2.3 + '@lezer/lr': 1.4.2 + json5: 2.2.3 + + '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3': + optional: true + + '@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.3': + optional: true + + '@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.3': + optional: true + + '@msgpackr-extract/msgpackr-extract-linux-arm@3.0.3': + optional: true + + '@msgpackr-extract/msgpackr-extract-linux-x64@3.0.3': + optional: true + + '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3': + optional: true + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.17.1 + + '@parcel/bundler-default@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))': + dependencies: + '@parcel/diagnostic': 2.12.0 + '@parcel/graph': 3.2.0 + '@parcel/plugin': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/rust': 2.12.0 + '@parcel/utils': 2.12.0 + nullthrows: 1.1.1 + transitivePeerDependencies: + - '@parcel/core' + + '@parcel/cache@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))': + dependencies: + '@parcel/core': 2.12.0(@swc/helpers@0.5.13) + '@parcel/fs': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))(@swc/helpers@0.5.13) + '@parcel/logger': 2.12.0 + '@parcel/utils': 2.12.0 + lmdb: 2.8.5 + + '@parcel/codeframe@2.12.0': + dependencies: + chalk: 4.1.2 + + '@parcel/compressor-raw@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))': + dependencies: + '@parcel/plugin': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + transitivePeerDependencies: + - '@parcel/core' + + '@parcel/config-default@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))(@swc/helpers@0.5.13)(typescript@5.6.3)': + dependencies: + '@parcel/bundler-default': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/compressor-raw': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/core': 2.12.0(@swc/helpers@0.5.13) + '@parcel/namer-default': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/optimizer-css': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/optimizer-htmlnano': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))(typescript@5.6.3) + '@parcel/optimizer-image': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/optimizer-svgo': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/optimizer-swc': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))(@swc/helpers@0.5.13) + '@parcel/packager-css': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/packager-html': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/packager-js': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/packager-raw': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/packager-svg': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/packager-wasm': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/reporter-dev-server': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/resolver-default': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/runtime-browser-hmr': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/runtime-js': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/runtime-react-refresh': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/runtime-service-worker': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/transformer-babel': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/transformer-css': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/transformer-html': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/transformer-image': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/transformer-js': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/transformer-json': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/transformer-postcss': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/transformer-posthtml': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/transformer-raw': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/transformer-react-refresh-wrap': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/transformer-svg': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + transitivePeerDependencies: + - '@swc/helpers' + - cssnano + - postcss + - purgecss + - relateurl + - srcset + - terser + - typescript + - uncss + + '@parcel/core@2.12.0(@swc/helpers@0.5.13)': + dependencies: + '@mischnic/json-sourcemap': 0.1.1 + '@parcel/cache': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/diagnostic': 2.12.0 + '@parcel/events': 2.12.0 + '@parcel/fs': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))(@swc/helpers@0.5.13) + '@parcel/graph': 3.2.0 + '@parcel/logger': 2.12.0 + '@parcel/package-manager': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))(@swc/helpers@0.5.13) + '@parcel/plugin': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/profiler': 2.12.0 + '@parcel/rust': 2.12.0 + '@parcel/source-map': 2.1.1 + '@parcel/types': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))(@swc/helpers@0.5.13) + '@parcel/utils': 2.12.0 + '@parcel/workers': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + abortcontroller-polyfill: 1.7.5 + base-x: 3.0.10 + browserslist: 4.24.0 + clone: 2.1.2 + dotenv: 7.0.0 + dotenv-expand: 5.1.0 + json5: 2.2.3 + msgpackr: 1.11.0 + nullthrows: 1.1.1 + semver: 7.6.3 + transitivePeerDependencies: + - '@swc/helpers' + + '@parcel/diagnostic@2.12.0': + dependencies: + '@mischnic/json-sourcemap': 0.1.1 + nullthrows: 1.1.1 + + '@parcel/events@2.12.0': {} + + '@parcel/fs@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))(@swc/helpers@0.5.13)': + dependencies: + '@parcel/core': 2.12.0(@swc/helpers@0.5.13) + '@parcel/rust': 2.12.0 + '@parcel/types': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))(@swc/helpers@0.5.13) + '@parcel/utils': 2.12.0 + '@parcel/watcher': 2.4.1 + '@parcel/workers': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + transitivePeerDependencies: + - '@swc/helpers' + + '@parcel/graph@3.2.0': + dependencies: + nullthrows: 1.1.1 + + '@parcel/logger@2.12.0': + dependencies: + '@parcel/diagnostic': 2.12.0 + '@parcel/events': 2.12.0 + + '@parcel/markdown-ansi@2.12.0': + dependencies: + chalk: 4.1.2 + + '@parcel/namer-default@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))': + dependencies: + '@parcel/diagnostic': 2.12.0 + '@parcel/plugin': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + nullthrows: 1.1.1 + transitivePeerDependencies: + - '@parcel/core' + + '@parcel/node-resolver-core@3.3.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))': + dependencies: + '@mischnic/json-sourcemap': 0.1.1 + '@parcel/diagnostic': 2.12.0 + '@parcel/fs': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))(@swc/helpers@0.5.13) + '@parcel/rust': 2.12.0 + '@parcel/utils': 2.12.0 + nullthrows: 1.1.1 + semver: 7.6.3 + transitivePeerDependencies: + - '@parcel/core' + + '@parcel/optimizer-css@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))': + dependencies: + '@parcel/diagnostic': 2.12.0 + '@parcel/plugin': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/source-map': 2.1.1 + '@parcel/utils': 2.12.0 + browserslist: 4.24.0 + lightningcss: 1.27.0 + nullthrows: 1.1.1 + transitivePeerDependencies: + - '@parcel/core' + + '@parcel/optimizer-htmlnano@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))(typescript@5.6.3)': + dependencies: + '@parcel/plugin': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + htmlnano: 2.1.1(svgo@2.8.0)(typescript@5.6.3) + nullthrows: 1.1.1 + posthtml: 0.16.6 + svgo: 2.8.0 + transitivePeerDependencies: + - '@parcel/core' + - cssnano + - postcss + - purgecss + - relateurl + - srcset + - terser + - typescript + - uncss + + '@parcel/optimizer-image@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))': + dependencies: + '@parcel/core': 2.12.0(@swc/helpers@0.5.13) + '@parcel/diagnostic': 2.12.0 + '@parcel/plugin': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/rust': 2.12.0 + '@parcel/utils': 2.12.0 + '@parcel/workers': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + + '@parcel/optimizer-svgo@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))': + dependencies: + '@parcel/diagnostic': 2.12.0 + '@parcel/plugin': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/utils': 2.12.0 + svgo: 2.8.0 + transitivePeerDependencies: + - '@parcel/core' + + '@parcel/optimizer-swc@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))(@swc/helpers@0.5.13)': + dependencies: + '@parcel/diagnostic': 2.12.0 + '@parcel/plugin': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/source-map': 2.1.1 + '@parcel/utils': 2.12.0 + '@swc/core': 1.7.36(@swc/helpers@0.5.13) + nullthrows: 1.1.1 + transitivePeerDependencies: + - '@parcel/core' + - '@swc/helpers' + + '@parcel/package-manager@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))(@swc/helpers@0.5.13)': + dependencies: + '@parcel/core': 2.12.0(@swc/helpers@0.5.13) + '@parcel/diagnostic': 2.12.0 + '@parcel/fs': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))(@swc/helpers@0.5.13) + '@parcel/logger': 2.12.0 + '@parcel/node-resolver-core': 3.3.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/types': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))(@swc/helpers@0.5.13) + '@parcel/utils': 2.12.0 + '@parcel/workers': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@swc/core': 1.7.36(@swc/helpers@0.5.13) + semver: 7.6.3 + transitivePeerDependencies: + - '@swc/helpers' + + '@parcel/packager-css@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))': + dependencies: + '@parcel/diagnostic': 2.12.0 + '@parcel/plugin': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/source-map': 2.1.1 + '@parcel/utils': 2.12.0 + lightningcss: 1.27.0 + nullthrows: 1.1.1 + transitivePeerDependencies: + - '@parcel/core' + + '@parcel/packager-html@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))': + dependencies: + '@parcel/plugin': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/types': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))(@swc/helpers@0.5.13) + '@parcel/utils': 2.12.0 + nullthrows: 1.1.1 + posthtml: 0.16.6 + transitivePeerDependencies: + - '@parcel/core' + + '@parcel/packager-js@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))': + dependencies: + '@parcel/diagnostic': 2.12.0 + '@parcel/plugin': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/rust': 2.12.0 + '@parcel/source-map': 2.1.1 + '@parcel/types': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))(@swc/helpers@0.5.13) + '@parcel/utils': 2.12.0 + globals: 13.24.0 + nullthrows: 1.1.1 + transitivePeerDependencies: + - '@parcel/core' + + '@parcel/packager-raw@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))': + dependencies: + '@parcel/plugin': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + transitivePeerDependencies: + - '@parcel/core' + + '@parcel/packager-svg@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))': + dependencies: + '@parcel/plugin': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/types': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))(@swc/helpers@0.5.13) + '@parcel/utils': 2.12.0 + posthtml: 0.16.6 + transitivePeerDependencies: + - '@parcel/core' + + '@parcel/packager-ts@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))': + dependencies: + '@parcel/plugin': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + transitivePeerDependencies: + - '@parcel/core' + + '@parcel/packager-wasm@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))': + dependencies: + '@parcel/plugin': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + transitivePeerDependencies: + - '@parcel/core' + + '@parcel/plugin@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))': + dependencies: + '@parcel/types': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))(@swc/helpers@0.5.13) + transitivePeerDependencies: + - '@parcel/core' + + '@parcel/profiler@2.12.0': + dependencies: + '@parcel/diagnostic': 2.12.0 + '@parcel/events': 2.12.0 + chrome-trace-event: 1.0.4 + + '@parcel/reporter-cli@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))': + dependencies: + '@parcel/plugin': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/types': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))(@swc/helpers@0.5.13) + '@parcel/utils': 2.12.0 + chalk: 4.1.2 + term-size: 2.2.1 + transitivePeerDependencies: + - '@parcel/core' + + '@parcel/reporter-dev-server@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))': + dependencies: + '@parcel/plugin': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/utils': 2.12.0 + transitivePeerDependencies: + - '@parcel/core' + + '@parcel/reporter-tracer@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))': + dependencies: + '@parcel/plugin': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/utils': 2.12.0 + chrome-trace-event: 1.0.4 + nullthrows: 1.1.1 + transitivePeerDependencies: + - '@parcel/core' + + '@parcel/resolver-default@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))': + dependencies: + '@parcel/node-resolver-core': 3.3.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/plugin': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + transitivePeerDependencies: + - '@parcel/core' + + '@parcel/runtime-browser-hmr@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))': + dependencies: + '@parcel/plugin': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/utils': 2.12.0 + transitivePeerDependencies: + - '@parcel/core' + + '@parcel/runtime-js@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))': + dependencies: + '@parcel/diagnostic': 2.12.0 + '@parcel/plugin': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/utils': 2.12.0 + nullthrows: 1.1.1 + transitivePeerDependencies: + - '@parcel/core' + + '@parcel/runtime-react-refresh@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))': + dependencies: + '@parcel/plugin': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/utils': 2.12.0 + react-error-overlay: 6.0.9 + react-refresh: 0.9.0 + transitivePeerDependencies: + - '@parcel/core' + + '@parcel/runtime-service-worker@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))': + dependencies: + '@parcel/plugin': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/utils': 2.12.0 + nullthrows: 1.1.1 + transitivePeerDependencies: + - '@parcel/core' + + '@parcel/rust@2.12.0': {} + + '@parcel/source-map@2.1.1': + dependencies: + detect-libc: 1.0.3 + + '@parcel/transformer-babel@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))': + dependencies: + '@parcel/diagnostic': 2.12.0 + '@parcel/plugin': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/source-map': 2.1.1 + '@parcel/utils': 2.12.0 + browserslist: 4.24.0 + json5: 2.2.3 + nullthrows: 1.1.1 + semver: 7.6.3 + transitivePeerDependencies: + - '@parcel/core' + + '@parcel/transformer-css@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))': + dependencies: + '@parcel/diagnostic': 2.12.0 + '@parcel/plugin': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/source-map': 2.1.1 + '@parcel/utils': 2.12.0 + browserslist: 4.24.0 + lightningcss: 1.27.0 + nullthrows: 1.1.1 + transitivePeerDependencies: + - '@parcel/core' + + '@parcel/transformer-html@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))': + dependencies: + '@parcel/diagnostic': 2.12.0 + '@parcel/plugin': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/rust': 2.12.0 + nullthrows: 1.1.1 + posthtml: 0.16.6 + posthtml-parser: 0.10.2 + posthtml-render: 3.0.0 + semver: 7.6.3 + srcset: 4.0.0 + transitivePeerDependencies: + - '@parcel/core' + + '@parcel/transformer-image@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))': + dependencies: + '@parcel/core': 2.12.0(@swc/helpers@0.5.13) + '@parcel/plugin': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/utils': 2.12.0 + '@parcel/workers': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + nullthrows: 1.1.1 + + '@parcel/transformer-js@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))': + dependencies: + '@parcel/core': 2.12.0(@swc/helpers@0.5.13) + '@parcel/diagnostic': 2.12.0 + '@parcel/plugin': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/rust': 2.12.0 + '@parcel/source-map': 2.1.1 + '@parcel/utils': 2.12.0 + '@parcel/workers': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@swc/helpers': 0.5.13 + browserslist: 4.24.0 + nullthrows: 1.1.1 + regenerator-runtime: 0.13.11 + semver: 7.6.3 + + '@parcel/transformer-json@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))': + dependencies: + '@parcel/plugin': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + json5: 2.2.3 + transitivePeerDependencies: + - '@parcel/core' + + '@parcel/transformer-postcss@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))': + dependencies: + '@parcel/diagnostic': 2.12.0 + '@parcel/plugin': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/rust': 2.12.0 + '@parcel/utils': 2.12.0 + clone: 2.1.2 + nullthrows: 1.1.1 + postcss-value-parser: 4.2.0 + semver: 7.6.3 + transitivePeerDependencies: + - '@parcel/core' + + '@parcel/transformer-posthtml@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))': + dependencies: + '@parcel/plugin': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/utils': 2.12.0 + nullthrows: 1.1.1 + posthtml: 0.16.6 + posthtml-parser: 0.10.2 + posthtml-render: 3.0.0 + semver: 7.6.3 + transitivePeerDependencies: + - '@parcel/core' + + '@parcel/transformer-raw@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))': + dependencies: + '@parcel/plugin': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + transitivePeerDependencies: + - '@parcel/core' + + '@parcel/transformer-react-refresh-wrap@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))': + dependencies: + '@parcel/plugin': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/utils': 2.12.0 + react-refresh: 0.9.0 + transitivePeerDependencies: + - '@parcel/core' + + '@parcel/transformer-svg@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))': + dependencies: + '@parcel/diagnostic': 2.12.0 + '@parcel/plugin': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/rust': 2.12.0 + nullthrows: 1.1.1 + posthtml: 0.16.6 + posthtml-parser: 0.10.2 + posthtml-render: 3.0.0 + semver: 7.6.3 + transitivePeerDependencies: + - '@parcel/core' + + '@parcel/transformer-typescript-types@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))(typescript@5.6.3)': + dependencies: + '@parcel/diagnostic': 2.12.0 + '@parcel/plugin': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/source-map': 2.1.1 + '@parcel/ts-utils': 2.12.0(typescript@5.6.3) + '@parcel/utils': 2.12.0 + nullthrows: 1.1.1 + typescript: 5.6.3 + transitivePeerDependencies: + - '@parcel/core' + + '@parcel/ts-utils@2.12.0(typescript@5.6.3)': + dependencies: + nullthrows: 1.1.1 + typescript: 5.6.3 + + '@parcel/types@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))(@swc/helpers@0.5.13)': + dependencies: + '@parcel/cache': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/diagnostic': 2.12.0 + '@parcel/fs': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))(@swc/helpers@0.5.13) + '@parcel/package-manager': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))(@swc/helpers@0.5.13) + '@parcel/source-map': 2.1.1 + '@parcel/workers': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + utility-types: 3.11.0 + transitivePeerDependencies: + - '@parcel/core' + - '@swc/helpers' + + '@parcel/utils@2.12.0': + dependencies: + '@parcel/codeframe': 2.12.0 + '@parcel/diagnostic': 2.12.0 + '@parcel/logger': 2.12.0 + '@parcel/markdown-ansi': 2.12.0 + '@parcel/rust': 2.12.0 + '@parcel/source-map': 2.1.1 + chalk: 4.1.2 + nullthrows: 1.1.1 + + '@parcel/watcher-android-arm64@2.4.1': + optional: true + + '@parcel/watcher-darwin-arm64@2.4.1': + optional: true + + '@parcel/watcher-darwin-x64@2.4.1': + optional: true + + '@parcel/watcher-freebsd-x64@2.4.1': + optional: true + + '@parcel/watcher-linux-arm-glibc@2.4.1': + optional: true + + '@parcel/watcher-linux-arm64-glibc@2.4.1': + optional: true + + '@parcel/watcher-linux-arm64-musl@2.4.1': + optional: true + + '@parcel/watcher-linux-x64-glibc@2.4.1': + optional: true + + '@parcel/watcher-linux-x64-musl@2.4.1': + optional: true + + '@parcel/watcher-win32-arm64@2.4.1': + optional: true + + '@parcel/watcher-win32-ia32@2.4.1': + optional: true + + '@parcel/watcher-win32-x64@2.4.1': + optional: true + + '@parcel/watcher@2.4.1': + dependencies: + detect-libc: 1.0.3 + is-glob: 4.0.3 + micromatch: 4.0.8 + node-addon-api: 7.1.1 + optionalDependencies: + '@parcel/watcher-android-arm64': 2.4.1 + '@parcel/watcher-darwin-arm64': 2.4.1 + '@parcel/watcher-darwin-x64': 2.4.1 + '@parcel/watcher-freebsd-x64': 2.4.1 + '@parcel/watcher-linux-arm-glibc': 2.4.1 + '@parcel/watcher-linux-arm64-glibc': 2.4.1 + '@parcel/watcher-linux-arm64-musl': 2.4.1 + '@parcel/watcher-linux-x64-glibc': 2.4.1 + '@parcel/watcher-linux-x64-musl': 2.4.1 + '@parcel/watcher-win32-arm64': 2.4.1 + '@parcel/watcher-win32-ia32': 2.4.1 + '@parcel/watcher-win32-x64': 2.4.1 + + '@parcel/workers@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))': + dependencies: + '@parcel/core': 2.12.0(@swc/helpers@0.5.13) + '@parcel/diagnostic': 2.12.0 + '@parcel/logger': 2.12.0 + '@parcel/profiler': 2.12.0 + '@parcel/types': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))(@swc/helpers@0.5.13) + '@parcel/utils': 2.12.0 + nullthrows: 1.1.1 + + '@swc/core-darwin-arm64@1.7.36': + optional: true + + '@swc/core-darwin-x64@1.7.36': + optional: true + + '@swc/core-linux-arm-gnueabihf@1.7.36': + optional: true + + '@swc/core-linux-arm64-gnu@1.7.36': + optional: true + + '@swc/core-linux-arm64-musl@1.7.36': + optional: true + + '@swc/core-linux-x64-gnu@1.7.36': + optional: true + + '@swc/core-linux-x64-musl@1.7.36': + optional: true + + '@swc/core-win32-arm64-msvc@1.7.36': + optional: true + + '@swc/core-win32-ia32-msvc@1.7.36': + optional: true + + '@swc/core-win32-x64-msvc@1.7.36': + optional: true + + '@swc/core@1.7.36(@swc/helpers@0.5.13)': + dependencies: + '@swc/counter': 0.1.3 + '@swc/types': 0.1.13 + optionalDependencies: + '@swc/core-darwin-arm64': 1.7.36 + '@swc/core-darwin-x64': 1.7.36 + '@swc/core-linux-arm-gnueabihf': 1.7.36 + '@swc/core-linux-arm64-gnu': 1.7.36 + '@swc/core-linux-arm64-musl': 1.7.36 + '@swc/core-linux-x64-gnu': 1.7.36 + '@swc/core-linux-x64-musl': 1.7.36 + '@swc/core-win32-arm64-msvc': 1.7.36 + '@swc/core-win32-ia32-msvc': 1.7.36 + '@swc/core-win32-x64-msvc': 1.7.36 + '@swc/helpers': 0.5.13 + + '@swc/counter@0.1.3': {} + + '@swc/helpers@0.5.13': + dependencies: + tslib: 2.8.0 + + '@swc/types@0.1.13': + dependencies: + '@swc/counter': 0.1.3 + + '@trysound/sax@0.2.0': {} + + '@types/body-parser@1.19.5': + dependencies: + '@types/connect': 3.4.38 + '@types/node': 22.7.7 + + '@types/connect@3.4.38': + dependencies: + '@types/node': 22.7.7 + + '@types/estree@1.0.6': {} + + '@types/express-serve-static-core@5.0.0': + dependencies: + '@types/node': 22.7.7 + '@types/qs': 6.9.16 + '@types/range-parser': 1.2.7 + '@types/send': 0.17.4 + + '@types/express-ws@3.0.5': + dependencies: + '@types/express': 5.0.0 + '@types/express-serve-static-core': 5.0.0 + '@types/ws': 8.5.12 + + '@types/express@5.0.0': + dependencies: + '@types/body-parser': 1.19.5 + '@types/express-serve-static-core': 5.0.0 + '@types/qs': 6.9.16 + '@types/serve-static': 1.15.7 + + '@types/http-errors@2.0.4': {} + + '@types/json-schema@7.0.15': {} + + '@types/mime@1.3.5': {} + + '@types/node@22.7.7': + dependencies: + undici-types: 6.19.8 + + '@types/qs@6.9.16': {} + + '@types/range-parser@1.2.7': {} + + '@types/semver@7.5.8': {} + + '@types/send@0.17.4': + dependencies: + '@types/mime': 1.3.5 + '@types/node': 22.7.7 + + '@types/serve-static@1.15.7': + dependencies: + '@types/http-errors': 2.0.4 + '@types/node': 22.7.7 + '@types/send': 0.17.4 + + '@types/uuid@10.0.0': {} + + '@types/ws@8.5.12': + dependencies: + '@types/node': 22.7.7 + + '@typescript-eslint/eslint-plugin@8.10.0(@typescript-eslint/parser@8.10.0(eslint@9.13.0)(typescript@5.6.3))(eslint@9.13.0)(typescript@5.6.3)': + dependencies: + '@eslint-community/regexpp': 4.11.1 + '@typescript-eslint/parser': 8.10.0(eslint@9.13.0)(typescript@5.6.3) + '@typescript-eslint/scope-manager': 8.10.0 + '@typescript-eslint/type-utils': 8.10.0(eslint@9.13.0)(typescript@5.6.3) + '@typescript-eslint/utils': 8.10.0(eslint@9.13.0)(typescript@5.6.3) + '@typescript-eslint/visitor-keys': 8.10.0 + eslint: 9.13.0 + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare: 1.4.0 + ts-api-utils: 1.3.0(typescript@5.6.3) + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.10.0(eslint@9.13.0)(typescript@5.6.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.10.0 + '@typescript-eslint/types': 8.10.0 + '@typescript-eslint/typescript-estree': 8.10.0(typescript@5.6.3) + '@typescript-eslint/visitor-keys': 8.10.0 + debug: 4.3.7(supports-color@5.5.0) + eslint: 9.13.0 + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.10.0': + dependencies: + '@typescript-eslint/types': 8.10.0 + '@typescript-eslint/visitor-keys': 8.10.0 + + '@typescript-eslint/type-utils@8.10.0(eslint@9.13.0)(typescript@5.6.3)': + dependencies: + '@typescript-eslint/typescript-estree': 8.10.0(typescript@5.6.3) + '@typescript-eslint/utils': 8.10.0(eslint@9.13.0)(typescript@5.6.3) + debug: 4.3.7(supports-color@5.5.0) + ts-api-utils: 1.3.0(typescript@5.6.3) + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - eslint + - supports-color + + '@typescript-eslint/types@8.10.0': {} + + '@typescript-eslint/typescript-estree@8.10.0(typescript@5.6.3)': + dependencies: + '@typescript-eslint/types': 8.10.0 + '@typescript-eslint/visitor-keys': 8.10.0 + debug: 4.3.7(supports-color@5.5.0) + fast-glob: 3.3.2 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.6.3 + ts-api-utils: 1.3.0(typescript@5.6.3) + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.10.0(eslint@9.13.0)(typescript@5.6.3)': + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@9.13.0) + '@typescript-eslint/scope-manager': 8.10.0 + '@typescript-eslint/types': 8.10.0 + '@typescript-eslint/typescript-estree': 8.10.0(typescript@5.6.3) + eslint: 9.13.0 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/visitor-keys@8.10.0': + dependencies: + '@typescript-eslint/types': 8.10.0 + eslint-visitor-keys: 3.4.3 + + abort-controller@3.0.0: + dependencies: + event-target-shim: 5.0.1 + + abortcontroller-polyfill@1.7.5: {} + + accepts@1.3.8: + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + + acorn-jsx@5.3.2(acorn@8.13.0): + dependencies: + acorn: 8.13.0 + + acorn@8.13.0: {} + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ansi-regex@5.0.1: {} + + ansi-styles@3.2.1: + dependencies: + color-convert: 1.9.3 + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + argparse@2.0.1: {} + + array-flatten@1.1.1: {} + + asynckit@0.4.0: {} + + atomic-sleep@1.0.0: {} + + axios@1.7.7: + dependencies: + follow-redirects: 1.15.9 + form-data: 4.0.1 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + balanced-match@1.0.2: {} + + base-x@3.0.10: + dependencies: + safe-buffer: 5.2.1 + + base64-js@1.5.1: {} + + binary-extensions@2.3.0: {} + + body-parser@1.20.3: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.13.0 + raw-body: 2.5.2 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + boolbase@1.0.0: {} + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.24.0: + dependencies: + caniuse-lite: 1.0.30001669 + electron-to-chromium: 1.5.41 + node-releases: 2.0.18 + update-browserslist-db: 1.1.1(browserslist@4.24.0) + + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + bytes@3.1.2: {} + + call-bind@1.0.7: + 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.2 + + callsites@3.1.0: {} + + caniuse-lite@1.0.30001669: {} + + chalk@2.4.2: + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chokidar@4.0.1: + dependencies: + readdirp: 4.0.2 + + chrome-trace-event@1.0.4: {} + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + clone@2.1.2: {} + + color-convert@1.9.3: + dependencies: + color-name: 1.1.3 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.3: {} + + color-name@1.1.4: {} + + colorette@2.0.20: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + commander@7.2.0: {} + + concat-map@0.0.1: {} + + concurrently@9.0.1: + 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 + + content-disposition@0.5.4: + dependencies: + safe-buffer: 5.2.1 + + content-type@1.0.5: {} + + cookie-signature@1.0.6: {} + + cookie@0.7.1: {} + + cosmiconfig@9.0.0(typescript@5.6.3): + dependencies: + env-paths: 2.2.1 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + parse-json: 5.2.0 + optionalDependencies: + typescript: 5.6.3 + + cross-spawn@7.0.3: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + css-select@4.3.0: + dependencies: + boolbase: 1.0.0 + css-what: 6.1.0 + domhandler: 4.3.1 + domutils: 2.8.0 + nth-check: 2.1.1 + + css-tree@1.1.3: + dependencies: + mdn-data: 2.0.14 + source-map: 0.6.1 + + css-what@6.1.0: {} + + csso@4.2.0: + dependencies: + css-tree: 1.1.3 + + dateformat@4.6.3: {} + + debug@2.6.9: + dependencies: + ms: 2.0.0 + + debug@4.3.7(supports-color@5.5.0): + dependencies: + ms: 2.1.3 + optionalDependencies: + supports-color: 5.5.0 + + deep-is@0.1.4: {} + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + + delayed-stream@1.0.0: {} + + depd@2.0.0: {} + + destroy@1.2.0: {} + + detect-libc@1.0.3: {} + + detect-libc@2.0.3: {} + + dom-serializer@1.4.1: + dependencies: + domelementtype: 2.3.0 + domhandler: 4.3.1 + entities: 2.2.0 + + domelementtype@2.3.0: {} + + domhandler@4.3.1: + dependencies: + domelementtype: 2.3.0 + + domutils@2.8.0: + dependencies: + dom-serializer: 1.4.1 + domelementtype: 2.3.0 + domhandler: 4.3.1 + + dotenv-expand@5.1.0: {} + + dotenv@7.0.0: {} + + ee-first@1.1.1: {} + + electron-to-chromium@1.5.41: {} + + emoji-regex@8.0.0: {} + + encodeurl@1.0.2: {} + + encodeurl@2.0.0: {} + + end-of-stream@1.4.4: + dependencies: + once: 1.4.0 + + entities@2.2.0: {} + + entities@3.0.1: {} + + env-paths@2.2.1: {} + + error-ex@1.3.2: + dependencies: + is-arrayish: 0.2.1 + + es-define-property@1.0.0: + dependencies: + get-intrinsic: 1.2.4 + + es-errors@1.3.0: {} + + escalade@3.2.0: {} + + escape-html@1.0.3: {} + + escape-string-regexp@1.0.5: {} + + escape-string-regexp@4.0.0: {} + + eslint-scope@8.1.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.1.0: {} + + eslint@9.13.0: + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@9.13.0) + '@eslint-community/regexpp': 4.11.1 + '@eslint/config-array': 0.18.0 + '@eslint/core': 0.7.0 + '@eslint/eslintrc': 3.1.0 + '@eslint/js': 9.13.0 + '@eslint/plugin-kit': 0.2.1 + '@humanfs/node': 0.16.5 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.3.1 + '@types/estree': 1.0.6 + '@types/json-schema': 7.0.15 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.7(supports-color@5.5.0) + escape-string-regexp: 4.0.0 + eslint-scope: 8.1.0 + eslint-visitor-keys: 4.1.0 + espree: 10.2.0 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + 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.4 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + + espree@10.2.0: + dependencies: + acorn: 8.13.0 + acorn-jsx: 5.3.2(acorn@8.13.0) + eslint-visitor-keys: 4.1.0 + + esquery@1.6.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + esutils@2.0.3: {} + + etag@1.8.1: {} + + event-target-shim@5.0.1: {} + + events@3.3.0: {} + + express-ws@5.0.2(express@4.21.1): + dependencies: + express: 4.21.1 + ws: 7.5.10 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + express@4.21.1: + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.3 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.7.1 + cookie-signature: 1.0.6 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.3.1 + fresh: 0.5.2 + http-errors: 2.0.0 + merge-descriptors: 1.0.3 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.10 + proxy-addr: 2.0.7 + qs: 6.13.0 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.19.0 + serve-static: 1.16.2 + setprototypeof: 1.2.0 + statuses: 2.0.1 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + fast-copy@3.0.2: {} + + fast-deep-equal@3.1.3: {} + + fast-glob@3.3.2: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fast-redact@3.5.0: {} + + fast-safe-stringify@2.1.1: {} + + fastq@1.17.1: + dependencies: + reusify: 1.0.4 + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + finalhandler@1.3.1: + dependencies: + debug: 2.6.9 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.1 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.3.1 + keyv: 4.5.4 + + flatted@3.3.1: {} + + follow-redirects@1.15.9: {} + + form-data@4.0.1: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + + forwarded@0.2.0: {} + + fresh@0.5.2: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + get-caller-file@2.0.5: {} + + get-intrinsic@1.2.4: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + + get-port@4.2.0: {} + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + globals@13.24.0: + dependencies: + type-fest: 0.20.2 + + globals@14.0.0: {} + + globals@15.11.0: {} + + gopd@1.0.1: + dependencies: + get-intrinsic: 1.2.4 + + graphemer@1.4.0: {} + + has-flag@3.0.0: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.0 + + has-proto@1.0.3: {} + + has-symbols@1.0.3: {} + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + help-me@5.0.0: {} + + htmlnano@2.1.1(svgo@2.8.0)(typescript@5.6.3): + dependencies: + cosmiconfig: 9.0.0(typescript@5.6.3) + posthtml: 0.16.6 + timsort: 0.3.0 + optionalDependencies: + svgo: 2.8.0 + transitivePeerDependencies: + - typescript + + htmlparser2@7.2.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 4.3.1 + domutils: 2.8.0 + entities: 3.0.1 + + http-errors@2.0.0: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.1 + toidentifier: 1.0.1 + + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + + ieee754@1.2.1: {} + + ignore-by-default@1.0.1: {} + + ignore@5.3.2: {} + + import-fresh@3.3.0: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + inherits@2.0.4: {} + + ipaddr.js@1.9.1: {} + + is-arrayish@0.2.1: {} + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-json@2.0.1: {} + + is-number@7.0.0: {} + + isexe@2.0.0: {} + + joycon@3.1.1: {} + + js-tokens@4.0.0: {} + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + json-buffer@3.0.1: {} + + json-parse-even-better-errors@2.3.1: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@2.2.3: {} + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lightningcss-darwin-arm64@1.27.0: + optional: true + + lightningcss-darwin-x64@1.27.0: + optional: true + + lightningcss-freebsd-x64@1.27.0: + optional: true + + lightningcss-linux-arm-gnueabihf@1.27.0: + optional: true + + lightningcss-linux-arm64-gnu@1.27.0: + optional: true + + lightningcss-linux-arm64-musl@1.27.0: + optional: true + + lightningcss-linux-x64-gnu@1.27.0: + optional: true + + lightningcss-linux-x64-musl@1.27.0: + optional: true + + lightningcss-win32-arm64-msvc@1.27.0: + optional: true + + lightningcss-win32-x64-msvc@1.27.0: + optional: true + + lightningcss@1.27.0: + dependencies: + detect-libc: 1.0.3 + optionalDependencies: + lightningcss-darwin-arm64: 1.27.0 + lightningcss-darwin-x64: 1.27.0 + lightningcss-freebsd-x64: 1.27.0 + lightningcss-linux-arm-gnueabihf: 1.27.0 + lightningcss-linux-arm64-gnu: 1.27.0 + lightningcss-linux-arm64-musl: 1.27.0 + lightningcss-linux-x64-gnu: 1.27.0 + lightningcss-linux-x64-musl: 1.27.0 + lightningcss-win32-arm64-msvc: 1.27.0 + lightningcss-win32-x64-msvc: 1.27.0 + + lines-and-columns@1.2.4: {} + + lmdb@2.8.5: + dependencies: + msgpackr: 1.11.0 + node-addon-api: 6.1.0 + node-gyp-build-optional-packages: 5.1.1 + ordered-binary: 1.5.2 + weak-lru-cache: 1.2.2 + optionalDependencies: + '@lmdb/lmdb-darwin-arm64': 2.8.5 + '@lmdb/lmdb-darwin-x64': 2.8.5 + '@lmdb/lmdb-linux-arm': 2.8.5 + '@lmdb/lmdb-linux-arm64': 2.8.5 + '@lmdb/lmdb-linux-x64': 2.8.5 + '@lmdb/lmdb-win32-x64': 2.8.5 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} + + lodash@4.17.21: {} + + mdn-data@2.0.14: {} + + media-typer@0.3.0: {} + + merge-descriptors@1.0.3: {} + + merge2@1.4.1: {} + + methods@1.1.2: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mime@1.6.0: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + minimist@1.2.8: {} + + ms@2.0.0: {} + + ms@2.1.3: {} + + msgpackr-extract@3.0.3: + dependencies: + node-gyp-build-optional-packages: 5.2.2 + optionalDependencies: + '@msgpackr-extract/msgpackr-extract-darwin-arm64': 3.0.3 + '@msgpackr-extract/msgpackr-extract-darwin-x64': 3.0.3 + '@msgpackr-extract/msgpackr-extract-linux-arm': 3.0.3 + '@msgpackr-extract/msgpackr-extract-linux-arm64': 3.0.3 + '@msgpackr-extract/msgpackr-extract-linux-x64': 3.0.3 + '@msgpackr-extract/msgpackr-extract-win32-x64': 3.0.3 + optional: true + + msgpackr@1.11.0: + optionalDependencies: + msgpackr-extract: 3.0.3 + + natural-compare@1.4.0: {} + + negotiator@0.6.3: {} + + node-addon-api@6.1.0: {} + + node-addon-api@7.1.1: {} + + node-gyp-build-optional-packages@5.1.1: + dependencies: + detect-libc: 2.0.3 + + node-gyp-build-optional-packages@5.2.2: + dependencies: + detect-libc: 2.0.3 + optional: true + + node-releases@2.0.18: {} + + nodemon@3.1.7: + dependencies: + chokidar: 3.6.0 + debug: 4.3.7(supports-color@5.5.0) + ignore-by-default: 1.0.1 + minimatch: 3.1.2 + pstree.remy: 1.1.8 + semver: 7.6.3 + simple-update-notifier: 2.0.0 + supports-color: 5.5.0 + touch: 3.1.1 + undefsafe: 2.0.5 + + normalize-path@3.0.0: {} + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + nullthrows@1.1.1: {} + + object-inspect@1.13.2: {} + + on-exit-leak-free@2.1.2: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + ordered-binary@1.5.2: {} + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + parcel@2.12.0(@swc/helpers@0.5.13)(typescript@5.6.3): + dependencies: + '@parcel/config-default': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))(@swc/helpers@0.5.13)(typescript@5.6.3) + '@parcel/core': 2.12.0(@swc/helpers@0.5.13) + '@parcel/diagnostic': 2.12.0 + '@parcel/events': 2.12.0 + '@parcel/fs': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))(@swc/helpers@0.5.13) + '@parcel/logger': 2.12.0 + '@parcel/package-manager': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))(@swc/helpers@0.5.13) + '@parcel/reporter-cli': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/reporter-dev-server': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/reporter-tracer': 2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13)) + '@parcel/utils': 2.12.0 + chalk: 4.1.2 + commander: 7.2.0 + get-port: 4.2.0 + transitivePeerDependencies: + - '@swc/helpers' + - cssnano + - postcss + - purgecss + - relateurl + - srcset + - terser + - typescript + - uncss + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse-json@5.2.0: + dependencies: + '@babel/code-frame': 7.25.7 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + + parseurl@1.3.3: {} + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + path-to-regexp@0.1.10: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + pino-abstract-transport@2.0.0: + dependencies: + split2: 4.2.0 + + pino-pretty@11.3.0: + dependencies: + colorette: 2.0.20 + dateformat: 4.6.3 + fast-copy: 3.0.2 + fast-safe-stringify: 2.1.1 + help-me: 5.0.0 + joycon: 3.1.1 + minimist: 1.2.8 + on-exit-leak-free: 2.1.2 + pino-abstract-transport: 2.0.0 + pump: 3.0.2 + readable-stream: 4.5.2 + secure-json-parse: 2.7.0 + sonic-boom: 4.2.0 + strip-json-comments: 3.1.1 + + pino-std-serializers@7.0.0: {} + + pino@9.5.0: + dependencies: + atomic-sleep: 1.0.0 + fast-redact: 3.5.0 + on-exit-leak-free: 2.1.2 + pino-abstract-transport: 2.0.0 + pino-std-serializers: 7.0.0 + process-warning: 4.0.0 + quick-format-unescaped: 4.0.4 + real-require: 0.2.0 + safe-stable-stringify: 2.5.0 + sonic-boom: 4.2.0 + thread-stream: 3.1.0 + + postcss-value-parser@4.2.0: {} + + posthtml-parser@0.10.2: + dependencies: + htmlparser2: 7.2.0 + + posthtml-parser@0.11.0: + dependencies: + htmlparser2: 7.2.0 + + posthtml-render@3.0.0: + dependencies: + is-json: 2.0.1 + + posthtml@0.16.6: + dependencies: + posthtml-parser: 0.11.0 + posthtml-render: 3.0.0 + + prelude-ls@1.2.1: {} + + prettier@3.3.3: {} + + process-warning@4.0.0: {} + + process@0.11.10: {} + + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + proxy-from-env@1.1.0: {} + + pstree.remy@1.1.8: {} + + pump@3.0.2: + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + + punycode@2.3.1: {} + + qs@6.13.0: + dependencies: + side-channel: 1.0.6 + + queue-microtask@1.2.3: {} + + quick-format-unescaped@4.0.4: {} + + range-parser@1.2.1: {} + + raw-body@2.5.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + + react-error-overlay@6.0.9: {} + + react-refresh@0.9.0: {} + + readable-stream@4.5.2: + dependencies: + abort-controller: 3.0.0 + buffer: 6.0.3 + events: 3.3.0 + process: 0.11.10 + string_decoder: 1.3.0 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + readdirp@4.0.2: {} + + real-require@0.2.0: {} + + regenerator-runtime@0.13.11: {} + + require-directory@2.1.1: {} + + resolve-from@4.0.0: {} + + reusify@1.0.4: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + rxjs@7.8.1: + dependencies: + tslib: 2.8.0 + + safe-buffer@5.2.1: {} + + safe-stable-stringify@2.5.0: {} + + safer-buffer@2.1.2: {} + + secure-json-parse@2.7.0: {} + + semver@7.6.3: {} + + send@0.19.0: + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.0 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + + serve-static@1.16.2: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.19.0 + transitivePeerDependencies: + - supports-color + + set-function-length@1.2.2: + 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 + + setprototypeof@1.2.0: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + shell-quote@1.8.1: {} + + side-channel@1.0.6: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + object-inspect: 1.13.2 + + simple-update-notifier@2.0.0: + dependencies: + semver: 7.6.3 + + sonic-boom@4.2.0: + dependencies: + atomic-sleep: 1.0.0 + + source-map@0.6.1: {} + + split2@4.2.0: {} + + srcset@4.0.0: {} + + stable@0.1.8: {} + + statuses@2.0.1: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-json-comments@3.1.1: {} + + supports-color@5.5.0: + dependencies: + has-flag: 3.0.0 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + + svgo@2.8.0: + dependencies: + '@trysound/sax': 0.2.0 + commander: 7.2.0 + css-select: 4.3.0 + css-tree: 1.1.3 + csso: 4.2.0 + picocolors: 1.1.1 + stable: 0.1.8 + + term-size@2.2.1: {} + + text-table@0.2.0: {} + + thread-stream@3.1.0: + dependencies: + real-require: 0.2.0 + + timsort@0.3.0: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + toidentifier@1.0.1: {} + + touch@3.1.1: {} + + tree-kill@1.2.2: {} + + ts-api-utils@1.3.0(typescript@5.6.3): + dependencies: + typescript: 5.6.3 + + tslib@2.8.0: {} + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + type-fest@0.20.2: {} + + type-is@1.6.18: + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + + typescript-eslint@8.10.0(eslint@9.13.0)(typescript@5.6.3): + dependencies: + '@typescript-eslint/eslint-plugin': 8.10.0(@typescript-eslint/parser@8.10.0(eslint@9.13.0)(typescript@5.6.3))(eslint@9.13.0)(typescript@5.6.3) + '@typescript-eslint/parser': 8.10.0(eslint@9.13.0)(typescript@5.6.3) + '@typescript-eslint/utils': 8.10.0(eslint@9.13.0)(typescript@5.6.3) + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - eslint + - supports-color + + typescript@5.6.3: {} + + undefsafe@2.0.5: {} + + undici-types@6.19.8: {} + + unpipe@1.0.0: {} + + update-browserslist-db@1.1.1(browserslist@4.24.0): + dependencies: + browserslist: 4.24.0 + escalade: 3.2.0 + picocolors: 1.1.1 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + utility-types@3.11.0: {} + + utils-merge@1.0.1: {} + + uuid@10.0.0: {} + + vary@1.1.2: {} + + weak-lru-cache@1.2.2: {} + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + word-wrap@1.2.5: {} + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrappy@1.0.2: {} + + ws@7.5.10: {} + + y18n@5.0.8: {} + + yargs-parser@21.1.1: {} + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + yocto-queue@0.1.0: {} diff --git a/src/PluginManager.ts b/src/PluginManager.ts new file mode 100644 index 0000000..45be6e1 --- /dev/null +++ b/src/PluginManager.ts @@ -0,0 +1,222 @@ +import * as fs from 'fs'; +import * as path from 'path'; +import * as semver from 'semver'; +import chokidar from 'chokidar'; + +import { Logger, SimpleEventBus } from './TypeHelper'; +import { SimpleServerPlugin } from '@board-bound/sdk'; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type ServerPlugin = SimpleServerPlugin; + +export interface LoadedPlugin { + file: string; + plugin: ServerPlugin; + enabled: boolean; + config?: Record; +} + +export class PluginManager { + private readonly configDir = path.resolve(process.env.CONFIG_DIR || './config'); + private readonly pluginDir = path.resolve(process.env.PLUGIN_DIR || './plugins'); + private readonly watchedFiles = new Set(); + private plugins: LoadedPlugin[] = []; + + constructor( + private readonly log: Logger, + private readonly bus: SimpleEventBus, + private readonly serverVersion: string, + ) { + log.debug('Started plugin manager'); + if (!fs.existsSync(this.pluginDir)) fs.mkdirSync(this.pluginDir); + log.debug('Plugin directory is ' + this.pluginDir); + if (!fs.existsSync(this.configDir)) fs.mkdirSync(this.configDir); + log.debug('Config directory is ' + this.configDir); + } + + async unloadPlugin(plugin: string|LoadedPlugin) { + const p = typeof plugin === 'string' ? this.plugins.find((x) => x.plugin.name === plugin) : plugin; + if (!p) { + this.log.warn(`Cannot unload plugin ${plugin} because it is not loaded`); + return; + } + this.log.debug('Unloading plugin ' + p.plugin.name); + if (p.enabled) await this.disablePlugin(p); + this.plugins = this.plugins.filter((x) => x.plugin.name !== p.plugin.name); + this.log.info({ + tag: 'plugin-unloaded', + plugin: p.plugin.name, + }, 'Unloaded plugin ' + p.plugin.name); + } + + async reloadPlugin(plugin: string|LoadedPlugin) { + const p = typeof plugin === 'string' ? this.plugins.find((x) => x.plugin.name === plugin) : plugin; + if (!p) { + this.log.warn(`Cannot reload plugin ${plugin} because it is not loaded`); + return; + } + this.log.debug('Reloading plugin ' + p.plugin.name); + this.unloadPlugin(p); + await this.loadPlugin(p.file); + await this.enablePlugin(p.plugin.name); + } + + private watchFile(file: string) { + if ((process.env.PLUGIN_WATCH || '').toLowerCase() !== 'true') return; + if (this.watchedFiles.has(file)) return; + this.watchedFiles.add(file); + const watcher = chokidar.watch(file); + let timeout: NodeJS.Timeout; + watcher.on('change', async () => { + if (timeout) clearTimeout(timeout); + timeout = setTimeout(async () => { + this.log.info(`Plugin ${file} changed, reloading`); + const p = this.plugins.find((x) => x.file === file); + if (p) this.reloadPlugin(p); + else this.loadPlugin(file); + }, 2500); + }); + } + + async loadPlugin(file: string) { + if (!file.endsWith('.js') && !file.endsWith('.cjs')) { + this.log.warn('Skipping ' + file + ' because it is not a .js or .cjs file'); + } + this.log.debug('Loading plugin ' + file); + this.watchFile(file); + const plugin = (await import(file)).default.default as ServerPlugin; + let invalid = false; + for (const k of ['name', 'version', 'author', 'serverVersion']) { + if (!plugin[k]) { + this.log.error('Plugin ' + file + ' is missing ' + k); + invalid = true; + } + } + if (invalid) return; + if (this.plugins.find((x) => x.plugin.name === plugin.name)) { + this.log.warn('Plugin ' + plugin.name + ' is already loaded, are there duplicates?'); + return; + } + this.log.info({ + tag: 'plugin-loaded', + plugin: plugin.name, + version: plugin.version, + }, 'Loaded plugin ' + plugin.name + ' v' + plugin.version + ' by ' + plugin.author); + const configFile = path.join(this.configDir, plugin.name + '.json'); + let config = plugin.defaultConfig; + if (fs.existsSync(configFile)) { + try { + config = JSON.parse(fs.readFileSync(configFile, 'utf8')); + this.log.debug('Loaded config for ' + plugin.name); + } catch (e: unknown) { + this.log.warn('Failed to load config for ' + plugin.name); + this.log.error(e); + } + } else if (config) { + this.log.info('Writing default config for ' + plugin.name); + fs.writeFileSync(configFile, JSON.stringify(plugin.defaultConfig, null, 2) + '\n'); + } + this.plugins.push({ file, plugin, config, enabled: false }); + } + + async loadPlugins() { + this.log.debug('Reading plugin directory'); + const files = fs.readdirSync(this.pluginDir).map((f) => path.join(this.pluginDir, f)); + files.push(...(process.env.PLUGIN_LOAD_DIRECT || '').split(',').map((f) => path.resolve(f))); + this.log.info('Found ' + files.length + ' plugins'); + for (const f of files) { + await this.loadPlugin(f); + } + } + + async enablePlugin(plugin: string|LoadedPlugin) { + const p = typeof plugin === 'string' ? this.plugins.find((x) => x.plugin.name === plugin) : plugin; + if (!p) { + this.log.warn(`Cannot enable plugin ${plugin} because it is not loaded`); + return; + } + if (p.enabled) { + this.log.warn(`Plugin ${p.plugin.name} is already enabled`); + return; + } + this.log.debug('Enabling plugin ' + p.plugin.name); + if (!semver.satisfies(this.serverVersion, p.plugin.serverVersion)) { + this.log.warn('Plugin ' + p.plugin.name + ' requires server version ' + p.plugin.serverVersion); + return; + } + let unmetDependencies = false; + if (p.plugin.dependencies) for (const d of Object.keys(p.plugin.dependencies)) { + const target = this.plugins.find((x) => x.plugin.name === d); + const data = { + tag: 'incompatible-dependency', + plugin: p.plugin.name, + required: d, + requiredVersion: p.plugin.dependencies[d], + targetVersion: (target ? target.plugin : {}).version, + }; + if (!target) { + this.log.warn(data, `Plugin ${data.plugin} requires ${data.required} but it is not loaded`); + unmetDependencies = true; + continue; + } + if (!semver.satisfies(target.plugin.version, p.plugin.dependencies[d])) { + this.log.warn(data, `Plugin ${data.plugin} requires ${data.required} ${data.requiredVersion} but ${data.targetVersion} is loaded`); + unmetDependencies = true; + continue; + } + if (!target.enabled) { + this.log.warn(data, `Plugin ${data.plugin} requires ${data.required} but it is not enabled`); + unmetDependencies = true; + continue; + } + } + if (unmetDependencies) return; + for (const e of p.plugin.events) this.bus.on(e.eventName, e.listener, e.priority); + if (p.plugin.onEnable) await p.plugin.onEnable(p.config, this.bus, this.log.child({ plugin: p.plugin.name })); + this.plugins = this.plugins.map((x) => x.file === p.file ? { ...x, enabled: true } : x); + this.log.info({ + tag: 'plugin-enabled', + plugin: p.plugin.name, + }, `Enabled plugin ${p.plugin.name} successfully`); + } + + async enablePlugins() { + const plugins = Array.of(...this.plugins).sort((a, b) => { + if (a.plugin.dependencies && a.plugin.dependencies[b.plugin.name]) return -1; + if (b.plugin.dependencies && b.plugin.dependencies[a.plugin.name]) return 1; + return 0; + }); + for (const p of plugins) { + if (p.enabled) continue; + await this.enablePlugin(p); + } + } + + async disablePlugin(plugin: string|LoadedPlugin) { + const p = typeof plugin === 'string' ? this.plugins.find((x) => x.plugin.name === plugin) : plugin; + if (!p) { + this.log.warn(`Cannot disable plugin ${plugin} because it is not loaded`); + return; + } + if (!p.enabled) { + this.log.warn(`Plugin ${p.plugin.name} is already disabled`); + return; + } + this.log.debug('Disabling plugin ' + p.plugin.name); + for (const e of p.plugin.events) this.bus.off(e.eventName, e.listener); + if (p.plugin.onDisable) await p.plugin.onDisable(this.bus, this.log.child({ plugin: p.plugin.name })); + this.plugins = this.plugins.map((x) => x.file === p.file ? { ...x, enabled: false } : x); + this.log.info({ + tag: 'plugin-disabled', + plugin: p.plugin.name, + }, 'Disabled plugin ' + p.plugin.name); + } + + async disablePlugins() { + const plugins = Array.of(...this.plugins).reverse(); + for (const p of plugins) { + if (!p.enabled) continue; + await this.disablePlugin(p); + } + } +} diff --git a/src/TypeHelper.ts b/src/TypeHelper.ts new file mode 100644 index 0000000..a2f4dcc --- /dev/null +++ b/src/TypeHelper.ts @@ -0,0 +1,10 @@ +import { BaseEventMap, BaseGameState, BaseGameStateTypes, EventBus } from "@board-bound/sdk"; +import type pino from "pino"; + +export type Logger = pino.Logger; + +export type SimpleEventBus = EventBus>; + +export function getNewEventBus() { + return new EventBus>(); +} diff --git a/src/handler/StatusHandler.ts b/src/handler/StatusHandler.ts new file mode 100644 index 0000000..2db5286 --- /dev/null +++ b/src/handler/StatusHandler.ts @@ -0,0 +1,14 @@ +import type { Application } from "express-ws"; +import { GameServer } from ".."; +import { SimpleEventBus } from "../TypeHelper"; +import { ModifiableData } from "@board-bound/sdk"; + +export function installStatusHandler(app: Application, server: GameServer, bus: SimpleEventBus) { + app.get("/status", async (req, res) => { + server.getLogger().info("Status check from " + req.ip); + const response = new ModifiableData({ status: "ok" }); + const success = await bus.emit("serverStatusRequest", server, { ip: req.ip, response }) + if (!success) res.status(560).json({ error: "Request canceled" }); + else res.json(response.get()); + }); +} diff --git a/src/handler/WsHandler.ts b/src/handler/WsHandler.ts new file mode 100644 index 0000000..a1e0054 --- /dev/null +++ b/src/handler/WsHandler.ts @@ -0,0 +1,128 @@ +import type { Application } from "express-ws"; +import type { WebSocket } from "ws"; +import { GameServer } from ".."; +import { SimpleEventBus } from "../TypeHelper"; +import { LOGO } from "../tools/LogoProvider"; + +import { ConnectedUser, ModifiableData } from "@board-bound/sdk"; + +export class WsConnectedUser extends ConnectedUser { + constructor( + public readonly id: string, + public readonly name: string, + public readonly ip: string, + private readonly server: GameServer, + private readonly ws: WebSocket, + private readonly bus: SimpleEventBus, + ) { + super(id, name, ip); + } + + async sendMessage(message: Record): Promise { + const data = new ModifiableData(message); + const res = await this.bus.emit('serverUserRawOutput', this.server, { user: this, message: data }); + if (!res) return; + this.server.getLogger().debug({ tag: 'ws-send', message: data.get(), id: this.id, ip: this.ip }, 'Sending message to user'); + this.ws.send(JSON.stringify(data.get())); + } + + async disconnect(message: string, code?: number): Promise { + const msg = code ? { error: message, code } : { message }; + this.sendMessage(msg); + this.ws.close(code ? 1008 : 1000); + await this.bus.emit('serverUserDisconnect', this.server, { user: this, message, code }); + } +} + +export function installWsHandler(app: Application, server: GameServer, bus: SimpleEventBus) { + const maxConnectionsPerIp = parseInt(process.env.MAX_CONNECTIONS_PER_IP || '10') || 10; + const maxConnectionsDifIp = parseInt(process.env.MAX_CONNECTIONS_DIF_IP || '100') || 100; + const connections = new Map(); + app.ws("/play", async (ws, req) => { + const ip = req.socket.remoteAddress; + const id = server.getUuid(); + const log = server.getLogger().child({tag: 'ws', ip, id}); + const send = (msg: Record) => ws.send(JSON.stringify(msg)); + + if (connections.has(ip)) { + const count = connections.get(ip) + 1; + if (count > maxConnectionsPerIp) { + log.warn('Too many connections from this IP'); + send({error: 'Too many connections from this IP', code: 429}); + ws.close(1008); + return; + } + connections.set(ip, count); + } else { + if (connections.size > maxConnectionsDifIp) { + log.warn('Too many different IPs connected'); + send({error: 'Too many different IPs connected', code: 429}); + ws.close(1008); + return; + } + connections.set(ip, 1); + } + + log.info('Received connection, awaiting login payload'); + const loginTimeout = setTimeout(() => { + log.warn('Login timeout reached, closing connection'); + send({ error: 'Login timeout reached', code: 408 }); + ws.close(1008); + }, 5000); + let loggedIn = false; + + // We send the logo to the client to display it. + // This is simple way to ensure the server protocol isn't + // reverse-engineered to publish it with a different license, + // as the logo is a trademark and copyrighted. + // Don't tamper with the logo, or clients will refuse to connect. + send({ message: 'Please login', code: 401, logo: LOGO }); + + ws.on('close', async () => { + const user = server.getConnectedUsers().find(u => u.id === id); + if (user) server.removeConnectedUser(user); + if (!loggedIn) clearTimeout(loginTimeout); + const count = connections.get(ip) - 1; + if (count <= 0) connections.delete(ip); + else connections.set(ip, count); + log.info('Websocket connection closed'); + }); + + ws.on('message', async (msg) => { + log.debug({ tag: 'ws-message', message: msg }, 'Received message from client'); + let payload: Record = {}; + try { + payload = JSON.parse(msg.toString()); + } catch { + log.warn('Invalid JSON payload received'); + send({ error: 'Invalid JSON payload', code: 400 }); + return; + } + if (!loggedIn) { + clearTimeout(loginTimeout); + const name = new ModifiableData(''); + loggedIn = await bus.emit('serverUserPreConnect', server, { + ip: req.socket.remoteAddress, + headers: req.headers as Record, + payload, + name, + }); + if (!loggedIn) { + log.warn('Preconnect event canceled connection'); + send({ error: 'Connection denied', code: 403 }); + ws.close(1008); + } else { + send({ message: 'Connected', code: 200 }); + const user = new WsConnectedUser(id, name.get(), ip, server, ws, bus); + server.addConnectedUser(user); + await bus.emit('serverUserConnect', server, user); + log.info('User connected successfully'); + } + return; + } + const user = server.getConnectedUsers().find(u => u.id === id); + const result = await bus.emit('serverUserRawInput', server, {user, payload}); + if (!result) send({error: 'Invalid input', code: 400}); + }); + }); +} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..ae0fb1b --- /dev/null +++ b/src/index.ts @@ -0,0 +1,64 @@ +import express from 'express'; +import expressWs from 'express-ws'; +import semver from 'semver'; +import pino from 'pino'; +import axios from 'axios'; + +import { ServerBase, BaseGameState, BaseGameStateTypes } from '@board-bound/sdk'; +import { v4 as uuidV4 } from 'uuid'; + +import { version as pVersion } from '../package.json'; + +import { getNewEventBus } from './TypeHelper'; +import { findFreePort } from './tools/PortFinder'; +import { installStatusHandler } from './handler/StatusHandler'; +import { installWsHandler } from './handler/WsHandler'; +import { PluginManager } from './PluginManager'; +import { getLocalIPAddress, getAllLocalIPAddresses, getPublicIPAddress } from './tools/IpFinder'; + +export class GameServer extends ServerBase> { + readonly version = pVersion; + private readonly ws = expressWs(express()); + private readonly bus = getNewEventBus(); + private readonly plugins: PluginManager; + protected readonly logger = pino(); + protected readonly uuid = uuidV4; + protected readonly semver = semver; + protected readonly axios = axios; + + constructor() { + super(); + this.logger.level = process.env.LOG_LEVEL || 'info'; + this.logger.info('Starting server with version ' + this.version); + this.plugins = new PluginManager(this.logger, this.bus, this.version); + this.start(); + } + + async start() { + await this.plugins.loadPlugins(); + await this.plugins.enablePlugins(); + this.logger.debug('Installing status handler'); + installStatusHandler(this.ws.app, this, this.bus); + this.logger.debug('Installing ws handler'); + installWsHandler(this.ws.app, this, this.bus); + this.logger.debug('Finding free port'); + const port = await findFreePort(this.logger); + this.logger.debug('Starting server on port ' + port); + this.ws.app.listen(port, '0.0.0.0', async () => { + const ips = getAllLocalIPAddresses(); + const publicIp = await getPublicIPAddress(); + const localIp = getLocalIPAddress(); + const data = { ips, localIp, publicIp, port }; + this.logger.info(`Server listening on port ${port}`); + this.logger.debug(data, 'IP information'); + this.bus.emit('serverAcceptingConnections', this, data); + }); + } + + async setGameState(gameState: BaseGameState): Promise { + super.setGameState(gameState); + await this.bus.emit('serverGameStateUpdate', this, null); + } +} + +new GameServer(); diff --git a/src/tools/IpFinder.ts b/src/tools/IpFinder.ts new file mode 100644 index 0000000..038e153 --- /dev/null +++ b/src/tools/IpFinder.ts @@ -0,0 +1,51 @@ +import os from 'os'; +import axios from 'axios'; + +export function getAllLocalIPAddresses(): string[] { + const interfaces = os.networkInterfaces(); + const addresses: string[] = []; + + for (const name in interfaces) { + const iface = interfaces[name]; + if (!iface) continue; + + for (const alias of iface) { + if (alias.family !== 'IPv4' || alias.internal) continue; + addresses.push(alias.address); + } + } + + return addresses; +} + +export function getLocalIPAddress(): string | null { + const interfaces = os.networkInterfaces(); + + for (const name in interfaces) { + const iface = interfaces[name]; + if (!iface) continue; + + for (const alias of iface) { + if (alias.family === 'IPv4' && !alias.internal) { + return alias.address; + } + } + } + + return null; +} + +export async function getPublicIPAddress(): Promise { + try { + const response = await axios.get('https://api.ipify.org', { + params: { format: 'json' }, + }); + + const ip = response.data?.ip; + if (!ip) throw new Error('Invalid response from IP service.'); + + return ip; + } catch (error) { + throw new Error(`Error fetching public IP address: ${error.message}`); + } +} diff --git a/src/tools/LogoProvider.ts b/src/tools/LogoProvider.ts new file mode 100644 index 0000000..06a318a --- /dev/null +++ b/src/tools/LogoProvider.ts @@ -0,0 +1,407 @@ +export const LOGO = ` +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 +KzAwOjAwFwhlkwAAAABJRU5ErkJggg== +`; diff --git a/src/tools/PortFinder.ts b/src/tools/PortFinder.ts new file mode 100644 index 0000000..25cb46a --- /dev/null +++ b/src/tools/PortFinder.ts @@ -0,0 +1,34 @@ +import * as net from 'net'; +import { Logger } from '../TypeHelper'; + +export async function isPortFree(port: number) { + return new Promise((resolve, reject) => { + const server = net.createServer(); + server.on('error', (err) => { + if (err.message.includes('EADDRINUSE')) { + resolve(false); + } else { + reject(err); + } + }); + server.listen(port, 'localhost', () => { + server.close(() => { + resolve(true); + }); + }); + }); +} + +export async function findFreePort(log: Logger) { + if (process.env.PORT) return parseInt(process.env.PORT) || 3000; + const range = [20_000, 30_000]; + let port = 0; + let counter = 0; + do { + counter++; + if (counter > 50) throw new Error('Could not find a free port'); + port = Math.floor(Math.random() * (range[1] - range[0])) + range[0]; + log.debug('Trying port ' + port); + } while (!await isPortFree(port)); + return port; +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..435e76a --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "experimentalDecorators": true, + "resolveJsonModule": true, + "target": "ESNext", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "paths": { + "gameSdk": ["../sdk/src/index.ts"] + } + } +}