From eb7670ed8f47e54dc7fec8ac1107b9a74d53a351 Mon Sep 17 00:00:00 2001 From: Hugo C <911307+hugocaillard@users.noreply.github.com> Date: Fri, 11 Aug 2023 18:04:18 +0200 Subject: [PATCH] feat: initialize clarinet-sdk with the core js lib (#1068) * feat: initialize clarinet-sdk with the test-core js lib * fix: clarity value arguments deserialisation * chore: version 0.0.4 * feat: clarity-sdk: get contracts interfaces * fat: implement get_data_var and get_map_entry * refactor: lint * chore: switch to webpack and handme esm * fix: rename cargo.toml to Cargo.toml * chore: handle cjs and esm * refactor: update components/clarinet-sdk/src/utils.rs Co-authored-by: Micaiah Reid * refactor: improve exports and address reviews * docs: update readme.md * docs: udpate readme.md --------- Co-authored-by: Micaiah Reid --- Cargo.lock | 17 + Cargo.toml | 1 + components/clarinet-deployments/src/types.rs | 1 + .../clarinet-files/src/wasm_fs_accessor.rs | 8 +- components/clarinet-sdk/.gitignore | 3 + components/clarinet-sdk/Cargo.toml | 76 + components/clarinet-sdk/README.md | 43 + .../clarinet-sdk/clarinet-sdk.code-workspace | 17 + components/clarinet-sdk/package-lock.json | 2555 +++++++++++++++++ components/clarinet-sdk/package.json | 50 + .../clarinet-sdk/src-ts/contractInterface.ts | 68 + components/clarinet-sdk/src-ts/index.ts | 119 + components/clarinet-sdk/src-ts/vfs.ts | 67 + components/clarinet-sdk/src/core.rs | 552 ++++ components/clarinet-sdk/src/lib.rs | 3 + components/clarinet-sdk/src/utils.rs | 223 ++ components/clarinet-sdk/tsconfig.base.json | 24 + components/clarinet-sdk/tsconfig.cjs.json | 8 + components/clarinet-sdk/tsconfig.esm.json | 8 + components/clarinet-sdk/webpack.config.dev.js | 46 + components/clarinet-sdk/webpack.config.js | 91 + .../src/analysis/ast_dependency_detector.rs | 2 +- .../clarity-repl/src/analysis/coverage.rs | 4 +- .../src/analysis/coverage_tests.rs | 2 +- .../clarity-repl/src/repl/interpreter.rs | 23 +- components/clarity-repl/src/repl/session.rs | 41 +- rust-toolchain | 2 +- 27 files changed, 4005 insertions(+), 49 deletions(-) create mode 100644 components/clarinet-sdk/.gitignore create mode 100644 components/clarinet-sdk/Cargo.toml create mode 100644 components/clarinet-sdk/README.md create mode 100644 components/clarinet-sdk/clarinet-sdk.code-workspace create mode 100644 components/clarinet-sdk/package-lock.json create mode 100644 components/clarinet-sdk/package.json create mode 100644 components/clarinet-sdk/src-ts/contractInterface.ts create mode 100644 components/clarinet-sdk/src-ts/index.ts create mode 100644 components/clarinet-sdk/src-ts/vfs.ts create mode 100644 components/clarinet-sdk/src/core.rs create mode 100644 components/clarinet-sdk/src/lib.rs create mode 100644 components/clarinet-sdk/src/utils.rs create mode 100644 components/clarinet-sdk/tsconfig.base.json create mode 100644 components/clarinet-sdk/tsconfig.cjs.json create mode 100644 components/clarinet-sdk/tsconfig.esm.json create mode 100644 components/clarinet-sdk/webpack.config.dev.js create mode 100644 components/clarinet-sdk/webpack.config.js diff --git a/Cargo.lock b/Cargo.lock index 32e5a82d3..37f8e46ad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -934,6 +934,23 @@ dependencies = [ "wasm-bindgen-futures", ] +[[package]] +name = "clarinet-sdk" +version = "0.0.1" +dependencies = [ + "clarinet-deployments", + "clarinet-files", + "clarity-repl 1.7.1", + "console_error_panic_hook", + "js-sys", + "serde", + "serde-wasm-bindgen", + "serde_json", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "clarinet-utils" version = "1.0.0" diff --git a/Cargo.toml b/Cargo.toml index c3a522a7d..88f5816f5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ members = [ "components/clarinet-deployments", "components/clarinet-files", "components/clarinet-utils", + "components/clarinet-sdk", "components/clarity-jupyter-kernel", "components/clarity-lsp", "components/clarity-repl", diff --git a/components/clarinet-deployments/src/types.rs b/components/clarinet-deployments/src/types.rs index ff7f19907..2f2fe5b2a 100644 --- a/components/clarinet-deployments/src/types.rs +++ b/components/clarinet-deployments/src/types.rs @@ -62,6 +62,7 @@ impl Into for EpochSpec { } } +#[derive(Debug, Clone)] pub struct DeploymentGenerationArtifacts { pub asts: BTreeMap, pub deps: BTreeMap, diff --git a/components/clarinet-files/src/wasm_fs_accessor.rs b/components/clarinet-files/src/wasm_fs_accessor.rs index 5f23578cb..49b3e9d08 100644 --- a/components/clarinet-files/src/wasm_fs_accessor.rs +++ b/components/clarinet-files/src/wasm_fs_accessor.rs @@ -23,12 +23,12 @@ struct WFSWriteRequest<'a> { } pub struct WASMFileSystemAccessor { - client_request_tx: JsFunction, + client_request: JsFunction, } impl WASMFileSystemAccessor { - pub fn new(client_request_tx: JsFunction) -> WASMFileSystemAccessor { - WASMFileSystemAccessor { client_request_tx } + pub fn new(client_request: JsFunction) -> WASMFileSystemAccessor { + WASMFileSystemAccessor { client_request } } fn get_request_promise( @@ -36,7 +36,7 @@ impl WASMFileSystemAccessor { action: String, data: &T, ) -> FileAccessorResult { - let request_promise = self.client_request_tx.call2( + let request_promise = self.client_request.call2( &JsValue::NULL, &JsValue::from(action), &encode_to_js(data).unwrap(), diff --git a/components/clarinet-sdk/.gitignore b/components/clarinet-sdk/.gitignore new file mode 100644 index 000000000..6580309a5 --- /dev/null +++ b/components/clarinet-sdk/.gitignore @@ -0,0 +1,3 @@ +dist/ +src-ts/sdk +node_modules/ diff --git a/components/clarinet-sdk/Cargo.toml b/components/clarinet-sdk/Cargo.toml new file mode 100644 index 000000000..169599996 --- /dev/null +++ b/components/clarinet-sdk/Cargo.toml @@ -0,0 +1,76 @@ +[package] +edition = "2021" +name = "clarinet-sdk" +version = "0.0.1" + +[lib] +crate-type = ["cdylib"] +name = "clarinet_sdk" +path = "src/lib.rs" + +[dependencies] +serde = { version = "1.0.136", features = ["derive"] } +serde_json = "1.0" +clarinet-files = { path = "../clarinet-files", default-features = false } +clarity-repl = { path = "../clarity-repl", default-features = false, optional = true } +clarinet-deployments = { path = "../clarinet-deployments", default-features = false } +# WASM +console_error_panic_hook = { version = "0.1", optional = true } +js-sys = { version = "0.3", optional = true } +serde-wasm-bindgen = { version = "0.5", optional = true } +wasm-bindgen = { version = "0.2", optional = true } +wasm-bindgen-futures = { version = "0.4", optional = true } +web-sys = { version = "0.3", features = ["console"], optional = true } + +[features] +default = ["wasm"] +wasm = [ + "wasm-bindgen", + "wasm-bindgen-futures", + "serde-wasm-bindgen", + "js-sys", + "web-sys", + "console_error_panic_hook", + "clarinet-deployments/wasm", + "clarity-repl/wasm", + "clarinet-files/wasm", +] + +# DEV +[profile.dev] +inherits = "release" +opt-level = 3 +debug = false +debug-assertions = false +incremental = false +codegen-units = 256 + +[profile.dev.build-override] +inherits = "release" +opt-level = 3 + +[package.metadata.wasm-pack.profile.dev] +wasm-opt = false + +[package.metadata.wasm-pack.profile.dev.wasm-bindgen] +debug-js-glue = false +demangle-name-section = true +dwarf-debug-info = false + +# RELEASE +[profile.release] +opt-level = 3 +debug = false +debug-assertions = false +lto = true +incremental = false +codegen-units = 16 + +[package.metadata.wasm-pack.profile.release] +wasm-opt = false +# wasm-opt = ['-O1'] + +[package.metadata.wasm-pack.profile.release.wasm-bindgen] +debug-js-glue = false +demangle-name-section = true +dwarf-debug-info = false diff --git a/components/clarinet-sdk/README.md b/components/clarinet-sdk/README.md new file mode 100644 index 000000000..12eabeab3 --- /dev/null +++ b/components/clarinet-sdk/README.md @@ -0,0 +1,43 @@ +# Clarinet SDK + +## Core + +### Usage + +```ts +import { Cl } from "@stacks/transactions"; +import { initVM } from "obscurity-sdk"; + +async function main() { + const vm = await initVM(); + const accounts = vm.getAccounts(); + const w1 = accounts.get("wallet_1"); + if (!w1) return; + + const call = vm.callPublicFn("counter", "increment", [Cl.uint(1)], w1); + console.log(call.result); // Cl.int(Cl.ok(true)) + + const counter = vm.getDataVar("counter", "counter"); + console.log(counter); // Cl.int(2) +} + +main(); +``` + +## Contributing + +Clone the clarinet repo adn switch to the sdk component +``` +git clone git@github.com:hirosystems/clarinet.git +cd clarinet/components/clarinet-sdk +``` + +Open the SDK workspace in VSCode: +``` +code ./clarinet-sdk.code-workspace +``` + +Compile the project (both WASM and JS): +``` +npm run build +``` diff --git a/components/clarinet-sdk/clarinet-sdk.code-workspace b/components/clarinet-sdk/clarinet-sdk.code-workspace new file mode 100644 index 000000000..f3508125d --- /dev/null +++ b/components/clarinet-sdk/clarinet-sdk.code-workspace @@ -0,0 +1,17 @@ +{ + "folders": [{ "path": "../../" }], + "settings": { + // "rust-analyzer.checkOnSave.command": "clippy -p clarinet-sdk -- --no-deps", + // "rust-analyzer.check.command": "check", + "rust-analyzer.check.overrideCommand": [ + "cargo", + "clippy", + "--no-default-features", + "--package=clarinet-sdk", + "--features=wasm", + "--message-format=json", + "--", + "--no-deps" + ] + } +} diff --git a/components/clarinet-sdk/package-lock.json b/components/clarinet-sdk/package-lock.json new file mode 100644 index 000000000..02584958a --- /dev/null +++ b/components/clarinet-sdk/package-lock.json @@ -0,0 +1,2555 @@ +{ + "name": "obscurity-sdk", + "version": "0.3.5", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "obscurity-sdk", + "version": "0.3.5", + "license": "GPL-3.0", + "dependencies": { + "@stacks/transactions": "^6.5.4" + }, + "devDependencies": { + "@types/node": "^20.4.5", + "@wasm-tool/wasm-pack-plugin": "^1.7.0", + "copy-webpack-plugin": "^11.0.0", + "rimraf": "^5.0.1", + "ts-loader": "^9.4.4", + "typescript": "^5.1.6", + "webpack": "^5.88.2", + "webpack-cli": "^5.1.4" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", + "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@noble/hashes": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.1.5.tgz", + "integrity": "sha512-LTMZiiLc+V4v1Yi16TD6aX2gmtKszNye0pQgbaLqkvhIqP7nVsSaJsWloGQjJfJ8offaoP5GtX3yY5swbcJxxQ==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@noble/secp256k1": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.7.1.tgz", + "integrity": "sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@stacks/common": { + "version": "6.5.5", + "resolved": "https://registry.npmjs.org/@stacks/common/-/common-6.5.5.tgz", + "integrity": "sha512-6v2AVHTTryvl1Govu5rmBXLywAyen2fU3doMCx/7Lk/tFLc4OjMEx4uf1wzpPx1zw/fwJnvoz74OrT/RSALDYw==", + "dependencies": { + "@types/bn.js": "^5.1.0", + "@types/node": "^18.0.4" + } + }, + "node_modules/@stacks/common/node_modules/@types/node": { + "version": "18.17.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.17.2.tgz", + "integrity": "sha512-wBo3KqP/PBqje5TI9UTiuL3yWfP6sdPtjtygSOqcYZWT232dfDeDOnkDps5wqZBP9NgGgYrNejinl0faAuE+HQ==" + }, + "node_modules/@stacks/network": { + "version": "6.5.5", + "resolved": "https://registry.npmjs.org/@stacks/network/-/network-6.5.5.tgz", + "integrity": "sha512-lw7+g6UhOpvWasMeRYMb2OGRKm9ptYkGt27Usg3Eo0z/pu20jZxvHXLBMdDQqxNQOOmwiG4FadICnwTlmnHaqw==", + "dependencies": { + "@stacks/common": "^6.5.5", + "cross-fetch": "^3.1.5" + } + }, + "node_modules/@stacks/transactions": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@stacks/transactions/-/transactions-6.7.0.tgz", + "integrity": "sha512-M/SxSkKk78cTa7hLxq36YcN+NnnSanvKgINfXnQGTL31dzvH3UfQbRzPZHEkjPRRN82E9XC0scu6Kpwq+qVbtA==", + "dependencies": { + "@noble/hashes": "1.1.5", + "@noble/secp256k1": "1.7.1", + "@stacks/common": "^6.5.5", + "@stacks/network": "^6.5.5", + "c32check": "^2.0.0", + "lodash.clonedeep": "^4.5.0" + } + }, + "node_modules/@types/bn.js": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.1.tgz", + "integrity": "sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/eslint": { + "version": "8.44.2", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.2.tgz", + "integrity": "sha512-sdPRb9K6iL5XZOmBubg8yiFp5yS/JdUDQsq5e6h95km91MCYMuvp7mh1fjPEYUhvHepKpZOjnEaMBR4PxjWDzg==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", + "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", + "dev": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", + "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", + "dev": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", + "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.4.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.7.tgz", + "integrity": "sha512-bUBrPjEry2QUTsnuEjzjbS7voGWCc30W0qzgMf90GPeDGFRakvrz47ju+oqDAKCXLUCe39u57/ORMl/O/04/9g==" + }, + "node_modules/@wasm-tool/wasm-pack-plugin": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@wasm-tool/wasm-pack-plugin/-/wasm-pack-plugin-1.7.0.tgz", + "integrity": "sha512-WikzYsw7nTd5CZxH75h7NxM/FLJAgqfWt+/gk3EL3wYKxiIlpMIYPja+sHQl3ARiicIYy4BDfxkbAVjRYlouTA==", + "dev": true, + "dependencies": { + "chalk": "^2.4.1", + "command-exists": "^1.2.7", + "watchpack": "^2.1.1", + "which": "^2.0.2" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", + "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", + "dev": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", + "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "dev": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", + "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "dev": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "dev": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "dev": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", + "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-opt": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6", + "@webassemblyjs/wast-printer": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", + "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", + "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", + "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", + "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webpack-cli/configtest": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", + "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/info": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", + "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/serve": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", + "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + }, + "peerDependenciesMeta": { + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-assertions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "dev": true, + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base-x": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.0.tgz", + "integrity": "sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==" + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.21.10", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz", + "integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001517", + "electron-to-chromium": "^1.4.477", + "node-releases": "^2.0.13", + "update-browserslist-db": "^1.0.11" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/c32check": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/c32check/-/c32check-2.0.0.tgz", + "integrity": "sha512-rpwfAcS/CMqo0oCqDf3r9eeLgScRE3l/xHDCXhM3UyrfvIn7PrLq63uHh7yYbv8NzaZn5MVsVhIRpQ+5GZ5HyA==", + "dependencies": { + "@noble/hashes": "^1.1.2", + "base-x": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001519", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001519.tgz", + "integrity": "sha512-0QHgqR+Jv4bxHMp8kZ1Kn8CH55OikjKJ6JmKkZYP1F3D7w+lnFXF70nG5eNfsZS89jadi5Ywy5UCSKLAglIRkg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/clone-deep/node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/command-exists": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", + "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", + "dev": true + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/copy-webpack-plugin": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz", + "integrity": "sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==", + "dev": true, + "dependencies": { + "fast-glob": "^3.2.11", + "glob-parent": "^6.0.1", + "globby": "^13.1.1", + "normalize-path": "^3.0.0", + "schema-utils": "^4.0.0", + "serialize-javascript": "^6.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/copy-webpack-plugin/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/copy-webpack-plugin/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/copy-webpack-plugin/node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/cross-fetch": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", + "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", + "dependencies": { + "node-fetch": "^2.6.12" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "node_modules/electron-to-chromium": { + "version": "1.4.488", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.488.tgz", + "integrity": "sha512-Dv4sTjiW7t/UWGL+H8ZkgIjtUAVZDgb/PwGWvMsCT7jipzUV/u5skbLXPFKb6iV0tiddVi/bcS2/kUrczeWgIQ==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/enhanced-resolve": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", + "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/envinfo": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.10.0.tgz", + "integrity": "sha512-ZtUjZO6l5mwTHvc1L9+1q5p/R3wTopcfqMW8r5t8SJSKqeVI/LtajORwRFEKpEFuekjD0VBjwu1HMxL4UalIRw==", + "dev": true, + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.0.tgz", + "integrity": "sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA==", + "dev": true + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true, + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/glob": { + "version": "10.3.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.3.tgz", + "integrity": "sha512-92vPiMb/iqpmEgsOoIDvTjc50wf9CCCvMzsi6W0JLPeUKE8TWP1a73PgqSrqy7iAZxaSD1YdzU7QZR5LF51MJw==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.0.3", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "node_modules/globby": { + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", + "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", + "dev": true, + "dependencies": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.3.0", + "ignore": "^5.2.4", + "merge2": "^1.4.1", + "slash": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/is-core-module": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", + "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jackspeak": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.2.2.tgz", + "integrity": "sha512-mgNtVv4vUuaKA97yxUHoA3+FkuhtxkjdXEWOyB/N76fjy0FjezEt34oy3epBtvCvS+7DyKwqCFWx/oJLV5+kCg==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true, + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==" + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.2.tgz", + "integrity": "sha512-eL79dXrE1q9dBbDCLg7xfn/vl7MS4F1gvJAgjJrQli/jbQWdUttuVawphqpffoIYfRdq78LHx6GP4bU/EQ2ATA==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/node-fetch": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz", + "integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-releases": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", + "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dev": true, + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.0.tgz", + "integrity": "sha512-svTf/fzsKHffP42sujkO/Rjs37BCIsQVRCeNYIm9WN8rgT7ffoUnRtZCqU+6BqcSBdv8gwJeTz8knJpgACeQMw==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dev": true, + "dependencies": { + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", + "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", + "dev": true, + "dependencies": { + "is-core-module": "^2.11.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.1.tgz", + "integrity": "sha512-OfFZdwtd3lZ+XZzYP/6gTACubwFcHdLRqS9UX3UwpU2dnGQYkPFISRwvM3w9IiB2w7bW5qGo/uAwE4SmXXSKvg==", + "dev": true, + "dependencies": { + "glob": "^10.2.5" + }, + "bin": { + "rimraf": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", + "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser": { + "version": "5.19.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.19.2.tgz", + "integrity": "sha512-qC5+dmecKJA4cpYxRa5aVkKehYsQKc+AHeKl0Oe62aYjBL8ZA33tTljktDHJSaxxMnbI5ZYw+o/S2DxxLu8OfA==", + "dev": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.9", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", + "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.17", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.16.8" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/ts-loader": { + "version": "9.4.4", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.4.tgz", + "integrity": "sha512-MLukxDHBl8OJ5Dk3y69IsKVFRA/6MwzEqBgh+OXMPB/OD01KQuWPFd1WAQP8a5PeSCAxfnkhiuWqfmFJzJQt9w==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "typescript": "*", + "webpack": "^5.0.0" + } + }, + "node_modules/ts-loader/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ts-loader/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/ts-loader/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/ts-loader/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/ts-loader/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/typescript": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", + "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", + "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/watchpack": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", + "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "dev": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/webpack": { + "version": "5.88.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz", + "integrity": "sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==", + "dev": true, + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.0", + "@webassemblyjs/ast": "^1.11.5", + "@webassemblyjs/wasm-edit": "^1.11.5", + "@webassemblyjs/wasm-parser": "^1.11.5", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.9.0", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.15.0", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.9", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.7", + "watchpack": "^2.4.0", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-cli": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", + "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", + "dev": true, + "dependencies": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^2.1.1", + "@webpack-cli/info": "^2.0.2", + "@webpack-cli/serve": "^2.0.5", + "colorette": "^2.0.14", + "commander": "^10.0.1", + "cross-spawn": "^7.0.3", + "envinfo": "^7.7.3", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", + "webpack-merge": "^5.7.3" + }, + "bin": { + "webpack-cli": "bin/cli.js" + }, + "engines": { + "node": ">=14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "5.x.x" + }, + "peerDependenciesMeta": { + "@webpack-cli/generators": { + "optional": true + }, + "webpack-bundle-analyzer": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/webpack-cli/node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, + "node_modules/webpack-cli/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/webpack-merge": { + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.9.0.tgz", + "integrity": "sha512-6NbRQw4+Sy50vYNTw7EyOn41OZItPiXB8GNv3INSoe3PSFaHJEz3SHTrYVaRm2LilNGnFUzh0FAwqPEmU/CwDg==", + "dev": true, + "dependencies": { + "clone-deep": "^4.0.1", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } +} diff --git a/components/clarinet-sdk/package.json b/components/clarinet-sdk/package.json new file mode 100644 index 000000000..5505f7f53 --- /dev/null +++ b/components/clarinet-sdk/package.json @@ -0,0 +1,50 @@ +{ + "name": "obscurity-sdk", + "version": "0.3.5", + "description": "clarity testing lib", + "repository": { + "type": "git", + "url": "https://github.com/hirosystems/clarinet" + }, + "files": [ + "dist" + ], + "main": "dist/cjs/index.js", + "module": "dist/esm/index.mjs", + "types": "./dist/esm/index.d.ts", + "exports": { + ".": { + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.mjs" + }, + "require": { + "types": "./dist/cjs/index.d.ts", + "default": "./dist/cjs/index.js" + } + } + }, + "scripts": { + "clean": "rimraf dist", + "dev-ts": "npm run build; webpack -c webpack.config.dev.js", + "build": "npm run clean; webpack -c webpack.config.js", + "prepare": "npm run build" + }, + "keywords": [], + "author": "hirosystems", + "license": "GPL-3.0", + "readme": "./README.md", + "dependencies": { + "@stacks/transactions": "^6.5.4" + }, + "devDependencies": { + "@types/node": "^20.4.5", + "@wasm-tool/wasm-pack-plugin": "^1.7.0", + "copy-webpack-plugin": "^11.0.0", + "rimraf": "^5.0.1", + "ts-loader": "^9.4.4", + "typescript": "^5.1.6", + "webpack": "^5.88.2", + "webpack-cli": "^5.1.4" + } +} diff --git a/components/clarinet-sdk/src-ts/contractInterface.ts b/components/clarinet-sdk/src-ts/contractInterface.ts new file mode 100644 index 000000000..449ce7f88 --- /dev/null +++ b/components/clarinet-sdk/src-ts/contractInterface.ts @@ -0,0 +1,68 @@ +export type ContractInterfaceFunctionAccess = "private" | "public" | "read_only"; + +export type ContractInterfaceTupleEntryType = { name: string; type: ContractInterfaceAtomType }; + +export type ContractInterfaceAtomType = + | "none" + | "int128" + | "uint128" + | "bool" + | "principal" + | { buffer: { length: number } } + | { "string-utf8": { length: number } } + | { "string-ascii": { length: number } } + | { tuple: ContractInterfaceTupleEntryType[] } + | { optional: ContractInterfaceAtomType } + | { response: { ok: ContractInterfaceAtomType; error: ContractInterfaceAtomType } } + | { list: { type: ContractInterfaceAtomType; length: number } } + | "trait_reference"; + +export type ContractInterfaceFunctionArg = { name: string; type: ContractInterfaceAtomType }; + +export type ContractInterfaceFunctionOutput = { type: ContractInterfaceAtomType }; + +export type ContractInterfaceFunction = { + name: string; + access: ContractInterfaceFunctionAccess; + args: ContractInterfaceFunctionArg[]; + outputs: ContractInterfaceFunctionOutput; +}; + +export type ContractInterfaceVariableAccess = "constant" | "variable"; + +export type ContractInterfaceVariable = { + name: string; + type: ContractInterfaceAtomType; + access: ContractInterfaceVariableAccess; +}; + +export type ContractInterfaceMap = { + name: string; + key: ContractInterfaceAtomType; + value: ContractInterfaceAtomType; +}; + +export type ContractInterfaceFungibleTokens = { name: string }; + +export type ContractInterfaceNonFungibleTokens = { name: string; type: ContractInterfaceAtomType }; + +export type StacksEpochId = + | "Epoch10" + | "Epoch20" + | "Epoch2_05" + | "Epoch21" + | "Epoch22" + | "Epoch23" + | "Epoch24"; + +export type ClarityVersion = "Clarity1" | "Clarity2"; + +export type ContractInterface = { + functions: ContractInterfaceFunction[]; + variables: ContractInterfaceVariable[]; + maps: ContractInterfaceMap[]; + fungible_tokens: ContractInterfaceFungibleTokens[]; + non_fungible_tokens: ContractInterfaceNonFungibleTokens[]; + epoch: StacksEpochId; + clarity_version: ClarityVersion; +}; diff --git a/components/clarinet-sdk/src-ts/index.ts b/components/clarinet-sdk/src-ts/index.ts new file mode 100644 index 000000000..4d2175815 --- /dev/null +++ b/components/clarinet-sdk/src-ts/index.ts @@ -0,0 +1,119 @@ +import { Cl, ClarityValue } from "@stacks/transactions"; + +import { vfs } from "./vfs"; +import type { ContractInterface } from "./contractInterface"; + +import type { SDK } from "./sdk"; +type WASMModule = typeof import("./sdk"); +const wasmModule = import("./sdk"); + +type CallFn = ( + contract: string, + method: string, + args: ClarityValue[], + sender: string +) => { + result: ClarityValue; + events: { event: string; data: { [key: string]: any } }[]; +}; +type GetDataVar = (contract: string, dataVar: string) => ClarityValue; +type GetMapEntry = (contract: string, mapName: string, mapKey: ClarityValue) => ClarityValue; +type GetAssetsMap = () => Map>; +type GetAccounts = () => Map; + +// because the session is wrapped in a proxy the types need to be hardcoded +export type ClarityVM = { + [K in keyof SDK]: K extends "callReadOnlyFn" | "callPublicFn" + ? CallFn + : K extends "getDataVar" + ? GetDataVar + : K extends "getMapEntry" + ? GetMapEntry + : K extends "getAccounts" + ? GetAccounts + : K extends "getAssetsMap" + ? GetAssetsMap + : K extends "getContractsInterfaces" + ? () => Map + : SDK[K]; +}; + +const getSessionProxy = (wasm: WASMModule) => ({ + get(session: SDK, prop: keyof SDK, receiver: any) { + // some of the WASM methods are proxied here to: + // - serialize clarity values input argument + // - desizeialize output into clarity values + + if (prop === "callReadOnlyFn" || prop === "callPublicFn") { + const callFn: CallFn = (contract, method, args, sender) => { + const response = session[prop]( + new wasm.CallContractArgs( + contract, + method, + args.map((a) => Cl.serialize(a)) + ), + sender + ); + const result = Cl.deserialize(response.result); + + const events = response.events.map((e: { event: string; data: Map }) => { + return { + event: e.event, + data: Object.fromEntries(e.data.entries()), + }; + }); + + return { result, events }; + }; + + return callFn; + } + + if (prop === "getDataVar") { + const getDataVar: GetDataVar = (...args) => { + const response = session.getDataVar(...args); + const result = Cl.deserialize(response); + return result; + }; + return getDataVar; + } + + if (prop === "getMapEntry") { + const getMapEntry: GetMapEntry = (contract, mapName, mapKey) => { + const response = session.getMapEntry(contract, mapName, Cl.serialize(mapKey)); + const result = Cl.deserialize(response); + return result; + }; + return getMapEntry; + } + + return Reflect.get(session, prop, receiver); + }, +}); + +// load wasm only once and memoize it +function memoizedInit() { + let vm: ClarityVM | null = null; + return async (manifestPath = "./Clarinet.toml") => { + const module = await wasmModule; + + // handle both CJS and ESM context + // - in CJS: `module.default` is a promise resolving + // - in ESM: `module` is directly the + // @ts-ignore + let wasm: WASMModule = + typeof module.default === "undefined" + ? (module as unknown as WASMModule) + : await module.default; + + if (!vm) { + console.log("init clarity vm"); + vm = new Proxy(new wasm.SDK(vfs), getSessionProxy(wasm)) as unknown as ClarityVM; + } + // start a new session + await vm.initSession(process.cwd(), manifestPath); + return vm; + }; +} + +export const initVM = memoizedInit(); diff --git a/components/clarinet-sdk/src-ts/vfs.ts b/components/clarinet-sdk/src-ts/vfs.ts new file mode 100644 index 000000000..543e74dbb --- /dev/null +++ b/components/clarinet-sdk/src-ts/vfs.ts @@ -0,0 +1,67 @@ +import * as fs from "node:fs/promises"; + +function fileArrayToString(bufferArray: Uint8Array) { + return Array.from(bufferArray) + .map((item) => String.fromCharCode(item)) + .join(""); +} + +function isValidReadEvent(e: any): e is { path: string } { + return typeof e?.path === "string"; +} + +function isValidReadManyEvent(e: any): e is { paths: string[] } { + return Array.isArray(e?.paths) && e.paths.every((s: unknown) => typeof s === "string"); +} + +function isValidWriteEvent(e: any): e is { path: string; content: number[] } { + return typeof e?.path === "string" && Array.isArray(e?.content); +} + +async function exists(event: unknown) { + if (!isValidReadEvent(event)) throw new Error("invalid read event"); + try { + await fs.stat(event.path); + return true; + } catch { + return false; + } +} + +async function readFile(event: unknown) { + if (!isValidReadEvent(event)) throw new Error("invalid read event"); + return fileArrayToString(await fs.readFile(event.path)); +} + +async function readFiles(event: any) { + if (!isValidReadManyEvent(event)) throw new Error("invalid read event"); + const files = await Promise.all( + event.paths.map(async (p) => { + try { + return fs.readFile(p); + } catch (err) { + console.warn(err); + return null; + } + }) + ); + return Object.fromEntries( + files.reduce((acc, f, i) => { + if (f === null) return acc; + return acc.concat([[event.paths[i], fileArrayToString(f)]]); + }, [] as [string, string][]) + ); +} + +async function writeFile(event: unknown) { + if (!isValidWriteEvent(event)) throw new Error("invalid write event"); + return fs.writeFile(event.path, Uint8Array.from(event.content)); +} + +export function vfs(action: string, data: unknown) { + if (action === "vfs/exists") return exists(data); + if (action === "vfs/readFile") return readFile(data); + if (action === "vfs/readFiles") return readFiles(data); + if (action === "vfs/writeFile") return writeFile(data); + throw new Error("invalid vfs action"); +} diff --git a/components/clarinet-sdk/src/core.rs b/components/clarinet-sdk/src/core.rs new file mode 100644 index 000000000..5b544978a --- /dev/null +++ b/components/clarinet-sdk/src/core.rs @@ -0,0 +1,552 @@ +use clarinet_deployments::types::{DeploymentGenerationArtifacts, DeploymentSpecification}; +use clarinet_deployments::{ + generate_default_deployment, initiate_session_from_deployment, + update_session_with_contracts_executions, update_session_with_genesis_accounts, +}; +use clarinet_files::chainhook_types::StacksNetwork; +use clarinet_files::{FileAccessor, FileLocation, ProjectManifest, WASMFileSystemAccessor}; +use clarity_repl::analysis::coverage::CoverageReporter; +use clarity_repl::clarity::analysis::contract_interface_builder::{ + build_contract_interface, ContractInterface, ContractInterfaceFunction, + ContractInterfaceFunctionAccess, +}; +use clarity_repl::clarity::stacks_common::types::StacksEpochId; +use clarity_repl::clarity::vm::types::QualifiedContractIdentifier; +use clarity_repl::clarity::{EvaluationResult, ExecutionResult}; +use clarity_repl::repl::{ + ClarityCodeSource, ClarityContract, ContractDeployer, Session, DEFAULT_CLARITY_VERSION, + DEFAULT_EPOCH, +}; +use js_sys::Function as JsFunction; +use serde::Deserialize; +use serde_wasm_bindgen::to_value as encode_to_js; +use std::collections::HashMap; +use std::{panic, path::PathBuf}; +use wasm_bindgen::prelude::*; +use wasm_bindgen::JsValue; + +use crate::utils::{self, serialize_event, uint8_to_string, uint8_to_value}; + +#[derive(Debug, Deserialize)] +#[wasm_bindgen] +pub struct CallContractArgs { + contract: String, + method: String, + args: Vec>, +} + +#[wasm_bindgen] +impl CallContractArgs { + #[wasm_bindgen(constructor)] + pub fn new(contract: String, method: String, args: Vec) -> Self { + Self { + contract, + method, + args: args.iter().map(|a| a.to_vec()).collect::>>(), + } + } +} + +#[derive(Debug, Deserialize)] +#[wasm_bindgen] +pub struct DeployContractArgs { + name: String, + content: String, +} + +#[wasm_bindgen] +impl DeployContractArgs { + #[wasm_bindgen(constructor)] + pub fn new(name: String, content: String) -> Self { + Self { name, content } + } +} + +#[derive(Debug, Deserialize)] +#[wasm_bindgen] +pub struct TransferSTXArgs { + amount: u64, + recipient: String, +} + +#[wasm_bindgen] +impl TransferSTXArgs { + #[wasm_bindgen(constructor)] + pub fn new(amount: u64, recipient: String) -> Self { + Self { amount, recipient } + } +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +#[wasm_bindgen] +pub struct TxArgs { + call_contract: Option, + deploy_contract: Option, + transfer_stx: Option, + sender: String, +} + +macro_rules! log { + ( $( $t:tt )* ) => { + web_sys::console::log_1(&format!( $( $t )* ).into()); + } +} + +#[wasm_bindgen(getter_with_clone)] +pub struct TransactionRes { + pub result: String, + pub events: js_sys::Array, +} + +#[wasm_bindgen(getter_with_clone)] +pub struct SessionReport { + pub coverage: String, +} + +pub fn execution_result_to_transaction_res(execution: &ExecutionResult) -> TransactionRes { + let result = match &execution.result { + EvaluationResult::Snippet(result) => utils::to_raw_value(&result.result), + _ => unreachable!("Contract value from snippet"), + }; + let events = js_sys::Array::new_with_length(execution.events.len() as u32); + for (i, event) in execution.events.iter().enumerate() { + events.set(i as u32, encode_to_js(&serialize_event(event)).unwrap()) + } + + TransactionRes { result, events } +} + +#[wasm_bindgen(getter_with_clone)] +pub struct SDK { + pub deployer: String, + file_accessor: Box, + session: Option, + accounts: HashMap, + contracts_locations: HashMap, + contracts_interfaces: HashMap, + cache: Option<(DeploymentSpecification, DeploymentGenerationArtifacts)>, +} + +#[wasm_bindgen] +impl SDK { + #[wasm_bindgen(constructor)] + pub fn new(fs_request: JsFunction) -> Self { + panic::set_hook(Box::new(console_error_panic_hook::hook)); + + let fs = Box::new(WASMFileSystemAccessor::new(fs_request)); + Self { + deployer: String::new(), + file_accessor: fs, + session: None, + accounts: HashMap::new(), + contracts_locations: HashMap::new(), + contracts_interfaces: HashMap::new(), + cache: None, + } + } + + #[wasm_bindgen(js_name=initSession)] + pub async fn init_session( + &mut self, + root: String, + manifest_path: String, + ) -> Result<(), String> { + let mut root_path = PathBuf::new(); + root_path.push(root); + let project_root = FileLocation::FileSystem { path: root_path }; + let manifest_location = FileLocation::try_parse(&manifest_path, Some(&project_root)) + .ok_or("failed to parse manifest location")?; + let manifest = + ProjectManifest::from_file_accessor(&manifest_location, &self.file_accessor).await?; + + let (deployment, artifacts) = match &self.cache { + Some(cache) => cache.clone(), + None => { + let cache = generate_default_deployment( + &manifest, + &StacksNetwork::Simnet, + false, + Some(&self.file_accessor), + Some(StacksEpochId::Epoch21), + ) + .await?; + self.cache = Some(cache.clone()); + cache + } + }; + + let mut session = initiate_session_from_deployment(&manifest); + + if let Some(ref spec) = deployment.genesis { + for wallet in spec.wallets.iter() { + if wallet.name == "deployer" { + self.deployer = wallet.address.to_string(); + } + self.accounts + .insert(wallet.name.clone(), wallet.address.to_string()); + } + } + + update_session_with_genesis_accounts(&mut session, &deployment); + let results = update_session_with_contracts_executions( + &mut session, + &deployment, + Some(&artifacts.asts), + false, + Some(StacksEpochId::Epoch21), + ); + + for (contract_id, (_, location)) in deployment.contracts { + self.contracts_locations + .insert(contract_id, location.clone()); + } + + for (contract_id, result) in results.into_iter() { + match result { + Ok(execution) => { + if let EvaluationResult::Contract(contract_result) = execution.result { + let interface = + build_contract_interface(&contract_result.contract.analysis); + self.contracts_interfaces.insert(contract_id, interface); + }; + } + Err(e) => { + log!("unable to load deployment: {:}", e[0].message); + std::process::exit(1); + } + } + } + + self.session = Some(session); + Ok(()) + } + + fn get_session(&self) -> &Session { + self.session + .as_ref() + .expect("Session not initialised. Call initSession() first") + } + + fn get_session_mut(&mut self) -> &mut Session { + self.session + .as_mut() + .expect("Session not initialised. Call initSession() first") + } + + #[wasm_bindgen(getter, js_name=blockHeight)] + pub fn block_height(&mut self) -> u32 { + let session = self.get_session_mut(); + session.interpreter.get_block_height() + } + + #[wasm_bindgen(js_name=getContractsInterfaces)] + pub fn get_contracts_interfaces(&self) -> Result { + Ok(encode_to_js(&self.contracts_interfaces)?) + } + + #[wasm_bindgen(js_name=getAssetsMap)] + pub fn get_assets_maps(&self) -> Result { + let session = &self.get_session(); + let assets_maps = session.get_assets_maps(); + Ok(encode_to_js(&assets_maps)?) + } + + #[wasm_bindgen(js_name=getAccounts)] + pub fn get_accounts(&mut self) -> Result { + Ok(encode_to_js(&self.accounts)?) + } + + #[wasm_bindgen(js_name=getDataVar)] + pub fn get_data_var(&mut self, contract: &str, var_name: &str) -> Result { + let contract_id = if contract.starts_with('S') { + contract.to_string() + } else { + format!("{}.{}", self.deployer, contract,) + }; + let contract_id = + QualifiedContractIdentifier::parse(&contract_id).map_err(|e| e.to_string())?; + + let session = self.get_session_mut(); + session + .interpreter + .get_data_var(&contract_id, var_name) + .ok_or("value not found".into()) + } + + #[wasm_bindgen(js_name=getMapEntry)] + pub fn get_map_entry( + &mut self, + contract: &str, + map_name: &str, + map_key: Vec, + ) -> Result { + let contract_id = if contract.starts_with('S') { + contract.to_string() + } else { + format!("{}.{}", self.deployer, contract,) + }; + let contract_id = + QualifiedContractIdentifier::parse(&contract_id).map_err(|e| e.to_string())?; + + let session = self.get_session_mut(); + session + .interpreter + .get_map_entry(&contract_id, map_name, &uint8_to_value(&map_key)) + .ok_or("value not found".into()) + } + + fn get_function_interface( + &self, + contract: &str, + method: &str, + ) -> Result<&ContractInterfaceFunction, String> { + let contract_id = + QualifiedContractIdentifier::parse(&format!("{}.{}", self.deployer, contract)) + .map_err(|e| e.to_string())?; + let contract_interface = self + .contracts_interfaces + .get(&contract_id) + .ok_or("unable to get contract interface")?; + + contract_interface + .functions + .iter() + .find(|func| func.name == method) + .ok_or(format!("contract {contract} has no function {method}")) + } + + fn invoke_contract_call( + &mut self, + call_contract_args: &CallContractArgs, + sender: &str, + test_name: &str, + ) -> Result { + let CallContractArgs { + contract, + method, + args, + } = call_contract_args; + + let clarity_args: Vec = args.iter().map(|a| uint8_to_string(a)).collect(); + + let session = self.get_session_mut(); + let (execution, _) = match session.invoke_contract_call( + contract, + method, + &clarity_args, + sender, + test_name.into(), + ) { + Ok(res) => res, + Err(diagnostics) => { + let mut message = format!( + "{}: {}::{}({})", + "Contract call error", + contract, + method, + clarity_args.join(", ") + ); + if let Some(diag) = diagnostics.last() { + message = format!("{} -> {}", message, diag.message); + } + log!("message: {}", message); + return Err(message); + } + }; + + Ok(execution_result_to_transaction_res(&execution)) + } + + #[wasm_bindgen(js_name=callReadOnlyFn)] + pub fn call_read_only_fn( + &mut self, + args: &CallContractArgs, + sender: &str, + ) -> Result { + let interface = self.get_function_interface(&args.contract, &args.method)?; + if interface.access != ContractInterfaceFunctionAccess::read_only { + return Err(format!("{} is not a read-only function", &args.method)); + } + + self.invoke_contract_call(args, sender, "read-only call") + } + + fn call_public_fn_private( + &mut self, + args: &CallContractArgs, + sender: &str, + advance_chain_tip: bool, + ) -> Result { + let interface = self.get_function_interface(&args.contract, &args.method)?; + if interface.access != ContractInterfaceFunctionAccess::public { + return Err(format!("{} is not a public function", &args.method)); + } + + let session = self.get_session_mut(); + if advance_chain_tip { + session.advance_chain_tip(1); + } + + self.invoke_contract_call(args, sender, "public call") + } + + fn transfer_stx_private( + &mut self, + args: &TransferSTXArgs, + sender: &str, + advance_chain_tip: bool, + ) -> Result { + let session = self.get_session_mut(); + let initial_tx_sender = session.get_tx_sender(); + session.set_tx_sender(sender.to_string()); + + let execution = match session.stx_transfer(args.amount, &args.recipient) { + Ok(res) => res, + Err(diagnostics) => { + let mut message = format!("{}: {}", "STX transfer error", sender); + if let Some(diag) = diagnostics.last() { + message = format!("{} -> {}", message, diag.message); + } + return Err(message); + } + }; + + if advance_chain_tip { + session.advance_chain_tip(1); + } + session.set_tx_sender(initial_tx_sender); + Ok(execution_result_to_transaction_res(&execution)) + } + + fn deploy_contract_private( + &mut self, + args: &DeployContractArgs, + sender: &str, + advance_chain_tip: bool, + ) -> Result { + let session = self.get_session_mut(); + let contract = ClarityContract { + code_source: ClarityCodeSource::ContractInMemory(args.content.clone()), + name: args.name.clone(), + deployer: ContractDeployer::Address(sender.to_string()), + clarity_version: DEFAULT_CLARITY_VERSION, + epoch: DEFAULT_EPOCH, + }; + + let execution = match session.deploy_contract( + &contract, + None, + false, + Some(args.name.clone()), + &mut None, + ) { + Ok(res) => res, + Err(diagnostics) => { + let mut message = format!( + "{}: {}.{}", + "Contract deployment runtime error", sender, args.name + ); + if let Some(diag) = diagnostics.last() { + message = format!("{} -> {}", message, diag.message); + } + return Err(message); + } + }; + + if advance_chain_tip { + session.advance_chain_tip(1); + } + Ok(execution_result_to_transaction_res(&execution)) + } + + #[wasm_bindgen(js_name=deployContract)] + pub fn deploy_contract( + &mut self, + args: &DeployContractArgs, + sender: &str, + ) -> Result { + self.deploy_contract_private(args, sender, true) + } + + #[wasm_bindgen(js_name = "transferSTX")] + pub fn transfer_stx( + &mut self, + args: &TransferSTXArgs, + sender: &str, + ) -> Result { + self.transfer_stx_private(args, sender, true) + } + + #[wasm_bindgen(js_name = "callPublicFn")] + pub fn call_public_fn( + &mut self, + args: &CallContractArgs, + sender: &str, + ) -> Result { + self.call_public_fn_private(args, sender, true) + } + + #[wasm_bindgen(js_name=mineBlock)] + pub fn mine_block_js(&mut self, txs: js_sys::Array) -> Result<(), String> { + for js_tx in txs.to_vec() { + let tx: TxArgs = match serde_wasm_bindgen::from_value(js_tx) { + Ok(tx) => tx, + Err(err) => return Err(format!("error: {}", err)), + }; + if let Some(contract_call_args) = tx.call_contract { + let _ = self.call_public_fn_private(&contract_call_args, &tx.sender, false); + } else if let Some(transfer_stx_args) = tx.transfer_stx { + let _ = self.transfer_stx_private(&transfer_stx_args, &tx.sender, false); + } else if let Some(deploy_contract_args) = tx.deploy_contract { + let _ = self.deploy_contract_private(&deploy_contract_args, &tx.sender, false); + } + } + + let session = self.get_session_mut(); + session.advance_chain_tip(1); + Ok(()) + } + + #[wasm_bindgen(js_name=mineEmptyBlock)] + pub fn mine_empty_block(&mut self) -> u32 { + let session = self.get_session_mut(); + session.advance_chain_tip(1) + } + + #[wasm_bindgen(js_name=mineEmptyBlocks)] + pub fn mine_empty_blocks(&mut self, count: Option) -> u32 { + let session = self.get_session_mut(); + session.advance_chain_tip(count.unwrap_or(1)) + } + + #[wasm_bindgen(js_name=runSnippet)] + pub fn run_snippet(&mut self, snippet: String) -> JsValue { + let session = self.get_session_mut(); + let (_, output) = session.handle_command(&snippet); + let output_as_array = js_sys::Array::new_with_length(output.len() as u32); + for string in output { + output_as_array.push(&JsValue::from_str(&string)); + } + // @todo: can actually return raw value like contract calls + output_as_array.into() + } + + #[wasm_bindgen(js_name=getReport)] + pub fn collect_report(&mut self) -> Result { + let contracts_locations = self.contracts_locations.clone(); + let session = self.get_session_mut(); + let mut coverage_reporter = CoverageReporter::new(); + coverage_reporter.asts.append(&mut session.asts); + for (contract_id, contract_location) in contracts_locations.iter() { + coverage_reporter + .contract_paths + .insert(contract_id.name.to_string(), contract_location.to_string()); + } + coverage_reporter + .reports + .append(&mut session.coverage_reports); + let coverage = coverage_reporter.build_lcov_content(); + Ok(SessionReport { coverage }) + } +} diff --git a/components/clarinet-sdk/src/lib.rs b/components/clarinet-sdk/src/lib.rs new file mode 100644 index 000000000..cde4e5b90 --- /dev/null +++ b/components/clarinet-sdk/src/lib.rs @@ -0,0 +1,3 @@ +pub mod core; + +mod utils; diff --git a/components/clarinet-sdk/src/utils.rs b/components/clarinet-sdk/src/utils.rs new file mode 100644 index 000000000..23aeae148 --- /dev/null +++ b/components/clarinet-sdk/src/utils.rs @@ -0,0 +1,223 @@ +use clarity_repl::clarity::{ + codec::StacksMessageCodec, + events::{FTEventType, NFTEventType, STXEventType}, + util::hash, + vm::{ + events::StacksTransactionEvent, + types::{CharType, SequenceData}, + }, + Value, +}; +use serde::{Deserialize, Serialize}; + +#[derive(Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +struct SmartContractEvent { + contract_identifier: String, + topic: String, + value: String, +} + +#[derive(Deserialize, Serialize)] +pub struct StacksEvent { + pub event: String, + pub data: serde_json::Value, +} + +#[allow(unused_macros)] +macro_rules! log { + ( $( $t:tt )* ) => { + web_sys::console::log_1(&format!( $( $t )* ).into()); + } +} + +pub fn serialize_event(event: &StacksTransactionEvent) -> StacksEvent { + match event { + StacksTransactionEvent::SmartContractEvent(data) => StacksEvent { + event: "print_event".into(), + data: data.json_serialize(), + }, + StacksTransactionEvent::STXEvent(STXEventType::STXTransferEvent(data)) => StacksEvent { + event: "stx_transfer_event".into(), + data: data.json_serialize(), + }, + StacksTransactionEvent::STXEvent(STXEventType::STXMintEvent(data)) => StacksEvent { + event: "stx_mint_event".into(), + data: data.json_serialize(), + }, + StacksTransactionEvent::STXEvent(STXEventType::STXBurnEvent(data)) => StacksEvent { + event: "stx_burn_event".into(), + data: data.json_serialize(), + }, + StacksTransactionEvent::STXEvent(STXEventType::STXLockEvent(data)) => StacksEvent { + event: "stx_lock_event".into(), + data: data.json_serialize(), + }, + StacksTransactionEvent::NFTEvent(NFTEventType::NFTTransferEvent(data)) => StacksEvent { + event: "nft_transfer_event".into(), + data: data.json_serialize(), + }, + StacksTransactionEvent::NFTEvent(NFTEventType::NFTMintEvent(data)) => StacksEvent { + event: "nft_mint_event".into(), + data: data.json_serialize(), + }, + StacksTransactionEvent::NFTEvent(NFTEventType::NFTBurnEvent(data)) => StacksEvent { + event: "nft_burn_event".into(), + data: data.json_serialize(), + }, + StacksTransactionEvent::FTEvent(FTEventType::FTTransferEvent(data)) => StacksEvent { + event: "ft_transfer_event".into(), + data: data.json_serialize(), + }, + StacksTransactionEvent::FTEvent(FTEventType::FTMintEvent(data)) => StacksEvent { + event: "ft_mint_event".into(), + data: data.json_serialize(), + }, + StacksTransactionEvent::FTEvent(FTEventType::FTBurnEvent(data)) => StacksEvent { + event: "ft_burn_event".into(), + data: data.json_serialize(), + }, + } +} + +pub fn to_raw_value(value: &Value) -> String { + let mut bytes = vec![]; + value + .consensus_serialize(&mut bytes) + .unwrap_or_else(|e| panic!("failed to parse clarity value: {}", e)); + let raw_value = bytes + .iter() + .map(|b| format!("{:02x}", b)) + .collect::>(); + format!("0x{}", raw_value.join("")) +} + +pub fn uint8_to_string(value: &[u8]) -> String { + value_to_string(&uint8_to_value(value)) +} + +pub fn uint8_to_value(mut value: &[u8]) -> Value { + Value::consensus_deserialize(&mut value) + .unwrap_or_else(|e| panic!("failed to parse clarity value: {}", e)) +} + +fn value_to_string(value: &Value) -> String { + match value { + Value::Tuple(tup_data) => { + let mut data = Vec::new(); + for (name, value) in tup_data.data_map.iter() { + data.push(format!("{}: {}", &**name, value_to_string(value))) + } + format!("{{ {} }}", data.join(", ")) + } + Value::Optional(opt_data) => match opt_data.data { + Some(ref x) => format!("(some {})", value_to_string(x)), + None => "none".to_string(), + }, + Value::Response(res_data) => match res_data.committed { + true => format!("(ok {})", value_to_string(&res_data.data)), + false => format!("(err {})", value_to_string(&res_data.data)), + }, + Value::Sequence(SequenceData::String(CharType::ASCII(data))) => { + format!("\"{}\"", String::from_utf8(data.data.clone()).unwrap()) + } + Value::Sequence(SequenceData::String(CharType::UTF8(data))) => { + let mut result = String::new(); + for c in data.data.iter() { + if c.len() > 1 { + // escape extended charset + result.push_str(&format!("\\u{{{}}}", hash::to_hex(&c[..]))); + } else { + result.push(c[0] as char) + } + } + format!("u\"{}\"", result) + } + Value::Sequence(SequenceData::List(list_data)) => { + let mut data = Vec::new(); + for value in list_data.data.iter() { + data.push(value_to_string(value)) + } + format!("(list {})", data.join(" ")) + } + _ => format!("{}", value), + } +} + +#[cfg(test)] +mod tests { + use super::value_to_string; + use clarity_repl::clarity::vm::types::{ + ASCIIData, CharType, ListData, ListTypeData, OptionalData, ResponseData, SequenceData, + SequencedValue, TupleData, TypeSignature, UTF8Data, NONE, + }; + use clarity_repl::clarity::vm::{ClarityName, Value}; + use std::convert::TryFrom; + + #[test] + fn test_value_to_string() { + let mut s = value_to_string(&Value::Int(42)); + assert_eq!(s, "42"); + + s = value_to_string(&Value::UInt(12345678909876)); + assert_eq!(s, "u12345678909876"); + + s = value_to_string(&Value::Bool(true)); + assert_eq!(s, "true"); + + s = value_to_string(&Value::buff_from(vec![1, 2, 3]).unwrap()); + assert_eq!(s, "0x010203"); + + s = value_to_string(&Value::buff_from(vec![1, 2, 3]).unwrap()); + assert_eq!(s, "0x010203"); + + s = value_to_string(&Value::Tuple( + TupleData::from_data(vec![( + ClarityName::try_from("foo".to_string()).unwrap(), + Value::Bool(true), + )]) + .unwrap(), + )); + assert_eq!(s, "{ foo: true }"); + + s = value_to_string(&Value::Optional(OptionalData { + data: Some(Box::new(Value::UInt(42))), + })); + assert_eq!(s, "(some u42)"); + + s = value_to_string(&NONE); + assert_eq!(s, "none"); + + s = value_to_string(&Value::Response(ResponseData { + committed: true, + data: Box::new(Value::Int(-321)), + })); + assert_eq!(s, "(ok -321)"); + + s = value_to_string(&Value::Response(ResponseData { + committed: false, + data: Box::new(Value::Sequence(SequenceData::String(CharType::ASCII( + ASCIIData { + data: "'foo'".as_bytes().to_vec(), + }, + )))), + })); + assert_eq!(s, "(err \"'foo'\")"); + + s = value_to_string(&Value::Sequence(SequenceData::String(CharType::ASCII( + ASCIIData { + data: "Hello, \"world\"\n".as_bytes().to_vec(), + }, + )))); + assert_eq!(s, "\"Hello, \"world\"\n\""); + + s = value_to_string(&UTF8Data::to_value(&"Hello, 'world'\n".as_bytes().to_vec())); + assert_eq!(s, "u\"Hello, 'world'\n\""); + + s = value_to_string(&Value::Sequence(SequenceData::List(ListData { + data: vec![Value::Int(-321)], + type_signature: ListTypeData::new_list(TypeSignature::IntType, 2).unwrap(), + }))); + assert_eq!(s, "(list -321)"); + } +} diff --git a/components/clarinet-sdk/tsconfig.base.json b/components/clarinet-sdk/tsconfig.base.json new file mode 100644 index 000000000..9b26c41c8 --- /dev/null +++ b/components/clarinet-sdk/tsconfig.base.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + // outdir, module and target are defined in esm and cjs configs + + "lib": ["es2022"], + + "moduleResolution": "Node", + "rootDir": "src-ts", + "resolveJsonModule": false, + "allowJs": false, + + "declaration": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "sourceMap": true, + + /* Type Checking */ + "strict": true, + "noImplicitAny": true, + "skipLibCheck": true + }, + "include": ["src-ts"], + "exclude": ["node_modules", "dist"] +} diff --git a/components/clarinet-sdk/tsconfig.cjs.json b/components/clarinet-sdk/tsconfig.cjs.json new file mode 100644 index 000000000..ca83f5bdd --- /dev/null +++ b/components/clarinet-sdk/tsconfig.cjs.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.base.json", + "compilerOptions": { + "module": "commonjs", + "outDir": "dist/cjs", + "target": "es2015" + } +} diff --git a/components/clarinet-sdk/tsconfig.esm.json b/components/clarinet-sdk/tsconfig.esm.json new file mode 100644 index 000000000..df6e95658 --- /dev/null +++ b/components/clarinet-sdk/tsconfig.esm.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.base.json", + "compilerOptions": { + "module": "esnext", + "outDir": "dist/esm", + "target": "esnext" + } +} diff --git a/components/clarinet-sdk/webpack.config.dev.js b/components/clarinet-sdk/webpack.config.dev.js new file mode 100644 index 000000000..7ce6f2d87 --- /dev/null +++ b/components/clarinet-sdk/webpack.config.dev.js @@ -0,0 +1,46 @@ +const path = require("path"); + +// watch and build src-ts only +// run npm run build to re-build rust sources + +/** @typedef {import('webpack').Configuration} WebpackConfig **/ + +/** @type WebpackConfig */ +const configBase = { + mode: "production", + entry: "./src-ts/index.ts", + resolve: { extensions: [".ts", ".js"] }, + optimization: { + minimize: false, + }, +}; + +/** @type WebpackConfig */ +const configESM = { + ...configBase, + target: "node20", + watch: true, + output: { + filename: "index.mjs", + path: path.resolve(__dirname, "dist/esm"), + library: { + type: "module", + }, + }, + module: { + rules: [ + { + test: /\.ts$/, + loader: "ts-loader", + exclude: /node_modules/, + options: { configFile: "tsconfig.esm.json" }, + }, + ], + }, + experiments: { + asyncWebAssembly: true, + outputModule: true, + }, +}; + +module.exports = [configESM]; diff --git a/components/clarinet-sdk/webpack.config.js b/components/clarinet-sdk/webpack.config.js new file mode 100644 index 000000000..3ee351439 --- /dev/null +++ b/components/clarinet-sdk/webpack.config.js @@ -0,0 +1,91 @@ +const path = require("path"); +const WasmPackPlugin = require("@wasm-tool/wasm-pack-plugin"); +const CopyPlugin = require("copy-webpack-plugin"); + +/** @typedef {import('webpack').Configuration} WebpackConfig **/ + +/** @type WebpackConfig */ +const configBase = { + mode: "production", + entry: "./src-ts/index.ts", + resolve: { extensions: [".ts", ".js"] }, + optimization: { + minimize: false, + }, +}; + +/** @type WebpackConfig */ +const configESM = { + ...configBase, + target: "node20", + output: { + filename: "index.mjs", + path: path.resolve(__dirname, "dist/esm"), + library: { + type: "module", + }, + }, + module: { + rules: [ + { + test: /\.ts$/, + loader: "ts-loader", + exclude: /node_modules/, + options: { configFile: "tsconfig.esm.json" }, + }, + ], + }, + experiments: { + asyncWebAssembly: true, + outputModule: true, + }, + plugins: [ + new WasmPackPlugin({ + crateDirectory: path.resolve(__dirname, "./"), + extraArgs: "--release --target=bundler", + outDir: path.resolve(__dirname, "./src-ts/sdk"), + }), + new CopyPlugin({ + patterns: [{ from: "./src-ts/sdk/index.d.ts", to: "sdk" }], + }), + ], +}; + +/** @type WebpackConfig */ +const configCJS = { + ...configBase, + target: "node20", + output: { + filename: "index.js", + path: path.resolve(__dirname, "dist/cjs"), + library: { + type: "commonjs", + }, + }, + module: { + rules: [ + { + test: /\.ts$/, + loader: "ts-loader", + exclude: /node_modules/, + options: { configFile: "tsconfig.cjs.json" }, + }, + ], + }, + experiments: { + asyncWebAssembly: true, + outputModule: false, + }, + plugins: [ + new WasmPackPlugin({ + crateDirectory: path.resolve(__dirname, "./"), + extraArgs: "--release --target=bundler", + outDir: path.resolve(__dirname, "./src-ts/sdk"), + }), + new CopyPlugin({ + patterns: [{ from: "./src-ts/sdk/index.d.ts", to: "sdk" }], + }), + ], +}; + +module.exports = [configESM, configCJS]; diff --git a/components/clarity-repl/src/analysis/ast_dependency_detector.rs b/components/clarity-repl/src/analysis/ast_dependency_detector.rs index fe4cf5e6c..26a3959eb 100644 --- a/components/clarity-repl/src/analysis/ast_dependency_detector.rs +++ b/components/clarity-repl/src/analysis/ast_dependency_detector.rs @@ -84,7 +84,7 @@ impl Ord for Dependency { } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct DependencySet { pub set: BTreeSet, } diff --git a/components/clarity-repl/src/analysis/coverage.rs b/components/clarity-repl/src/analysis/coverage.rs index fb5c0b57e..d5a9adc3e 100644 --- a/components/clarity-repl/src/analysis/coverage.rs +++ b/components/clarity-repl/src/analysis/coverage.rs @@ -73,14 +73,14 @@ impl CoverageReporter { ))?; create_dir_all(filepath)?; let mut out = File::create(filename)?; - let content = self.build_lcov_file(); + let content = self.build_lcov_content(); write!(out, "{}", content)?; Ok(()) } - pub fn build_lcov_file(&self) -> String { + pub fn build_lcov_content(&self) -> String { let mut file_content = String::new(); let mut filtered_asts = HashMap::new(); diff --git a/components/clarity-repl/src/analysis/coverage_tests.rs b/components/clarity-repl/src/analysis/coverage_tests.rs index 66a71cd8f..97305af7e 100644 --- a/components/clarity-repl/src/analysis/coverage_tests.rs +++ b/components/clarity-repl/src/analysis/coverage_tests.rs @@ -29,7 +29,7 @@ fn get_coverage_report(contract: &str, snippets: Vec) -> (TestCoverageRe .insert(contract_id.name.to_string(), "/contract-0.clar".into()); coverage_reporter.reports.append(&mut vec![report.clone()]); - let lcov_content = coverage_reporter.build_lcov_file(); + let lcov_content = coverage_reporter.build_lcov_content(); (report, lcov_content) } diff --git a/components/clarity-repl/src/repl/interpreter.rs b/components/clarity-repl/src/repl/interpreter.rs index 58489dced..d948e6364 100644 --- a/components/clarity-repl/src/repl/interpreter.rs +++ b/components/clarity-repl/src/repl/interpreter.rs @@ -23,7 +23,7 @@ use clarity::vm::contexts::{CallStack, ContractContext, Environment, GlobalConte use clarity::vm::contracts::Contract; use clarity::vm::costs::cost_functions::ClarityCostFunction; use clarity::vm::costs::{runtime_cost, ExecutionCost, LimitedCostTracker}; -use clarity::vm::database::ClarityDatabase; +use clarity::vm::database::{ClarityDatabase, StoreType}; use clarity::vm::diagnostic::{Diagnostic, Level}; use clarity::vm::errors::Error; use clarity::vm::representations::SymbolicExpressionType::{Atom, List}; @@ -420,6 +420,27 @@ impl ClarityInterpreter { analysis_db.commit(); } + pub fn get_data_var( + &mut self, + contract_id: &QualifiedContractIdentifier, + var_name: &str, + ) -> Option { + let key = ClarityDatabase::make_key_for_trip(contract_id, StoreType::Variable, var_name); + let value_hex = self.datastore.get(&key)?; + Some(format!("0x{value_hex}")) + } + + pub fn get_map_entry( + &mut self, + contract_id: &QualifiedContractIdentifier, + map_name: &str, + map_key: &Value, + ) -> Option { + let key = ClarityDatabase::make_key_for_data_map_entry(contract_id, map_name, map_key); + let value_hex = self.datastore.get(&key)?; + Some(format!("0x{value_hex}")) + } + #[allow(unused_assignments)] pub fn execute<'a, 'hooks>( &'a mut self, diff --git a/components/clarity-repl/src/repl/session.rs b/components/clarity-repl/src/repl/session.rs index a8c681f06..53842791f 100644 --- a/components/clarity-repl/src/repl/session.rs +++ b/components/clarity-repl/src/repl/session.rs @@ -126,7 +126,6 @@ pub struct Session { api_reference: HashMap, pub coverage_reports: Vec, pub costs_reports: Vec, - pub initial_contracts_analysis: Vec<(ContractAnalysis, String, String)>, pub show_costs: bool, pub executed: Vec, pub current_epoch: StacksEpochId, @@ -154,7 +153,6 @@ impl Session { api_reference: build_api_reference(), coverage_reports: vec![], costs_reports: vec![], - initial_contracts_analysis: vec![], show_costs: false, settings, executed: Vec::new(), @@ -609,9 +607,8 @@ impl Session { test_name: String, ) -> Result<(ExecutionResult, QualifiedContractIdentifier), Vec> { let initial_tx_sender = self.get_tx_sender(); - // Kludge for handling fully qualified contract_id vs sugared syntax - let first_char = contract.chars().next().unwrap(); - let contract_id = if first_char.to_string() == "S" { + // Handle fully qualified contract_id and sugared syntax + let contract_id = if contract.starts_with("S") { contract.to_string() } else { format!("{}.{}", initial_tx_sender, contract,) @@ -660,40 +657,6 @@ impl Session { Ok((execution, contract_identifier)) } - // pub fn build_ast( - // &mut self, - // snippet: &str, - // name: Option<&str>, - // ) -> Result<(QualifiedContractIdentifier, ContractAST, Vec), Vec> { - // let (contract_name, is_tx) = match name { - // Some(name) => (name.to_string(), false), - // None => (format!("contract-{}", self.contracts.len()), true), - // }; - // let tx_sender = self.interpreter.get_tx_sender().to_address(); - // let id = format!("{}.{}", tx_sender, contract_name); - // let contract_identifier = QualifiedContractIdentifier::parse(&id).unwrap(); - - // let (ast, diagnostics, success) = self - // .interpreter - // .build_ast(contract_identifier.clone(), snippet.to_string()); - - // let mut output = Vec::::new(); - // let lines = snippet.lines(); - // let formatted_lines: Vec = lines.map(|l| l.to_string()).collect(); - // for diagnostic in &diagnostics { - // output.append(&mut output_diagnostic( - // &diagnostic, - // &contract_name, - // &formatted_lines, - // )); - // } - // if success { - // Ok((contract_identifier, ast, output)) - // } else { - // Err(output) - // } - // } - pub fn eval<'a>( &'a mut self, snippet: String, diff --git a/rust-toolchain b/rust-toolchain index 969710ab0..22048ac5b 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,2 +1,2 @@ [toolchain] -channel = "1.67.0" +channel = "1.70.0"