From 852d289d2db78c6ba5a5d564fef3b5a4480d6a3a Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 2 Nov 2024 12:34:41 +0100 Subject: [PATCH 01/12] initial web-app scaffold --- .github/workflows/test.yaml | 25 + .gitignore | 26 + Cargo.lock | 1504 +++++++++++++++++ Cargo.toml | 20 + dnas/generic_dna/workdir/dna.yaml | 21 + .../zomes/coordinator/generic_zome/Cargo.toml | 13 + .../zomes/coordinator/generic_zome/src/lib.rs | 29 + .../zomes/integrity/generic_zome/Cargo.toml | 12 + .../zomes/integrity/generic_zome/src/lib.rs | 204 +++ flake.lock | 195 +++ flake.nix | 33 + package.json | 32 + tests/package.json | 16 + tests/src/generic_dna/generic_zome/common.ts | 12 + tests/tsconfig.json | 9 + tests/vitest.config.ts | 8 + ui/.gitignore | 25 + ui/index.html | 18 + ui/package.json | 31 + ui/src/assets/holochainLogo.svg | 45 + ui/src/contexts.ts | 4 + ui/src/declarations.d.ts | 9 + ui/src/generic_dna/generic_zome/types.ts | 39 + ui/src/holochain-app.ts | 82 + ui/src/index.css | 261 +++ ui/src/shared-styles.ts | 4 + ui/tsconfig.json | 21 + ui/vite.config.ts | 8 + workdir/happ.yaml | 18 + workdir/web-happ.yaml | 6 + 30 files changed, 2730 insertions(+) create mode 100644 .github/workflows/test.yaml create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 dnas/generic_dna/workdir/dna.yaml create mode 100644 dnas/generic_dna/zomes/coordinator/generic_zome/Cargo.toml create mode 100644 dnas/generic_dna/zomes/coordinator/generic_zome/src/lib.rs create mode 100644 dnas/generic_dna/zomes/integrity/generic_zome/Cargo.toml create mode 100644 dnas/generic_dna/zomes/integrity/generic_zome/src/lib.rs create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 package.json create mode 100644 tests/package.json create mode 100644 tests/src/generic_dna/generic_zome/common.ts create mode 100644 tests/tsconfig.json create mode 100644 tests/vitest.config.ts create mode 100644 ui/.gitignore create mode 100644 ui/index.html create mode 100644 ui/package.json create mode 100644 ui/src/assets/holochainLogo.svg create mode 100644 ui/src/contexts.ts create mode 100644 ui/src/declarations.d.ts create mode 100644 ui/src/generic_dna/generic_zome/types.ts create mode 100644 ui/src/holochain-app.ts create mode 100644 ui/src/index.css create mode 100644 ui/src/shared-styles.ts create mode 100644 ui/tsconfig.json create mode 100644 ui/vite.config.ts create mode 100644 workdir/happ.yaml create mode 100644 workdir/web-happ.yaml diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000..cf6324b --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,25 @@ +name: "test" +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + testbuild: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install nix + uses: cachix/install-nix-action@v27 + with: + install_url: https://releases.nixos.org/nix/nix-2.23.2/install + + - uses: cachix/cachix-action@v15 + with: + name: holochain-ci + + - name: Install and test + run: | + nix develop --command bash -c "npm install && npm run test" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9da1688 --- /dev/null +++ b/.gitignore @@ -0,0 +1,26 @@ +# editors +/.idea +/.vscode + +# system files +.DS_Store + +# build +/dist/ +/target/ +/.cargo/ + +# package manager +/**/node_modules/ +/.yarn + +# generated and compiled files +*.happ +*.webhapp +*.zip +*.dna + +# temporary files +.hc* +.running +.hc diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..8e68886 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,1504 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "blake2b_simd" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23285ad32269793932e830392f2fe2f83e26488fd3ec778883a93c8323735780" +dependencies = [ + "arrayref", + "arrayvec", + "constant_time_eq", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "camino" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-platform" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cc" +version = "1.1.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3788d6ac30243803df38a3e9991cf37e41210232916d41a8222ae378f912624" +dependencies = [ + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "num-traits", + "serde", + "windows-targets 0.52.6", +] + +[[package]] +name = "colored" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" +dependencies = [ + "lazy_static", + "windows-sys", +] + +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "cpufeatures" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "darling" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +dependencies = [ + "darling_core 0.14.4", + "darling_macro 0.14.4", +] + +[[package]] +name = "darling" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +dependencies = [ + "darling_core 0.20.10", + "darling_macro 0.20.10", +] + +[[package]] +name = "darling_core" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.10.0", + "syn 1.0.109", +] + +[[package]] +name = "darling_core" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.11.1", + "syn 2.0.86", +] + +[[package]] +name = "darling_macro" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +dependencies = [ + "darling_core 0.14.4", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "darling_macro" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +dependencies = [ + "darling_core 0.20.10", + "quote", + "syn 2.0.86", +] + +[[package]] +name = "derive_more" +version = "0.99.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.86", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.86", +] + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "gcollections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f551fdf23ef80329f754919669147a71c67b6cfe3569cd93b6fabdd62044377" +dependencies = [ + "bit-set", + "num-integer", + "num-traits", + "trilean", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "generic_zome" +version = "0.0.1" +dependencies = [ + "generic_zome_integrity", + "hdk", + "serde", +] + +[[package]] +name = "generic_zome_integrity" +version = "0.0.1" +dependencies = [ + "hdi", + "serde", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "hashbrown" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" + +[[package]] +name = "hdi" +version = "0.6.0-dev.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea8e480e2393530bb6dac2962e9d203e88dda19a611d84b94e4b344e01af5524" +dependencies = [ + "getrandom", + "hdk_derive", + "holo_hash", + "holochain_integrity_types", + "holochain_wasmer_guest", + "paste", + "serde", + "serde_bytes", + "tracing", + "tracing-core", +] + +[[package]] +name = "hdk" +version = "0.5.0-dev.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd300c5521f7d91e8b72c2699c329b39c4564d2e28fc4dab58bc1a25ba7be9ea" +dependencies = [ + "getrandom", + "hdi", + "hdk_derive", + "holo_hash", + "holochain_wasmer_guest", + "holochain_zome_types", + "paste", + "serde", + "serde_bytes", + "thiserror", + "tracing", + "tracing-core", +] + +[[package]] +name = "hdk_derive" +version = "0.5.0-dev.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "081025f237cd95c3787f874b66d070992a1f61f03174ad0b3785b7ebc382a833" +dependencies = [ + "darling 0.14.4", + "heck", + "holochain_integrity_types", + "paste", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "holo_hash" +version = "0.5.0-dev.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4125906ccb19a314cb50ab3bcedd89dce378418b9875e78d102a412b2e0e2935" +dependencies = [ + "base64", + "blake2b_simd", + "derive_more", + "holochain_serialized_bytes", + "holochain_util", + "holochain_wasmer_common", + "kitsune_p2p_dht_arc", + "serde", + "serde_bytes", + "thiserror", +] + +[[package]] +name = "holochain_integrity_types" +version = "0.5.0-dev.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e362fe68ac58399cc92ecf564d72f0abf3559a37b7bf23dd17a8f07fc12b8562" +dependencies = [ + "holo_hash", + "holochain_secure_primitive", + "holochain_serialized_bytes", + "holochain_util", + "kitsune_p2p_timestamp", + "serde", + "serde_bytes", + "subtle", + "tracing", +] + +[[package]] +name = "holochain_nonce" +version = "0.5.0-dev.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ddfd5d439236f7851cafbb50675cc21b4e5bacc97b0940e0afbeb06ffd88e92" +dependencies = [ + "getrandom", + "holochain_secure_primitive", + "kitsune_p2p_timestamp", +] + +[[package]] +name = "holochain_secure_primitive" +version = "0.5.0-dev.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82afd5d62bfd82248770c4e8a81af26a3f5f95950b87273e5e0e36c98140bc33" +dependencies = [ + "paste", + "serde", + "subtle", +] + +[[package]] +name = "holochain_serialized_bytes" +version = "0.0.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719fa847cf9f772f7e8e1a6f11d801e1383cc5af043292042665da9a6ce5c742" +dependencies = [ + "holochain_serialized_bytes_derive", + "rmp-serde", + "serde", + "serde-transcode", + "serde_bytes", + "serde_json", + "thiserror", +] + +[[package]] +name = "holochain_serialized_bytes_derive" +version = "0.0.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e6a221b5650251e09ef0b9223cf39e72b5222492cffc6bb4bdf36b2a6bc91aa" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "holochain_util" +version = "0.5.0-dev.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b4b3ecd06e1770fe32d122a1f98dee059be8c5e5a30a97f09d04c35c89298" +dependencies = [ + "cfg-if", + "colored", + "dunce", + "futures", + "once_cell", +] + +[[package]] +name = "holochain_wasmer_common" +version = "0.0.96" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c6dc4e75554cf8e0306f8e429a6112f734de74467a0a2c810f97c7b7036b689" +dependencies = [ + "holochain_serialized_bytes", + "serde", + "serde_bytes", + "test-fuzz", + "thiserror", +] + +[[package]] +name = "holochain_wasmer_guest" +version = "0.0.96" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa3d0105471c4f0fa2d9644c7113e4f7ed5385ed5dbb980eab14eb7c6efaff8a" +dependencies = [ + "holochain_serialized_bytes", + "holochain_wasmer_common", + "parking_lot", + "paste", + "serde", + "tracing", +] + +[[package]] +name = "holochain_zome_types" +version = "0.5.0-dev.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb4c42858c57e1d4e05e96b09dc46b64f4a964f8a0fa8b5a03497988115b8c3a" +dependencies = [ + "derive_more", + "holo_hash", + "holochain_integrity_types", + "holochain_nonce", + "holochain_serialized_bytes", + "holochain_wasmer_common", + "kitsune_p2p_block", + "kitsune_p2p_timestamp", + "serde", + "serde_bytes", + "subtle", + "thiserror", + "tracing", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "indexmap" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "intervallum" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18bfda24d3930aa647f90044d5ef87d0c8120f13b86b2d60e8aade66e656e659" +dependencies = [ + "bit-set", + "gcollections", + "num-integer", + "num-traits", + "trilean", +] + +[[package]] +name = "itertools" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "js-sys" +version = "0.3.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "kitsune_p2p_bin_data" +version = "0.5.0-dev.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4629de79b97738bada705efbe2a0b56ff80fda500eb2031627069f5a51adfa55" +dependencies = [ + "base64", + "derive_more", + "holochain_util", + "kitsune_p2p_dht_arc", + "serde", + "serde_bytes", + "shrinkwraprs", +] + +[[package]] +name = "kitsune_p2p_block" +version = "0.5.0-dev.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07d221a8c3ca518bd752ef7b08965b8d5a24d46dcf7c5b8a7ad8bcdd1d43c9b1" +dependencies = [ + "kitsune_p2p_bin_data", + "kitsune_p2p_timestamp", + "serde", +] + +[[package]] +name = "kitsune_p2p_dht_arc" +version = "0.5.0-dev.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9491afd841f355b448c20e6792f3e8c36ead8f7bd0c26ca7ee468718076266b" +dependencies = [ + "derive_more", + "gcollections", + "intervallum", + "num-traits", + "serde", +] + +[[package]] +name = "kitsune_p2p_timestamp" +version = "0.5.0-dev.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528c144c80b366cf2dd2a8eee0d2f993bee281a1f51fa47a01b59c7ad92861a6" +dependencies = [ + "chrono", + "serde", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.161" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.52.6", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pin-project-lite" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "prettyplease" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" +dependencies = [ + "proc-macro2", + "syn 2.0.86", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "redox_syscall" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +dependencies = [ + "bitflags 2.6.0", +] + +[[package]] +name = "rmp" +version = "0.8.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "228ed7c16fa39782c3b3468e974aec2795e9089153cd08ee2e9aefb3613334c4" +dependencies = [ + "byteorder", + "num-traits", + "paste", +] + +[[package]] +name = "rmp-serde" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52e599a477cf9840e92f2cde9a7189e67b42c57532749bf90aea6ec10facd4db" +dependencies = [ + "byteorder", + "rmp", + "serde", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +dependencies = [ + "serde", +] + +[[package]] +name = "serde" +version = "1.0.203" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-transcode" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "590c0e25c2a5bb6e85bf5c1bce768ceb86b316e7a01bdf07d2cb4ec2271990e2" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_bytes" +version = "0.11.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.203" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.86", +] + +[[package]] +name = "serde_json" +version = "1.0.132" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" +dependencies = [ + "indexmap", + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "shrinkwraprs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e63e6744142336dfb606fe2b068afa2e1cca1ee6a5d8377277a92945d81fa331" +dependencies = [ + "bitflags 1.3.2", + "itertools 0.8.2", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89275301d38033efb81a6e60e3497e734dfcc62571f2854bf4b16690398824c" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "test-fuzz" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ab7a9bb33d134e863862ab9dad2ac7e022ac89707914627f498fe0f29248d9b" +dependencies = [ + "serde", + "test-fuzz-internal", + "test-fuzz-macro", + "test-fuzz-runtime", +] + +[[package]] +name = "test-fuzz-internal" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0bef5dd380747bd7b6e636a8032a24aa34fcecaf843e59fc97d299681922e86" +dependencies = [ + "bincode", + "cargo_metadata", + "serde", +] + +[[package]] +name = "test-fuzz-macro" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7e6b4c7391a38f0f026972ec2200bcfd1ec45533aa266fdae5858d011afc500" +dependencies = [ + "darling 0.20.10", + "heck", + "itertools 0.13.0", + "once_cell", + "prettyplease", + "proc-macro2", + "quote", + "syn 2.0.86", +] + +[[package]] +name = "test-fuzz-runtime" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9fbe6fb7481ec6d9bf64ae2c5d49cb1b40f8da624a91031482af7b08168c679" +dependencies = [ + "hex", + "num-traits", + "serde", + "sha1", + "test-fuzz-internal", +] + +[[package]] +name = "thiserror" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d171f59dbaa811dbbb1aee1e73db92ec2b122911a48e1390dfe327a821ddede" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b08be0f17bd307950653ce45db00cd31200d82b624b36e181337d9c7d92765b5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.86", +] + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.86", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "trilean" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683ba5022fe6dbd7133cad150478ccf51bdb6d861515181e5fc6b4323d4fa424" + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" +dependencies = [ + "cfg-if", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.86", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.86", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..b9dc9ac --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,20 @@ +[profile.dev] +opt-level = "z" + +[profile.release] +opt-level = "z" + +[workspace] +members = ["dnas/*/zomes/coordinator/*", "dnas/*/zomes/integrity/*"] +resolver = "2" + +[workspace.dependencies] +hdi = "=0.6.0-dev.1" +hdk = "=0.5.0-dev.3" +serde = "1.0" + +[workspace.dependencies.generic_zome] +path = "dnas/generic_dna/zomes/coordinator/generic_zome" + +[workspace.dependencies.generic_zome_integrity] +path = "dnas/generic_dna/zomes/integrity/generic_zome" diff --git a/dnas/generic_dna/workdir/dna.yaml b/dnas/generic_dna/workdir/dna.yaml new file mode 100644 index 0000000..b32711f --- /dev/null +++ b/dnas/generic_dna/workdir/dna.yaml @@ -0,0 +1,21 @@ +manifest_version: '1' +name: generic_dna +integrity: + network_seed: null + properties: null + origin_time: 1730546542842577 + zomes: + - name: generic_zome_integrity + hash: null + bundled: '../../../target/wasm32-unknown-unknown/release/generic_zome_integrity.wasm' + dependencies: null + dylib: null +coordinator: + zomes: + - name: generic_zome + hash: null + bundled: '../../../target/wasm32-unknown-unknown/release/generic_zome.wasm' + dependencies: + - name: generic_zome_integrity + dylib: null +lineage: [] diff --git a/dnas/generic_dna/zomes/coordinator/generic_zome/Cargo.toml b/dnas/generic_dna/zomes/coordinator/generic_zome/Cargo.toml new file mode 100644 index 0000000..67cb5e1 --- /dev/null +++ b/dnas/generic_dna/zomes/coordinator/generic_zome/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "generic_zome" +version = "0.0.1" +edition = "2021" + +[lib] +crate-type = ["cdylib", "rlib"] +name = "generic_zome" + +[dependencies] +hdk = { workspace = true } +serde = { workspace = true } +generic_zome_integrity = { workspace = true } diff --git a/dnas/generic_dna/zomes/coordinator/generic_zome/src/lib.rs b/dnas/generic_dna/zomes/coordinator/generic_zome/src/lib.rs new file mode 100644 index 0000000..828111b --- /dev/null +++ b/dnas/generic_dna/zomes/coordinator/generic_zome/src/lib.rs @@ -0,0 +1,29 @@ +use hdk::prelude::*; +use generic_zome_integrity::*; + +// Called the first time a zome call is made to the cell containing this zome +#[hdk_extern] +pub fn init() -> ExternResult { + Ok(InitCallbackResult::Pass) +} + +// Don't modify this enum if you want the scaffolding tool to generate appropriate signals for your entries and links +#[derive(Serialize, Deserialize, Debug)] +#[serde(tag = "type")] +pub enum Signal {} + +// Whenever an action is committed, we emit a signal to the UI elements to reactively update them +#[hdk_extern(infallible)] +pub fn post_commit(committed_actions: Vec) { + // Don't modify this loop if you want the scaffolding tool to generate appropriate signals for your entries and links + for action in committed_actions { + if let Err(err) = signal_action(action) { + error!("Error signaling new action: {:?}", err); + } + } +} + +// Don't modify this function if you want the scaffolding tool to generate appropriate signals for your entries and links +fn signal_action(action: SignedActionHashed) -> ExternResult<()> { + Ok(()) +} diff --git a/dnas/generic_dna/zomes/integrity/generic_zome/Cargo.toml b/dnas/generic_dna/zomes/integrity/generic_zome/Cargo.toml new file mode 100644 index 0000000..33cc9f6 --- /dev/null +++ b/dnas/generic_dna/zomes/integrity/generic_zome/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "generic_zome_integrity" +version = "0.0.1" +edition = "2021" + +[lib] +crate-type = ["cdylib", "rlib"] +name = "generic_zome_integrity" + +[dependencies] +hdi = { workspace = true } +serde = { workspace = true } diff --git a/dnas/generic_dna/zomes/integrity/generic_zome/src/lib.rs b/dnas/generic_dna/zomes/integrity/generic_zome/src/lib.rs new file mode 100644 index 0000000..1b20c0e --- /dev/null +++ b/dnas/generic_dna/zomes/integrity/generic_zome/src/lib.rs @@ -0,0 +1,204 @@ +use hdi::prelude::*; + +// Validation you perform during the genesis process. Nobody else on the network performs it, only you. +// There *is no* access to network calls in this callback +#[hdk_extern] +pub fn genesis_self_check( + + _data: GenesisSelfCheckData, +) -> ExternResult { + Ok(ValidateCallbackResult::Valid) +} + +// Validation the network performs when you try to join, you can't perform this validation yourself as you are not a member yet. +// There *is* access to network calls in this function +pub fn validate_agent_joining( + + _agent_pub_key: AgentPubKey, + _membrane_proof: &Option, +) -> ExternResult { + Ok(ValidateCallbackResult::Valid) +} + +// This is the unified validation callback for all entries and link types in this integrity zome +// Below is a match template for all of the variants of `DHT Ops` and entry and link types +// +// Holochain has already performed the following validation for you: +// - The action signature matches on the hash of its content and is signed by its author +// - The previous action exists, has a lower timestamp than the new action, and incremented sequence number +// - The previous action author is the same as the new action author +// - The timestamp of each action is after the DNA's origin time +// - AgentActivity authorities check that the agent hasn't forked their chain +// - The entry hash in the action matches the entry content +// - The entry type in the action matches the entry content +// - The entry size doesn't exceed the maximum entry size (currently 4MB) +// - Private entry types are not included in the Op content, and public entry types are +// - If the `Op` is an update or a delete, the original action exists and is a `Create` or `Update` action +// - If the `Op` is an update, the original entry exists and is of the same type as the new one +// - If the `Op` is a delete link, the original action exists and is a `CreateLink` action +// - Link tags don't exceed the maximum tag size (currently 1KB) +// - Countersigned entries include an action from each required signer +// +// You can read more about validation here: https://docs.rs/hdi/latest/hdi/index.html#data-validation +#[hdk_extern] +pub fn validate(op: Op) -> ExternResult { + match op.flattened::<(), ()>()? { + FlatOp::StoreEntry(store_entry) => { + match store_entry { + OpEntry::CreateEntry { app_entry, action } => { + Ok( + ValidateCallbackResult::Invalid( + "There are no entry types in this integrity zome".to_string(), + ), + ) + } + OpEntry::UpdateEntry { app_entry, action, .. } => { + Ok( + ValidateCallbackResult::Invalid( + "There are no entry types in this integrity zome".to_string(), + ), + ) + } + _ => Ok(ValidateCallbackResult::Valid), + } + } + FlatOp::RegisterUpdate(update_entry) => { + match update_entry { + OpUpdate::Entry { app_entry, action } => { + Ok( + ValidateCallbackResult::Invalid( + "There are no entry types in this integrity zome".to_string(), + ), + ) + } + _ => Ok(ValidateCallbackResult::Valid), + } + } + FlatOp::RegisterDelete(delete_entry) => { + Ok( + ValidateCallbackResult::Invalid( + "There are no entry types in this integrity zome".to_string(), + ), + ) + } + FlatOp::RegisterCreateLink { + link_type, + base_address, + target_address, + tag, + action, + } => { + Ok( + ValidateCallbackResult::Invalid( + "There are no link types in this integrity zome".to_string(), + ), + ) + } + FlatOp::RegisterDeleteLink { + link_type, + base_address, + target_address, + tag, + original_action, + action, + } => { + Ok( + ValidateCallbackResult::Invalid( + "There are no link types in this integrity zome".to_string(), + ), + ) + } + FlatOp::StoreRecord(store_record) => { + match store_record { + // Complementary validation to the `StoreEntry` Op, in which the record itself is validated + // If you want to optimize performance, you can remove the validation for an entry type here and keep it in `StoreEntry` + // Notice that doing so will cause `must_get_valid_record` for this record to return a valid record even if the `StoreEntry` validation failed + OpRecord::CreateEntry { app_entry, action } => { + Ok( + ValidateCallbackResult::Invalid( + "There are no entry types in this integrity zome".to_string(), + ), + ) + } + // Complementary validation to the `RegisterUpdate` Op, in which the record itself is validated + // If you want to optimize performance, you can remove the validation for an entry type here and keep it in `StoreEntry` and in `RegisterUpdate` + // Notice that doing so will cause `must_get_valid_record` for this record to return a valid record even if the other validations failed + OpRecord::UpdateEntry { original_action_hash, app_entry, action, .. } => { + Ok( + ValidateCallbackResult::Invalid( + "There are no entry types in this integrity zome".to_string(), + ), + ) + } + // Complementary validation to the `RegisterDelete` Op, in which the record itself is validated + // If you want to optimize performance, you can remove the validation for an entry type here and keep it in `RegisterDelete` + // Notice that doing so will cause `must_get_valid_record` for this record to return a valid record even if the `RegisterDelete` validation failed + OpRecord::DeleteEntry { original_action_hash, action, .. } => { + Ok( + ValidateCallbackResult::Invalid( + "There are no entry types in this integrity zome".to_string(), + ), + ) + } + // Complementary validation to the `RegisterCreateLink` Op, in which the record itself is validated + // If you want to optimize performance, you can remove the validation for an entry type here and keep it in `RegisterCreateLink` + // Notice that doing so will cause `must_get_valid_record` for this record to return a valid record even if the `RegisterCreateLink` validation failed + OpRecord::CreateLink { + base_address, + target_address, + tag, + link_type, + action, + } => { + Ok( + ValidateCallbackResult::Invalid( + "There are no link types in this integrity zome".to_string(), + ), + ) + } + // Complementary validation to the `RegisterDeleteLink` Op, in which the record itself is validated + // If you want to optimize performance, you can remove the validation for an entry type here and keep it in `RegisterDeleteLink` + // Notice that doing so will cause `must_get_valid_record` for this record to return a valid record even if the `RegisterDeleteLink` validation failed + OpRecord::DeleteLink { original_action_hash, base_address, action } => { + Ok( + ValidateCallbackResult::Invalid( + "There are no link types in this integrity zome".to_string(), + ), + ) + } + OpRecord::CreatePrivateEntry { .. } => Ok(ValidateCallbackResult::Valid), + OpRecord::UpdatePrivateEntry { .. } => Ok(ValidateCallbackResult::Valid), + OpRecord::CreateCapClaim { .. } => Ok(ValidateCallbackResult::Valid), + OpRecord::CreateCapGrant { .. } => Ok(ValidateCallbackResult::Valid), + OpRecord::UpdateCapClaim { .. } => Ok(ValidateCallbackResult::Valid), + OpRecord::UpdateCapGrant { .. } => Ok(ValidateCallbackResult::Valid), + OpRecord::Dna { .. } => Ok(ValidateCallbackResult::Valid), + OpRecord::OpenChain { .. } => Ok(ValidateCallbackResult::Valid), + OpRecord::CloseChain { .. } => Ok(ValidateCallbackResult::Valid), + OpRecord::InitZomesComplete { .. } => Ok(ValidateCallbackResult::Valid), + _ => Ok(ValidateCallbackResult::Valid), + } + } + FlatOp::RegisterAgentActivity(agent_activity) => { + match agent_activity { + OpActivity::CreateAgent { agent, action } => { + let previous_action = must_get_action(action.prev_action)?; + match previous_action.action() { + Action::AgentValidationPkg( + AgentValidationPkg { membrane_proof, .. }, + ) => validate_agent_joining(agent, membrane_proof), + _ => { + Ok( + ValidateCallbackResult::Invalid( + "The previous action for a `CreateAgent` action must be an `AgentValidationPkg`" + .to_string(), + ), + ) + } + } + } + _ => Ok(ValidateCallbackResult::Valid), + } + } + } +} diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..f2421e7 --- /dev/null +++ b/flake.lock @@ -0,0 +1,195 @@ +{ + "nodes": { + "crane": { + "locked": { + "lastModified": 1727974419, + "narHash": "sha256-WD0//20h+2/yPGkO88d2nYbb23WMWYvnRyDQ9Dx4UHg=", + "owner": "ipetkov", + "repo": "crane", + "rev": "37e4f9f0976cb9281cd3f0c70081e5e0ecaee93f", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1727826117, + "narHash": "sha256-K5ZLCyfO/Zj9mPFldf3iwS6oZStJcU4tSpiXTMYaaL0=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "3d04084d54bedc3d6b8b736c70ef449225c361b1", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "hc-launch": { + "flake": false, + "locked": { + "lastModified": 1727250978, + "narHash": "sha256-6u/VjFRV4eQQS4H0he7C0n7uNjzBBtkeoyN46jTO0mc=", + "owner": "holochain", + "repo": "hc-launch", + "rev": "92afce654187be5abef67d34df20bd6464524cf3", + "type": "github" + }, + "original": { + "owner": "holochain", + "ref": "holochain-weekly", + "repo": "hc-launch", + "type": "github" + } + }, + "hc-scaffold": { + "flake": false, + "locked": { + "lastModified": 1729842397, + "narHash": "sha256-RGojwMWA5MXAsK/vy78Gb2JYoKrD+zzY0rl3KLt1LK4=", + "owner": "holochain", + "repo": "scaffolding", + "rev": "27715e5fdf56e03720f22f77068c1f16c33f0881", + "type": "github" + }, + "original": { + "owner": "holochain", + "ref": "holochain-weekly", + "repo": "scaffolding", + "type": "github" + } + }, + "holochain": { + "flake": false, + "locked": { + "lastModified": 1730250209, + "narHash": "sha256-U1TVtxcZDwKuLiHhnQbkHFSNUuE22yiTrFQZ4ftWJeg=", + "owner": "holochain", + "repo": "holochain", + "rev": "37736e8f1a79b4aa52cdb1e497e9001e2b001053", + "type": "github" + }, + "original": { + "owner": "holochain", + "ref": "holochain-0.5.0-dev.3", + "repo": "holochain", + "type": "github" + } + }, + "holonix": { + "inputs": { + "crane": "crane", + "flake-parts": "flake-parts", + "hc-launch": "hc-launch", + "hc-scaffold": "hc-scaffold", + "holochain": "holochain", + "lair-keystore": "lair-keystore", + "nixpkgs": "nixpkgs", + "rust-overlay": "rust-overlay" + }, + "locked": { + "lastModified": 1730384720, + "narHash": "sha256-HiBXYzs6WOApQnbHPo6YiIggNJISHGpW1tCgh4Ii0y4=", + "owner": "holochain", + "repo": "holonix", + "rev": "272605580cfc84066eee10ae42d9bf30150ca230", + "type": "github" + }, + "original": { + "owner": "holochain", + "ref": "main", + "repo": "holonix", + "type": "github" + } + }, + "lair-keystore": { + "flake": false, + "locked": { + "lastModified": 1726865440, + "narHash": "sha256-+ARQs+Sfmh8QXMyjjHjm6Ib8Ag86Jm2vnyB6l3zTCgA=", + "owner": "holochain", + "repo": "lair", + "rev": "9f306efed597765b70da704e1739ecc67f2510e0", + "type": "github" + }, + "original": { + "owner": "holochain", + "ref": "lair_keystore-v0.5.2", + "repo": "lair", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1717179513, + "narHash": "sha256-vboIEwIQojofItm2xGCdZCzW96U85l9nDW3ifMuAIdM=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "63dacb46bf939521bdc93981b4cbb7ecb58427a0", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "24.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib": { + "locked": { + "lastModified": 1727825735, + "narHash": "sha256-0xHYkMkeLVQAMa7gvkddbPqpxph+hDzdu1XdGPJR+Os=", + "type": "tarball", + "url": "https://github.com/NixOS/nixpkgs/archive/fb192fec7cc7a4c26d51779e9bab07ce6fa5597a.tar.gz" + }, + "original": { + "type": "tarball", + "url": "https://github.com/NixOS/nixpkgs/archive/fb192fec7cc7a4c26d51779e9bab07ce6fa5597a.tar.gz" + } + }, + "root": { + "inputs": { + "flake-parts": [ + "holonix", + "flake-parts" + ], + "holonix": "holonix", + "nixpkgs": [ + "holonix", + "nixpkgs" + ] + } + }, + "rust-overlay": { + "inputs": { + "nixpkgs": [ + "holonix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1728268235, + "narHash": "sha256-lJMFnMO4maJuNO6PQ5fZesrTmglze3UFTTBuKGwR1Nw=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "25685cc2c7054efc31351c172ae77b21814f2d42", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..644aa47 --- /dev/null +++ b/flake.nix @@ -0,0 +1,33 @@ +{ + description = "Flake for Holochain app development"; + + inputs = { + holonix.url = "github:holochain/holonix?ref=main"; + + nixpkgs.follows = "holonix/nixpkgs"; + flake-parts.follows = "holonix/flake-parts"; + + }; + + outputs = inputs@{ flake-parts, ... }: flake-parts.lib.mkFlake { inherit inputs; } { + systems = builtins.attrNames inputs.holonix.devShells; + perSystem = { inputs', pkgs, ... }: { + formatter = pkgs.nixpkgs-fmt; + + devShells.default = pkgs.mkShell { + inputsFrom = [ inputs'.holonix.devShells.default ]; + + packages = (with pkgs; [ + nodejs_20 + binaryen + + + ]); + + shellHook = '' + export PS1='\[\033[1;34m\][holonix:\w]\$\[\033[0m\] ' + ''; + }; + }; + }; +} \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..fab6ec1 --- /dev/null +++ b/package.json @@ -0,0 +1,32 @@ +{ + "name": "generic-dna-dev", + "private": true, + "workspaces": [ + "ui", + "tests" + ], + "scripts": { + "start": "AGENTS=${AGENTS:-2} BOOTSTRAP_PORT=$(get-port) SIGNAL_PORT=$(get-port) npm run network", + "network": "hc sandbox clean && npm run build:happ && UI_PORT=$(get-port) concurrently \"npm run start --workspace ui\" \"npm run launch:happ\" \"holochain-playground\"", + "test": "npm run build:zomes && hc app pack workdir --recursive && npm run test --workspace tests", + "launch:happ": "hc-spin -n $AGENTS --ui-port $UI_PORT workdir/generic-dna.happ", + "start:tauri": "AGENTS=${AGENTS:-2} BOOTSTRAP_PORT=$(get-port) SIGNAL_PORT=$(get-port) npm run network:tauri", + "network:tauri": "hc sandbox clean && npm run build:happ && UI_PORT=$(get-port) concurrently \"npm run start --workspace ui\" \"npm run launch:tauri\" \"holochain-playground\"", + "launch:tauri": "concurrently \"hc run-local-services --bootstrap-port $BOOTSTRAP_PORT --signal-port $SIGNAL_PORT\" \"echo pass | RUST_LOG=warn hc launch --piped -n $AGENTS workdir/generic-dna.happ --ui-port $UI_PORT network --bootstrap http://127.0.0.1:\"$BOOTSTRAP_PORT\" webrtc ws://127.0.0.1:\"$SIGNAL_PORT\"\"", + "package": "npm run build:happ && npm run package --workspace ui && hc web-app pack workdir --recursive", + "build:happ": "npm run build:zomes && hc app pack workdir --recursive", + "build:zomes": "cargo build --release --target wasm32-unknown-unknown" + }, + "devDependencies": { + "@holochain-playground/cli": "^0.300.1", + "@holochain/hc-spin": "^0.400.0-dev.3", + "concurrently": "^6.5.1", + "get-port-cli": "^3.0.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "hcScaffold": { + "template": "lit" + } +} \ No newline at end of file diff --git a/tests/package.json b/tests/package.json new file mode 100644 index 0000000..9f170df --- /dev/null +++ b/tests/package.json @@ -0,0 +1,16 @@ +{ + "name": "tests", + "version": "0.1.0", + "private": true, + "scripts": { + "test": "vitest run" + }, + "dependencies": { + "@msgpack/msgpack": "^2.8.0", + "@holochain/client": "^0.19.0-dev.0", + "@holochain/tryorama": "^0.18.0-dev.0", + "typescript": "^4.9.4", + "vitest": "^0.28.4" + }, + "type": "module" +} diff --git a/tests/src/generic_dna/generic_zome/common.ts b/tests/src/generic_dna/generic_zome/common.ts new file mode 100644 index 0000000..10ee7dd --- /dev/null +++ b/tests/src/generic_dna/generic_zome/common.ts @@ -0,0 +1,12 @@ +import { + ActionHash, + AppBundleSource, + fakeActionHash, + fakeAgentPubKey, + fakeDnaHash, + fakeEntryHash, + hashFrom32AndType, + NewEntryAction, + Record, +} from "@holochain/client"; +import { CallableCell } from "@holochain/tryorama"; diff --git a/tests/tsconfig.json b/tests/tsconfig.json new file mode 100644 index 0000000..8864384 --- /dev/null +++ b/tests/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "target": "ES2017", + "module": "ESNext", + "moduleResolution": "node", + "esModuleInterop": true, + "allowSyntheticDefaultImports": true + } +} diff --git a/tests/vitest.config.ts b/tests/vitest.config.ts new file mode 100644 index 0000000..2fd7bf7 --- /dev/null +++ b/tests/vitest.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + threads: false, + testTimeout: 60 * 1000 * 4, // 4 mins + }, +}); diff --git a/ui/.gitignore b/ui/.gitignore new file mode 100644 index 0000000..23452c8 --- /dev/null +++ b/ui/.gitignore @@ -0,0 +1,25 @@ +## editors +/.idea +/.vscode + +## system files +.DS_Store + +## npm +/node_modules/ +/npm-debug.log + +## testing +/coverage/ + +## temp folders +/.tmp/ + +# build +/_site/ +/dist/ +/out-tsc/ + +storybook-static +.rollup.cache +*.tsbuildinfo \ No newline at end of file diff --git a/ui/index.html b/ui/index.html new file mode 100644 index 0000000..ec918a3 --- /dev/null +++ b/ui/index.html @@ -0,0 +1,18 @@ + + + + + + + + Generic Dna + + + + + + + \ No newline at end of file diff --git a/ui/package.json b/ui/package.json new file mode 100644 index 0000000..1a654cf --- /dev/null +++ b/ui/package.json @@ -0,0 +1,31 @@ +{ + "name": "ui", + "version": "0.1.0", + "scripts": { + "start": "vite --port $UI_PORT --clearScreen false", + "build": "vite build", + "format": "prettier \"**/*.ts\" --write --ignore-path .gitignore", + "package": "npm run build && rimraf dist.zip && cd dist && bestzip ../dist.zip *" + }, + "dependencies": { + "@holochain/client": "^0.19.0-dev.0", + "@lit/context": "^1.1.3", + "@lit/task": "^1.0.1", + "@msgpack/msgpack": "^2.8.0", + "lit": "^3.2.1" + }, + "devDependencies": { + "bestzip": "^2.2.1", + "prettier": "^2.8.8", + "rimraf": "^5.0.10", + "tslib": "^2.8.0", + "typescript": "^5.6.3", + "vite": "^5.4.10", + "vite-plugin-checker": "^0.5.6" + }, + "prettier": { + "singleQuote": true, + "arrowParens": "avoid" + }, + "type": "module" +} \ No newline at end of file diff --git a/ui/src/assets/holochainLogo.svg b/ui/src/assets/holochainLogo.svg new file mode 100644 index 0000000..d5b87c9 --- /dev/null +++ b/ui/src/assets/holochainLogo.svg @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ui/src/contexts.ts b/ui/src/contexts.ts new file mode 100644 index 0000000..a5af1e2 --- /dev/null +++ b/ui/src/contexts.ts @@ -0,0 +1,4 @@ +import { AppClient } from "@holochain/client"; +import { createContext } from "@lit/context"; + +export const clientContext = createContext("AppClient"); diff --git a/ui/src/declarations.d.ts b/ui/src/declarations.d.ts new file mode 100644 index 0000000..bac3728 --- /dev/null +++ b/ui/src/declarations.d.ts @@ -0,0 +1,9 @@ +declare module "*.svg" { + const content: string; + export default content; +} + +declare module "*.css?inline" { + const content: string; + export default content; +} diff --git a/ui/src/generic_dna/generic_zome/types.ts b/ui/src/generic_dna/generic_zome/types.ts new file mode 100644 index 0000000..1e5f59d --- /dev/null +++ b/ui/src/generic_dna/generic_zome/types.ts @@ -0,0 +1,39 @@ +import { + ActionHash, + AgentPubKey, + Create, + CreateLink, + Delete, + DeleteLink, + DnaHash, + EntryHash, + ExternalHash, + Record, + SignedActionHashed, + Update, +} from "@holochain/client"; + +export type GenericZomeSignal = { + type: "EntryCreated"; + action: SignedActionHashed; + app_entry: EntryTypes; +} | { + type: "EntryUpdated"; + action: SignedActionHashed; + app_entry: EntryTypes; + original_app_entry: EntryTypes; +} | { + type: "EntryDeleted"; + action: SignedActionHashed; + original_app_entry: EntryTypes; +} | { + type: "LinkCreated"; + action: SignedActionHashed; + link_type: string; +} | { + type: "LinkDeleted"; + action: SignedActionHashed; + link_type: string; +}; + +export type EntryTypes = {}; diff --git a/ui/src/holochain-app.ts b/ui/src/holochain-app.ts new file mode 100644 index 0000000..66c052c --- /dev/null +++ b/ui/src/holochain-app.ts @@ -0,0 +1,82 @@ +import { ActionHash, AppClient, AppWebsocket, HolochainError } from "@holochain/client"; +import { provide } from "@lit/context"; +import { css, html, LitElement } from "lit"; +import { customElement, property, state } from "lit/decorators.js"; + +import HolochainLogo from "./assets/holochainLogo.svg"; +import { clientContext } from "./contexts"; +import { sharedStyles } from "./shared-styles"; + +@customElement("holochain-app") +export class HolochainApp extends LitElement { + @state() + loading = false; + + @state() + error: HolochainError | undefined; + + @provide({ context: clientContext }) + @property({ type: Object }) + client!: AppClient; + + async firstUpdated() { + this.loading = true; + try { + this.client = await AppWebsocket.connect(); + } catch (e) { + this.error = e as HolochainError; + } finally { + this.loading = false; + } + } + + render() { + if (this.loading) return html``; + return html` +
+
+ + + +
+

Holochain Lit hApp

+
+
+ ${this.loading ? html`

connecting...

` : ""} + ${this.error ? html`

${this.error.message}

` : html`

Client is connected.

`} +
+

Import scaffolded components into src/holochain-app.ts to use your hApp

+

Click on the Holochain logo to learn more

+
+
+ `; + } + + static styles = css` + ${sharedStyles} + + .logo { + height: 15em; + padding: 1.5em; + will-change: filter; + transition: filter 300ms; + width: auto; + } + + .logo:hover { + filter: drop-shadow(0 0 2em #646cffaa); + } + + .logo.holochain:hover { + filter: drop-shadow(0 0 2em #61dafbaa); + } + + .card { + padding: 2em; + } + + .read-the-docs { + color: #888; + } + `; +} diff --git a/ui/src/index.css b/ui/src/index.css new file mode 100644 index 0000000..9cb3efd --- /dev/null +++ b/ui/src/index.css @@ -0,0 +1,261 @@ +:root { + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + line-height: 1.5; + font-weight: 400; + + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} +a:hover { + color: #535bf2; +} + +body { + margin: 0; + display: flex; + justify-content: center; + text-align: center; + align-items: center; + min-width: 320px; + min-height: 100vh; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +button { + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: inherit; + background-color: #1a1a1a; + cursor: pointer; + transition: border-color 0.25s; +} +button:hover { + border-color: #646cff; +} +button:focus, +button:focus-visible { + outline: 4px auto -webkit-focus-ring-color; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + a:hover { + color: #747bff; + } + button { + background-color: #f9f9f9; + } +} + +label { + display: block; + margin-bottom: 0.5em; + font-weight: 500; +} + +input { + display: block; + width: 540px; + padding: 0.75em; + margin: 0.5em 0; + border: 1px solid #ccc; + border-radius: 4px; + font-family: inherit; + font-size: 1em; + color: inherit; + background-color: #2c2c2c; + transition: border-color 0.25s, box-shadow 0.25s; +} + +input[type="checkbox"] { + display: inline-block; + width: auto; + margin-bottom: 1em; + transform: scale(1.5); + margin-right: 0.5em; + vertical-align: middle; +} + +input:focus { + outline: none; + border-color: #646cff; + box-shadow: 0 0 0 4px rgba(100, 108, 255, 0.2); +} + +textarea { + display: block; + width: 540px; + height: 150px; + padding: 0.75em; + margin: 0.5em 0; + border: 1px solid #ccc; + border-radius: 4px; + font-family: inherit; + font-size: 1em; + color: inherit; + background-color: #2c2c2c; + transition: border-color 0.25s, box-shadow 0.25s; + resize: none; +} + +textarea:focus { + outline: none; + border-color: #646cff; + box-shadow: 0 0 0 4px rgba(100, 108, 255, 0.2); +} + +@media (prefers-color-scheme: light) { + input, + textarea { + background-color: #ffffff; + border-color: #ccc; + } + + input:focus, + textarea:focus { + border-color: #646cff; + box-shadow: 0 0 0 4px rgba(100, 108, 255, 0.2); + } +} + +select { + display: block; + width: 566px; + padding: 0.75em; + margin: 1em 0; + border: 1px solid #ccc; + border-radius: 4px; + font-family: inherit; + font-size: 1em; + color: inherit; + background-color: #2c2c2c; + transition: border-color 0.25s, box-shadow 0.25s; +} + +select:focus { + outline: none; + border-color: #646cff; + box-shadow: 0 0 0 4px rgba(100, 108, 255, 0.2); +} + +@media (prefers-color-scheme: light) { + select { + background-color: #ffffff; + border-color: #ccc; + } + + select:focus { + border-color: #646cff; + box-shadow: 0 0 0 4px rgba(100, 108, 255, 0.2); + } +} + +.alert { + font-size: 1.2em; + font-weight: bold; + color: rgba(255, 255, 255, 0.87); + text-align: center; + padding: 2rem; + background-color: #333333; + border: 1px solid #555555; + border-radius: 8px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + margin: 1rem auto; + max-width: 500px; +} + +section { + padding: 2rem; + margin: 1rem 0; + background-color: #333333; + border: 1px solid #555555; + border-radius: 8px; + box-shadow: 0 8px 16px rgba(0, 0, 0, 0.3); + transition: transform 0.3s, box-shadow 0.3s; + max-width: 500px; +} + +section:hover { + transform: translateY(-5px); + box-shadow: 0 12px 24px rgba(0, 0, 0, 0.4); +} + +section div { + margin-bottom: 1.5rem; + padding: 1rem; + background-color: #444444; + border: 1px solid #666666; + border-radius: 4px; +} + +section input { + width: 440px; +} + +section select { + width: 464px; +} + +section textarea { + width: 440px; +} + +section div:last-child { + margin-bottom: 0; +} + +section p, +section span { + margin: 0; + font-size: 1em; + line-height: 1.6; + color: rgba(255, 255, 255, 0.87); +} + +section div:has(button) { + display: flex; + justify-content: space-between; + align-items: center; +} + +progress { + width: 100%; + height: 1.5em; +} + +progress::-webkit-progress-bar { + background-color: #444444; + border-radius: 8px; +} + +progress::-webkit-progress-value { + background-color: #646cff; + border-radius: 8px; +} + +progress::-moz-progress-bar { + background-color: #646cff; + border-radius: 8px; +} diff --git a/ui/src/shared-styles.ts b/ui/src/shared-styles.ts new file mode 100644 index 0000000..16fbca3 --- /dev/null +++ b/ui/src/shared-styles.ts @@ -0,0 +1,4 @@ +import { css, unsafeCSS } from "lit"; +import styles from "./index.css?inline"; + +export const sharedStyles = css`${unsafeCSS(styles)}`; diff --git a/ui/tsconfig.json b/ui/tsconfig.json new file mode 100644 index 0000000..4914f5b --- /dev/null +++ b/ui/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "target": "es2018", + "module": "esnext", + "moduleResolution": "node", + "noEmitOnError": true, + "useDefineForClassFields": false, + "lib": ["es2017", "dom"], + "strict": true, + "esModuleInterop": false, + "allowSyntheticDefaultImports": true, + "experimentalDecorators": true, + "importHelpers": true, + "outDir": "dist", + "sourceMap": true, + "inlineSources": true, + "incremental": true, + "skipLibCheck": true + }, + "include": ["src/**/*.ts", "src/**/*.d.ts"] +} diff --git a/ui/vite.config.ts b/ui/vite.config.ts new file mode 100644 index 0000000..a163def --- /dev/null +++ b/ui/vite.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from "vite"; +import checker from "vite-plugin-checker"; + +export default defineConfig({ + plugins: [ + checker({ typescript: true }), + ], +}); diff --git a/workdir/happ.yaml b/workdir/happ.yaml new file mode 100644 index 0000000..08b160e --- /dev/null +++ b/workdir/happ.yaml @@ -0,0 +1,18 @@ +manifest_version: '1' +name: generic-dna +description: null +roles: +- name: generic_dna + provisioning: + strategy: create + deferred: false + dna: + bundled: '../dnas/generic_dna/workdir/generic_dna.dna' + modifiers: + network_seed: null + properties: null + origin_time: null + quantum_time: null + installed_hash: null + clone_limit: 0 +allow_deferred_memproofs: false diff --git a/workdir/web-happ.yaml b/workdir/web-happ.yaml new file mode 100644 index 0000000..a3a05cc --- /dev/null +++ b/workdir/web-happ.yaml @@ -0,0 +1,6 @@ +manifest_version: '1' +name: generic-dna +ui: + bundled: '../ui/dist.zip' +happ_manifest: + bundled: './generic-dna.happ' From 2457a9b2dfdf1f3059c1102e8d3eb913d4e1583c Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 2 Nov 2024 12:37:15 +0100 Subject: [PATCH 02/12] scaffold entry-type thing --- Cargo.lock | 52 +-- Cargo.toml | 4 +- .../zomes/coordinator/generic_zome/src/lib.rs | 113 +++++- .../coordinator/generic_zome/src/thing.rs | 134 +++++++ .../zomes/integrity/generic_zome/src/lib.rs | 365 +++++++++++++----- .../zomes/integrity/generic_zome/src/thing.rs | 84 ++++ tests/src/generic_dna/generic_zome/common.ts | 17 + .../generic_dna/generic_zome/thing.test.ts | 218 +++++++++++ .../generic_dna/generic_zome/create-thing.ts | 89 +++++ ui/src/generic_dna/generic_zome/edit-thing.ts | 115 ++++++ .../generic_dna/generic_zome/thing-detail.ts | 112 ++++++ ui/src/generic_dna/generic_zome/types.ts | 9 +- 12 files changed, 1187 insertions(+), 125 deletions(-) create mode 100644 dnas/generic_dna/zomes/coordinator/generic_zome/src/thing.rs create mode 100644 dnas/generic_dna/zomes/integrity/generic_zome/src/thing.rs create mode 100644 tests/src/generic_dna/generic_zome/thing.test.ts create mode 100644 ui/src/generic_dna/generic_zome/create-thing.ts create mode 100644 ui/src/generic_dna/generic_zome/edit-thing.ts create mode 100644 ui/src/generic_dna/generic_zome/thing-detail.ts diff --git a/Cargo.lock b/Cargo.lock index 8e68886..3edeadc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -480,9 +480,9 @@ checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" [[package]] name = "hdi" -version = "0.6.0-dev.1" +version = "0.5.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea8e480e2393530bb6dac2962e9d203e88dda19a611d84b94e4b344e01af5524" +checksum = "60c3e7a067ee10f42db15bee27fb44482f93a43ff2b131fee31ac4fd8f49ccc2" dependencies = [ "getrandom", "hdk_derive", @@ -498,9 +498,9 @@ dependencies = [ [[package]] name = "hdk" -version = "0.5.0-dev.3" +version = "0.4.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd300c5521f7d91e8b72c2699c329b39c4564d2e28fc4dab58bc1a25ba7be9ea" +checksum = "c5d9305ed14e2dba02088e89a65d44294a701e35f715c9cd8692b70299666e86" dependencies = [ "getrandom", "hdi", @@ -518,9 +518,9 @@ dependencies = [ [[package]] name = "hdk_derive" -version = "0.5.0-dev.1" +version = "0.4.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "081025f237cd95c3787f874b66d070992a1f61f03174ad0b3785b7ebc382a833" +checksum = "4103bbeaec462f7f0643a418823dad035ed8e108d6d36322d6544f7565b5dbf5" dependencies = [ "darling 0.14.4", "heck", @@ -546,9 +546,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "holo_hash" -version = "0.5.0-dev.1" +version = "0.4.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4125906ccb19a314cb50ab3bcedd89dce378418b9875e78d102a412b2e0e2935" +checksum = "190c060ed23f60135e8ba0ff08c77a7ca283af35cc4aadf321433bfade7bcf5b" dependencies = [ "base64", "blake2b_simd", @@ -564,9 +564,9 @@ dependencies = [ [[package]] name = "holochain_integrity_types" -version = "0.5.0-dev.1" +version = "0.4.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e362fe68ac58399cc92ecf564d72f0abf3559a37b7bf23dd17a8f07fc12b8562" +checksum = "55fd6b8aa759be57a51c6af632d81e50e3200ac10d38dd35e094c1ed957591b9" dependencies = [ "holo_hash", "holochain_secure_primitive", @@ -581,9 +581,9 @@ dependencies = [ [[package]] name = "holochain_nonce" -version = "0.5.0-dev.0" +version = "0.4.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ddfd5d439236f7851cafbb50675cc21b4e5bacc97b0940e0afbeb06ffd88e92" +checksum = "e1e9d716254b6d1eba405b5fc0f09dc8d4260482fa06dbe98a4c610b38fd83de" dependencies = [ "getrandom", "holochain_secure_primitive", @@ -592,9 +592,9 @@ dependencies = [ [[package]] name = "holochain_secure_primitive" -version = "0.5.0-dev.0" +version = "0.4.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82afd5d62bfd82248770c4e8a81af26a3f5f95950b87273e5e0e36c98140bc33" +checksum = "3160015099d36ece72a40d78fe08033837dd5c8ea9cb23f01782986238a66480" dependencies = [ "paste", "serde", @@ -628,9 +628,9 @@ dependencies = [ [[package]] name = "holochain_util" -version = "0.5.0-dev.0" +version = "0.4.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915b4b3ecd06e1770fe32d122a1f98dee059be8c5e5a30a97f09d04c35c89298" +checksum = "89b36a8bd9f79cbe6de5fded86b9074c54081a97367660c466d25f5ac6841dc1" dependencies = [ "cfg-if", "colored", @@ -668,9 +668,9 @@ dependencies = [ [[package]] name = "holochain_zome_types" -version = "0.5.0-dev.3" +version = "0.4.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb4c42858c57e1d4e05e96b09dc46b64f4a964f8a0fa8b5a03497988115b8c3a" +checksum = "073de2496e0f7d5ed28d2fe20b366a9d0d81c85bc420936de4a4ca4bcfd772a7" dependencies = [ "derive_more", "holo_hash", @@ -774,9 +774,9 @@ dependencies = [ [[package]] name = "kitsune_p2p_bin_data" -version = "0.5.0-dev.1" +version = "0.4.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4629de79b97738bada705efbe2a0b56ff80fda500eb2031627069f5a51adfa55" +checksum = "bdb7c39b8e0c7c2f37457ab7005903bda9c30d4d2f45d84c61776dc025863559" dependencies = [ "base64", "derive_more", @@ -789,9 +789,9 @@ dependencies = [ [[package]] name = "kitsune_p2p_block" -version = "0.5.0-dev.1" +version = "0.4.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07d221a8c3ca518bd752ef7b08965b8d5a24d46dcf7c5b8a7ad8bcdd1d43c9b1" +checksum = "9d331df99fe02990b7ae8c3767ea9437519a158e353905dea49a022f3511bee8" dependencies = [ "kitsune_p2p_bin_data", "kitsune_p2p_timestamp", @@ -800,9 +800,9 @@ dependencies = [ [[package]] name = "kitsune_p2p_dht_arc" -version = "0.5.0-dev.1" +version = "0.4.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9491afd841f355b448c20e6792f3e8c36ead8f7bd0c26ca7ee468718076266b" +checksum = "8a821f0daf7ac92fc4bcd59e4b121387756ca8a68fcfe87b7efeac863b5483ab" dependencies = [ "derive_more", "gcollections", @@ -813,9 +813,9 @@ dependencies = [ [[package]] name = "kitsune_p2p_timestamp" -version = "0.5.0-dev.0" +version = "0.4.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528c144c80b366cf2dd2a8eee0d2f993bee281a1f51fa47a01b59c7ad92861a6" +checksum = "ca09ee47fe55fd72e12b2af9fd91bce5e6e0db04ecaa156ca75dd901a019af80" dependencies = [ "chrono", "serde", diff --git a/Cargo.toml b/Cargo.toml index b9dc9ac..717e003 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,8 +9,8 @@ members = ["dnas/*/zomes/coordinator/*", "dnas/*/zomes/integrity/*"] resolver = "2" [workspace.dependencies] -hdi = "=0.6.0-dev.1" -hdk = "=0.5.0-dev.3" +hdi = "0.5.0-rc.0" +hdk = "0.4.0-rc.0" serde = "1.0" [workspace.dependencies.generic_zome] diff --git a/dnas/generic_dna/zomes/coordinator/generic_zome/src/lib.rs b/dnas/generic_dna/zomes/coordinator/generic_zome/src/lib.rs index 828111b..f762512 100644 --- a/dnas/generic_dna/zomes/coordinator/generic_zome/src/lib.rs +++ b/dnas/generic_dna/zomes/coordinator/generic_zome/src/lib.rs @@ -1,5 +1,6 @@ -use hdk::prelude::*; +pub mod thing; use generic_zome_integrity::*; +use hdk::prelude::*; // Called the first time a zome call is made to the cell containing this zome #[hdk_extern] @@ -10,7 +11,30 @@ pub fn init() -> ExternResult { // Don't modify this enum if you want the scaffolding tool to generate appropriate signals for your entries and links #[derive(Serialize, Deserialize, Debug)] #[serde(tag = "type")] -pub enum Signal {} +pub enum Signal { + LinkCreated { + action: SignedActionHashed, + link_type: LinkTypes, + }, + LinkDeleted { + action: SignedActionHashed, + create_link_action: SignedActionHashed, + link_type: LinkTypes, + }, + EntryCreated { + action: SignedActionHashed, + app_entry: EntryTypes, + }, + EntryUpdated { + action: SignedActionHashed, + app_entry: EntryTypes, + original_app_entry: EntryTypes, + }, + EntryDeleted { + action: SignedActionHashed, + original_app_entry: EntryTypes, + }, +} // Whenever an action is committed, we emit a signal to the UI elements to reactively update them #[hdk_extern(infallible)] @@ -25,5 +49,88 @@ pub fn post_commit(committed_actions: Vec) { // Don't modify this function if you want the scaffolding tool to generate appropriate signals for your entries and links fn signal_action(action: SignedActionHashed) -> ExternResult<()> { - Ok(()) + match action.hashed.content.clone() { + Action::CreateLink(create_link) => { + if let Ok(Some(link_type)) = + LinkTypes::from_type(create_link.zome_index, create_link.link_type) + { + emit_signal(Signal::LinkCreated { action, link_type })?; + } + Ok(()) + } + Action::DeleteLink(delete_link) => { + let record = get(delete_link.link_add_address.clone(), GetOptions::default())?.ok_or( + wasm_error!(WasmErrorInner::Guest( + "Failed to fetch CreateLink action".to_string() + )), + )?; + match record.action() { + Action::CreateLink(create_link) => { + if let Ok(Some(link_type)) = + LinkTypes::from_type(create_link.zome_index, create_link.link_type) + { + emit_signal(Signal::LinkDeleted { + action, + link_type, + create_link_action: record.signed_action.clone(), + })?; + } + Ok(()) + } + _ => Err(wasm_error!(WasmErrorInner::Guest( + "Create Link should exist".to_string() + ))), + } + } + Action::Create(_create) => { + if let Ok(Some(app_entry)) = get_entry_for_action(&action.hashed.hash) { + emit_signal(Signal::EntryCreated { action, app_entry })?; + } + Ok(()) + } + Action::Update(update) => { + if let Ok(Some(app_entry)) = get_entry_for_action(&action.hashed.hash) { + if let Ok(Some(original_app_entry)) = + get_entry_for_action(&update.original_action_address) + { + emit_signal(Signal::EntryUpdated { + action, + app_entry, + original_app_entry, + })?; + } + } + Ok(()) + } + Action::Delete(delete) => { + if let Ok(Some(original_app_entry)) = get_entry_for_action(&delete.deletes_address) { + emit_signal(Signal::EntryDeleted { + action, + original_app_entry, + })?; + } + Ok(()) + } + _ => Ok(()), + } +} + +fn get_entry_for_action(action_hash: &ActionHash) -> ExternResult> { + let record = match get_details(action_hash.clone(), GetOptions::default())? { + Some(Details::Record(record_details)) => record_details.record, + _ => return Ok(None), + }; + let entry = match record.entry().as_option() { + Some(entry) => entry, + None => return Ok(None), + }; + let (zome_index, entry_index) = match record.action().entry_type() { + Some(EntryType::App(AppEntryDef { + zome_index, + entry_index, + .. + })) => (zome_index, entry_index), + _ => return Ok(None), + }; + EntryTypes::deserialize_from_type(*zome_index, *entry_index, entry) } diff --git a/dnas/generic_dna/zomes/coordinator/generic_zome/src/thing.rs b/dnas/generic_dna/zomes/coordinator/generic_zome/src/thing.rs new file mode 100644 index 0000000..8feb71d --- /dev/null +++ b/dnas/generic_dna/zomes/coordinator/generic_zome/src/thing.rs @@ -0,0 +1,134 @@ +use generic_zome_integrity::*; +use hdk::prelude::*; + +#[hdk_extern] +pub fn create_thing(thing: Thing) -> ExternResult { + let thing_hash = create_entry(&EntryTypes::Thing(thing.clone()))?; + let record = get(thing_hash.clone(), GetOptions::default())?.ok_or(wasm_error!( + WasmErrorInner::Guest("Could not find the newly created Thing".to_string()) + ))?; + Ok(record) +} + +#[hdk_extern] +pub fn get_latest_thing(original_thing_hash: ActionHash) -> ExternResult> { + let links = get_links( + GetLinksInputBuilder::try_new(original_thing_hash.clone(), LinkTypes::ThingUpdates)? + .build(), + )?; + let latest_link = links + .into_iter() + .max_by(|link_a, link_b| link_a.timestamp.cmp(&link_b.timestamp)); + let latest_thing_hash = match latest_link { + Some(link) => { + link.target + .clone() + .into_action_hash() + .ok_or(wasm_error!(WasmErrorInner::Guest( + "No action hash associated with link".to_string() + )))? + } + None => original_thing_hash.clone(), + }; + get(latest_thing_hash, GetOptions::default()) +} + +#[hdk_extern] +pub fn get_original_thing(original_thing_hash: ActionHash) -> ExternResult> { + let Some(details) = get_details(original_thing_hash, GetOptions::default())? else { + return Ok(None); + }; + match details { + Details::Record(details) => Ok(Some(details.record)), + _ => Err(wasm_error!(WasmErrorInner::Guest( + "Malformed get details response".to_string() + ))), + } +} + +#[hdk_extern] +pub fn get_all_revisions_for_thing(original_thing_hash: ActionHash) -> ExternResult> { + let Some(original_record) = get_original_thing(original_thing_hash.clone())? else { + return Ok(vec![]); + }; + let links = get_links( + GetLinksInputBuilder::try_new(original_thing_hash.clone(), LinkTypes::ThingUpdates)? + .build(), + )?; + let get_input: Vec = links + .into_iter() + .map(|link| { + Ok(GetInput::new( + link.target + .into_action_hash() + .ok_or(wasm_error!(WasmErrorInner::Guest( + "No action hash associated with link".to_string() + )))? + .into(), + GetOptions::default(), + )) + }) + .collect::>>()?; + let records = HDK.with(|hdk| hdk.borrow().get(get_input))?; + let mut records: Vec = records.into_iter().flatten().collect(); + records.insert(0, original_record); + Ok(records) +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct UpdateThingInput { + pub original_thing_hash: ActionHash, + pub previous_thing_hash: ActionHash, + pub updated_thing: Thing, +} + +#[hdk_extern] +pub fn update_thing(input: UpdateThingInput) -> ExternResult { + let updated_thing_hash = update_entry(input.previous_thing_hash.clone(), &input.updated_thing)?; + create_link( + input.original_thing_hash.clone(), + updated_thing_hash.clone(), + LinkTypes::ThingUpdates, + (), + )?; + let record = get(updated_thing_hash.clone(), GetOptions::default())?.ok_or(wasm_error!( + WasmErrorInner::Guest("Could not find the newly updated Thing".to_string()) + ))?; + Ok(record) +} + +#[hdk_extern] +pub fn delete_thing(original_thing_hash: ActionHash) -> ExternResult { + delete_entry(original_thing_hash) +} + +#[hdk_extern] +pub fn get_all_deletes_for_thing( + original_thing_hash: ActionHash, +) -> ExternResult>> { + let Some(details) = get_details(original_thing_hash, GetOptions::default())? else { + return Ok(None); + }; + match details { + Details::Entry(_) => Err(wasm_error!(WasmErrorInner::Guest( + "Malformed details".into() + ))), + Details::Record(record_details) => Ok(Some(record_details.deletes)), + } +} + +#[hdk_extern] +pub fn get_oldest_delete_for_thing( + original_thing_hash: ActionHash, +) -> ExternResult> { + let Some(mut deletes) = get_all_deletes_for_thing(original_thing_hash)? else { + return Ok(None); + }; + deletes.sort_by(|delete_a, delete_b| { + delete_a + .action() + .timestamp() + .cmp(&delete_b.action().timestamp()) + }); + Ok(deletes.first().cloned()) +} diff --git a/dnas/generic_dna/zomes/integrity/generic_zome/src/lib.rs b/dnas/generic_dna/zomes/integrity/generic_zome/src/lib.rs index 1b20c0e..dd4cfad 100644 --- a/dnas/generic_dna/zomes/integrity/generic_zome/src/lib.rs +++ b/dnas/generic_dna/zomes/integrity/generic_zome/src/lib.rs @@ -1,19 +1,31 @@ +pub mod thing; use hdi::prelude::*; +pub use thing::*; + +#[derive(Serialize, Deserialize)] +#[serde(tag = "type")] +#[hdk_entry_types] +#[unit_enum(UnitEntryTypes)] +pub enum EntryTypes { + Thing(Thing), +} + +#[derive(Serialize, Deserialize)] +#[hdk_link_types] +pub enum LinkTypes { + ThingUpdates, +} // Validation you perform during the genesis process. Nobody else on the network performs it, only you. // There *is no* access to network calls in this callback #[hdk_extern] -pub fn genesis_self_check( - - _data: GenesisSelfCheckData, -) -> ExternResult { +pub fn genesis_self_check(_data: GenesisSelfCheckData) -> ExternResult { Ok(ValidateCallbackResult::Valid) } // Validation the network performs when you try to join, you can't perform this validation yourself as you are not a member yet. // There *is* access to network calls in this function pub fn validate_agent_joining( - _agent_pub_key: AgentPubKey, _membrane_proof: &Option, ) -> ExternResult { @@ -22,7 +34,6 @@ pub fn validate_agent_joining( // This is the unified validation callback for all entries and link types in this integrity zome // Below is a match template for all of the variants of `DHT Ops` and entry and link types -// // Holochain has already performed the following validation for you: // - The action signature matches on the hash of its content and is signed by its author // - The previous action exists, has a lower timestamp than the new action, and incremented sequence number @@ -38,48 +49,102 @@ pub fn validate_agent_joining( // - If the `Op` is a delete link, the original action exists and is a `CreateLink` action // - Link tags don't exceed the maximum tag size (currently 1KB) // - Countersigned entries include an action from each required signer -// -// You can read more about validation here: https://docs.rs/hdi/latest/hdi/index.html#data-validation +// You can read more about validation here: http// ocs.rs/hdi/latest/hdi/index.html#data-validation #[hdk_extern] pub fn validate(op: Op) -> ExternResult { - match op.flattened::<(), ()>()? { - FlatOp::StoreEntry(store_entry) => { - match store_entry { - OpEntry::CreateEntry { app_entry, action } => { - Ok( - ValidateCallbackResult::Invalid( - "There are no entry types in this integrity zome".to_string(), - ), - ) + match op.flattened::()? { + FlatOp::StoreEntry(store_entry) => match store_entry { + OpEntry::CreateEntry { app_entry, action } => match app_entry { + EntryTypes::Thing(thing) => { + validate_create_thing(EntryCreationAction::Create(action), thing) } - OpEntry::UpdateEntry { app_entry, action, .. } => { - Ok( - ValidateCallbackResult::Invalid( - "There are no entry types in this integrity zome".to_string(), - ), - ) + }, + OpEntry::UpdateEntry { + app_entry, action, .. + } => match app_entry { + EntryTypes::Thing(thing) => { + validate_create_thing(EntryCreationAction::Update(action), thing) } - _ => Ok(ValidateCallbackResult::Valid), - } - } - FlatOp::RegisterUpdate(update_entry) => { - match update_entry { - OpUpdate::Entry { app_entry, action } => { - Ok( - ValidateCallbackResult::Invalid( - "There are no entry types in this integrity zome".to_string(), - ), - ) + }, + _ => Ok(ValidateCallbackResult::Valid), + }, + FlatOp::RegisterUpdate(update_entry) => match update_entry { + OpUpdate::Entry { app_entry, action } => { + let original_action = must_get_action(action.clone().original_action_address)? + .action() + .to_owned(); + let original_create_action = match EntryCreationAction::try_from(original_action) { + Ok(action) => action, + Err(e) => { + return Ok(ValidateCallbackResult::Invalid(format!( + "Expected to get EntryCreationAction from Action: {e:?}" + ))); + } + }; + match app_entry { + EntryTypes::Thing(thing) => { + let original_app_entry = + must_get_valid_record(action.clone().original_action_address)?; + let original_thing = match Thing::try_from(original_app_entry) { + Ok(entry) => entry, + Err(e) => { + return Ok(ValidateCallbackResult::Invalid(format!( + "Expected to get Thing from Record: {e:?}" + ))); + } + }; + validate_update_thing(action, thing, original_create_action, original_thing) + } } - _ => Ok(ValidateCallbackResult::Valid), } - } + _ => Ok(ValidateCallbackResult::Valid), + }, FlatOp::RegisterDelete(delete_entry) => { - Ok( - ValidateCallbackResult::Invalid( - "There are no entry types in this integrity zome".to_string(), + let original_action_hash = delete_entry.clone().action.deletes_address; + let original_record = must_get_valid_record(original_action_hash)?; + let original_record_action = original_record.action().clone(); + let original_action = match EntryCreationAction::try_from(original_record_action) { + Ok(action) => action, + Err(e) => { + return Ok(ValidateCallbackResult::Invalid(format!( + "Expected to get EntryCreationAction from Action: {e:?}" + ))); + } + }; + let app_entry_type = match original_action.entry_type() { + EntryType::App(app_entry_type) => app_entry_type, + _ => { + return Ok(ValidateCallbackResult::Valid); + } + }; + let entry = match original_record.entry().as_option() { + Some(entry) => entry, + None => { + return Ok(ValidateCallbackResult::Invalid( + "Original record for a delete must contain an entry".to_string(), + )); + } + }; + let original_app_entry = match EntryTypes::deserialize_from_type( + app_entry_type.zome_index, + app_entry_type.entry_index, + entry, + )? { + Some(app_entry) => app_entry, + None => { + return Ok(ValidateCallbackResult::Invalid( + "Original app entry must be one of the defined entry types for this zome" + .to_string(), + )); + } + }; + match original_app_entry { + EntryTypes::Thing(original_thing) => validate_delete_thing( + delete_entry.clone().action, + original_action, + original_thing, ), - ) + } } FlatOp::RegisterCreateLink { link_type, @@ -87,13 +152,11 @@ pub fn validate(op: Op) -> ExternResult { target_address, tag, action, - } => { - Ok( - ValidateCallbackResult::Invalid( - "There are no link types in this integrity zome".to_string(), - ), - ) - } + } => match link_type { + LinkTypes::ThingUpdates => { + validate_create_link_thing_updates(action, base_address, target_address, tag) + } + }, FlatOp::RegisterDeleteLink { link_type, base_address, @@ -101,44 +164,134 @@ pub fn validate(op: Op) -> ExternResult { tag, original_action, action, - } => { - Ok( - ValidateCallbackResult::Invalid( - "There are no link types in this integrity zome".to_string(), - ), - ) - } + } => match link_type { + LinkTypes::ThingUpdates => validate_delete_link_thing_updates( + action, + original_action, + base_address, + target_address, + tag, + ), + }, FlatOp::StoreRecord(store_record) => { match store_record { // Complementary validation to the `StoreEntry` Op, in which the record itself is validated // If you want to optimize performance, you can remove the validation for an entry type here and keep it in `StoreEntry` // Notice that doing so will cause `must_get_valid_record` for this record to return a valid record even if the `StoreEntry` validation failed - OpRecord::CreateEntry { app_entry, action } => { - Ok( - ValidateCallbackResult::Invalid( - "There are no entry types in this integrity zome".to_string(), - ), - ) - } + OpRecord::CreateEntry { app_entry, action } => match app_entry { + EntryTypes::Thing(thing) => { + validate_create_thing(EntryCreationAction::Create(action), thing) + } + }, // Complementary validation to the `RegisterUpdate` Op, in which the record itself is validated // If you want to optimize performance, you can remove the validation for an entry type here and keep it in `StoreEntry` and in `RegisterUpdate` // Notice that doing so will cause `must_get_valid_record` for this record to return a valid record even if the other validations failed - OpRecord::UpdateEntry { original_action_hash, app_entry, action, .. } => { - Ok( - ValidateCallbackResult::Invalid( - "There are no entry types in this integrity zome".to_string(), - ), - ) + OpRecord::UpdateEntry { + original_action_hash, + app_entry, + action, + .. + } => { + let original_record = must_get_valid_record(original_action_hash)?; + let original_action = original_record.action().clone(); + let original_action = match original_action { + Action::Create(create) => EntryCreationAction::Create(create), + Action::Update(update) => EntryCreationAction::Update(update), + _ => { + return Ok(ValidateCallbackResult::Invalid( + "Original action for an update must be a Create or Update action" + .to_string(), + )); + } + }; + match app_entry { + EntryTypes::Thing(thing) => { + let result = validate_create_thing( + EntryCreationAction::Update(action.clone()), + thing.clone(), + )?; + if let ValidateCallbackResult::Valid = result { + let original_thing: Option = original_record + .entry() + .to_app_option() + .map_err(|e| wasm_error!(e))?; + let original_thing = match original_thing { + Some(thing) => thing, + None => { + return Ok( + ValidateCallbackResult::Invalid( + "The updated entry type must be the same as the original entry type" + .to_string(), + ), + ); + } + }; + validate_update_thing( + action, + thing, + original_action, + original_thing, + ) + } else { + Ok(result) + } + } + } } // Complementary validation to the `RegisterDelete` Op, in which the record itself is validated // If you want to optimize performance, you can remove the validation for an entry type here and keep it in `RegisterDelete` // Notice that doing so will cause `must_get_valid_record` for this record to return a valid record even if the `RegisterDelete` validation failed - OpRecord::DeleteEntry { original_action_hash, action, .. } => { - Ok( - ValidateCallbackResult::Invalid( - "There are no entry types in this integrity zome".to_string(), - ), - ) + OpRecord::DeleteEntry { + original_action_hash, + action, + .. + } => { + let original_record = must_get_valid_record(original_action_hash)?; + let original_action = original_record.action().clone(); + let original_action = match original_action { + Action::Create(create) => EntryCreationAction::Create(create), + Action::Update(update) => EntryCreationAction::Update(update), + _ => { + return Ok(ValidateCallbackResult::Invalid( + "Original action for a delete must be a Create or Update action" + .to_string(), + )); + } + }; + let app_entry_type = match original_action.entry_type() { + EntryType::App(app_entry_type) => app_entry_type, + _ => { + return Ok(ValidateCallbackResult::Valid); + } + }; + let entry = match original_record.entry().as_option() { + Some(entry) => entry, + None => { + return Ok(ValidateCallbackResult::Invalid( + "Original record for a delete must contain an entry".to_string(), + )); + } + }; + let original_app_entry = match EntryTypes::deserialize_from_type( + app_entry_type.zome_index, + app_entry_type.entry_index, + entry, + )? { + Some(app_entry) => app_entry, + None => { + return Ok( + ValidateCallbackResult::Invalid( + "Original app entry must be one of the defined entry types for this zome" + .to_string(), + ), + ); + } + }; + match original_app_entry { + EntryTypes::Thing(original_thing) => { + validate_delete_thing(action, original_action, original_thing) + } + } } // Complementary validation to the `RegisterCreateLink` Op, in which the record itself is validated // If you want to optimize performance, you can remove the validation for an entry type here and keep it in `RegisterCreateLink` @@ -149,22 +302,50 @@ pub fn validate(op: Op) -> ExternResult { tag, link_type, action, - } => { - Ok( - ValidateCallbackResult::Invalid( - "There are no link types in this integrity zome".to_string(), - ), - ) - } + } => match link_type { + LinkTypes::ThingUpdates => validate_create_link_thing_updates( + action, + base_address, + target_address, + tag, + ), + }, // Complementary validation to the `RegisterDeleteLink` Op, in which the record itself is validated // If you want to optimize performance, you can remove the validation for an entry type here and keep it in `RegisterDeleteLink` // Notice that doing so will cause `must_get_valid_record` for this record to return a valid record even if the `RegisterDeleteLink` validation failed - OpRecord::DeleteLink { original_action_hash, base_address, action } => { - Ok( - ValidateCallbackResult::Invalid( - "There are no link types in this integrity zome".to_string(), + OpRecord::DeleteLink { + original_action_hash, + base_address, + action, + } => { + let record = must_get_valid_record(original_action_hash)?; + let create_link = match record.action() { + Action::CreateLink(create_link) => create_link.clone(), + _ => { + return Ok(ValidateCallbackResult::Invalid( + "The action that a DeleteLink deletes must be a CreateLink" + .to_string(), + )); + } + }; + let link_type = match LinkTypes::from_type( + create_link.zome_index, + create_link.link_type, + )? { + Some(lt) => lt, + None => { + return Ok(ValidateCallbackResult::Valid); + } + }; + match link_type { + LinkTypes::ThingUpdates => validate_delete_link_thing_updates( + action, + create_link.clone(), + base_address, + create_link.target_address, + create_link.tag, ), - ) + } } OpRecord::CreatePrivateEntry { .. } => Ok(ValidateCallbackResult::Valid), OpRecord::UpdatePrivateEntry { .. } => Ok(ValidateCallbackResult::Valid), @@ -179,11 +360,10 @@ pub fn validate(op: Op) -> ExternResult { _ => Ok(ValidateCallbackResult::Valid), } } - FlatOp::RegisterAgentActivity(agent_activity) => { - match agent_activity { - OpActivity::CreateAgent { agent, action } => { - let previous_action = must_get_action(action.prev_action)?; - match previous_action.action() { + FlatOp::RegisterAgentActivity(agent_activity) => match agent_activity { + OpActivity::CreateAgent { agent, action } => { + let previous_action = must_get_action(action.prev_action)?; + match previous_action.action() { Action::AgentValidationPkg( AgentValidationPkg { membrane_proof, .. }, ) => validate_agent_joining(agent, membrane_proof), @@ -196,9 +376,8 @@ pub fn validate(op: Op) -> ExternResult { ) } } - } - _ => Ok(ValidateCallbackResult::Valid), } - } + _ => Ok(ValidateCallbackResult::Valid), + }, } } diff --git a/dnas/generic_dna/zomes/integrity/generic_zome/src/thing.rs b/dnas/generic_dna/zomes/integrity/generic_zome/src/thing.rs new file mode 100644 index 0000000..b0d663b --- /dev/null +++ b/dnas/generic_dna/zomes/integrity/generic_zome/src/thing.rs @@ -0,0 +1,84 @@ +use hdi::prelude::*; + +#[derive(Clone, PartialEq)] +#[hdk_entry_helper] +pub struct Thing { + pub content: String, +} + +pub fn validate_create_thing( + _action: EntryCreationAction, + _thing: Thing, +) -> ExternResult { + // TODO: add the appropriate validation rules + Ok(ValidateCallbackResult::Valid) +} + +pub fn validate_update_thing( + _action: Update, + _thing: Thing, + _original_action: EntryCreationAction, + _original_thing: Thing, +) -> ExternResult { + // TODO: add the appropriate validation rules + Ok(ValidateCallbackResult::Valid) +} + +pub fn validate_delete_thing( + _action: Delete, + _original_action: EntryCreationAction, + _original_thing: Thing, +) -> ExternResult { + // TODO: add the appropriate validation rules + Ok(ValidateCallbackResult::Valid) +} + +pub fn validate_create_link_thing_updates( + _action: CreateLink, + base_address: AnyLinkableHash, + target_address: AnyLinkableHash, + _tag: LinkTag, +) -> ExternResult { + // Check the entry type for the given action hash + let action_hash = base_address + .into_action_hash() + .ok_or(wasm_error!(WasmErrorInner::Guest( + "No action hash associated with link".to_string() + )))?; + let record = must_get_valid_record(action_hash)?; + let _thing: crate::Thing = record + .entry() + .to_app_option() + .map_err(|e| wasm_error!(e))? + .ok_or(wasm_error!(WasmErrorInner::Guest( + "Linked action must reference an entry".to_string() + )))?; + // Check the entry type for the given action hash + let action_hash = + target_address + .into_action_hash() + .ok_or(wasm_error!(WasmErrorInner::Guest( + "No action hash associated with link".to_string() + )))?; + let record = must_get_valid_record(action_hash)?; + let _thing: crate::Thing = record + .entry() + .to_app_option() + .map_err(|e| wasm_error!(e))? + .ok_or(wasm_error!(WasmErrorInner::Guest( + "Linked action must reference an entry".to_string() + )))?; + Ok(ValidateCallbackResult::Valid) +} + +pub fn validate_delete_link_thing_updates( + _action: DeleteLink, + _original_action: CreateLink, + _base: AnyLinkableHash, + _target: AnyLinkableHash, + _tag: LinkTag, +) -> ExternResult { + Ok(ValidateCallbackResult::Invalid( + "ThingUpdates links cannot be deleted".to_string(), + )) +} diff --git a/tests/src/generic_dna/generic_zome/common.ts b/tests/src/generic_dna/generic_zome/common.ts index 10ee7dd..8b3edc1 100644 --- a/tests/src/generic_dna/generic_zome/common.ts +++ b/tests/src/generic_dna/generic_zome/common.ts @@ -10,3 +10,20 @@ import { Record, } from "@holochain/client"; import { CallableCell } from "@holochain/tryorama"; + +export async function sampleThing(cell: CallableCell, partialThing = {}) { + return { + ...{ + content: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", + }, + ...partialThing, + }; +} + +export async function createThing(cell: CallableCell, thing = undefined): Promise { + return cell.callZome({ + zome_name: "generic_zome", + fn_name: "create_thing", + payload: thing || await sampleThing(cell), + }); +} diff --git a/tests/src/generic_dna/generic_zome/thing.test.ts b/tests/src/generic_dna/generic_zome/thing.test.ts new file mode 100644 index 0000000..be6a96b --- /dev/null +++ b/tests/src/generic_dna/generic_zome/thing.test.ts @@ -0,0 +1,218 @@ +import { assert, test } from "vitest"; + +import { + ActionHash, + AppBundleSource, + CreateLink, + DeleteLink, + fakeActionHash, + fakeAgentPubKey, + fakeEntryHash, + Link, + NewEntryAction, + Record, + SignedActionHashed, +} from "@holochain/client"; +import { CallableCell, dhtSync, runScenario } from "@holochain/tryorama"; +import { decode } from "@msgpack/msgpack"; + +import { createThing, sampleThing } from "./common.js"; + +test("create Thing", async () => { + await runScenario(async scenario => { + // Construct proper paths for your app. + // This assumes app bundle created by the `hc app pack` command. + const testAppPath = process.cwd() + "/../workdir/generic-dna.happ"; + + // Set up the app to be installed + const appSource = { appBundleSource: { path: testAppPath } }; + + // Add 2 players with the test app to the Scenario. The returned players + // can be destructured. + const [alice, bob] = await scenario.addPlayersWithApps([appSource, appSource]); + + // Shortcut peer discovery through gossip and register all agents in every + // conductor of the scenario. + await scenario.shareAllAgents(); + + // Alice creates a Thing + const record: Record = await createThing(alice.cells[0]); + assert.ok(record); + }); +}); + +test("create and read Thing", async () => { + await runScenario(async scenario => { + // Construct proper paths for your app. + // This assumes app bundle created by the `hc app pack` command. + const testAppPath = process.cwd() + "/../workdir/generic-dna.happ"; + + // Set up the app to be installed + const appSource = { appBundleSource: { path: testAppPath } }; + + // Add 2 players with the test app to the Scenario. The returned players + // can be destructured. + const [alice, bob] = await scenario.addPlayersWithApps([appSource, appSource]); + + // Shortcut peer discovery through gossip and register all agents in every + // conductor of the scenario. + await scenario.shareAllAgents(); + + const sample = await sampleThing(alice.cells[0]); + + // Alice creates a Thing + const record: Record = await createThing(alice.cells[0], sample); + assert.ok(record); + + // Wait for the created entry to be propagated to the other node. + await dhtSync([alice, bob], alice.cells[0].cell_id[0]); + + // Bob gets the created Thing + const createReadOutput: Record = await bob.cells[0].callZome({ + zome_name: "generic_zome", + fn_name: "get_original_thing", + payload: record.signed_action.hashed.hash, + }); + assert.deepEqual(sample, decode((createReadOutput.entry as any).Present.entry) as any); + }); +}); + +test("create and update Thing", async () => { + await runScenario(async scenario => { + // Construct proper paths for your app. + // This assumes app bundle created by the `hc app pack` command. + const testAppPath = process.cwd() + "/../workdir/generic-dna.happ"; + + // Set up the app to be installed + const appSource = { appBundleSource: { path: testAppPath } }; + + // Add 2 players with the test app to the Scenario. The returned players + // can be destructured. + const [alice, bob] = await scenario.addPlayersWithApps([appSource, appSource]); + + // Shortcut peer discovery through gossip and register all agents in every + // conductor of the scenario. + await scenario.shareAllAgents(); + + // Alice creates a Thing + const record: Record = await createThing(alice.cells[0]); + assert.ok(record); + + const originalActionHash = record.signed_action.hashed.hash; + + // Alice updates the Thing + let contentUpdate: any = await sampleThing(alice.cells[0]); + let updateInput = { + original_thing_hash: originalActionHash, + previous_thing_hash: originalActionHash, + updated_thing: contentUpdate, + }; + + let updatedRecord: Record = await alice.cells[0].callZome({ + zome_name: "generic_zome", + fn_name: "update_thing", + payload: updateInput, + }); + assert.ok(updatedRecord); + + // Wait for the updated entry to be propagated to the other node. + await dhtSync([alice, bob], alice.cells[0].cell_id[0]); + + // Bob gets the updated Thing + const readUpdatedOutput0: Record = await bob.cells[0].callZome({ + zome_name: "generic_zome", + fn_name: "get_latest_thing", + payload: updatedRecord.signed_action.hashed.hash, + }); + assert.deepEqual(contentUpdate, decode((readUpdatedOutput0.entry as any).Present.entry) as any); + + // Alice updates the Thing again + contentUpdate = await sampleThing(alice.cells[0]); + updateInput = { + original_thing_hash: originalActionHash, + previous_thing_hash: updatedRecord.signed_action.hashed.hash, + updated_thing: contentUpdate, + }; + + updatedRecord = await alice.cells[0].callZome({ + zome_name: "generic_zome", + fn_name: "update_thing", + payload: updateInput, + }); + assert.ok(updatedRecord); + + // Wait for the updated entry to be propagated to the other node. + await dhtSync([alice, bob], alice.cells[0].cell_id[0]); + + // Bob gets the updated Thing + const readUpdatedOutput1: Record = await bob.cells[0].callZome({ + zome_name: "generic_zome", + fn_name: "get_latest_thing", + payload: updatedRecord.signed_action.hashed.hash, + }); + assert.deepEqual(contentUpdate, decode((readUpdatedOutput1.entry as any).Present.entry) as any); + + // Bob gets all the revisions for Thing + const revisions: Record[] = await bob.cells[0].callZome({ + zome_name: "generic_zome", + fn_name: "get_all_revisions_for_thing", + payload: originalActionHash, + }); + assert.equal(revisions.length, 3); + assert.deepEqual(contentUpdate, decode((revisions[2].entry as any).Present.entry) as any); + }); +}); + +test("create and delete Thing", async () => { + await runScenario(async scenario => { + // Construct proper paths for your app. + // This assumes app bundle created by the `hc app pack` command. + const testAppPath = process.cwd() + "/../workdir/generic-dna.happ"; + + // Set up the app to be installed + const appSource = { appBundleSource: { path: testAppPath } }; + + // Add 2 players with the test app to the Scenario. The returned players + // can be destructured. + const [alice, bob] = await scenario.addPlayersWithApps([appSource, appSource]); + + // Shortcut peer discovery through gossip and register all agents in every + // conductor of the scenario. + await scenario.shareAllAgents(); + + const sample = await sampleThing(alice.cells[0]); + + // Alice creates a Thing + const record: Record = await createThing(alice.cells[0], sample); + assert.ok(record); + + await dhtSync([alice, bob], alice.cells[0].cell_id[0]); + + // Alice deletes the Thing + const deleteActionHash = await alice.cells[0].callZome({ + zome_name: "generic_zome", + fn_name: "delete_thing", + payload: record.signed_action.hashed.hash, + }); + assert.ok(deleteActionHash); + + // Wait for the entry deletion to be propagated to the other node. + await dhtSync([alice, bob], alice.cells[0].cell_id[0]); + + // Bob gets the oldest delete for the Thing + const oldestDeleteForThing: SignedActionHashed = await bob.cells[0].callZome({ + zome_name: "generic_zome", + fn_name: "get_oldest_delete_for_thing", + payload: record.signed_action.hashed.hash, + }); + assert.ok(oldestDeleteForThing); + + // Bob gets the deletions for the Thing + const deletesForThing: SignedActionHashed[] = await bob.cells[0].callZome({ + zome_name: "generic_zome", + fn_name: "get_all_deletes_for_thing", + payload: record.signed_action.hashed.hash, + }); + assert.equal(deletesForThing.length, 1); + }); +}); diff --git a/ui/src/generic_dna/generic_zome/create-thing.ts b/ui/src/generic_dna/generic_zome/create-thing.ts new file mode 100644 index 0000000..83b3c46 --- /dev/null +++ b/ui/src/generic_dna/generic_zome/create-thing.ts @@ -0,0 +1,89 @@ +import { + ActionHash, + AgentPubKey, + AppClient, + DnaHash, + EntryHash, + HolochainError, + InstalledCell, + Record, +} from "@holochain/client"; +import { consume } from "@lit/context"; +import { html, LitElement } from "lit"; +import { customElement, property, state } from "lit/decorators.js"; + +import { clientContext } from "../../contexts"; +import { sharedStyles } from "../../shared-styles"; +import { Thing } from "./types"; + +@customElement("create-thing") +export class CreateThing extends LitElement { + @consume({ context: clientContext }) + client!: AppClient; + + @state() + _content: string = ""; + + firstUpdated() { + } + + isThingValid() { + return true && this._content !== ""; + } + + async createThing() { + const thing: Thing = { + content: this._content, + }; + + try { + const record: Record = await this.client.callZome({ + cap_secret: null, + role_name: "generic_dna", + zome_name: "generic_zome", + fn_name: "create_thing", + payload: thing, + }); + + this.dispatchEvent( + new CustomEvent("thing-created", { + composed: true, + bubbles: true, + detail: { + thingHash: record.signed_action.hashed.hash, + }, + }), + ); + } catch (e) { + alert((e as HolochainError).message); + } + } + + render() { + return html` +
+

Create Thing

+
+ + { + this._content = (e.target as any).value; + }} + required +> +
+ + +
+ `; + } + + static styles = sharedStyles; +} diff --git a/ui/src/generic_dna/generic_zome/edit-thing.ts b/ui/src/generic_dna/generic_zome/edit-thing.ts new file mode 100644 index 0000000..04ae05b --- /dev/null +++ b/ui/src/generic_dna/generic_zome/edit-thing.ts @@ -0,0 +1,115 @@ +import { ActionHash, AgentPubKey, AppClient, DnaHash, EntryHash, HolochainError, Record } from "@holochain/client"; +import { consume } from "@lit/context"; +import { decode } from "@msgpack/msgpack"; +import { html, LitElement } from "lit"; +import { customElement, property, state } from "lit/decorators.js"; + +import { clientContext } from "../../contexts"; +import { Thing } from "./types"; + +@customElement("edit-thing") +export class EditThing extends LitElement { + @consume({ context: clientContext }) + client!: AppClient; + + @property({ + hasChanged: (newVal: ActionHash, oldVal: ActionHash) => newVal?.toString() !== oldVal?.toString(), + }) + originalThingHash!: ActionHash; + + @property() + currentRecord!: Record; + + get currentThing() { + return decode((this.currentRecord.entry as any).Present.entry) as Thing; + } + + @state() + _content!: string; + + isThingValid() { + return true && this._content !== ""; + } + + connectedCallback() { + super.connectedCallback(); + if (!this.currentRecord) { + throw new Error(`The currentRecord property is required for the edit-thing element`); + } + + if (!this.originalThingHash) { + throw new Error(`The originalThingHash property is required for the edit-thing element`); + } + + this._content = this.currentThing.content; + } + + async updateThing() { + const thing: Thing = { + content: this._content!, + }; + + try { + const updateRecord: Record = await this.client.callZome({ + cap_secret: null, + role_name: "generic_dna", + zome_name: "generic_zome", + fn_name: "update_thing", + payload: { + original_thing_hash: this.originalThingHash, + previous_thing_hash: this.currentRecord.signed_action.hashed.hash, + updated_thing: thing, + }, + }); + + this.dispatchEvent( + new CustomEvent("thing-updated", { + composed: true, + bubbles: true, + detail: { + originalThingHash: this.originalThingHash, + previousThingHash: this.currentRecord.signed_action.hashed.hash, + updatedThingHash: updateRecord.signed_action.hashed.hash, + }, + }), + ); + } catch (e) { + alert((e as HolochainError).message); + } + } + + render() { + return html` +
+
+ + { + this._content = (e.target as any).value; + }} + required +> +
+ + +
+ + +
+
+ `; + } +} diff --git a/ui/src/generic_dna/generic_zome/thing-detail.ts b/ui/src/generic_dna/generic_zome/thing-detail.ts new file mode 100644 index 0000000..06ef86d --- /dev/null +++ b/ui/src/generic_dna/generic_zome/thing-detail.ts @@ -0,0 +1,112 @@ +import { ActionHash, AppClient, DnaHash, EntryHash, HolochainError, Record } from "@holochain/client"; +import { consume } from "@lit/context"; +import { Task } from "@lit/task"; +import { decode } from "@msgpack/msgpack"; +import { html, LitElement } from "lit"; +import { customElement, property, state } from "lit/decorators.js"; + +import "./edit-thing"; + +import { clientContext } from "../../contexts"; +import { Thing } from "./types"; + +@customElement("thing-detail") +export class ThingDetail extends LitElement { + @consume({ context: clientContext }) + client!: AppClient; + + @property({ + hasChanged: (newVal: ActionHash, oldVal: ActionHash) => newVal?.toString() !== oldVal?.toString(), + }) + thingHash!: ActionHash; + + _fetchRecord = new Task(this, ([thingHash]: Array) => + this.client.callZome({ + cap_secret: null, + role_name: "generic_dna", + zome_name: "generic_zome", + fn_name: "get_latest_thing", + payload: thingHash, + }) as Promise, () => [this.thingHash]); + + @state() + _editing = false; + + firstUpdated() { + if (!this.thingHash) { + throw new Error(`The thingHash property is required for the thing-detail element`); + } + } + + async deleteThing() { + try { + await this.client.callZome({ + cap_secret: null, + role_name: "generic_dna", + zome_name: "generic_zome", + fn_name: "delete_thing", + payload: this.thingHash, + }); + this.dispatchEvent( + new CustomEvent("thing-deleted", { + bubbles: true, + composed: true, + detail: { + thingHash: this.thingHash, + }, + }), + ); + this._fetchRecord.run(); + } catch (e) { + alert((e as HolochainError).message); + } + } + + renderDetail(record: Record) { + const thing = decode((record.entry as any).Present.entry) as Thing; + + return html` +
+
+ Content: + ${thing.content} +
+ +
+ + +
+
+ `; + } + + renderThing(record: Record | undefined) { + if (!record) return html`
The requested thing was not found.
`; + if (this._editing) { + return html` + { + this._editing = false; + await this._fetchRecord.run(); + }} + @edit-canceled=${() => { + this._editing = false; + }} + > + `; + } + return this.renderDetail(record); + } + + render() { + return this._fetchRecord.render({ + pending: () => html``, + complete: (record) => this.renderThing(record), + error: (e: any) => html`
Error fetching the thing: ${e.message}
`, + }); + } +} diff --git a/ui/src/generic_dna/generic_zome/types.ts b/ui/src/generic_dna/generic_zome/types.ts index 1e5f59d..7324045 100644 --- a/ui/src/generic_dna/generic_zome/types.ts +++ b/ui/src/generic_dna/generic_zome/types.ts @@ -36,4 +36,11 @@ export type GenericZomeSignal = { link_type: string; }; -export type EntryTypes = {}; +/* dprint-ignore-start */ +export type EntryTypes = + | ({ type: 'Thing'; } & Thing); +/* dprint-ignore-end */ + +export interface Thing { + content: string; +} From 620fe7942502799f04a970933ce643d0ef4a656e Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 2 Nov 2024 12:49:23 +0100 Subject: [PATCH 03/12] scaffold link-type and create other link types --- .../generic_zome/src/{thing.rs => api.rs} | 0 .../zomes/coordinator/generic_zome/src/lib.rs | 13 +-- .../generic_zome/src/thing_to_agents.rs | 64 ++++++++++++ .../zomes/integrity/generic_zome/src/lib.rs | 74 +++++++++++++- .../zomes/integrity/generic_zome/src/thing.rs | 10 +- .../generic_zome/src/thing_to_agents.rs | 34 +++++++ .../integrity/generic_zome/src/to_agent.rs | 34 +++++++ .../integrity/generic_zome/src/to_anchor.rs | 34 +++++++ .../integrity/generic_zome/src/to_thing.rs | 34 +++++++ .../generic_zome/thing-to-agents.test.ts | 99 +++++++++++++++++++ 10 files changed, 384 insertions(+), 12 deletions(-) rename dnas/generic_dna/zomes/coordinator/generic_zome/src/{thing.rs => api.rs} (100%) create mode 100644 dnas/generic_dna/zomes/coordinator/generic_zome/src/thing_to_agents.rs create mode 100644 dnas/generic_dna/zomes/integrity/generic_zome/src/thing_to_agents.rs create mode 100644 dnas/generic_dna/zomes/integrity/generic_zome/src/to_agent.rs create mode 100644 dnas/generic_dna/zomes/integrity/generic_zome/src/to_anchor.rs create mode 100644 dnas/generic_dna/zomes/integrity/generic_zome/src/to_thing.rs create mode 100644 tests/src/generic_dna/generic_zome/thing-to-agents.test.ts diff --git a/dnas/generic_dna/zomes/coordinator/generic_zome/src/thing.rs b/dnas/generic_dna/zomes/coordinator/generic_zome/src/api.rs similarity index 100% rename from dnas/generic_dna/zomes/coordinator/generic_zome/src/thing.rs rename to dnas/generic_dna/zomes/coordinator/generic_zome/src/api.rs diff --git a/dnas/generic_dna/zomes/coordinator/generic_zome/src/lib.rs b/dnas/generic_dna/zomes/coordinator/generic_zome/src/lib.rs index f762512..9040034 100644 --- a/dnas/generic_dna/zomes/coordinator/generic_zome/src/lib.rs +++ b/dnas/generic_dna/zomes/coordinator/generic_zome/src/lib.rs @@ -1,14 +1,15 @@ -pub mod thing; +pub mod api; +pub mod thing_to_agents; use generic_zome_integrity::*; use hdk::prelude::*; -// Called the first time a zome call is made to the cell containing this zome +/// Called the first time a zome call is made to the cell containing this zome #[hdk_extern] pub fn init() -> ExternResult { Ok(InitCallbackResult::Pass) } -// Don't modify this enum if you want the scaffolding tool to generate appropriate signals for your entries and links +/// Don't modify this enum if you want the scaffolding tool to generate appropriate signals for your entries and links #[derive(Serialize, Deserialize, Debug)] #[serde(tag = "type")] pub enum Signal { @@ -36,10 +37,10 @@ pub enum Signal { }, } -// Whenever an action is committed, we emit a signal to the UI elements to reactively update them +/// Whenever an action is committed, we emit a signal to the UI elements to reactively update them #[hdk_extern(infallible)] pub fn post_commit(committed_actions: Vec) { - // Don't modify this loop if you want the scaffolding tool to generate appropriate signals for your entries and links + /// Don't modify this loop if you want the scaffolding tool to generate appropriate signals for your entries and links for action in committed_actions { if let Err(err) = signal_action(action) { error!("Error signaling new action: {:?}", err); @@ -47,7 +48,7 @@ pub fn post_commit(committed_actions: Vec) { } } -// Don't modify this function if you want the scaffolding tool to generate appropriate signals for your entries and links +/// Don't modify this function if you want the scaffolding tool to generate appropriate signals for your entries and links fn signal_action(action: SignedActionHashed) -> ExternResult<()> { match action.hashed.content.clone() { Action::CreateLink(create_link) => { diff --git a/dnas/generic_dna/zomes/coordinator/generic_zome/src/thing_to_agents.rs b/dnas/generic_dna/zomes/coordinator/generic_zome/src/thing_to_agents.rs new file mode 100644 index 0000000..61dd4b3 --- /dev/null +++ b/dnas/generic_dna/zomes/coordinator/generic_zome/src/thing_to_agents.rs @@ -0,0 +1,64 @@ +use generic_zome_integrity::*; +use hdk::prelude::*; + +#[derive(Serialize, Deserialize, Debug)] +pub struct AddAgentForThingInput { + pub base_thing_hash: ActionHash, + pub target_agent: AgentPubKey, +} + +#[hdk_extern] +pub fn add_agent_for_thing(input: AddAgentForThingInput) -> ExternResult<()> { + create_link( + input.base_thing_hash.clone(), + input.target_agent.clone(), + LinkTypes::ThingToAgents, + (), + )?; + Ok(()) +} + +#[hdk_extern] +pub fn get_agents_for_thing(thing_hash: ActionHash) -> ExternResult> { + get_links(GetLinksInputBuilder::try_new(thing_hash, LinkTypes::ThingToAgents)?.build()) +} + +#[hdk_extern] +pub fn get_deleted_agents_for_thing( + thing_hash: ActionHash, +) -> ExternResult)>> { + let details = get_link_details( + thing_hash, + LinkTypes::ThingToAgents, + None, + GetOptions::default(), + )?; + Ok(details + .into_inner() + .into_iter() + .filter(|(_link, deletes)| !deletes.is_empty()) + .collect()) +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct RemoveAgentForThingInput { + pub base_thing_hash: ActionHash, + pub target_agent: AgentPubKey, +} + +#[hdk_extern] +pub fn delete_agent_for_thing(input: RemoveAgentForThingInput) -> ExternResult<()> { + let links = get_links( + GetLinksInputBuilder::try_new(input.base_thing_hash.clone(), LinkTypes::ThingToAgents)? + .build(), + )?; + for link in links { + if AgentPubKey::from(link.target.clone().into_entry_hash().ok_or(wasm_error!( + WasmErrorInner::Guest("No entry_hash associated with link".to_string()) + ))?) == input.target_agent.clone().into_hash().into() + { + delete_link(link.create_link_hash)?; + } + } + Ok(()) +} diff --git a/dnas/generic_dna/zomes/integrity/generic_zome/src/lib.rs b/dnas/generic_dna/zomes/integrity/generic_zome/src/lib.rs index dd4cfad..4bf1a6d 100644 --- a/dnas/generic_dna/zomes/integrity/generic_zome/src/lib.rs +++ b/dnas/generic_dna/zomes/integrity/generic_zome/src/lib.rs @@ -1,5 +1,14 @@ +pub mod thing_to_agents; +pub use thing_to_agents::*; +pub mod to_agent; +pub use to_agent::*; +pub mod to_anchor; +pub use to_anchor::*; +pub mod to_thing; +pub use to_thing::*; pub mod thing; use hdi::prelude::*; + pub use thing::*; #[derive(Serialize, Deserialize)] @@ -14,6 +23,9 @@ pub enum EntryTypes { #[hdk_link_types] pub enum LinkTypes { ThingUpdates, + ToThing, + ToAgent, + ToAnchor, } // Validation you perform during the genesis process. Nobody else on the network performs it, only you. @@ -49,7 +61,7 @@ pub fn validate_agent_joining( // - If the `Op` is a delete link, the original action exists and is a `CreateLink` action // - Link tags don't exceed the maximum tag size (currently 1KB) // - Countersigned entries include an action from each required signer -// You can read more about validation here: http// ocs.rs/hdi/latest/hdi/index.html#data-validation +// You can read more about validation here: htt// ocs.rs/hdi/latest/hdi/index.html#data-validation #[hdk_extern] pub fn validate(op: Op) -> ExternResult { match op.flattened::()? { @@ -156,6 +168,15 @@ pub fn validate(op: Op) -> ExternResult { LinkTypes::ThingUpdates => { validate_create_link_thing_updates(action, base_address, target_address, tag) } + LinkTypes::ToAgent => { + validate_create_link_to_agent(action, base_address, target_address, tag) + } + LinkTypes::ToAnchor => { + validate_create_link_to_anchor(action, base_address, target_address, tag) + } + LinkTypes::ToThing => { + validate_create_link_to_thing(action, base_address, target_address, tag) + } }, FlatOp::RegisterDeleteLink { link_type, @@ -172,6 +193,27 @@ pub fn validate(op: Op) -> ExternResult { target_address, tag, ), + LinkTypes::ToAgent => validate_delete_link_to_agent( + action, + original_action, + base_address, + target_address, + tag, + ), + LinkTypes::ToAnchor => validate_delete_link_to_anchor( + action, + original_action, + base_address, + target_address, + tag, + ), + LinkTypes::ToThing => validate_delete_link_to_thing( + action, + original_action, + base_address, + target_address, + tag, + ), }, FlatOp::StoreRecord(store_record) => { match store_record { @@ -309,6 +351,15 @@ pub fn validate(op: Op) -> ExternResult { target_address, tag, ), + LinkTypes::ToAgent => { + validate_create_link_to_agent(action, base_address, target_address, tag) + } + LinkTypes::ToAnchor => { + validate_create_link_to_anchor(action, base_address, target_address, tag) + } + LinkTypes::ToThing => { + validate_create_link_to_thing(action, base_address, target_address, tag) + } }, // Complementary validation to the `RegisterDeleteLink` Op, in which the record itself is validated // If you want to optimize performance, you can remove the validation for an entry type here and keep it in `RegisterDeleteLink` @@ -345,6 +396,27 @@ pub fn validate(op: Op) -> ExternResult { create_link.target_address, create_link.tag, ), + LinkTypes::ToAgent => validate_delete_link_to_agent( + action, + create_link.clone(), + base_address, + create_link.target_address, + create_link.tag, + ), + LinkTypes::ToAnchor => validate_delete_link_to_anchor( + action, + create_link.clone(), + base_address, + create_link.target_address, + create_link.tag, + ), + LinkTypes::ToThing => validate_delete_link_to_thing( + action, + create_link.clone(), + base_address, + create_link.target_address, + create_link.tag, + ), } } OpRecord::CreatePrivateEntry { .. } => Ok(ValidateCallbackResult::Valid), diff --git a/dnas/generic_dna/zomes/integrity/generic_zome/src/thing.rs b/dnas/generic_dna/zomes/integrity/generic_zome/src/thing.rs index b0d663b..ff58f4f 100644 --- a/dnas/generic_dna/zomes/integrity/generic_zome/src/thing.rs +++ b/dnas/generic_dna/zomes/integrity/generic_zome/src/thing.rs @@ -10,7 +10,7 @@ pub fn validate_create_thing( _action: EntryCreationAction, _thing: Thing, ) -> ExternResult { - // TODO: add the appropriate validation rules + /// TODO: add the appropriate validation rules Ok(ValidateCallbackResult::Valid) } @@ -20,7 +20,7 @@ pub fn validate_update_thing( _original_action: EntryCreationAction, _original_thing: Thing, ) -> ExternResult { - // TODO: add the appropriate validation rules + /// TODO: add the appropriate validation rules Ok(ValidateCallbackResult::Valid) } @@ -29,7 +29,7 @@ pub fn validate_delete_thing( _original_action: EntryCreationAction, _original_thing: Thing, ) -> ExternResult { - // TODO: add the appropriate validation rules + /// TODO: add the appropriate validation rules Ok(ValidateCallbackResult::Valid) } @@ -39,7 +39,7 @@ pub fn validate_create_link_thing_updates( target_address: AnyLinkableHash, _tag: LinkTag, ) -> ExternResult { - // Check the entry type for the given action hash + /// Check the entry type for the given action hash let action_hash = base_address .into_action_hash() .ok_or(wasm_error!(WasmErrorInner::Guest( @@ -53,7 +53,7 @@ pub fn validate_create_link_thing_updates( .ok_or(wasm_error!(WasmErrorInner::Guest( "Linked action must reference an entry".to_string() )))?; - // Check the entry type for the given action hash + /// Check the entry type for the given action hash let action_hash = target_address .into_action_hash() diff --git a/dnas/generic_dna/zomes/integrity/generic_zome/src/thing_to_agents.rs b/dnas/generic_dna/zomes/integrity/generic_zome/src/thing_to_agents.rs new file mode 100644 index 0000000..59071ec --- /dev/null +++ b/dnas/generic_dna/zomes/integrity/generic_zome/src/thing_to_agents.rs @@ -0,0 +1,34 @@ +use hdi::prelude::*; + +pub fn validate_create_link_thing_to_agents( + _action: CreateLink, + base_address: AnyLinkableHash, + _target_address: AnyLinkableHash, + _tag: LinkTag, +) -> ExternResult { + // Check the entry type for the given action hash + let action_hash = base_address + .into_action_hash() + .ok_or(wasm_error!(WasmErrorInner::Guest( + "No action hash associated with link".to_string() + )))?; + let record = must_get_valid_record(action_hash)?; + let _thing: crate::Thing = record + .entry() + .to_app_option() + .map_err(|e| wasm_error!(e))? + .ok_or(wasm_error!(WasmErrorInner::Guest( + "Linked action must reference an entry".to_string() + )))?; + Ok(ValidateCallbackResult::Valid) +} + +pub fn validate_delete_link_thing_to_agents( + _action: DeleteLink, + _original_action: CreateLink, + _base: AnyLinkableHash, + _target: AnyLinkableHash, + _tag: LinkTag, +) -> ExternResult { + Ok(ValidateCallbackResult::Valid) +} diff --git a/dnas/generic_dna/zomes/integrity/generic_zome/src/to_agent.rs b/dnas/generic_dna/zomes/integrity/generic_zome/src/to_agent.rs new file mode 100644 index 0000000..3807594 --- /dev/null +++ b/dnas/generic_dna/zomes/integrity/generic_zome/src/to_agent.rs @@ -0,0 +1,34 @@ +use hdi::prelude::*; + +pub fn validate_create_link_to_agent( + _action: CreateLink, + base_address: AnyLinkableHash, + _target_address: AnyLinkableHash, + _tag: LinkTag, +) -> ExternResult { + // Check the entry type for the given action hash + let action_hash = base_address + .into_action_hash() + .ok_or(wasm_error!(WasmErrorInner::Guest( + "No action hash associated with link".to_string() + )))?; + let record = must_get_valid_record(action_hash)?; + let _thing: crate::Thing = record + .entry() + .to_app_option() + .map_err(|e| wasm_error!(e))? + .ok_or(wasm_error!(WasmErrorInner::Guest( + "Linked action must reference an entry".to_string() + )))?; + Ok(ValidateCallbackResult::Valid) +} + +pub fn validate_delete_link_to_agent( + _action: DeleteLink, + _original_action: CreateLink, + _base: AnyLinkableHash, + _target: AnyLinkableHash, + _tag: LinkTag, +) -> ExternResult { + Ok(ValidateCallbackResult::Valid) +} diff --git a/dnas/generic_dna/zomes/integrity/generic_zome/src/to_anchor.rs b/dnas/generic_dna/zomes/integrity/generic_zome/src/to_anchor.rs new file mode 100644 index 0000000..c64ec32 --- /dev/null +++ b/dnas/generic_dna/zomes/integrity/generic_zome/src/to_anchor.rs @@ -0,0 +1,34 @@ +use hdi::prelude::*; + +pub fn validate_create_link_to_anchor( + _action: CreateLink, + base_address: AnyLinkableHash, + _target_address: AnyLinkableHash, + _tag: LinkTag, +) -> ExternResult { + // Check the entry type for the given action hash + let action_hash = base_address + .into_action_hash() + .ok_or(wasm_error!(WasmErrorInner::Guest( + "No action hash associated with link".to_string() + )))?; + let record = must_get_valid_record(action_hash)?; + let _thing: crate::Thing = record + .entry() + .to_app_option() + .map_err(|e| wasm_error!(e))? + .ok_or(wasm_error!(WasmErrorInner::Guest( + "Linked action must reference an entry".to_string() + )))?; + Ok(ValidateCallbackResult::Valid) +} + +pub fn validate_delete_link_to_anchor( + _action: DeleteLink, + _original_action: CreateLink, + _base: AnyLinkableHash, + _target: AnyLinkableHash, + _tag: LinkTag, +) -> ExternResult { + Ok(ValidateCallbackResult::Valid) +} diff --git a/dnas/generic_dna/zomes/integrity/generic_zome/src/to_thing.rs b/dnas/generic_dna/zomes/integrity/generic_zome/src/to_thing.rs new file mode 100644 index 0000000..11b12fe --- /dev/null +++ b/dnas/generic_dna/zomes/integrity/generic_zome/src/to_thing.rs @@ -0,0 +1,34 @@ +use hdi::prelude::*; + +pub fn validate_create_link_to_thing( + _action: CreateLink, + base_address: AnyLinkableHash, + _target_address: AnyLinkableHash, + _tag: LinkTag, +) -> ExternResult { + // Check the entry type for the given action hash + let action_hash = base_address + .into_action_hash() + .ok_or(wasm_error!(WasmErrorInner::Guest( + "No action hash associated with link".to_string() + )))?; + let record = must_get_valid_record(action_hash)?; + let _thing: crate::Thing = record + .entry() + .to_app_option() + .map_err(|e| wasm_error!(e))? + .ok_or(wasm_error!(WasmErrorInner::Guest( + "Linked action must reference an entry".to_string() + )))?; + Ok(ValidateCallbackResult::Valid) +} + +pub fn validate_delete_link_to_thing( + _action: DeleteLink, + _original_action: CreateLink, + _base: AnyLinkableHash, + _target: AnyLinkableHash, + _tag: LinkTag, +) -> ExternResult { + Ok(ValidateCallbackResult::Valid) +} diff --git a/tests/src/generic_dna/generic_zome/thing-to-agents.test.ts b/tests/src/generic_dna/generic_zome/thing-to-agents.test.ts new file mode 100644 index 0000000..64c02bd --- /dev/null +++ b/tests/src/generic_dna/generic_zome/thing-to-agents.test.ts @@ -0,0 +1,99 @@ +import { assert, test } from "vitest"; + +import { + ActionHash, + AppBundleSource, + CreateLink, + DeleteLink, + fakeActionHash, + fakeAgentPubKey, + fakeEntryHash, + hashFrom32AndType, + Link, + NewEntryAction, + Record, + SignedActionHashed, +} from "@holochain/client"; +import { CallableCell, dhtSync, runScenario } from "@holochain/tryorama"; +import { decode } from "@msgpack/msgpack"; + +import { createThing } from "./common.js"; + +test("link a Thing to a Agent", async () => { + await runScenario(async scenario => { + // Construct proper paths for your app. + // This assumes app bundle created by the `hc app pack` command. + const testAppPath = process.cwd() + "/../workdir/generic-dna.happ"; + + // Set up the app to be installed + const appSource = { appBundleSource: { path: testAppPath } }; + + // Add 2 players with the test app to the Scenario. The returned players + // can be destructured. + const [alice, bob] = await scenario.addPlayersWithApps([appSource, appSource]); + + // Shortcut peer discovery through gossip and register all agents in every + // conductor of the scenario. + await scenario.shareAllAgents(); + + const baseRecord = await createThing(alice.cells[0]); + const baseAddress = baseRecord.signed_action.hashed.hash; + const targetAddress = alice.agentPubKey; + + // Bob gets the links, should be empty + let linksOutput: Link[] = await bob.cells[0].callZome({ + zome_name: "generic_zome", + fn_name: "get_agents_for_thing", + payload: baseAddress, + }); + assert.equal(linksOutput.length, 0); + + // Alice creates a link from Thing to Agent + await alice.cells[0].callZome({ + zome_name: "generic_zome", + fn_name: "add_agent_for_thing", + payload: { + base_thing_hash: baseAddress, + target_agent: targetAddress, + }, + }); + + await dhtSync([alice, bob], alice.cells[0].cell_id[0]); + + // Bob gets the links again + linksOutput = await bob.cells[0].callZome({ + zome_name: "generic_zome", + fn_name: "get_agents_for_thing", + payload: baseAddress, + }); + assert.equal(linksOutput.length, 1); + + await alice.cells[0].callZome({ + zome_name: "generic_zome", + fn_name: "delete_agent_for_thing", + payload: { + base_thing_hash: baseAddress, + target_agent: targetAddress, + }, + }); + + await dhtSync([alice, bob], alice.cells[0].cell_id[0]); + + // Bob gets the links again + linksOutput = await bob.cells[0].callZome({ + zome_name: "generic_zome", + fn_name: "get_agents_for_thing", + payload: baseAddress, + }); + assert.equal(linksOutput.length, 0); + + // Bob gets the deleted links + let deletedLinksOutput: Array<[SignedActionHashed, SignedActionHashed[]]> = await bob + .cells[0].callZome({ + zome_name: "generic_zome", + fn_name: "get_deleted_agents_for_thing", + payload: baseAddress, + }); + assert.equal(deletedLinksOutput.length, 1); + }); +}); From b2543e9a83cc17f6c9ec1d3163d9db9d78c494ba Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 2 Nov 2024 16:36:26 +0100 Subject: [PATCH 04/12] add api for creating, updating and deleting Thing --- .../zomes/coordinator/generic_zome/src/api.rs | 480 +++++++++++++++--- .../zomes/integrity/generic_zome/src/lib.rs | 8 +- .../generic_zome/src/link_tag_content.rs | 29 ++ .../zomes/integrity/generic_zome/src/thing.rs | 14 +- .../generic_zome/src/thing_to_agents.rs | 2 +- .../integrity/generic_zome/src/to_agent.rs | 2 +- .../integrity/generic_zome/src/to_anchor.rs | 2 +- .../integrity/generic_zome/src/to_thing.rs | 2 +- 8 files changed, 464 insertions(+), 75 deletions(-) create mode 100644 dnas/generic_dna/zomes/integrity/generic_zome/src/link_tag_content.rs diff --git a/dnas/generic_dna/zomes/coordinator/generic_zome/src/api.rs b/dnas/generic_dna/zomes/coordinator/generic_zome/src/api.rs index 8feb71d..5bb1474 100644 --- a/dnas/generic_dna/zomes/coordinator/generic_zome/src/api.rs +++ b/dnas/generic_dna/zomes/coordinator/generic_zome/src/api.rs @@ -1,20 +1,187 @@ use generic_zome_integrity::*; use hdk::prelude::*; +#[derive(Serialize, Deserialize, Clone, Debug)] +#[serde(tag = "type")] +pub enum LinkDirection { + From, + To, + Bidirectional, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +#[serde(tag = "type")] +pub enum NodeId { + Agent(AgentPubKey), + Anchor(String), + Thing(ActionHash), +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +#[serde(tag = "type")] +pub enum Node { + Agent(AgentPubKey), + Anchor(String), + Thing(ThingEntry), +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct LinkInput { + pub direction: LinkDirection, + pub node_id: NodeId, + pub tag: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct Thing { + pub id: ActionHash, + pub content: String, + pub creator: AgentPubKey, + pub created_at: Timestamp, + pub updated_at: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct CreateThingInput { + pub content: String, + pub links: Option>, +} + #[hdk_extern] -pub fn create_thing(thing: Thing) -> ExternResult { - let thing_hash = create_entry(&EntryTypes::Thing(thing.clone()))?; - let record = get(thing_hash.clone(), GetOptions::default())?.ok_or(wasm_error!( - WasmErrorInner::Guest("Could not find the newly created Thing".to_string()) +pub fn create_thing(input: CreateThingInput) -> ExternResult { + // 1. Create the Thing entry + let thing_id = create_entry(&EntryTypes::Thing(ThingEntry { + content: input.content.clone(), + }))?; + + let thing_record = get(thing_id.clone(), GetOptions::default())?.ok_or(wasm_error!( + WasmErrorInner::Guest("Failed to get record that was just created.".into()) ))?; - Ok(record) + + // 2. Create all links as necessary + match input.links { + Some(links) => { + for link in links { + match link.node_id { + NodeId::Agent(agent) => match link.direction { + LinkDirection::To => { + create_link( + thing_id.clone(), + agent, + LinkTypes::ToAgent, + derive_link_tag(link.tag, None)?, + )?; + } + LinkDirection::From => { + create_link( + agent, + thing_id.clone(), + LinkTypes::ToThing, + derive_link_tag(link.tag, None)?, + )?; + } + LinkDirection::Bidirectional => { + let backlink_action_hash = create_link( + agent.clone(), + thing_id.clone(), + LinkTypes::ToThing, + derive_link_tag(link.tag.clone(), None)?, + )?; + create_link( + thing_id.clone(), + agent, + LinkTypes::ToAgent, + derive_link_tag(link.tag, Some(backlink_action_hash))?, + )?; + } + }, + NodeId::Anchor(anchor) => { + let path = Path::from(anchor); + let path_entry_hash = path.path_entry_hash()?; + match link.direction { + LinkDirection::To => { + create_link( + thing_id.clone(), + path_entry_hash, + LinkTypes::ToAgent, + derive_link_tag(link.tag, None)?, + )?; + } + LinkDirection::From => { + create_link( + path_entry_hash, + thing_id.clone(), + LinkTypes::ToThing, + derive_link_tag(link.tag, None)?, + )?; + } + LinkDirection::Bidirectional => { + let backlink_action_hash = create_link( + path_entry_hash.clone(), + thing_id.clone(), + LinkTypes::ToThing, + derive_link_tag(link.tag.clone(), None)?, + )?; + create_link( + thing_id.clone(), + path_entry_hash, + LinkTypes::ToAgent, + derive_link_tag(link.tag, Some(backlink_action_hash))?, + )?; + } + } + } + NodeId::Thing(action_hash) => match link.direction { + LinkDirection::To => { + create_link( + thing_id.clone(), + action_hash, + LinkTypes::ToAgent, + derive_link_tag(link.tag, None)?, + )?; + } + LinkDirection::From => { + create_link( + action_hash, + thing_id.clone(), + LinkTypes::ToThing, + derive_link_tag(link.tag, None)?, + )?; + } + LinkDirection::Bidirectional => { + let backlink_action_hash = create_link( + action_hash.clone(), + thing_id.clone(), + LinkTypes::ToThing, + derive_link_tag(link.tag.clone(), None)?, + )?; + create_link( + thing_id.clone(), + action_hash, + LinkTypes::ToAgent, + derive_link_tag(link.tag, Some(backlink_action_hash))?, + )?; + } + }, + } + } + } + None => (), + } + + Ok(Thing { + id: thing_id, + content: input.content, + creator: thing_record.action().author().clone(), + created_at: thing_record.action().timestamp(), + updated_at: None, + }) } #[hdk_extern] -pub fn get_latest_thing(original_thing_hash: ActionHash) -> ExternResult> { +pub fn get_latest_thing(thing_id: ActionHash) -> ExternResult> { let links = get_links( - GetLinksInputBuilder::try_new(original_thing_hash.clone(), LinkTypes::ThingUpdates)? - .build(), + GetLinksInputBuilder::try_new(thing_id.clone(), LinkTypes::ThingUpdates)?.build(), )?; let latest_link = links .into_iter() @@ -28,32 +195,32 @@ pub fn get_latest_thing(original_thing_hash: ActionHash) -> ExternResult original_thing_hash.clone(), + None => thing_id.clone(), }; get(latest_thing_hash, GetOptions::default()) } #[hdk_extern] -pub fn get_original_thing(original_thing_hash: ActionHash) -> ExternResult> { - let Some(details) = get_details(original_thing_hash, GetOptions::default())? else { - return Ok(None); - }; - match details { - Details::Record(details) => Ok(Some(details.record)), - _ => Err(wasm_error!(WasmErrorInner::Guest( - "Malformed get details response".to_string() - ))), +pub fn get_original_thing(original_thing_id: ActionHash) -> ExternResult> { + let maybe_thing_record = get(original_thing_id.clone(), GetOptions::default())?; + match maybe_thing_record { + Some(record) => { + let thing = thing_record_to_thing(record)?; + Ok(Some(thing)) + } + None => Ok(None), } } #[hdk_extern] -pub fn get_all_revisions_for_thing(original_thing_hash: ActionHash) -> ExternResult> { - let Some(original_record) = get_original_thing(original_thing_hash.clone())? else { - return Ok(vec![]); +pub fn get_all_revisions_for_thing(thing_id: ActionHash) -> ExternResult> { + let Some(original_record) = get(thing_id.clone(), GetOptions::default())? else { + return Err(wasm_error!(WasmErrorInner::Guest( + "No original record found for this thing_id (action hash).".into() + ))); }; let links = get_links( - GetLinksInputBuilder::try_new(original_thing_hash.clone(), LinkTypes::ThingUpdates)? - .build(), + GetLinksInputBuilder::try_new(thing_id.clone(), LinkTypes::ThingUpdates)?.build(), )?; let get_input: Vec = links .into_iter() @@ -72,63 +239,254 @@ pub fn get_all_revisions_for_thing(original_thing_hash: ActionHash) -> ExternRes let records = HDK.with(|hdk| hdk.borrow().get(get_input))?; let mut records: Vec = records.into_iter().flatten().collect(); records.insert(0, original_record); - Ok(records) + Ok(records + .into_iter() + .map(|r| thing_record_to_thing(r).ok()) + .filter_map(|t| t) + .collect()) } #[derive(Serialize, Deserialize, Debug)] pub struct UpdateThingInput { - pub original_thing_hash: ActionHash, - pub previous_thing_hash: ActionHash, - pub updated_thing: Thing, + pub thing_id: ActionHash, + pub updated_content: String, } #[hdk_extern] -pub fn update_thing(input: UpdateThingInput) -> ExternResult { - let updated_thing_hash = update_entry(input.previous_thing_hash.clone(), &input.updated_thing)?; +pub fn update_thing(input: UpdateThingInput) -> ExternResult { + let updated_thing_hash = create_entry(&EntryTypes::Thing(ThingEntry { + content: input.updated_content.clone(), + }))?; + + let thing_record = get(input.thing_id.clone(), GetOptions::default())?.ok_or(wasm_error!( + WasmErrorInner::Guest("Failed to get record of original Thing.".into()) + ))?; + + let updated_thing_record = get(updated_thing_hash.clone(), GetOptions::default())?.ok_or( + wasm_error!(WasmErrorInner::Guest( + "Failed to get record of Thing update that was just created.".into() + )), + )?; + create_link( - input.original_thing_hash.clone(), - updated_thing_hash.clone(), + input.thing_id.clone(), + updated_thing_hash, LinkTypes::ThingUpdates, (), )?; - let record = get(updated_thing_hash.clone(), GetOptions::default())?.ok_or(wasm_error!( - WasmErrorInner::Guest("Could not find the newly updated Thing".to_string()) - ))?; - Ok(record) + + Ok(Thing { + id: input.thing_id, + content: input.updated_content, + creator: thing_record.action().author().clone(), + created_at: thing_record.action().timestamp(), + updated_at: Some(updated_thing_record.action().timestamp()), + }) } -#[hdk_extern] -pub fn delete_thing(original_thing_hash: ActionHash) -> ExternResult { - delete_entry(original_thing_hash) +#[derive(Serialize, Deserialize, Debug)] +pub struct DeleteThingInput { + pub thing_id: ActionHash, + pub delete_backlinks: bool, + pub delete_links_from_creator: bool, + pub delete_links: Option>, } +/// Deletes a thing and all associated links and backlinks #[hdk_extern] -pub fn get_all_deletes_for_thing( - original_thing_hash: ActionHash, -) -> ExternResult>> { - let Some(details) = get_details(original_thing_hash, GetOptions::default())? else { - return Ok(None); +pub fn delete_thing(input: DeleteThingInput) -> ExternResult<()> { + let thing_record = match get(input.thing_id.clone(), GetOptions::default())? { + Some(r) => r, + None => { + return Err(wasm_error!(WasmErrorInner::Guest( + "Did not find Thing to delete.".into() + ))) + } }; - match details { - Details::Entry(_) => Err(wasm_error!(WasmErrorInner::Guest( - "Malformed details".into() - ))), - Details::Record(record_details) => Ok(Some(record_details.deletes)), + + // 1. Delete the original Thing entry (don't care about updates as they are anyway + // not retreivable without the original Thing entry) + delete_entry(input.thing_id.clone())?; + + // 2. Delete all backlinks from bidirectional links + if input.delete_backlinks { + let links_to_agents = get_links( + GetLinksInputBuilder::try_new(input.thing_id.clone(), LinkTypes::ToAgent)?.build(), + )?; + for link in links_to_agents { + let link_tag_content = deserialize_link_tag(link.tag.0)?; + if let Some(backlink_action_hash) = link_tag_content.backlink_action_hash { + delete_link(backlink_action_hash)?; + } + } + let links_to_things = get_links( + GetLinksInputBuilder::try_new(input.thing_id.clone(), LinkTypes::ToAgent)?.build(), + )?; + for link in links_to_things { + let link_tag_content = deserialize_link_tag(link.tag.0)?; + if let Some(backlink_action_hash) = link_tag_content.backlink_action_hash { + delete_link(backlink_action_hash)?; + } + } + let links_to_anchors = get_links( + GetLinksInputBuilder::try_new(input.thing_id.clone(), LinkTypes::ToAgent)?.build(), + )?; + for link in links_to_anchors { + let link_tag_content = deserialize_link_tag(link.tag.0)?; + if let Some(backlink_action_hash) = link_tag_content.backlink_action_hash { + delete_link(backlink_action_hash)?; + } + } + } + + // 3. Delete all links from the creator to the Thing + if input.delete_links_from_creator { + let links_from_creator = get_links( + GetLinksInputBuilder::try_new( + thing_record.action().author().clone(), + LinkTypes::ToAgent, + )? + .build(), + )?; + for link in links_from_creator { + if link.target == input.thing_id.clone().into() { + delete_link(link.create_link_hash)?; + } + } + } + + // 3. Delete all links that are passed explicitly in the input + // let all_to_links = get_links(input) + if let Some(delete_links) = input.delete_links { + let to_links_to_delete = delete_links + .clone() + .into_iter() + .map(|l| match l.direction { + LinkDirection::To => Some(l), + _ => None, + }) + .filter_map(|l| l) + .collect::>(); + + // We save ourselves the get_links below if there are no LinkInput with LinkDirection::To + if to_links_to_delete.len() > 0 { + let links = get_links( + GetLinksInputBuilder::try_new(input.thing_id.clone(), LinkTypes::ToAgent)?.build(), + )?; + for to_link in to_links_to_delete { + match to_link.direction { + LinkDirection::To => match to_link.node_id { + NodeId::Agent(agent) => { + delete_links_with_target(&links, agent.into())?; + } + NodeId::Anchor(anchor) => { + let path = Path::from(anchor); + let path_entry_hash = path.path_entry_hash()?; + delete_links_with_target(&links, path_entry_hash.into())?; + } + NodeId::Thing(action_hash) => { + delete_links_with_target(&links, action_hash.into())?; + } + }, + _ => (), + } + } + } + + for link_to_delete in delete_links { + match link_to_delete.direction { + LinkDirection::To => (), // We already handled this above if any LinkInput with Linkdirection::To is present + LinkDirection::From | LinkDirection::Bidirectional => { + // In this case delete all links pointing towards the Thing to delete + // We don't care to delete the links pointing away from the Thing in case + // of a bidirectional link, since we assume that such links will not + // be discoverabke anymore anyway once the Thing as been deleted + match link_to_delete.node_id { + NodeId::Agent(agent) => { + delete_links_for_base_with_target( + agent.into(), + input.thing_id.clone().into(), + LinkTypes::ToThing, + )?; + } + NodeId::Anchor(anchor) => { + let path = Path::from(anchor); + let path_entry_hash = path.path_entry_hash()?; + delete_links_for_base_with_target( + path_entry_hash.into(), + input.thing_id.clone().into(), + LinkTypes::ToThing, + )?; + } + NodeId::Thing(action_hash) => { + delete_links_for_base_with_target( + action_hash.into(), + input.thing_id.clone().into(), + LinkTypes::ToThing, + )?; + } + } + } + } + } } + + Ok(()) } -#[hdk_extern] -pub fn get_oldest_delete_for_thing( - original_thing_hash: ActionHash, -) -> ExternResult> { - let Some(mut deletes) = get_all_deletes_for_thing(original_thing_hash)? else { - return Ok(None); +fn derive_link_tag( + input: Option>, + backlink_action_hash: Option, +) -> ExternResult { + let link_tag_content = LinkTagContent { + tag: input, + backlink_action_hash, }; - deletes.sort_by(|delete_a, delete_b| { - delete_a - .action() - .timestamp() - .cmp(&delete_b.action().timestamp()) - }); - Ok(deletes.first().cloned()) + let serialized_content = serialize_link_tag(link_tag_content)?; + Ok(LinkTag::from(serialized_content)) +} + +/// Deletes all links for a base that are pointing to the given target +fn delete_links_for_base_with_target( + base: AnyLinkableHash, + target: AnyLinkableHash, + link_type: LinkTypes, +) -> ExternResult<()> { + let links = get_links(GetLinksInputBuilder::try_new(base, link_type)?.build())?; + for link in links { + if link.target == target { + delete_link(link.create_link_hash)?; + } + } + Ok(()) +} + +fn delete_links_with_target(links: &Vec, target: AnyLinkableHash) -> ExternResult<()> { + for link in links { + if link.target == target { + delete_link(link.create_link_hash.clone())?; + } + } + Ok(()) +} + +fn thing_record_to_thing(record: Record) -> ExternResult { + let thing_entry = record + .entry() + .to_app_option::() + .map_err(|e| { + wasm_error!(WasmErrorInner::Guest( + format!("Failed to deserialize Record at the given action hash (thing_id) to a ThingEntry: {e}") + )) + })? + .ok_or(wasm_error!(WasmErrorInner::Guest( + "No Thing associated to this thing id (AcionHash).".into() + )))?; + Ok(Thing { + id: record.action_address().clone(), + content: thing_entry.content, + creator: record.action().author().clone(), + created_at: record.action().timestamp(), + updated_at: None, + }) } diff --git a/dnas/generic_dna/zomes/integrity/generic_zome/src/lib.rs b/dnas/generic_dna/zomes/integrity/generic_zome/src/lib.rs index 4bf1a6d..56c9ace 100644 --- a/dnas/generic_dna/zomes/integrity/generic_zome/src/lib.rs +++ b/dnas/generic_dna/zomes/integrity/generic_zome/src/lib.rs @@ -6,6 +6,8 @@ pub mod to_anchor; pub use to_anchor::*; pub mod to_thing; pub use to_thing::*; +pub mod link_tag_content; +pub use link_tag_content::*; pub mod thing; use hdi::prelude::*; @@ -16,7 +18,7 @@ pub use thing::*; #[hdk_entry_types] #[unit_enum(UnitEntryTypes)] pub enum EntryTypes { - Thing(Thing), + Thing(ThingEntry), } #[derive(Serialize, Deserialize)] @@ -97,7 +99,7 @@ pub fn validate(op: Op) -> ExternResult { EntryTypes::Thing(thing) => { let original_app_entry = must_get_valid_record(action.clone().original_action_address)?; - let original_thing = match Thing::try_from(original_app_entry) { + let original_thing = match ThingEntry::try_from(original_app_entry) { Ok(entry) => entry, Err(e) => { return Ok(ValidateCallbackResult::Invalid(format!( @@ -253,7 +255,7 @@ pub fn validate(op: Op) -> ExternResult { thing.clone(), )?; if let ValidateCallbackResult::Valid = result { - let original_thing: Option = original_record + let original_thing: Option = original_record .entry() .to_app_option() .map_err(|e| wasm_error!(e))?; diff --git a/dnas/generic_dna/zomes/integrity/generic_zome/src/link_tag_content.rs b/dnas/generic_dna/zomes/integrity/generic_zome/src/link_tag_content.rs new file mode 100644 index 0000000..0c769f9 --- /dev/null +++ b/dnas/generic_dna/zomes/integrity/generic_zome/src/link_tag_content.rs @@ -0,0 +1,29 @@ +use hdi::prelude::*; + +#[derive(Serialize, Deserialize, SerializedBytes, Debug)] +pub struct LinkTagContent { + pub tag: Option>, + // action hash of the backlink. Used to efficiently delete the backlink + // without having to do a get_links and filter by link targets. + // This seems worth it since relationship tags may potentially be + // used by many many different AssetRelation entries. + pub backlink_action_hash: Option, +} + +pub fn serialize_link_tag(link_tag_content: LinkTagContent) -> ExternResult> { + Ok(ExternIO::encode(link_tag_content) + .map_err(|e| { + wasm_error!(WasmErrorInner::Guest(format!( + "Failed to encode link tag content: {e}" + ))) + })? + .into_vec()) +} + +pub fn deserialize_link_tag(tag: Vec) -> ExternResult { + ExternIO::from(tag).decode::().map_err(|e| { + wasm_error!(WasmErrorInner::Guest(format!( + "Failed to decode link tag content: {e}" + ))) + }) +} diff --git a/dnas/generic_dna/zomes/integrity/generic_zome/src/thing.rs b/dnas/generic_dna/zomes/integrity/generic_zome/src/thing.rs index ff58f4f..7f8679e 100644 --- a/dnas/generic_dna/zomes/integrity/generic_zome/src/thing.rs +++ b/dnas/generic_dna/zomes/integrity/generic_zome/src/thing.rs @@ -2,13 +2,13 @@ use hdi::prelude::*; #[derive(Clone, PartialEq)] #[hdk_entry_helper] -pub struct Thing { +pub struct ThingEntry { pub content: String, } pub fn validate_create_thing( _action: EntryCreationAction, - _thing: Thing, + _thing: ThingEntry, ) -> ExternResult { /// TODO: add the appropriate validation rules Ok(ValidateCallbackResult::Valid) @@ -16,9 +16,9 @@ pub fn validate_create_thing( pub fn validate_update_thing( _action: Update, - _thing: Thing, + _thing: ThingEntry, _original_action: EntryCreationAction, - _original_thing: Thing, + _original_thing: ThingEntry, ) -> ExternResult { /// TODO: add the appropriate validation rules Ok(ValidateCallbackResult::Valid) @@ -27,7 +27,7 @@ pub fn validate_update_thing( pub fn validate_delete_thing( _action: Delete, _original_action: EntryCreationAction, - _original_thing: Thing, + _original_thing: ThingEntry, ) -> ExternResult { /// TODO: add the appropriate validation rules Ok(ValidateCallbackResult::Valid) @@ -46,7 +46,7 @@ pub fn validate_create_link_thing_updates( "No action hash associated with link".to_string() )))?; let record = must_get_valid_record(action_hash)?; - let _thing: crate::Thing = record + let _thing: crate::ThingEntry = record .entry() .to_app_option() .map_err(|e| wasm_error!(e))? @@ -61,7 +61,7 @@ pub fn validate_create_link_thing_updates( "No action hash associated with link".to_string() )))?; let record = must_get_valid_record(action_hash)?; - let _thing: crate::Thing = record + let _thing: crate::ThingEntry = record .entry() .to_app_option() .map_err(|e| wasm_error!(e))? diff --git a/dnas/generic_dna/zomes/integrity/generic_zome/src/thing_to_agents.rs b/dnas/generic_dna/zomes/integrity/generic_zome/src/thing_to_agents.rs index 59071ec..3a12cfc 100644 --- a/dnas/generic_dna/zomes/integrity/generic_zome/src/thing_to_agents.rs +++ b/dnas/generic_dna/zomes/integrity/generic_zome/src/thing_to_agents.rs @@ -13,7 +13,7 @@ pub fn validate_create_link_thing_to_agents( "No action hash associated with link".to_string() )))?; let record = must_get_valid_record(action_hash)?; - let _thing: crate::Thing = record + let _thing: crate::ThingEntry = record .entry() .to_app_option() .map_err(|e| wasm_error!(e))? diff --git a/dnas/generic_dna/zomes/integrity/generic_zome/src/to_agent.rs b/dnas/generic_dna/zomes/integrity/generic_zome/src/to_agent.rs index 3807594..5670b7a 100644 --- a/dnas/generic_dna/zomes/integrity/generic_zome/src/to_agent.rs +++ b/dnas/generic_dna/zomes/integrity/generic_zome/src/to_agent.rs @@ -13,7 +13,7 @@ pub fn validate_create_link_to_agent( "No action hash associated with link".to_string() )))?; let record = must_get_valid_record(action_hash)?; - let _thing: crate::Thing = record + let _thing: crate::ThingEntry = record .entry() .to_app_option() .map_err(|e| wasm_error!(e))? diff --git a/dnas/generic_dna/zomes/integrity/generic_zome/src/to_anchor.rs b/dnas/generic_dna/zomes/integrity/generic_zome/src/to_anchor.rs index c64ec32..2623fff 100644 --- a/dnas/generic_dna/zomes/integrity/generic_zome/src/to_anchor.rs +++ b/dnas/generic_dna/zomes/integrity/generic_zome/src/to_anchor.rs @@ -13,7 +13,7 @@ pub fn validate_create_link_to_anchor( "No action hash associated with link".to_string() )))?; let record = must_get_valid_record(action_hash)?; - let _thing: crate::Thing = record + let _thing: crate::ThingEntry = record .entry() .to_app_option() .map_err(|e| wasm_error!(e))? diff --git a/dnas/generic_dna/zomes/integrity/generic_zome/src/to_thing.rs b/dnas/generic_dna/zomes/integrity/generic_zome/src/to_thing.rs index 11b12fe..e654959 100644 --- a/dnas/generic_dna/zomes/integrity/generic_zome/src/to_thing.rs +++ b/dnas/generic_dna/zomes/integrity/generic_zome/src/to_thing.rs @@ -13,7 +13,7 @@ pub fn validate_create_link_to_thing( "No action hash associated with link".to_string() )))?; let record = must_get_valid_record(action_hash)?; - let _thing: crate::Thing = record + let _thing: crate::ThingEntry = record .entry() .to_app_option() .map_err(|e| wasm_error!(e))? From ca3f5de5f8b4d9d63216e5a329b5e088d93eba4b Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 2 Nov 2024 17:07:25 +0100 Subject: [PATCH 05/12] added get_* functions --- .../zomes/coordinator/generic_zome/src/api.rs | 120 ++++++++++++++++-- .../generic_zome/src/link_tag_content.rs | 4 + 2 files changed, 110 insertions(+), 14 deletions(-) diff --git a/dnas/generic_dna/zomes/coordinator/generic_zome/src/api.rs b/dnas/generic_dna/zomes/coordinator/generic_zome/src/api.rs index 5bb1474..876c3c3 100644 --- a/dnas/generic_dna/zomes/coordinator/generic_zome/src/api.rs +++ b/dnas/generic_dna/zomes/coordinator/generic_zome/src/api.rs @@ -22,7 +22,7 @@ pub enum NodeId { pub enum Node { Agent(AgentPubKey), Anchor(String), - Thing(ThingEntry), + Thing(Thing), } #[derive(Serialize, Deserialize, Clone, Debug)] @@ -69,7 +69,7 @@ pub fn create_thing(input: CreateThingInput) -> ExternResult { thing_id.clone(), agent, LinkTypes::ToAgent, - derive_link_tag(link.tag, None)?, + derive_link_tag(link.tag, None, None)?, )?; } LinkDirection::From => { @@ -77,7 +77,7 @@ pub fn create_thing(input: CreateThingInput) -> ExternResult { agent, thing_id.clone(), LinkTypes::ToThing, - derive_link_tag(link.tag, None)?, + derive_link_tag(link.tag, None, None)?, )?; } LinkDirection::Bidirectional => { @@ -85,18 +85,18 @@ pub fn create_thing(input: CreateThingInput) -> ExternResult { agent.clone(), thing_id.clone(), LinkTypes::ToThing, - derive_link_tag(link.tag.clone(), None)?, + derive_link_tag(link.tag.clone(), None, None)?, )?; create_link( thing_id.clone(), agent, LinkTypes::ToAgent, - derive_link_tag(link.tag, Some(backlink_action_hash))?, + derive_link_tag(link.tag, Some(backlink_action_hash), None)?, )?; } }, NodeId::Anchor(anchor) => { - let path = Path::from(anchor); + let path = Path::from(anchor.clone()); let path_entry_hash = path.path_entry_hash()?; match link.direction { LinkDirection::To => { @@ -104,7 +104,7 @@ pub fn create_thing(input: CreateThingInput) -> ExternResult { thing_id.clone(), path_entry_hash, LinkTypes::ToAgent, - derive_link_tag(link.tag, None)?, + derive_link_tag(link.tag, None, Some(anchor))?, )?; } LinkDirection::From => { @@ -112,7 +112,7 @@ pub fn create_thing(input: CreateThingInput) -> ExternResult { path_entry_hash, thing_id.clone(), LinkTypes::ToThing, - derive_link_tag(link.tag, None)?, + derive_link_tag(link.tag, None, Some(anchor))?, )?; } LinkDirection::Bidirectional => { @@ -120,13 +120,17 @@ pub fn create_thing(input: CreateThingInput) -> ExternResult { path_entry_hash.clone(), thing_id.clone(), LinkTypes::ToThing, - derive_link_tag(link.tag.clone(), None)?, + derive_link_tag(link.tag.clone(), None, Some(anchor.clone()))?, )?; create_link( thing_id.clone(), path_entry_hash, LinkTypes::ToAgent, - derive_link_tag(link.tag, Some(backlink_action_hash))?, + derive_link_tag( + link.tag, + Some(backlink_action_hash), + Some(anchor), + )?, )?; } } @@ -137,7 +141,7 @@ pub fn create_thing(input: CreateThingInput) -> ExternResult { thing_id.clone(), action_hash, LinkTypes::ToAgent, - derive_link_tag(link.tag, None)?, + derive_link_tag(link.tag, None, None)?, )?; } LinkDirection::From => { @@ -145,7 +149,7 @@ pub fn create_thing(input: CreateThingInput) -> ExternResult { action_hash, thing_id.clone(), LinkTypes::ToThing, - derive_link_tag(link.tag, None)?, + derive_link_tag(link.tag, None, None)?, )?; } LinkDirection::Bidirectional => { @@ -153,13 +157,13 @@ pub fn create_thing(input: CreateThingInput) -> ExternResult { action_hash.clone(), thing_id.clone(), LinkTypes::ToThing, - derive_link_tag(link.tag.clone(), None)?, + derive_link_tag(link.tag.clone(), None, None)?, )?; create_link( thing_id.clone(), action_hash, LinkTypes::ToAgent, - derive_link_tag(link.tag, Some(backlink_action_hash))?, + derive_link_tag(link.tag, Some(backlink_action_hash), None)?, )?; } }, @@ -434,13 +438,101 @@ pub fn delete_thing(input: DeleteThingInput) -> ExternResult<()> { Ok(()) } +#[hdk_extern] +pub fn get_all_linked_nodes(node_id: NodeId) -> ExternResult> { + let mut linked_nodes: Vec = Vec::new(); + let linked_things = get_linked_things(node_id.clone())?; + for thing in linked_things { + let node = Node::Thing(thing); + linked_nodes.push(node); + } + let linked_anchors = get_linked_anchors(node_id.clone())?; + for anchor in linked_anchors { + let node = Node::Anchor(anchor); + linked_nodes.push(node); + } + let linked_agents = get_linked_agents(node_id)?; + for agent in linked_agents { + let node = Node::Agent(agent); + linked_nodes.push(node); + } + Ok(linked_nodes) +} + +#[hdk_extern] +pub fn get_linked_agents(node_id: NodeId) -> ExternResult> { + let base: AnyLinkableHash = match node_id { + NodeId::Agent(a) => a.into(), + NodeId::Anchor(a) => Path::from(a).path_entry_hash()?.into(), + NodeId::Thing(a) => a.into(), + }; + let links = get_links(GetLinksInputBuilder::try_new(base, LinkTypes::ToAgent)?.build())?; + Ok(links + .into_iter() + .map(|l| l.target.into_agent_pub_key()) + .filter_map(|a| a) + .collect()) +} + +#[hdk_extern] +pub fn get_linked_anchors(node_id: NodeId) -> ExternResult> { + let base: AnyLinkableHash = match node_id { + NodeId::Agent(a) => a.into(), + NodeId::Anchor(a) => Path::from(a).path_entry_hash()?.into(), + NodeId::Thing(a) => a.into(), + }; + let links = get_links(GetLinksInputBuilder::try_new(base, LinkTypes::ToAnchor)?.build())?; + + Ok(links + .into_iter() + .map(|l| deserialize_link_tag(l.tag.0).ok()) + .filter_map(|c| c) + .map(|c| c.anchor) + .filter_map(|a| a) + .collect()) +} + +#[hdk_extern] +pub fn get_linked_things(node_id: NodeId) -> ExternResult> { + let base: AnyLinkableHash = match node_id { + NodeId::Agent(a) => a.into(), + NodeId::Anchor(a) => Path::from(a).path_entry_hash()?.into(), + NodeId::Thing(a) => a.into(), + }; + let links = get_links(GetLinksInputBuilder::try_new(base, LinkTypes::ToThing)?.build())?; + let get_input: Vec = links + .into_iter() + .map(|link| { + Ok(GetInput::new( + link.target + .into_action_hash() + .ok_or(wasm_error!(WasmErrorInner::Guest( + "No action hash associated with link".to_string() + )))? + .into(), + GetOptions::default(), + )) + }) + .collect::>>()?; + + let records = HDK.with(|hdk| hdk.borrow().get(get_input))?; + Ok(records + .into_iter() + .filter_map(|r| r) + .map(|r| thing_record_to_thing(r).ok()) + .filter_map(|t| t) + .collect()) +} + fn derive_link_tag( input: Option>, backlink_action_hash: Option, + anchor: Option, ) -> ExternResult { let link_tag_content = LinkTagContent { tag: input, backlink_action_hash, + anchor, }; let serialized_content = serialize_link_tag(link_tag_content)?; Ok(LinkTag::from(serialized_content)) diff --git a/dnas/generic_dna/zomes/integrity/generic_zome/src/link_tag_content.rs b/dnas/generic_dna/zomes/integrity/generic_zome/src/link_tag_content.rs index 0c769f9..0ee2add 100644 --- a/dnas/generic_dna/zomes/integrity/generic_zome/src/link_tag_content.rs +++ b/dnas/generic_dna/zomes/integrity/generic_zome/src/link_tag_content.rs @@ -8,6 +8,10 @@ pub struct LinkTagContent { // This seems worth it since relationship tags may potentially be // used by many many different AssetRelation entries. pub backlink_action_hash: Option, + // For links to anchors we store the anchor string as well to be able + // to retrieve the anchor string that they're pointing to directly + // from the link + pub anchor: Option, } pub fn serialize_link_tag(link_tag_content: LinkTagContent) -> ExternResult> { From 08e0f537f454d60e8250153b9c4f585788fb20f3 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 2 Nov 2024 17:55:15 +0100 Subject: [PATCH 06/12] added create_links_from_node and delete_links_from_node zome functions and consolidated some of the code --- .../zomes/coordinator/generic_zome/src/api.rs | 348 ++++++++++++------ .../zomes/coordinator/generic_zome/src/lib.rs | 1 - .../generic_zome/src/thing_to_agents.rs | 64 ---- 3 files changed, 226 insertions(+), 187 deletions(-) delete mode 100644 dnas/generic_dna/zomes/coordinator/generic_zome/src/thing_to_agents.rs diff --git a/dnas/generic_dna/zomes/coordinator/generic_zome/src/api.rs b/dnas/generic_dna/zomes/coordinator/generic_zome/src/api.rs index 876c3c3..7bfcec7 100644 --- a/dnas/generic_dna/zomes/coordinator/generic_zome/src/api.rs +++ b/dnas/generic_dna/zomes/coordinator/generic_zome/src/api.rs @@ -62,112 +62,7 @@ pub fn create_thing(input: CreateThingInput) -> ExternResult { match input.links { Some(links) => { for link in links { - match link.node_id { - NodeId::Agent(agent) => match link.direction { - LinkDirection::To => { - create_link( - thing_id.clone(), - agent, - LinkTypes::ToAgent, - derive_link_tag(link.tag, None, None)?, - )?; - } - LinkDirection::From => { - create_link( - agent, - thing_id.clone(), - LinkTypes::ToThing, - derive_link_tag(link.tag, None, None)?, - )?; - } - LinkDirection::Bidirectional => { - let backlink_action_hash = create_link( - agent.clone(), - thing_id.clone(), - LinkTypes::ToThing, - derive_link_tag(link.tag.clone(), None, None)?, - )?; - create_link( - thing_id.clone(), - agent, - LinkTypes::ToAgent, - derive_link_tag(link.tag, Some(backlink_action_hash), None)?, - )?; - } - }, - NodeId::Anchor(anchor) => { - let path = Path::from(anchor.clone()); - let path_entry_hash = path.path_entry_hash()?; - match link.direction { - LinkDirection::To => { - create_link( - thing_id.clone(), - path_entry_hash, - LinkTypes::ToAgent, - derive_link_tag(link.tag, None, Some(anchor))?, - )?; - } - LinkDirection::From => { - create_link( - path_entry_hash, - thing_id.clone(), - LinkTypes::ToThing, - derive_link_tag(link.tag, None, Some(anchor))?, - )?; - } - LinkDirection::Bidirectional => { - let backlink_action_hash = create_link( - path_entry_hash.clone(), - thing_id.clone(), - LinkTypes::ToThing, - derive_link_tag(link.tag.clone(), None, Some(anchor.clone()))?, - )?; - create_link( - thing_id.clone(), - path_entry_hash, - LinkTypes::ToAgent, - derive_link_tag( - link.tag, - Some(backlink_action_hash), - Some(anchor), - )?, - )?; - } - } - } - NodeId::Thing(action_hash) => match link.direction { - LinkDirection::To => { - create_link( - thing_id.clone(), - action_hash, - LinkTypes::ToAgent, - derive_link_tag(link.tag, None, None)?, - )?; - } - LinkDirection::From => { - create_link( - action_hash, - thing_id.clone(), - LinkTypes::ToThing, - derive_link_tag(link.tag, None, None)?, - )?; - } - LinkDirection::Bidirectional => { - let backlink_action_hash = create_link( - action_hash.clone(), - thing_id.clone(), - LinkTypes::ToThing, - derive_link_tag(link.tag.clone(), None, None)?, - )?; - create_link( - thing_id.clone(), - action_hash, - LinkTypes::ToAgent, - derive_link_tag(link.tag, Some(backlink_action_hash), None)?, - )?; - } - }, - } + create_link_from_node_by_hash(thing_id.clone().into(), link)?; } } None => (), @@ -461,11 +356,7 @@ pub fn get_all_linked_nodes(node_id: NodeId) -> ExternResult> { #[hdk_extern] pub fn get_linked_agents(node_id: NodeId) -> ExternResult> { - let base: AnyLinkableHash = match node_id { - NodeId::Agent(a) => a.into(), - NodeId::Anchor(a) => Path::from(a).path_entry_hash()?.into(), - NodeId::Thing(a) => a.into(), - }; + let base = linkable_hash_from_node_id(node_id)?; let links = get_links(GetLinksInputBuilder::try_new(base, LinkTypes::ToAgent)?.build())?; Ok(links .into_iter() @@ -476,13 +367,8 @@ pub fn get_linked_agents(node_id: NodeId) -> ExternResult> { #[hdk_extern] pub fn get_linked_anchors(node_id: NodeId) -> ExternResult> { - let base: AnyLinkableHash = match node_id { - NodeId::Agent(a) => a.into(), - NodeId::Anchor(a) => Path::from(a).path_entry_hash()?.into(), - NodeId::Thing(a) => a.into(), - }; + let base = linkable_hash_from_node_id(node_id)?; let links = get_links(GetLinksInputBuilder::try_new(base, LinkTypes::ToAnchor)?.build())?; - Ok(links .into_iter() .map(|l| deserialize_link_tag(l.tag.0).ok()) @@ -494,11 +380,7 @@ pub fn get_linked_anchors(node_id: NodeId) -> ExternResult> { #[hdk_extern] pub fn get_linked_things(node_id: NodeId) -> ExternResult> { - let base: AnyLinkableHash = match node_id { - NodeId::Agent(a) => a.into(), - NodeId::Anchor(a) => Path::from(a).path_entry_hash()?.into(), - NodeId::Thing(a) => a.into(), - }; + let base = linkable_hash_from_node_id(node_id)?; let links = get_links(GetLinksInputBuilder::try_new(base, LinkTypes::ToThing)?.build())?; let get_input: Vec = links .into_iter() @@ -524,6 +406,228 @@ pub fn get_linked_things(node_id: NodeId) -> ExternResult> { .collect()) } +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct CreateOrDeleteLinkInput { + pub src: NodeId, + pub links: Vec, +} + +#[hdk_extern] +pub fn create_links_from_node(input: CreateOrDeleteLinkInput) -> ExternResult<()> { + let base: HoloHash = linkable_hash_from_node_id(input.src)?; + for link in input.links { + create_link_from_node_by_hash(base.clone(), link)?; + } + Ok(()) +} + +#[hdk_extern] +pub fn delete_links_from_node(input: CreateOrDeleteLinkInput) -> ExternResult<()> { + let base = linkable_hash_from_node_id(input.src)?; + + let anchor_link_inputs = input + .links + .clone() + .into_iter() + .map(|l| match l.node_id { + NodeId::Agent(_) => Some(l), + _ => None, + }) + .filter_map(|l| l) + .collect::>(); + + let agent_link_inputs = input + .links + .clone() + .into_iter() + .map(|l| match l.node_id { + NodeId::Agent(_) => Some(l), + _ => None, + }) + .filter_map(|l| l) + .collect::>(); + + let thing_link_inputs = input + .links + .clone() + .into_iter() + .map(|l| match l.node_id { + NodeId::Agent(_) => Some(l), + _ => None, + }) + .filter_map(|l| l) + .collect::>(); + + if anchor_link_inputs.len() > 0 { + for link_input in anchor_link_inputs { + let links_to_anchors = get_links( + GetLinksInputBuilder::try_new(base.clone(), LinkTypes::ToAnchor)?.build(), + )?; + for link in links_to_anchors { + let target = linkable_hash_from_node_id(link_input.node_id.clone())?; + if target == link.target { + let link_tag_content = deserialize_link_tag(link.tag.0)?; + if let Some(backlink_action_hash) = link_tag_content.backlink_action_hash { + delete_link(backlink_action_hash)?; + } + delete_link(link.create_link_hash)?; + } + } + } + } + + if agent_link_inputs.len() > 0 { + for link_input in agent_link_inputs { + let links_to_agents = get_links( + GetLinksInputBuilder::try_new(base.clone(), LinkTypes::ToAgent)?.build(), + )?; + for link in links_to_agents { + let target = linkable_hash_from_node_id(link_input.node_id.clone())?; + if target == link.target { + let link_tag_content = deserialize_link_tag(link.tag.0)?; + if let Some(backlink_action_hash) = link_tag_content.backlink_action_hash { + delete_link(backlink_action_hash)?; + } + delete_link(link.create_link_hash)?; + } + } + } + } + + if thing_link_inputs.len() > 0 { + for link_input in thing_link_inputs { + let links_to_things = get_links( + GetLinksInputBuilder::try_new(base.clone(), LinkTypes::ToThing)?.build(), + )?; + for link in links_to_things { + let target = linkable_hash_from_node_id(link_input.node_id.clone())?; + if target == link.target { + let link_tag_content = deserialize_link_tag(link.tag.0)?; + if let Some(backlink_action_hash) = link_tag_content.backlink_action_hash { + delete_link(backlink_action_hash)?; + } + delete_link(link.create_link_hash)?; + } + } + } + } + Ok(()) +} + +fn create_link_from_node_by_hash(src: AnyLinkableHash, link: LinkInput) -> ExternResult<()> { + match link.node_id { + NodeId::Agent(agent) => match link.direction { + LinkDirection::To => { + create_link( + src.clone(), + agent, + LinkTypes::ToAgent, + derive_link_tag(link.tag, None, None)?, + )?; + } + LinkDirection::From => { + create_link( + agent, + src.clone(), + LinkTypes::ToThing, + derive_link_tag(link.tag, None, None)?, + )?; + } + LinkDirection::Bidirectional => { + let backlink_action_hash = create_link( + agent.clone(), + src.clone(), + LinkTypes::ToThing, + derive_link_tag(link.tag.clone(), None, None)?, + )?; + create_link( + src.clone(), + agent, + LinkTypes::ToAgent, + derive_link_tag(link.tag, Some(backlink_action_hash), None)?, + )?; + } + }, + NodeId::Anchor(anchor) => { + let path = Path::from(anchor.clone()); + let path_entry_hash = path.path_entry_hash()?; + match link.direction { + LinkDirection::To => { + create_link( + src.clone(), + path_entry_hash, + LinkTypes::ToAgent, + derive_link_tag(link.tag, None, Some(anchor))?, + )?; + } + LinkDirection::From => { + create_link( + path_entry_hash, + src.clone(), + LinkTypes::ToThing, + derive_link_tag(link.tag, None, Some(anchor))?, + )?; + } + LinkDirection::Bidirectional => { + let backlink_action_hash = create_link( + path_entry_hash.clone(), + src.clone(), + LinkTypes::ToThing, + derive_link_tag(link.tag.clone(), None, Some(anchor.clone()))?, + )?; + create_link( + src.clone(), + path_entry_hash, + LinkTypes::ToAgent, + derive_link_tag(link.tag, Some(backlink_action_hash), Some(anchor))?, + )?; + } + } + } + NodeId::Thing(action_hash) => match link.direction { + LinkDirection::To => { + create_link( + src.clone(), + action_hash, + LinkTypes::ToAgent, + derive_link_tag(link.tag, None, None)?, + )?; + } + LinkDirection::From => { + create_link( + action_hash, + src.clone(), + LinkTypes::ToThing, + derive_link_tag(link.tag, None, None)?, + )?; + } + LinkDirection::Bidirectional => { + let backlink_action_hash = create_link( + action_hash.clone(), + src.clone(), + LinkTypes::ToThing, + derive_link_tag(link.tag.clone(), None, None)?, + )?; + create_link( + src.clone(), + action_hash, + LinkTypes::ToAgent, + derive_link_tag(link.tag, Some(backlink_action_hash), None)?, + )?; + } + }, + } + Ok(()) +} + +fn linkable_hash_from_node_id(node_id: NodeId) -> ExternResult { + match node_id { + NodeId::Agent(a) => Ok(a.into()), + NodeId::Anchor(a) => Ok(Path::from(a).path_entry_hash()?.into()), + NodeId::Thing(a) => Ok(a.into()), + } +} + fn derive_link_tag( input: Option>, backlink_action_hash: Option, diff --git a/dnas/generic_dna/zomes/coordinator/generic_zome/src/lib.rs b/dnas/generic_dna/zomes/coordinator/generic_zome/src/lib.rs index 9040034..d41fa24 100644 --- a/dnas/generic_dna/zomes/coordinator/generic_zome/src/lib.rs +++ b/dnas/generic_dna/zomes/coordinator/generic_zome/src/lib.rs @@ -1,5 +1,4 @@ pub mod api; -pub mod thing_to_agents; use generic_zome_integrity::*; use hdk::prelude::*; diff --git a/dnas/generic_dna/zomes/coordinator/generic_zome/src/thing_to_agents.rs b/dnas/generic_dna/zomes/coordinator/generic_zome/src/thing_to_agents.rs deleted file mode 100644 index 61dd4b3..0000000 --- a/dnas/generic_dna/zomes/coordinator/generic_zome/src/thing_to_agents.rs +++ /dev/null @@ -1,64 +0,0 @@ -use generic_zome_integrity::*; -use hdk::prelude::*; - -#[derive(Serialize, Deserialize, Debug)] -pub struct AddAgentForThingInput { - pub base_thing_hash: ActionHash, - pub target_agent: AgentPubKey, -} - -#[hdk_extern] -pub fn add_agent_for_thing(input: AddAgentForThingInput) -> ExternResult<()> { - create_link( - input.base_thing_hash.clone(), - input.target_agent.clone(), - LinkTypes::ThingToAgents, - (), - )?; - Ok(()) -} - -#[hdk_extern] -pub fn get_agents_for_thing(thing_hash: ActionHash) -> ExternResult> { - get_links(GetLinksInputBuilder::try_new(thing_hash, LinkTypes::ThingToAgents)?.build()) -} - -#[hdk_extern] -pub fn get_deleted_agents_for_thing( - thing_hash: ActionHash, -) -> ExternResult)>> { - let details = get_link_details( - thing_hash, - LinkTypes::ThingToAgents, - None, - GetOptions::default(), - )?; - Ok(details - .into_inner() - .into_iter() - .filter(|(_link, deletes)| !deletes.is_empty()) - .collect()) -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct RemoveAgentForThingInput { - pub base_thing_hash: ActionHash, - pub target_agent: AgentPubKey, -} - -#[hdk_extern] -pub fn delete_agent_for_thing(input: RemoveAgentForThingInput) -> ExternResult<()> { - let links = get_links( - GetLinksInputBuilder::try_new(input.base_thing_hash.clone(), LinkTypes::ThingToAgents)? - .build(), - )?; - for link in links { - if AgentPubKey::from(link.target.clone().into_entry_hash().ok_or(wasm_error!( - WasmErrorInner::Guest("No entry_hash associated with link".to_string()) - ))?) == input.target_agent.clone().into_hash().into() - { - delete_link(link.create_link_hash)?; - } - } - Ok(()) -} From 0239bc9f52b11e0bc77b7a8e99af21fb505ac2e7 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 2 Nov 2024 17:57:21 +0100 Subject: [PATCH 07/12] removed unused file, changed js-client version --- .../generic_zome/src/thing_to_agents.rs | 34 ------------------- ui/package.json | 2 +- 2 files changed, 1 insertion(+), 35 deletions(-) delete mode 100644 dnas/generic_dna/zomes/integrity/generic_zome/src/thing_to_agents.rs diff --git a/dnas/generic_dna/zomes/integrity/generic_zome/src/thing_to_agents.rs b/dnas/generic_dna/zomes/integrity/generic_zome/src/thing_to_agents.rs deleted file mode 100644 index 3a12cfc..0000000 --- a/dnas/generic_dna/zomes/integrity/generic_zome/src/thing_to_agents.rs +++ /dev/null @@ -1,34 +0,0 @@ -use hdi::prelude::*; - -pub fn validate_create_link_thing_to_agents( - _action: CreateLink, - base_address: AnyLinkableHash, - _target_address: AnyLinkableHash, - _tag: LinkTag, -) -> ExternResult { - // Check the entry type for the given action hash - let action_hash = base_address - .into_action_hash() - .ok_or(wasm_error!(WasmErrorInner::Guest( - "No action hash associated with link".to_string() - )))?; - let record = must_get_valid_record(action_hash)?; - let _thing: crate::ThingEntry = record - .entry() - .to_app_option() - .map_err(|e| wasm_error!(e))? - .ok_or(wasm_error!(WasmErrorInner::Guest( - "Linked action must reference an entry".to_string() - )))?; - Ok(ValidateCallbackResult::Valid) -} - -pub fn validate_delete_link_thing_to_agents( - _action: DeleteLink, - _original_action: CreateLink, - _base: AnyLinkableHash, - _target: AnyLinkableHash, - _tag: LinkTag, -) -> ExternResult { - Ok(ValidateCallbackResult::Valid) -} diff --git a/ui/package.json b/ui/package.json index 1a654cf..87cc843 100644 --- a/ui/package.json +++ b/ui/package.json @@ -8,7 +8,7 @@ "package": "npm run build && rimraf dist.zip && cd dist && bestzip ../dist.zip *" }, "dependencies": { - "@holochain/client": "^0.19.0-dev.0", + "@holochain/client": "^0.18.0-rc.0", "@lit/context": "^1.1.3", "@lit/task": "^1.0.1", "@msgpack/msgpack": "^2.8.0", From ee2f67e0a1d9bff0aba6303018130483d44a694f Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 2 Nov 2024 18:09:41 +0100 Subject: [PATCH 08/12] changed flake.nix, added and changed npm packages --- .../zomes/integrity/generic_zome/src/lib.rs | 2 - flake.lock | 22 +- flake.nix | 8 +- package-lock.json | 7391 +++++++++++++++++ ui/package.json | 1 + ui/src/genericDnaClient.ts | 0 6 files changed, 7407 insertions(+), 17 deletions(-) create mode 100644 package-lock.json create mode 100644 ui/src/genericDnaClient.ts diff --git a/dnas/generic_dna/zomes/integrity/generic_zome/src/lib.rs b/dnas/generic_dna/zomes/integrity/generic_zome/src/lib.rs index 56c9ace..443171e 100644 --- a/dnas/generic_dna/zomes/integrity/generic_zome/src/lib.rs +++ b/dnas/generic_dna/zomes/integrity/generic_zome/src/lib.rs @@ -1,5 +1,3 @@ -pub mod thing_to_agents; -pub use thing_to_agents::*; pub mod to_agent; pub use to_agent::*; pub mod to_anchor; diff --git a/flake.lock b/flake.lock index f2421e7..69ae0fe 100644 --- a/flake.lock +++ b/flake.lock @@ -53,11 +53,11 @@ "hc-scaffold": { "flake": false, "locked": { - "lastModified": 1729842397, - "narHash": "sha256-RGojwMWA5MXAsK/vy78Gb2JYoKrD+zzY0rl3KLt1LK4=", + "lastModified": 1728659843, + "narHash": "sha256-3A15jw8uf5t8mONlAtJngDB+n0wNKA3cB+lZ2mHF/RY=", "owner": "holochain", "repo": "scaffolding", - "rev": "27715e5fdf56e03720f22f77068c1f16c33f0881", + "rev": "d36abccbfbff833a8eb73b38be848856b0d38f53", "type": "github" }, "original": { @@ -70,16 +70,16 @@ "holochain": { "flake": false, "locked": { - "lastModified": 1730250209, - "narHash": "sha256-U1TVtxcZDwKuLiHhnQbkHFSNUuE22yiTrFQZ4ftWJeg=", + "lastModified": 1728079169, + "narHash": "sha256-sbQiTsh5dhI8ioQIfYkdNsCQCCT+vef+RhXumvYiVQQ=", "owner": "holochain", "repo": "holochain", - "rev": "37736e8f1a79b4aa52cdb1e497e9001e2b001053", + "rev": "d2868417b921850206247595f0e00d6eaf1b84f2", "type": "github" }, "original": { "owner": "holochain", - "ref": "holochain-0.5.0-dev.3", + "ref": "holochain-0.4.0-rc.0", "repo": "holochain", "type": "github" } @@ -96,16 +96,16 @@ "rust-overlay": "rust-overlay" }, "locked": { - "lastModified": 1730384720, - "narHash": "sha256-HiBXYzs6WOApQnbHPo6YiIggNJISHGpW1tCgh4Ii0y4=", + "lastModified": 1729097922, + "narHash": "sha256-HqzaJJ8BFpUitdW76puLZ91Byp8lGoYIUl5fGdsUarM=", "owner": "holochain", "repo": "holonix", - "rev": "272605580cfc84066eee10ae42d9bf30150ca230", + "rev": "81f74bf1445b17fe0c5d556936c6df837ea54ba9", "type": "github" }, "original": { "owner": "holochain", - "ref": "main", + "ref": "main-0.4", "repo": "holonix", "type": "github" } diff --git a/flake.nix b/flake.nix index 644aa47..9e4b55a 100644 --- a/flake.nix +++ b/flake.nix @@ -2,11 +2,11 @@ description = "Flake for Holochain app development"; inputs = { - holonix.url = "github:holochain/holonix?ref=main"; + holonix.url = "github:holochain/holonix?ref=main-0.4"; nixpkgs.follows = "holonix/nixpkgs"; flake-parts.follows = "holonix/flake-parts"; - + }; outputs = inputs@{ flake-parts, ... }: flake-parts.lib.mkFlake { inherit inputs; } { @@ -20,8 +20,8 @@ packages = (with pkgs; [ nodejs_20 binaryen - - + + ]); shellHook = '' diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..34b94da --- /dev/null +++ b/package-lock.json @@ -0,0 +1,7391 @@ +{ + "name": "generic-dna-dev", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "generic-dna-dev", + "workspaces": [ + "ui", + "tests" + ], + "devDependencies": { + "@holochain-playground/cli": "^0.300.1", + "@holochain/hc-spin": "^0.400.0-dev.3", + "concurrently": "^6.5.1", + "get-port-cli": "^3.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bitgo/blake2b": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@bitgo/blake2b/-/blake2b-3.2.4.tgz", + "integrity": "sha512-46PEgEVPxecNJ/xczggIllSxIkFIvvbVM0OfIDdNJ5qpFHUeBCkNIiGdzC3fYZlsv7bVTdUZOj79GcFBLMYBqA==", + "license": "ISC", + "dependencies": { + "@bitgo/blake2b-wasm": "^3.2.3", + "nanoassert": "^2.0.0" + } + }, + "node_modules/@bitgo/blake2b-wasm": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/@bitgo/blake2b-wasm/-/blake2b-wasm-3.2.3.tgz", + "integrity": "sha512-NaurBrMaEpjfg7EdUJgW/c6byt27O6q1ZaxB5Ita10MjjYjUu0SyYF4q7JPNxpHF/lMxb0YZakOxigbDBu9Jjw==", + "license": "MIT", + "dependencies": { + "nanoassert": "^1.0.0" + } + }, + "node_modules/@bitgo/blake2b-wasm/node_modules/nanoassert": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/nanoassert/-/nanoassert-1.1.0.tgz", + "integrity": "sha512-C40jQ3NzfkP53NsO8kEOFd79p4b9kDXQMwgiY1z8ZwrDZgUyom0AHwGegF4Dm99L+YoYhuaB0ceerUcXmqr1rQ==", + "license": "ISC" + }, + "node_modules/@colors/colors": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", + "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", + "license": "MIT", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@dabh/diagnostics": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", + "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", + "license": "MIT", + "dependencies": { + "colorspace": "1.1.x", + "enabled": "2.0.x", + "kuler": "^2.0.0" + } + }, + "node_modules/@electron-toolkit/preload": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@electron-toolkit/preload/-/preload-3.0.1.tgz", + "integrity": "sha512-EzoQmpK8jqqU8YnM5jRe0GJjGVJPke2KtANqz8QtN2JPT96ViOvProBdK5C6riCm0j1T8jjAGVQCZLQy9OVoIA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "electron": ">=13.0.0" + } + }, + "node_modules/@electron-toolkit/utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@electron-toolkit/utils/-/utils-3.0.0.tgz", + "integrity": "sha512-GaXHDhiT7KCvMJjXdp/QqpYinq69T/Pdl49Z1XLf8mKGf63dnsODMWyrmIjEQ0z/vG7dO8qF3fvmI6Eb2lUNZA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "electron": ">=13.0.0" + } + }, + "node_modules/@electron/get": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.3.tgz", + "integrity": "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.1", + "env-paths": "^2.2.0", + "fs-extra": "^8.1.0", + "got": "^11.8.5", + "progress": "^2.0.3", + "semver": "^6.2.0", + "sumchecker": "^3.0.1" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "global-agent": "^3.0.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@holochain-open-dev/utils": { + "version": "0.400.0-dev.4", + "resolved": "https://registry.npmjs.org/@holochain-open-dev/utils/-/utils-0.400.0-dev.4.tgz", + "integrity": "sha512-/SJIrR2uPJqXPHQ18a2fSjs83G94zbluMA34103iMqnN06JXWfSyiZWHrgovgP9MQ2DXDK1D9QahsTHzvmlQwQ==", + "dependencies": { + "@holochain/client": "^0.18.0-dev.13", + "@msgpack/msgpack": "^2.8.0", + "blakejs": "^1.2.1", + "emittery": "^1.0.1", + "lodash-es": "^4.17.21", + "sort-keys": "^5.0.0" + } + }, + "node_modules/@holochain-open-dev/utils/node_modules/@holochain/client": { + "version": "0.18.0-rc.0", + "resolved": "https://registry.npmjs.org/@holochain/client/-/client-0.18.0-rc.0.tgz", + "integrity": "sha512-y9dfvrnUL4OeIhW+yHUnsjsBMoWvL1HnvUKGjfoBQDBsqJGpanmysV6ALScNErF5axPVZ30/m0nmQ9NgpFzUGg==", + "dependencies": { + "@bitgo/blake2b": "^3.2.4", + "@holochain/serialization": "^0.1.0-beta-rc.3", + "@msgpack/msgpack": "^2.8.0", + "emittery": "^1.0.1", + "isomorphic-ws": "^5.0.0", + "js-base64": "^3.7.5", + "libsodium-wrappers": "^0.7.13", + "lodash-es": "^4.17.21", + "ws": "^8.14.2" + }, + "engines": { + "node": ">=18.0.0 || >=20.0.0" + } + }, + "node_modules/@holochain-open-dev/utils/node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@holochain-open-dev/utils/node_modules/sort-keys": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-5.1.0.tgz", + "integrity": "sha512-aSbHV0DaBcr7u0PVHXzM6NbZNAtrr9sF6+Qfs9UUVG7Ll3jQ6hHi8F/xqIIcn2rvIVbr0v/2zyjSdwSV47AgLQ==", + "dependencies": { + "is-plain-obj": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@holochain-playground/cli": { + "version": "0.300.1", + "resolved": "https://registry.npmjs.org/@holochain-playground/cli/-/cli-0.300.1.tgz", + "integrity": "sha512-9cFMXbD+eTkpEWzoiVWC1O5U1ylHRubds7ovqzZZgF7bDGWDkEm4PYbcEIDnBRLrTo6QCkK2jQF5lj6SxX43UA==", + "dev": true, + "license": "MIT", + "bin": { + "holochain-playground": "dist/app.js" + } + }, + "node_modules/@holochain/client": { + "version": "0.18.0-dev.0", + "resolved": "https://registry.npmjs.org/@holochain/client/-/client-0.18.0-dev.0.tgz", + "integrity": "sha512-xQ4J5rG+t1aJrtzZK8BsJYLsYHgG4zoUvsmoUuiKZcvVRlxPldX+p6rWYWz0JuDxlTE5hjmJmBTPWXd+WVHGNw==", + "dev": true, + "license": "CAL-1.0", + "dependencies": { + "@bitgo/blake2b": "^3.2.4", + "@holochain/serialization": "^0.1.0-beta-rc.3", + "@msgpack/msgpack": "^2.8.0", + "emittery": "^1.0.1", + "isomorphic-ws": "^5.0.0", + "js-base64": "^3.7.5", + "libsodium-wrappers": "^0.7.13", + "lodash-es": "^4.17.21", + "ws": "^8.14.2" + }, + "engines": { + "node": ">=18.0.0 || >=20.0.0" + } + }, + "node_modules/@holochain/hc-spin": { + "version": "0.400.0-dev.3", + "resolved": "https://registry.npmjs.org/@holochain/hc-spin/-/hc-spin-0.400.0-dev.3.tgz", + "integrity": "sha512-xuS57cmxhP8saDMlsjZvt10muMYmcYqRUMGmjhRBORy10Xxpqd9yDV2CR2BNLsAdZdBFaAzuFW0twvpVI9KfFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron-toolkit/preload": "^3.0.0", + "@electron-toolkit/utils": "^3.0.0", + "@holochain/client": "0.18.0-dev.0", + "@holochain/hc-spin-rust-utils": "^0.300.1", + "@msgpack/msgpack": "^2.8.0", + "bufferutil": "4.0.8", + "commander": "11.1.0", + "electron": "^29.3.1", + "electron-context-menu": "3.6.1", + "get-port": "7.0.0", + "nanoid": "5.0.4", + "split": "1.0.1" + }, + "bin": { + "hc-spin": "dist/cli.js" + } + }, + "node_modules/@holochain/hc-spin-rust-utils": { + "version": "0.300.1", + "resolved": "https://registry.npmjs.org/@holochain/hc-spin-rust-utils/-/hc-spin-rust-utils-0.300.1.tgz", + "integrity": "sha512-vMC6cgqJ8gOT7dGunTyYd6frqax+XQO9v4ZB5YL6amws9xu9lL6OqG1igNJfGimAbqCaQTd1bq8Ctr+HF8AYyg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@holochain/hc-spin-rust-utils-darwin-arm64": "0.300.1", + "@holochain/hc-spin-rust-utils-darwin-x64": "0.300.1", + "@holochain/hc-spin-rust-utils-linux-x64-gnu": "0.300.1", + "@holochain/hc-spin-rust-utils-win32-x64-msvc": "0.300.1" + } + }, + "node_modules/@holochain/hc-spin-rust-utils-darwin-arm64": { + "version": "0.300.1", + "resolved": "https://registry.npmjs.org/@holochain/hc-spin-rust-utils-darwin-arm64/-/hc-spin-rust-utils-darwin-arm64-0.300.1.tgz", + "integrity": "sha512-IOt+hTVRByaqpzuZ+pN7tTAqNPXsPxE6oc+Hqjo5D4aWP3oeD2b6bEEDRfBicMuUTp7spIqKgT/4Dj0pQtLvyw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@holochain/hc-spin-rust-utils-darwin-x64": { + "version": "0.300.1", + "resolved": "https://registry.npmjs.org/@holochain/hc-spin-rust-utils-darwin-x64/-/hc-spin-rust-utils-darwin-x64-0.300.1.tgz", + "integrity": "sha512-ffxAB9o5XhvwcXi1F6MsURoxhxJbo3HvlBpD0F2VNfyv/zCd15gb8HvcskhcvQFKlCEHigRrilOxHP5Aks8I3w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@holochain/hc-spin-rust-utils-linux-x64-gnu": { + "version": "0.300.1", + "resolved": "https://registry.npmjs.org/@holochain/hc-spin-rust-utils-linux-x64-gnu/-/hc-spin-rust-utils-linux-x64-gnu-0.300.1.tgz", + "integrity": "sha512-SKUJdvKIRkqixgaChnkLvBNWgZgFGLI5tNeV/8WMdxCKqD2kLJzUFSIafl1arck9964iSfsCRMG8/5fpfE+sZg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@holochain/hc-spin-rust-utils-win32-x64-msvc": { + "version": "0.300.1", + "resolved": "https://registry.npmjs.org/@holochain/hc-spin-rust-utils-win32-x64-msvc/-/hc-spin-rust-utils-win32-x64-msvc-0.300.1.tgz", + "integrity": "sha512-S+PcygFnkVbR1/5FF66P7gBju3+PfOd1BLgfDpF6kghSJfb3qSN1h93vPujxeoQcs1qtT3DqMarG2BmyCe9RPA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@holochain/serialization": { + "version": "0.1.0-beta-rc.3", + "resolved": "https://registry.npmjs.org/@holochain/serialization/-/serialization-0.1.0-beta-rc.3.tgz", + "integrity": "sha512-DJx4V2KXHVLciyOGjOYKTM/JLBpBEZ3RsPIRCgf7qmwhQdxXvhi2p+oFFRD51yUT5uC1/MzIVeJCl/R60PwFbw==", + "license": "CAL-1.0" + }, + "node_modules/@holochain/tryorama": { + "version": "0.18.0-dev.0", + "resolved": "https://registry.npmjs.org/@holochain/tryorama/-/tryorama-0.18.0-dev.0.tgz", + "integrity": "sha512-2pHTbKB3iQDQKLWlbZmcDXSEjCQYIPSk5npW091XNEkQZn0RKSgeElIzKNDUwvXwsxfSstK5waxqRwdvsnz6UQ==", + "license": "MIT", + "dependencies": { + "@holochain/client": "^0.19.0-dev.0", + "get-port": "^6.1.2", + "lodash": "^4.17.21", + "uuid": "^8.3.2", + "winston": "^3.8.2", + "ws": "^8.11.0" + }, + "engines": { + "node": ">=18.0.0 || >=20.0.0" + } + }, + "node_modules/@holochain/tryorama/node_modules/@holochain/client": { + "version": "0.19.0-dev.1", + "resolved": "https://registry.npmjs.org/@holochain/client/-/client-0.19.0-dev.1.tgz", + "integrity": "sha512-yYx9liPF62pp8XxR3zRFzaK8YTzxRlyLl9dIWHBhgOIbrRmUywWSlyvCfyvceLY/LgP8vn9hesJ9E0BF3osBHQ==", + "license": "CAL-1.0", + "dependencies": { + "@bitgo/blake2b": "^3.2.4", + "@holochain/serialization": "^0.1.0-beta-rc.3", + "@msgpack/msgpack": "^2.8.0", + "emittery": "^1.0.1", + "isomorphic-ws": "^5.0.0", + "js-base64": "^3.7.5", + "libsodium-wrappers": "^0.7.13", + "lodash-es": "^4.17.21", + "ws": "^8.14.2" + }, + "engines": { + "node": ">=18.0.0 || >=20.0.0" + } + }, + "node_modules/@holochain/tryorama/node_modules/get-port": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-6.1.2.tgz", + "integrity": "sha512-BrGGraKm2uPqurfGVj/z97/zv8dPleC6x9JBNRTrDNtCkkRF4rPwrQXFgL7+I+q8QSdU4ntLQX2D7KIxSy8nGw==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@lit-labs/ssr-dom-shim": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.2.1.tgz", + "integrity": "sha512-wx4aBmgeGvFmOKucFKY+8VFJSYZxs9poN3SDNQFF6lT6NrQUnHiPB2PWz2sc4ieEcAaYYzN+1uWahEeTq2aRIQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@lit/context": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@lit/context/-/context-1.1.3.tgz", + "integrity": "sha512-Auh37F4S0PZM93HTDfZWs97mmzaQ7M3vnTc9YvxAGyP3UItSK/8Fs0vTOGT+njuvOwbKio/l8Cx/zWL4vkutpQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@lit/reactive-element": "^1.6.2 || ^2.0.0" + } + }, + "node_modules/@lit/reactive-element": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.0.4.tgz", + "integrity": "sha512-GFn91inaUa2oHLak8awSIigYz0cU0Payr1rcFsrkf5OJ5eSPxElyZfKh0f2p9FsTiZWXQdWGJeXZICEfXXYSXQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@lit-labs/ssr-dom-shim": "^1.2.0" + } + }, + "node_modules/@lit/task": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@lit/task/-/task-1.0.1.tgz", + "integrity": "sha512-fVLDtmwCau8NywnFIXaJxsCZjzaIxnVq+cFRKYC1Y4tA4/0rMTvF6DLZZ2JE51BwzOluaKtgJX8x1QDsQtAaIw==", + "license": "BSD-3-Clause", + "dependencies": { + "@lit/reactive-element": "^1.0.0 || ^2.0.0" + } + }, + "node_modules/@msgpack/msgpack": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@msgpack/msgpack/-/msgpack-2.8.0.tgz", + "integrity": "sha512-h9u4u/jiIRKbq25PM+zymTyW6bhTzELvOoUd+AvYriWOAKpLGnIamaET3pnHYoI5iYphAHBI4ayx0MehR+VVPQ==", + "license": "ISC", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@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, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.3.tgz", + "integrity": "sha512-ufb2CH2KfBWPJok95frEZZ82LtDl0A6QKTa8MoM+cWwDZvVGl5/jNb79pIhRvAalUu+7LD91VYR0nwRD799HkQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.3.tgz", + "integrity": "sha512-iAHpft/eQk9vkWIV5t22V77d90CRofgR2006UiCjHcHJFVI1E0oBkQIAbz+pLtthFw3hWEmVB4ilxGyBf48i2Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.3.tgz", + "integrity": "sha512-QPW2YmkWLlvqmOa2OwrfqLJqkHm7kJCIMq9kOz40Zo9Ipi40kf9ONG5Sz76zszrmIZZ4hgRIkez69YnTHgEz1w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.3.tgz", + "integrity": "sha512-KO0pN5x3+uZm1ZXeIfDqwcvnQ9UEGN8JX5ufhmgH5Lz4ujjZMAnxQygZAVGemFWn+ZZC0FQopruV4lqmGMshow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.24.3.tgz", + "integrity": "sha512-CsC+ZdIiZCZbBI+aRlWpYJMSWvVssPuWqrDy/zi9YfnatKKSLFCe6fjna1grHuo/nVaHG+kiglpRhyBQYRTK4A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.24.3.tgz", + "integrity": "sha512-F0nqiLThcfKvRQhZEzMIXOQG4EeX61im61VYL1jo4eBxv4aZRmpin6crnBJQ/nWnCsjH5F6J3W6Stdm0mBNqBg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.3.tgz", + "integrity": "sha512-KRSFHyE/RdxQ1CSeOIBVIAxStFC/hnBgVcaiCkQaVC+EYDtTe4X7z5tBkFyRoBgUGtB6Xg6t9t2kulnX6wJc6A==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.3.tgz", + "integrity": "sha512-h6Q8MT+e05zP5BxEKz0vi0DhthLdrNEnspdLzkoFqGwnmOzakEHSlXfVyA4HJ322QtFy7biUAVFPvIDEDQa6rw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.3.tgz", + "integrity": "sha512-fKElSyXhXIJ9pqiYRqisfirIo2Z5pTTve5K438URf08fsypXrEkVmShkSfM8GJ1aUyvjakT+fn2W7Czlpd/0FQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.3.tgz", + "integrity": "sha512-YlddZSUk8G0px9/+V9PVilVDC6ydMz7WquxozToozSnfFK6wa6ne1ATUjUvjin09jp34p84milxlY5ikueoenw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.3.tgz", + "integrity": "sha512-yNaWw+GAO8JjVx3s3cMeG5Esz1cKVzz8PkTJSfYzE5u7A+NvGmbVFEHP+BikTIyYWuz0+DX9kaA3pH9Sqxp69g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.3.tgz", + "integrity": "sha512-lWKNQfsbpv14ZCtM/HkjCTm4oWTKTfxPmr7iPfp3AHSqyoTz5AgLemYkWLwOBWc+XxBbrU9SCokZP0WlBZM9lA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.3.tgz", + "integrity": "sha512-HoojGXTC2CgCcq0Woc/dn12wQUlkNyfH0I1ABK4Ni9YXyFQa86Fkt2Q0nqgLfbhkyfQ6003i3qQk9pLh/SpAYw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.3.tgz", + "integrity": "sha512-mnEOh4iE4USSccBOtcrjF5nj+5/zm6NcNhbSEfR3Ot0pxBwvEn5QVUXcuOwwPkapDtGZ6pT02xLoPaNv06w7KQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.3.tgz", + "integrity": "sha512-rMTzawBPimBQkG9NKpNHvquIUTQPzrnPxPbCY1Xt+mFkW7pshvyIS5kYgcf74goxXOQk0CP3EoOC1zcEezKXhw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.3.tgz", + "integrity": "sha512-2lg1CE305xNvnH3SyiKwPVsTVLCg4TmNCF1z7PSHX2uZY2VbUpdkgAllVoISD7JO7zu+YynpWNSKAtOrX3AiuA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.3.tgz", + "integrity": "sha512-9SjYp1sPyxJsPWuhOCX6F4jUMXGbVVd5obVpoVEi8ClZqo52ViZewA6eFz85y8ezuOA+uJMP5A5zo6Oz4S5rVQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.3.tgz", + "integrity": "sha512-HGZgRFFYrMrP3TJlq58nR1xy8zHKId25vhmm5S9jETEfDf6xybPxsavFTJaufe2zgOGYJBskGlj49CwtEuFhWQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "dev": true, + "license": "MIT", + "dependencies": { + "defer-to-connect": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@types/cacheable-request": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", + "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-cache-semantics": "*", + "@types/keyv": "^3.1.4", + "@types/node": "*", + "@types/responselike": "^1.0.0" + } + }, + "node_modules/@types/chai": { + "version": "4.3.20", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.20.tgz", + "integrity": "sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==", + "license": "MIT" + }, + "node_modules/@types/chai-subset": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/chai-subset/-/chai-subset-1.3.5.tgz", + "integrity": "sha512-c2mPnw+xHtXDoHmdtcCXGwyLMiauiAyxWMzhGpqHC4nqI/Y5G2XhTampslK2rb59kpcuHon03UH8W6iYUzw88A==", + "license": "MIT", + "dependencies": { + "@types/chai": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/keyv": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.17.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.5.tgz", + "integrity": "sha512-n8FYY/pRxu496441gIcAQFZPKXbhsd6VZygcq+PTSZ75eMh/Ke0hCAROdUa21qiFqKNsPPYic46yXDO1JGiPBQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/responselike": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", + "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/triple-beam": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz", + "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==", + "license": "MIT" + }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "license": "MIT" + }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@vitest/expect": { + "version": "0.28.5", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.28.5.tgz", + "integrity": "sha512-gqTZwoUTwepwGIatnw4UKpQfnoyV0Z9Czn9+Lo2/jLIt4/AXLTn+oVZxlQ7Ng8bzcNkR+3DqLJ08kNr8jRmdNQ==", + "license": "MIT", + "dependencies": { + "@vitest/spy": "0.28.5", + "@vitest/utils": "0.28.5", + "chai": "^4.3.7" + } + }, + "node_modules/@vitest/runner": { + "version": "0.28.5", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.28.5.tgz", + "integrity": "sha512-NKkHtLB+FGjpp5KmneQjTcPLWPTDfB7ie+MmF1PnUBf/tGe2OjGxWyB62ySYZ25EYp9krR5Bw0YPLS/VWh1QiA==", + "license": "MIT", + "dependencies": { + "@vitest/utils": "0.28.5", + "p-limit": "^4.0.0", + "pathe": "^1.1.0" + } + }, + "node_modules/@vitest/runner/node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@vitest/runner/node_modules/yocto-queue": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", + "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@vitest/spy": { + "version": "0.28.5", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.28.5.tgz", + "integrity": "sha512-7if6rsHQr9zbmvxN7h+gGh2L9eIIErgf8nSKYDlg07HHimCxp4H6I/X/DPXktVPPLQfiZ1Cw2cbDIx9fSqDjGw==", + "license": "MIT", + "dependencies": { + "tinyspy": "^1.0.2" + } + }, + "node_modules/@vitest/utils": { + "version": "0.28.5", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.28.5.tgz", + "integrity": "sha512-UyZdYwdULlOa4LTUSwZ+Paz7nBHGTT72jKwdFSV4IjHF1xsokp+CabMdhjvVhYwkLfO88ylJT46YMilnkSARZA==", + "license": "MIT", + "dependencies": { + "cli-truncate": "^3.1.0", + "diff": "^5.1.0", + "loupe": "^2.3.6", + "picocolors": "^1.0.0", + "pretty-format": "^27.5.1" + } + }, + "node_modules/@vitest/utils/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@vitest/utils/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==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@vitest/utils/node_modules/cli-truncate": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz", + "integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==", + "license": "MIT", + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@vitest/utils/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==", + "license": "MIT" + }, + "node_modules/@vitest/utils/node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@vitest/utils/node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/@vitest/utils/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==", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@vitest/utils/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==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/archiver": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.2.tgz", + "integrity": "sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "archiver-utils": "^2.1.0", + "async": "^3.2.4", + "buffer-crc32": "^0.2.1", + "readable-stream": "^3.6.0", + "readdir-glob": "^1.1.2", + "tar-stream": "^2.2.0", + "zip-stream": "^4.1.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/archiver-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", + "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob": "^7.1.4", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^2.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/archiver-utils/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/archiver-utils/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/archiver-utils/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "license": "MIT" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/bestzip": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/bestzip/-/bestzip-2.2.1.tgz", + "integrity": "sha512-XdAb87RXqOqF7C6UgQG9IqpEHJvS6IOUo0bXWEAebjSSdhDjsbcqFKdHpn5Q7QHz2pGr3Zmw4wgG3LlzdyDz7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "archiver": "^5.3.0", + "async": "^3.2.0", + "glob": "^7.1.6", + "which": "^2.0.2", + "yargs": "^16.2.0" + }, + "bin": { + "bestzip": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/blakejs": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==" + }, + "node_modules/boolean": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", + "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/buffer-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==", + "license": "MIT" + }, + "node_modules/bufferutil": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.8.tgz", + "integrity": "sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==", + "devOptional": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.6.0" + } + }, + "node_modules/cacheable-request": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/camelcase-keys": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-7.0.2.tgz", + "integrity": "sha512-Rjs1H+A9R+Ig+4E/9oyB66UC5Mj9Xq3N//vcLf2WzgdTi/3gUu3Z9KoqmlrEG4VuuLK8wJHofxzdQXz/knhiYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase": "^6.3.0", + "map-obj": "^4.1.0", + "quick-lru": "^5.1.1", + "type-fest": "^1.2.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chai": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", + "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", + "license": "MIT", + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/clone-response": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", + "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/color": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.3", + "color-string": "^1.6.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/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==", + "license": "MIT" + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "license": "MIT", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/color/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==", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color/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==", + "license": "MIT" + }, + "node_modules/colorspace": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", + "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", + "license": "MIT", + "dependencies": { + "color": "^3.1.3", + "text-hex": "1.0.x" + } + }, + "node_modules/commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + } + }, + "node_modules/compress-commons": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.2.tgz", + "integrity": "sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "^0.2.13", + "crc32-stream": "^4.0.2", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/concurrently": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-6.5.1.tgz", + "integrity": "sha512-FlSwNpGjWQfRwPLXvJ/OgysbBxPkWpiVjy1042b0U7on7S7qwwMIILRj7WTN1mTgqa582bG6NFuScOoh6Zgdag==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "date-fns": "^2.16.1", + "lodash": "^4.17.21", + "rxjs": "^6.6.3", + "spawn-command": "^0.0.2-1", + "supports-color": "^8.1.0", + "tree-kill": "^1.2.2", + "yargs": "^16.2.0" + }, + "bin": { + "concurrently": "bin/concurrently.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "license": "MIT" + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/crc32-stream": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.3.tgz", + "integrity": "sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "crc-32": "^1.2.0", + "readable-stream": "^3.4.0" + }, + "engines": { + "node": ">= 10" + } + }, + "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, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/date-fns": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.21.0" + }, + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, + "node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-5.0.1.tgz", + "integrity": "sha512-VfxadyCECXgQlkoEAjeghAr5gY3Hf+IKjKb+X8tGVDtveCjN+USwprd2q3QXBR9T1+x2DG0XZF5/w+7HAtSaXA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decamelize-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", + "dev": true, + "license": "MIT", + "dependencies": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decamelize-keys/node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-eql": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", + "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", + "license": "MIT", + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "license": "MIT" + }, + "node_modules/electron": { + "version": "29.4.6", + "resolved": "https://registry.npmjs.org/electron/-/electron-29.4.6.tgz", + "integrity": "sha512-fz8ndj8cmmf441t4Yh2FDP3Rn0JhLkVGvtUf2YVMbJ5SdJPlc0JWll9jYkhh60jDKVVCr/tBAmfxqRnXMWJpzg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@electron/get": "^2.0.0", + "@types/node": "^20.9.0", + "extract-zip": "^2.0.1" + }, + "bin": { + "electron": "cli.js" + }, + "engines": { + "node": ">= 12.20.55" + } + }, + "node_modules/electron-context-menu": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/electron-context-menu/-/electron-context-menu-3.6.1.tgz", + "integrity": "sha512-lcpO6tzzKUROeirhzBjdBWNqayEThmdW+2I2s6H6QMrwqTVyT3EK47jW3Nxm60KTxl5/bWfEoIruoUNn57/QkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "cli-truncate": "^2.1.0", + "electron-dl": "^3.2.1", + "electron-is-dev": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/electron-dl": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/electron-dl/-/electron-dl-3.5.2.tgz", + "integrity": "sha512-i104cl+u8yJ0lhpRAtUWfeGuWuL1PL6TBiw2gLf0MMIBjfgE485Ags2mcySx4uWU9P9uj/vsD3jd7X+w1lzZxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "ext-name": "^5.0.0", + "pupa": "^2.0.1", + "unused-filename": "^2.1.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/electron-is-dev": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/electron-is-dev/-/electron-is-dev-2.0.0.tgz", + "integrity": "sha512-3X99K852Yoqu9AcW50qz3ibYBWY79/pBhlMCab8ToEWS48R0T9tyxRiQhwylE7zQdXrMnx2JKqUJyMPmt5FBqA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/emittery": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-1.0.3.tgz", + "integrity": "sha512-tJdCJitoy2lrC2ldJcqN4vkqJ00lT+tOWNT1hBJjO/3FDMJa5TTIiYGCKGkn/WfCyOzUMObeohbVTj00fhiLiA==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/enabled": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", + "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==", + "license": "MIT" + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-goat": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", + "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/ext-list": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz", + "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "^1.28.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ext-name": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz", + "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ext-list": "^2.0.0", + "sort-keys-length": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/fecha": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", + "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==", + "license": "MIT" + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fn.name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", + "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==", + "license": "MIT" + }, + "node_modules/foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true, + "license": "MIT" + }, + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-port": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-7.0.0.tgz", + "integrity": "sha512-mDHFgApoQd+azgMdwylJrv2DX47ywGq1i5VFJE7fZ0dttNq3iQMfsU4IvEgBHojA3KqEudyu7Vq+oN8kNaNkWw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-port-cli": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-port-cli/-/get-port-cli-3.0.0.tgz", + "integrity": "sha512-060GMr81KapTzSobWNrQVAqHeUaFRZhPj/lNnzdCcfVodFN497wRgEamnTCNgldJuiR6TXxdtkFidcYQ/nSVDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-port": "^6.0.0", + "meow": "^10.1.1" + }, + "bin": { + "get-port": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-port-cli/node_modules/get-port": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-6.1.2.tgz", + "integrity": "sha512-BrGGraKm2uPqurfGVj/z97/zv8dPleC6x9JBNRTrDNtCkkRF4rPwrQXFgL7+I+q8QSdU4ntLQX2D7KIxSy8nGw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/global-agent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", + "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "boolean": "^3.0.1", + "es6-error": "^4.1.1", + "matcher": "^3.0.0", + "roarr": "^2.15.3", + "semver": "^7.3.2", + "serialize-error": "^7.0.1" + }, + "engines": { + "node": ">=10.0" + } + }, + "node_modules/global-agent/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/got": { + "version": "11.8.6", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", + "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=10.19.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "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, + "license": "ISC" + }, + "node_modules/hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "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, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/isomorphic-ws": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz", + "integrity": "sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==", + "license": "MIT", + "peerDependencies": { + "ws": "*" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/js-base64": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.7.tgz", + "integrity": "sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==", + "license": "BSD-3-Clause" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-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, + "license": "MIT" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/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, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kuler": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", + "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==", + "license": "MIT" + }, + "node_modules/lazystream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "^2.0.5" + }, + "engines": { + "node": ">= 0.6.3" + } + }, + "node_modules/lazystream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/lazystream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/lazystream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/libsodium": { + "version": "0.7.15", + "resolved": "https://registry.npmjs.org/libsodium/-/libsodium-0.7.15.tgz", + "integrity": "sha512-sZwRknt/tUpE2AwzHq3jEyUU5uvIZHtSssktXq7owd++3CSgn8RGrv6UZJJBpP7+iBghBqe7Z06/2M31rI2NKw==", + "license": "ISC" + }, + "node_modules/libsodium-wrappers": { + "version": "0.7.15", + "resolved": "https://registry.npmjs.org/libsodium-wrappers/-/libsodium-wrappers-0.7.15.tgz", + "integrity": "sha512-E4anqJQwcfiC6+Yrl01C1m8p99wEhLmJSs0VQqST66SbQXXBoaJY0pF4BNjRYa/sOQAxx6lXAaAFIlx+15tXJQ==", + "license": "ISC", + "dependencies": { + "libsodium": "^0.7.15" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lit": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/lit/-/lit-3.2.1.tgz", + "integrity": "sha512-1BBa1E/z0O9ye5fZprPtdqnc0BFzxIxTTOO/tQFmyC/hj1O3jL4TfmLBw0WEwjAokdLwpclkvGgDJwTIh0/22w==", + "license": "BSD-3-Clause", + "dependencies": { + "@lit/reactive-element": "^2.0.4", + "lit-element": "^4.1.0", + "lit-html": "^3.2.0" + } + }, + "node_modules/lit-element": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.1.1.tgz", + "integrity": "sha512-HO9Tkkh34QkTeUmEdNYhMT8hzLid7YlMlATSi1q4q17HE5d9mrrEHJ/o8O2D0cMi182zK1F3v7x0PWFjrhXFew==", + "license": "BSD-3-Clause", + "dependencies": { + "@lit-labs/ssr-dom-shim": "^1.2.0", + "@lit/reactive-element": "^2.0.4", + "lit-html": "^3.2.0" + } + }, + "node_modules/lit-html": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.2.1.tgz", + "integrity": "sha512-qI/3lziaPMSKsrwlxH/xMgikhQ0EGOX2ICU73Bi/YHFvz2j/yMCIrw4+puF2IpQ4+upd3EWbvnHM9+PnJn48YA==", + "license": "BSD-3-Clause", + "dependencies": { + "@types/trusted-types": "^2.0.2" + } + }, + "node_modules/local-pkg": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.3.tgz", + "integrity": "sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "license": "MIT" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.difference": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", + "integrity": "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.pick": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", + "integrity": "sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.union": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", + "integrity": "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/logform": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.6.1.tgz", + "integrity": "sha512-CdaO738xRapbKIMVn2m4F6KTj4j7ooJ8POVnebSgKo3KBz5axNXRAL7ZdRjIV6NOr2Uf4vjtRkxrFETOioCqSA==", + "license": "MIT", + "dependencies": { + "@colors/colors": "1.6.0", + "@types/triple-beam": "^1.3.2", + "fecha": "^4.2.0", + "ms": "^2.1.1", + "safe-stable-stringify": "^2.3.1", + "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.1" + } + }, + "node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/matcher": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", + "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "escape-string-regexp": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/meow": { + "version": "10.1.5", + "resolved": "https://registry.npmjs.org/meow/-/meow-10.1.5.tgz", + "integrity": "sha512-/d+PQ4GKmGvM9Bee/DPa8z3mXs/pkvJE2KEThngVNOqtmljC6K7NMPxtc2JeZYTmpWb9k/TmxjeL18ez3h7vCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/minimist": "^1.2.2", + "camelcase-keys": "^7.0.0", + "decamelize": "^5.0.0", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.2", + "read-pkg-up": "^8.0.0", + "redent": "^4.0.0", + "trim-newlines": "^4.0.2", + "type-fest": "^1.2.2", + "yargs-parser": "^20.2.9" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.53.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.53.0.tgz", + "integrity": "sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mlly": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.2.tgz", + "integrity": "sha512-tN3dvVHYVz4DhSXinXIk7u9syPYaJvio118uomkovAtWBT+RdbP6Lfh/5Lvo519YMmwBafwlh20IPTXIStscpA==", + "license": "MIT", + "dependencies": { + "acorn": "^8.12.1", + "pathe": "^1.1.2", + "pkg-types": "^1.2.0", + "ufo": "^1.5.4" + } + }, + "node_modules/modify-filename": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/modify-filename/-/modify-filename-1.1.0.tgz", + "integrity": "sha512-EickqnKq3kVVaZisYuCxhtKbZjInCuwgwZWyAmRIp1NTMhri7r3380/uqwrUHfaDiPzLVTuoNy4whX66bxPVog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/nanoassert": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/nanoassert/-/nanoassert-2.0.0.tgz", + "integrity": "sha512-7vO7n28+aYO4J+8w96AzhmU8G+Y/xpPDJz/se19ICsqj/momRbb9mh9ZUtkoJ5X3nTnPdhEJyc0qnM6yAsHBaA==", + "license": "ISC" + }, + "node_modules/nanoid": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.4.tgz", + "integrity": "sha512-vAjmBf13gsmhXSgBrtIclinISzFFy22WwCYoyilZlsrRXNIHSwgFQ1bEdjRwMT3aoadeIF6HMuDRlOxzfXV8ig==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.js" + }, + "engines": { + "node": "^18 || >=20" + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.2", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.2.tgz", + "integrity": "sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==", + "devOptional": true, + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/one-time": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", + "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", + "license": "MIT", + "dependencies": { + "fn.name": "1.x.x" + } + }, + "node_modules/p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/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, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-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, + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "license": "MIT" + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-types": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.2.1.tgz", + "integrity": "sha512-sQoqa8alT3nHjGuTjuKgOnvjo4cljkufdtLMnO2LBP/wRwuDlo1tkaEdMxCRhyGRPacv/ztlZgDPm2b7FAmEvw==", + "license": "MIT", + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.2", + "pathe": "^1.1.2" + } + }, + "node_modules/postcss": { + "version": "8.4.47", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", + "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.0", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss/node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true, + "license": "MIT" + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/pump": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", + "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/pupa": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", + "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-goat": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "license": "MIT" + }, + "node_modules/read-pkg": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-6.0.0.tgz", + "integrity": "sha512-X1Fu3dPuk/8ZLsMhEj5f4wFAF0DWoK7qhGJvgaijocXxBmSToKfbFtqbxMO7bVjNA1dmE5huAzjXj/ey86iw9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^3.0.2", + "parse-json": "^5.2.0", + "type-fest": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-8.0.0.tgz", + "integrity": "sha512-snVCqPczksT0HS2EC+SxUndvSzn6LRCwpfSvLrIfR5BKDQQZMaI6jPRC9dYvYFDRAuFEAnkwww8kBBNE/3VvzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^5.0.0", + "read-pkg": "^6.0.0", + "type-fest": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdir-glob": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", + "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.1.0" + } + }, + "node_modules/readdir-glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/readdir-glob/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/redent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-4.0.0.tgz", + "integrity": "sha512-tYkDkVVtYkSVhuQ4zBgfvciymHaeuel+zFKXShfDnFP5SyVEP7qo70Rf1jTOTCx3vGNAbnEi/xFkcfQVMIBWag==", + "dev": true, + "license": "MIT", + "dependencies": { + "indent-string": "^5.0.0", + "strip-indent": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true, + "license": "MIT" + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "is-core-module": "^2.13.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-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "lowercase-keys": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/roarr": { + "version": "2.15.4", + "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", + "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "boolean": "^3.0.1", + "detect-node": "^2.0.4", + "globalthis": "^1.0.1", + "json-stringify-safe": "^5.0.1", + "semver-compare": "^1.0.0", + "sprintf-js": "^1.1.2" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/rollup": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.3.tgz", + "integrity": "sha512-HBW896xR5HGmoksbi3JBDtmVzWiPAYqp7wip50hjQ67JbDz61nyoMPdqu1DvVW9asYb2M65Z20ZHsyJCMqMyDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.24.3", + "@rollup/rollup-android-arm64": "4.24.3", + "@rollup/rollup-darwin-arm64": "4.24.3", + "@rollup/rollup-darwin-x64": "4.24.3", + "@rollup/rollup-freebsd-arm64": "4.24.3", + "@rollup/rollup-freebsd-x64": "4.24.3", + "@rollup/rollup-linux-arm-gnueabihf": "4.24.3", + "@rollup/rollup-linux-arm-musleabihf": "4.24.3", + "@rollup/rollup-linux-arm64-gnu": "4.24.3", + "@rollup/rollup-linux-arm64-musl": "4.24.3", + "@rollup/rollup-linux-powerpc64le-gnu": "4.24.3", + "@rollup/rollup-linux-riscv64-gnu": "4.24.3", + "@rollup/rollup-linux-s390x-gnu": "4.24.3", + "@rollup/rollup-linux-x64-gnu": "4.24.3", + "@rollup/rollup-linux-x64-musl": "4.24.3", + "@rollup/rollup-win32-arm64-msvc": "4.24.3", + "@rollup/rollup-win32-ia32-msvc": "4.24.3", + "@rollup/rollup-win32-x64-msvc": "4.24.3", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/rxjs/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true, + "license": "0BSD" + }, + "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==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-stable-stringify": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/serialize-error": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", + "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "type-fest": "^0.13.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/serialize-error/node_modules/type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "license": "ISC" + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "license": "MIT" + }, + "node_modules/slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sort-keys-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz", + "integrity": "sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "sort-keys": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "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==", + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/spawn-command": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2.tgz", + "integrity": "sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==", + "dev": true + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.20", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", + "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "through": "2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true, + "license": "BSD-3-Clause", + "optional": true + }, + "node_modules/stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "license": "MIT" + }, + "node_modules/std-env": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", + "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", + "license": "MIT" + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.0.0.tgz", + "integrity": "sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "min-indent": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-literal": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-1.3.0.tgz", + "integrity": "sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==", + "license": "MIT", + "dependencies": { + "acorn": "^8.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/sumchecker": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", + "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "debug": "^4.1.0" + }, + "engines": { + "node": ">= 8.0" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/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, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tests": { + "resolved": "tests", + "link": true + }, + "node_modules/text-hex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", + "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==", + "license": "MIT" + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "license": "MIT" + }, + "node_modules/tinypool": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.3.1.tgz", + "integrity": "sha512-zLA1ZXlstbU2rlpA4CIeVaqvWq41MTWqLY3FfsAXgC8+f7Pk7zroaJQxDgxn1xNudKW6Kmj4808rPFShUlIRmQ==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-1.1.1.tgz", + "integrity": "sha512-UVq5AXt/gQlti7oxoIg5oi/9r0WpF7DGEVwXgqWSMmyN16+e3tl5lIvTaOpJ3TAtu5xFzWccFRM4R5NaWHF+4g==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/trim-newlines": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-4.1.1.tgz", + "integrity": "sha512-jRKj0n0jXWo6kh62nA5TEh3+4igKDXLvzBJcPpiizP7oOolUrYIxmVBG9TOtHYFHoddUk6YvAkGeGoSVTXfQXQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/triple-beam": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", + "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==", + "license": "MIT", + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, + "node_modules/type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/ufo": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz", + "integrity": "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==", + "license": "MIT" + }, + "node_modules/ui": { + "resolved": "ui", + "link": true + }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "license": "MIT" + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unused-filename": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unused-filename/-/unused-filename-2.1.0.tgz", + "integrity": "sha512-BMiNwJbuWmqCpAM1FqxCTD7lXF97AvfQC8Kr/DIeA6VtvhJaMDupZ82+inbjl5yVP44PcxOuCSxye1QMS0wZyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "modify-filename": "^1.1.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/vite": { + "version": "5.4.10", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.10.tgz", + "integrity": "sha512-1hvaPshuPUtxeQ0hsVH3Mud0ZanOLwVTneA1EgbAM5LhaZEqyPWGRQ7BtaMvUrTDeEaC8pxtj6a6jku3x4z6SQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "0.28.5", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.28.5.tgz", + "integrity": "sha512-LmXb9saMGlrMZbXTvOveJKwMTBTNUH66c8rJnQ0ZPNX+myPEol64+szRzXtV5ORb0Hb/91yq+/D3oERoyAt6LA==", + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.4", + "mlly": "^1.1.0", + "pathe": "^1.1.0", + "picocolors": "^1.0.0", + "source-map": "^0.6.1", + "source-map-support": "^0.5.21", + "vite": "^3.0.0 || ^4.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": ">=v14.16.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/vite-node/node_modules/@esbuild/android-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/android-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/android-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/darwin-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/darwin-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/freebsd-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/freebsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-loong64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-mips64el": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-ppc64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-riscv64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-s390x": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/netbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/openbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/sunos-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/win32-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/win32-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/win32-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/esbuild": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" + } + }, + "node_modules/vite-node/node_modules/rollup": { + "version": "3.29.5", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.5.tgz", + "integrity": "sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w==", + "license": "MIT", + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=14.18.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/vite-node/node_modules/vite": { + "version": "4.5.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.5.tgz", + "integrity": "sha512-ifW3Lb2sMdX+WU91s3R0FyQlAyLxOzCSCP37ujw0+r5POeHPwe6udWVIElKQq8gk3t7b8rkmvqC6IHBpCff4GQ==", + "license": "MIT", + "dependencies": { + "esbuild": "^0.18.10", + "postcss": "^8.4.27", + "rollup": "^3.27.1" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@types/node": ">= 14", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vitest": { + "version": "0.28.5", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.28.5.tgz", + "integrity": "sha512-pyCQ+wcAOX7mKMcBNkzDwEHRGqQvHUl0XnoHR+3Pb1hytAHISgSxv9h0gUiSiYtISXUU3rMrKiKzFYDrI6ZIHA==", + "license": "MIT", + "dependencies": { + "@types/chai": "^4.3.4", + "@types/chai-subset": "^1.3.3", + "@types/node": "*", + "@vitest/expect": "0.28.5", + "@vitest/runner": "0.28.5", + "@vitest/spy": "0.28.5", + "@vitest/utils": "0.28.5", + "acorn": "^8.8.1", + "acorn-walk": "^8.2.0", + "cac": "^6.7.14", + "chai": "^4.3.7", + "debug": "^4.3.4", + "local-pkg": "^0.4.2", + "pathe": "^1.1.0", + "picocolors": "^1.0.0", + "source-map": "^0.6.1", + "std-env": "^3.3.1", + "strip-literal": "^1.0.0", + "tinybench": "^2.3.1", + "tinypool": "^0.3.1", + "tinyspy": "^1.0.2", + "vite": "^3.0.0 || ^4.0.0", + "vite-node": "0.28.5", + "why-is-node-running": "^2.2.2" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": ">=v14.16.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@vitest/browser": "*", + "@vitest/ui": "*", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/@esbuild/android-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/android-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/android-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/darwin-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/darwin-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/freebsd-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/freebsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-loong64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-mips64el": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-ppc64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-riscv64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-s390x": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/netbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/openbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/sunos-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/win32-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/win32-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/win32-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/esbuild": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" + } + }, + "node_modules/vitest/node_modules/rollup": { + "version": "3.29.5", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.5.tgz", + "integrity": "sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w==", + "license": "MIT", + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=14.18.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/vitest/node_modules/vite": { + "version": "4.5.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.5.tgz", + "integrity": "sha512-ifW3Lb2sMdX+WU91s3R0FyQlAyLxOzCSCP37ujw0+r5POeHPwe6udWVIElKQq8gk3t7b8rkmvqC6IHBpCff4GQ==", + "license": "MIT", + "dependencies": { + "esbuild": "^0.18.10", + "postcss": "^8.4.27", + "rollup": "^3.27.1" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@types/node": ">= 14", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vscode-jsonrpc": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz", + "integrity": "sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0 || >=10.0.0" + } + }, + "node_modules/vscode-languageclient": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-7.0.0.tgz", + "integrity": "sha512-P9AXdAPlsCgslpP9pRxYPqkNYV7Xq8300/aZDpO35j1fJm/ncize8iGswzYlcvFw5DQUx4eVk+KvfXdL0rehNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimatch": "^3.0.4", + "semver": "^7.3.4", + "vscode-languageserver-protocol": "3.16.0" + }, + "engines": { + "vscode": "^1.52.0" + } + }, + "node_modules/vscode-languageclient/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/vscode-languageserver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-7.0.0.tgz", + "integrity": "sha512-60HTx5ID+fLRcgdHfmz0LDZAXYEV68fzwG0JWwEPBode9NuMYTIxuYXPg4ngO8i8+Ou0lM7y6GzaYWbiDL0drw==", + "dev": true, + "license": "MIT", + "dependencies": { + "vscode-languageserver-protocol": "3.16.0" + }, + "bin": { + "installServerIntoExtension": "bin/installServerIntoExtension" + } + }, + "node_modules/vscode-languageserver-protocol": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0.tgz", + "integrity": "sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A==", + "dev": true, + "license": "MIT", + "dependencies": { + "vscode-jsonrpc": "6.0.0", + "vscode-languageserver-types": "3.16.0" + } + }, + "node_modules/vscode-languageserver-textdocument": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz", + "integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==", + "dev": true, + "license": "MIT" + }, + "node_modules/vscode-languageserver-types": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz", + "integrity": "sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA==", + "dev": true, + "license": "MIT" + }, + "node_modules/vscode-uri": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz", + "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/winston": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.16.0.tgz", + "integrity": "sha512-xz7+cyGN5M+4CmmD4Npq1/4T+UZaz7HaeTlAruFUTjk79CNMq+P6H30vlE4z0qfqJ01VHYQwd7OZo03nYm/+lg==", + "license": "MIT", + "dependencies": { + "@colors/colors": "^1.6.0", + "@dabh/diagnostics": "^2.0.2", + "async": "^3.2.3", + "is-stream": "^2.0.0", + "logform": "^2.6.0", + "one-time": "^1.0.0", + "readable-stream": "^3.4.0", + "safe-stable-stringify": "^2.3.1", + "stack-trace": "0.0.x", + "triple-beam": "^1.3.0", + "winston-transport": "^4.7.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/winston-transport": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.8.0.tgz", + "integrity": "sha512-qxSTKswC6llEMZKgCQdaWgDuMJQnhuvF5f2Nk3SNXc4byfQ+voo2mX1Px9dkNOuR8p0KAjfPG29PuYUSIb+vSA==", + "license": "MIT", + "dependencies": { + "logform": "^2.6.1", + "readable-stream": "^4.5.2", + "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/winston-transport/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/winston-transport/node_modules/readable-stream": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", + "license": "MIT", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zip-stream": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.1.tgz", + "integrity": "sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "archiver-utils": "^3.0.4", + "compress-commons": "^4.1.2", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/zip-stream/node_modules/archiver-utils": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-3.0.4.tgz", + "integrity": "sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob": "^7.2.3", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, + "tests": { + "version": "0.1.0", + "dependencies": { + "@holochain/client": "^0.19.0-dev.0", + "@holochain/tryorama": "^0.18.0-dev.0", + "@msgpack/msgpack": "^2.8.0", + "typescript": "^4.9.4", + "vitest": "^0.28.4" + } + }, + "tests/node_modules/@holochain/client": { + "version": "0.19.0-dev.1", + "resolved": "https://registry.npmjs.org/@holochain/client/-/client-0.19.0-dev.1.tgz", + "integrity": "sha512-yYx9liPF62pp8XxR3zRFzaK8YTzxRlyLl9dIWHBhgOIbrRmUywWSlyvCfyvceLY/LgP8vn9hesJ9E0BF3osBHQ==", + "license": "CAL-1.0", + "dependencies": { + "@bitgo/blake2b": "^3.2.4", + "@holochain/serialization": "^0.1.0-beta-rc.3", + "@msgpack/msgpack": "^2.8.0", + "emittery": "^1.0.1", + "isomorphic-ws": "^5.0.0", + "js-base64": "^3.7.5", + "libsodium-wrappers": "^0.7.13", + "lodash-es": "^4.17.21", + "ws": "^8.14.2" + }, + "engines": { + "node": ">=18.0.0 || >=20.0.0" + } + }, + "ui": { + "version": "0.1.0", + "dependencies": { + "@holochain-open-dev/utils": "0.400.0-dev.4", + "@holochain/client": "^0.18.0-rc.0", + "@lit/context": "^1.1.3", + "@lit/task": "^1.0.1", + "@msgpack/msgpack": "^2.8.0", + "lit": "^3.2.1" + }, + "devDependencies": { + "bestzip": "^2.2.1", + "prettier": "^2.8.8", + "rimraf": "^5.0.10", + "tslib": "^2.8.0", + "typescript": "^5.6.3", + "vite": "^5.4.10", + "vite-plugin-checker": "^0.5.6" + } + }, + "ui/node_modules/@holochain/client": { + "version": "0.18.0-rc.0", + "resolved": "https://registry.npmjs.org/@holochain/client/-/client-0.18.0-rc.0.tgz", + "integrity": "sha512-y9dfvrnUL4OeIhW+yHUnsjsBMoWvL1HnvUKGjfoBQDBsqJGpanmysV6ALScNErF5axPVZ30/m0nmQ9NgpFzUGg==", + "license": "CAL-1.0", + "dependencies": { + "@bitgo/blake2b": "^3.2.4", + "@holochain/serialization": "^0.1.0-beta-rc.3", + "@msgpack/msgpack": "^2.8.0", + "emittery": "^1.0.1", + "isomorphic-ws": "^5.0.0", + "js-base64": "^3.7.5", + "libsodium-wrappers": "^0.7.13", + "lodash-es": "^4.17.21", + "ws": "^8.14.2" + }, + "engines": { + "node": ">=18.0.0 || >=20.0.0" + } + }, + "ui/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "ui/node_modules/camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "ui/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "ui/node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "ui/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, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "ui/node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "ui/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true + }, + "ui/node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "ui/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "ui/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, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "ui/node_modules/meow": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", + "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize": "^1.2.0", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "ui/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, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "ui/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, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "ui/node_modules/quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "ui/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "ui/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "ui/node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "ui/node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "peer": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "ui/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "ui/node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "ui/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "bin": { + "semver": "bin/semver" + } + }, + "ui/node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "ui/node_modules/trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "ui/node_modules/type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "ui/node_modules/typescript": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "ui/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "ui/node_modules/vite-plugin-checker": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/vite-plugin-checker/-/vite-plugin-checker-0.5.6.tgz", + "integrity": "sha512-ftRyON0gORUHDxcDt2BErmsikKSkfvl1i2DoP6Jt2zDO9InfvM6tqO1RkXhSjkaXEhKPea6YOnhFaZxW3BzudQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "ansi-escapes": "^4.3.0", + "chalk": "^4.1.1", + "chokidar": "^3.5.1", + "commander": "^8.0.0", + "fast-glob": "^3.2.7", + "fs-extra": "^11.1.0", + "lodash.debounce": "^4.0.8", + "lodash.pick": "^4.4.0", + "npm-run-path": "^4.0.1", + "strip-ansi": "^6.0.0", + "tiny-invariant": "^1.1.0", + "vscode-languageclient": "^7.0.0", + "vscode-languageserver": "^7.0.0", + "vscode-languageserver-textdocument": "^1.0.1", + "vscode-uri": "^3.0.2" + }, + "engines": { + "node": ">=14.16" + }, + "peerDependencies": { + "eslint": ">=7", + "meow": "^9.0.0", + "optionator": "^0.9.1", + "stylelint": ">=13", + "typescript": "*", + "vite": ">=2.0.0", + "vls": "*", + "vti": "*", + "vue-tsc": "*" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + }, + "meow": { + "optional": true + }, + "optionator": { + "optional": true + }, + "stylelint": { + "optional": true + }, + "typescript": { + "optional": true + }, + "vls": { + "optional": true + }, + "vti": { + "optional": true + }, + "vue-tsc": { + "optional": true + } + } + } + } +} diff --git a/ui/package.json b/ui/package.json index 87cc843..c4d8d19 100644 --- a/ui/package.json +++ b/ui/package.json @@ -9,6 +9,7 @@ }, "dependencies": { "@holochain/client": "^0.18.0-rc.0", + "@holochain-open-dev/utils": "0.400.0-dev.4", "@lit/context": "^1.1.3", "@lit/task": "^1.0.1", "@msgpack/msgpack": "^2.8.0", diff --git a/ui/src/genericDnaClient.ts b/ui/src/genericDnaClient.ts new file mode 100644 index 0000000..e69de29 From 5b55b9adfc45ee5fd0742a398432f9274d38332f Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 2 Nov 2024 18:13:44 +0100 Subject: [PATCH 09/12] added logic to check tag equality when deleting link --- .../zomes/coordinator/generic_zome/src/api.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dnas/generic_dna/zomes/coordinator/generic_zome/src/api.rs b/dnas/generic_dna/zomes/coordinator/generic_zome/src/api.rs index 7bfcec7..dcd81d8 100644 --- a/dnas/generic_dna/zomes/coordinator/generic_zome/src/api.rs +++ b/dnas/generic_dna/zomes/coordinator/generic_zome/src/api.rs @@ -465,8 +465,8 @@ pub fn delete_links_from_node(input: CreateOrDeleteLinkInput) -> ExternResult<() )?; for link in links_to_anchors { let target = linkable_hash_from_node_id(link_input.node_id.clone())?; - if target == link.target { - let link_tag_content = deserialize_link_tag(link.tag.0)?; + let link_tag_content = deserialize_link_tag(link.tag.0)?; + if target == link.target && link_input.tag == link_tag_content.tag { if let Some(backlink_action_hash) = link_tag_content.backlink_action_hash { delete_link(backlink_action_hash)?; } @@ -483,8 +483,8 @@ pub fn delete_links_from_node(input: CreateOrDeleteLinkInput) -> ExternResult<() )?; for link in links_to_agents { let target = linkable_hash_from_node_id(link_input.node_id.clone())?; - if target == link.target { - let link_tag_content = deserialize_link_tag(link.tag.0)?; + let link_tag_content = deserialize_link_tag(link.tag.0)?; + if target == link.target && link_input.tag == link_tag_content.tag { if let Some(backlink_action_hash) = link_tag_content.backlink_action_hash { delete_link(backlink_action_hash)?; } @@ -501,8 +501,8 @@ pub fn delete_links_from_node(input: CreateOrDeleteLinkInput) -> ExternResult<() )?; for link in links_to_things { let target = linkable_hash_from_node_id(link_input.node_id.clone())?; - if target == link.target { - let link_tag_content = deserialize_link_tag(link.tag.0)?; + let link_tag_content = deserialize_link_tag(link.tag.0)?; + if target == link.target && link_input.tag == link_tag_content.tag { if let Some(backlink_action_hash) = link_tag_content.backlink_action_hash { delete_link(backlink_action_hash)?; } From 15b7b8dbb6e9f1ccfed3aa1a57a27c5a75c3048c Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 2 Nov 2024 20:02:21 +0100 Subject: [PATCH 10/12] fixed logic in get_linked_things to get latest versions of Things, fixed type naming, added serde enum content variables --- .../zomes/coordinator/generic_zome/src/api.rs | 36 ++++++++----------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/dnas/generic_dna/zomes/coordinator/generic_zome/src/api.rs b/dnas/generic_dna/zomes/coordinator/generic_zome/src/api.rs index dcd81d8..56b226f 100644 --- a/dnas/generic_dna/zomes/coordinator/generic_zome/src/api.rs +++ b/dnas/generic_dna/zomes/coordinator/generic_zome/src/api.rs @@ -10,7 +10,7 @@ pub enum LinkDirection { } #[derive(Serialize, Deserialize, Clone, Debug)] -#[serde(tag = "type")] +#[serde(tag = "type", content = "id")] pub enum NodeId { Agent(AgentPubKey), Anchor(String), @@ -18,7 +18,7 @@ pub enum NodeId { } #[derive(Serialize, Deserialize, Clone, Debug)] -#[serde(tag = "type")] +#[serde(tag = "type", content = "content")] pub enum Node { Agent(AgentPubKey), Anchor(String), @@ -382,23 +382,15 @@ pub fn get_linked_anchors(node_id: NodeId) -> ExternResult> { pub fn get_linked_things(node_id: NodeId) -> ExternResult> { let base = linkable_hash_from_node_id(node_id)?; let links = get_links(GetLinksInputBuilder::try_new(base, LinkTypes::ToThing)?.build())?; - let get_input: Vec = links - .into_iter() - .map(|link| { - Ok(GetInput::new( - link.target - .into_action_hash() - .ok_or(wasm_error!(WasmErrorInner::Guest( - "No action hash associated with link".to_string() - )))? - .into(), - GetOptions::default(), - )) - }) - .collect::>>()?; - - let records = HDK.with(|hdk| hdk.borrow().get(get_input))?; - Ok(records + let mut latest_maybe_things: Vec> = Vec::new(); + for link in links { + let maybe_thing_id = link.target.into_action_hash(); + if let Some(thing_id) = maybe_thing_id { + let latest_thing = get_latest_thing(thing_id)?; + latest_maybe_things.push(latest_thing); + } + } + Ok(latest_maybe_things .into_iter() .filter_map(|r| r) .map(|r| thing_record_to_thing(r).ok()) @@ -407,13 +399,13 @@ pub fn get_linked_things(node_id: NodeId) -> ExternResult> { } #[derive(Serialize, Deserialize, Clone, Debug)] -pub struct CreateOrDeleteLinkInput { +pub struct CreateOrDeleteLinksInput { pub src: NodeId, pub links: Vec, } #[hdk_extern] -pub fn create_links_from_node(input: CreateOrDeleteLinkInput) -> ExternResult<()> { +pub fn create_links_from_node(input: CreateOrDeleteLinksInput) -> ExternResult<()> { let base: HoloHash = linkable_hash_from_node_id(input.src)?; for link in input.links { create_link_from_node_by_hash(base.clone(), link)?; @@ -422,7 +414,7 @@ pub fn create_links_from_node(input: CreateOrDeleteLinkInput) -> ExternResult<() } #[hdk_extern] -pub fn delete_links_from_node(input: CreateOrDeleteLinkInput) -> ExternResult<()> { +pub fn delete_links_from_node(input: CreateOrDeleteLinksInput) -> ExternResult<()> { let base = linkable_hash_from_node_id(input.src)?; let anchor_link_inputs = input From fcb54e1c632675a689041d9f01697d01e5ef3f77 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 2 Nov 2024 20:07:34 +0100 Subject: [PATCH 11/12] added SimpleHolochain class --- ui/src/genericDnaClient.ts | 0 ui/src/simpleHolochain.ts | 231 +++++++++++++++++++++++++++++++++++++ ui/src/types.ts | 150 ++++++++++++++++++++++++ 3 files changed, 381 insertions(+) delete mode 100644 ui/src/genericDnaClient.ts create mode 100644 ui/src/simpleHolochain.ts create mode 100644 ui/src/types.ts diff --git a/ui/src/genericDnaClient.ts b/ui/src/genericDnaClient.ts deleted file mode 100644 index e69de29..0000000 diff --git a/ui/src/simpleHolochain.ts b/ui/src/simpleHolochain.ts new file mode 100644 index 0000000..7fe12ba --- /dev/null +++ b/ui/src/simpleHolochain.ts @@ -0,0 +1,231 @@ +import { ZomeClient } from '@holochain-open-dev/utils'; +import { + AgentPubKey, + AppCallZomeRequest, + AppClient, + AppWebsocket, + AppWebsocketConnectionOptions, +} from '@holochain/client'; +import { + CreateOrDeleteLinksInput, + CreateThingInput, + DeleteThingInput, + GenericZomeSignal, + LinkDirection, + LinkDirectionRust, + LinkInput, + LinkInputRust, + NodeContent, + NodeId, + Thing, + ThingId, + UpdateThingInput, +} from './types'; + +export class SimpleHolochain { + private client: AppClient; + private zomeClient: ZomeClient; + private roleName: string; + private zomeName: string; + + private constructor( + client: AppClient, + zomeClient: ZomeClient, + roleName: string = 'generic_dna', + zomeName: string = 'generic_zome' + ) { + this.client = client; + this.zomeClient = zomeClient; + this.roleName = roleName; + this.zomeName = zomeName; + // TODO set up signal listener. Potentially emit signal to conductor + } + + static async connect(options: AppWebsocketConnectionOptions = {}) { + const client = await AppWebsocket.connect(options); + const zomeClient = new ZomeClient( + client, + 'generic_dna', + 'generic_zome' + ); + return new SimpleHolochain(client, zomeClient); + } + + /** + * Creates a "Thing", i.e. an arbitrary piece of content in the DHT. You are responsible + * yourself for making sure that the content adheres to the format you want + * it to adhere. + * + * @param content + * @param links + * @returns + */ + async createThing(content: string, links?: LinkInput[]): Promise { + let input: CreateThingInput = { + content, + links: links ? links.map(link => linkInputToRustFormat(link)) : undefined, + }; + return this.callZome('create_thing', input); + } + + /** + * Update the content of a thing without changing any of + * the links that point to or from it. + * + * @param thingId + * @param updatedContent + * @returns + */ + async updateThing(thingId: ThingId, updatedContent: string): Promise { + let input: UpdateThingInput = { + thing_id: thingId, + updated_content: updatedContent, + }; + return this.callZome('udpate_thing', input); + } + + /** + * Deletes a Thing as well as optionally any backlinks of + * 'bidirectional' links that were created with this Thing + * as the source. A Thing is unaware of 'from' links + * pointing to it from elsewhere (including bidirectional links * that were created from another node as the src). + * Such links (or any other links) need to be explicitly deleted * by passing them with the 'links' argument or using the + * `deleteLink` function. + * + * @param thingId + * @param deleteBacklinks + * @param deleteLinksFromCreator + * @param deleteLinks + * @returns + */ + async deleteThing( + thingId: ThingId, + deleteBacklinks: boolean, + deleteLinksFromCreator: boolean, + deleteLinks?: LinkInput[] + ): Promise { + let input: DeleteThingInput = { + thing_id: thingId, + delete_backlinks: deleteBacklinks, + delete_links_from_creator: deleteLinksFromCreator, + delete_links: deleteLinks + ? deleteLinks.map(link => linkInputToRustFormat(link)) + : undefined, + }; + return this.callZome('delete_thing', input); + } + + /** + * Gets the latest known version of a thing (it's possible that other peers + * have updated it but they are now offline and we don't know about it) + * + * @param thingId + * @returns + */ + async getThing(thingId: ThingId): Promise { + return this.callZome('get_thing', thingId); + } + + /** + * Get all the nodes that are linked from the specified source node + * + * @param src + * @returns + */ + async getAllLinkedNodes(src: NodeId): Promise { + return this.callZome('get_all_linked_nodes', src); + } + + /** + * Get all the agents that are linked from the specified source node + * + * @param src + * @returns + */ + async getLinkedAgents(src: NodeId): Promise { + return this.callZome('get_linked_agents', src); + } + + /** + * Get all the anchors that are linked from the specified source node + * + * @param src + * @returns + */ + async getLinkedAnchors(src: NodeId): Promise { + return this.callZome('get_linked_anchors', src); + } + + /** + * Get the latest versions of all Things that are linked from the + * specified source node + * + * @param src + * @returns + */ + async getLinkedThings(src: NodeId): Promise { + return this.callZome('get_linked_things', src); + } + + /** + * Creates links from a specified source node + * + * @param src + * @param links + * @returns + */ + async createLinks(src: NodeId, links: LinkInput[]): Promise { + const input: CreateOrDeleteLinksInput = { + src, + links: links.map(link => linkInputToRustFormat(link)), + }; + return this.callZome('create_links_from_node', input); + } + + /** + * Will delete the specified links. + * If a tag is provided in the LinkInput, only links + * with this same tag will be deleted. Otherwise only + * links without tag will be deleted. + * + * @param src + * @param links + * @returns + */ + async deleteLinks(src: NodeId, links: LinkInput[]): Promise { + const input: CreateOrDeleteLinksInput = { + src, + links: links.map(link => linkInputToRustFormat(link)), + }; + return this.callZome('delete_links_from_node', input); + } + + private callZome(fn_name: string, payload: any) { + const req: AppCallZomeRequest = { + role_name: this.roleName, + zome_name: this.zomeName, + fn_name, + payload, + }; + return this.client.callZome(req); + } +} + +function linkInputToRustFormat(linkInput: LinkInput): LinkInputRust { + let linkDirection: LinkDirectionRust; + switch (linkInput.direction) { + case LinkDirection.From: + linkDirection = { + type: 'From', + }; + case LinkDirection.To: + linkDirection = { type: 'To' }; + case LinkDirection.Bidirectional: + linkDirection = { type: 'Bidirectional' }; + } + return { + direction: linkDirection, + nodeId: linkInput.nodeId, + tag: linkInput.tag, + }; +} diff --git a/ui/src/types.ts b/ui/src/types.ts new file mode 100644 index 0000000..cc9fcf1 --- /dev/null +++ b/ui/src/types.ts @@ -0,0 +1,150 @@ +import { + ActionHash, + ActionHashB64, + AgentPubKey, + AgentPubKeyB64, + Create, + CreateLink, + Delete, + DeleteLink, + SignedActionHashed, + Update, +} from '@holochain/client'; + +export type GenericZomeSignal = + | { + type: 'EntryCreated'; + action: SignedActionHashed; + app_entry: EntryTypes; + } + | { + type: 'EntryUpdated'; + action: SignedActionHashed; + app_entry: EntryTypes; + original_app_entry: EntryTypes; + } + | { + type: 'EntryDeleted'; + action: SignedActionHashed; + original_app_entry: EntryTypes; + } + | { + type: 'LinkCreated'; + action: SignedActionHashed; + link_type: string; + } + | { + type: 'LinkDeleted'; + action: SignedActionHashed; + link_type: string; + }; + +/* dprint-ignore-start */ +export type EntryTypes = { type: 'Thing' } & ThingEntry; +/* dprint-ignore-end */ + +export interface ThingEntry { + content: string; +} + +/** + * A node in the graph can be of three distinct types, identified in different ways + */ +export type NodeId = + | { + type: 'anchor'; + id: string; + } + | { + type: 'thing'; + id: ThingId; // "id" --> original action hash + } + | { + type: 'agent'; + id: AgentPubKey; + }; + +export type NodeContent = + | { + type: 'anchor'; + content: string; + } + | { + type: 'thing'; + content: Thing; + } + | { + type: 'agent'; + content: AgentPubKey; + }; + +/** + * An anchor is a known location identified by a string to + * or from which things can be linked + */ +export type Anchor = string; + +/** + * A thing is a piece of arbitrary content identified by a + * ThingHash + */ +export type Thing = { + id: ThingId; + content: string; + creator: AgentPubKey; + created_at: number; + updated_at: number; +}; + +export type ThingId = ActionHash; + +export enum LinkDirection { + From, + To, + Bidirectional, +} + +export type LinkInput = { + direction: LinkDirection; + nodeId: NodeId; + tag?: Uint8Array; +}; + +export type LinkDirectionRust = + | { + type: 'From'; + } + | { + type: 'To'; + } + | { + type: 'Bidirectional'; + }; + +export type LinkInputRust = { + direction: LinkDirectionRust; + nodeId: NodeId; + tag?: Uint8Array; +}; + +export type CreateThingInput = { + content: string; + links?: LinkInputRust[]; +}; + +export type UpdateThingInput = { + thing_id: ActionHash; + updated_content: string; +}; + +export type DeleteThingInput = { + thing_id: ActionHash, + delete_backlinks: boolean, + delete_links_from_creator: boolean, + delete_links?: LinkInputRust[], +} + +export type CreateOrDeleteLinksInput = { + src: NodeId, + links: LinkInputRust[], +}; \ No newline at end of file From 58930b2f79e896534a22374b0dc4fd94c004df95 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 2 Nov 2024 22:39:33 +0100 Subject: [PATCH 12/12] added SimpleHolochain js class --- lib/dist/index.d.ts | 102 ++++++++++ lib/dist/index.js | 180 ++++++++++++++++++ lib/dist/index.js.map | 1 + lib/dist/types.d.ts | 109 +++++++++++ lib/dist/types.js | 7 + lib/dist/types.js.map | 1 + lib/package.json | 30 +++ ui/src/simpleHolochain.ts => lib/src/index.ts | 2 + {ui => lib}/src/types.ts | 2 - lib/tsconfig.json | 23 +++ package-lock.json | 65 +++++++ package.json | 4 +- ui/package.json | 1 + ui/src/contexts.ts | 4 +- ui/src/elements/create-thing.ts | 73 +++++++ .../generic_zome => elements}/edit-thing.ts | 47 ++--- ui/src/elements/thing-detail.ts | 111 +++++++++++ .../generic_dna/generic_zome/create-thing.ts | 89 --------- .../generic_dna/generic_zome/thing-detail.ts | 112 ----------- ui/src/generic_dna/generic_zome/types.ts | 46 ----- ui/src/holochain-app.ts | 9 +- 21 files changed, 726 insertions(+), 292 deletions(-) create mode 100644 lib/dist/index.d.ts create mode 100644 lib/dist/index.js create mode 100644 lib/dist/index.js.map create mode 100644 lib/dist/types.d.ts create mode 100644 lib/dist/types.js create mode 100644 lib/dist/types.js.map create mode 100644 lib/package.json rename ui/src/simpleHolochain.ts => lib/src/index.ts (99%) rename {ui => lib}/src/types.ts (98%) create mode 100644 lib/tsconfig.json create mode 100644 ui/src/elements/create-thing.ts rename ui/src/{generic_dna/generic_zome => elements}/edit-thing.ts (58%) create mode 100644 ui/src/elements/thing-detail.ts delete mode 100644 ui/src/generic_dna/generic_zome/create-thing.ts delete mode 100644 ui/src/generic_dna/generic_zome/thing-detail.ts delete mode 100644 ui/src/generic_dna/generic_zome/types.ts diff --git a/lib/dist/index.d.ts b/lib/dist/index.d.ts new file mode 100644 index 0000000..e40d521 --- /dev/null +++ b/lib/dist/index.d.ts @@ -0,0 +1,102 @@ +import { AgentPubKey, AppWebsocketConnectionOptions } from '@holochain/client'; +import { LinkInput, NodeContent, NodeId, Thing, ThingId } from './types'; +export * from './types'; +export declare class SimpleHolochain { + private client; + private zomeClient; + private roleName; + private zomeName; + private constructor(); + static connect(options?: AppWebsocketConnectionOptions): Promise; + /** + * Creates a "Thing", i.e. an arbitrary piece of content in the DHT. You are responsible + * yourself for making sure that the content adheres to the format you want + * it to adhere. + * + * @param content + * @param links + * @returns + */ + createThing(content: string, links?: LinkInput[]): Promise; + /** + * Update the content of a thing without changing any of + * the links that point to or from it. + * + * @param thingId + * @param updatedContent + * @returns + */ + updateThing(thingId: ThingId, updatedContent: string): Promise; + /** + * Deletes a Thing as well as optionally any backlinks of + * 'bidirectional' links that were created with this Thing + * as the source. A Thing is unaware of 'from' links + * pointing to it from elsewhere (including bidirectional links * that were created from another node as the src). + * Such links (or any other links) need to be explicitly deleted * by passing them with the 'links' argument or using the + * `deleteLink` function. + * + * @param thingId + * @param deleteBacklinks + * @param deleteLinksFromCreator + * @param deleteLinks + * @returns + */ + deleteThing(thingId: ThingId, deleteBacklinks: boolean, deleteLinksFromCreator: boolean, deleteLinks?: LinkInput[]): Promise; + /** + * Gets the latest known version of a thing (it's possible that other peers + * have updated it but they are now offline and we don't know about it) + * + * @param thingId + * @returns + */ + getThing(thingId: ThingId): Promise; + /** + * Get all the nodes that are linked from the specified source node + * + * @param src + * @returns + */ + getAllLinkedNodes(src: NodeId): Promise; + /** + * Get all the agents that are linked from the specified source node + * + * @param src + * @returns + */ + getLinkedAgents(src: NodeId): Promise; + /** + * Get all the anchors that are linked from the specified source node + * + * @param src + * @returns + */ + getLinkedAnchors(src: NodeId): Promise; + /** + * Get the latest versions of all Things that are linked from the + * specified source node + * + * @param src + * @returns + */ + getLinkedThings(src: NodeId): Promise; + /** + * Creates links from a specified source node + * + * @param src + * @param links + * @returns + */ + createLinks(src: NodeId, links: LinkInput[]): Promise; + /** + * Will delete the specified links. + * If a tag is provided in the LinkInput, only links + * with this same tag will be deleted. Otherwise only + * links without tag will be deleted. + * + * @param src + * @param links + * @returns + */ + deleteLinks(src: NodeId, links: LinkInput[]): Promise; + private callZome; +} diff --git a/lib/dist/index.js b/lib/dist/index.js new file mode 100644 index 0000000..470b959 --- /dev/null +++ b/lib/dist/index.js @@ -0,0 +1,180 @@ +import { ZomeClient } from '@holochain-open-dev/utils'; +import { AppWebsocket, } from '@holochain/client'; +import { LinkDirection, } from './types'; +export * from './types'; +export class SimpleHolochain { + constructor(client, zomeClient, roleName = 'generic_dna', zomeName = 'generic_zome') { + this.client = client; + this.zomeClient = zomeClient; + this.roleName = roleName; + this.zomeName = zomeName; + // TODO set up signal listener. Potentially emit signal to conductor + } + static async connect(options = {}) { + const client = await AppWebsocket.connect(options); + const zomeClient = new ZomeClient(client, 'generic_dna', 'generic_zome'); + return new SimpleHolochain(client, zomeClient); + } + /** + * Creates a "Thing", i.e. an arbitrary piece of content in the DHT. You are responsible + * yourself for making sure that the content adheres to the format you want + * it to adhere. + * + * @param content + * @param links + * @returns + */ + async createThing(content, links) { + let input = { + content, + links: links ? links.map(link => linkInputToRustFormat(link)) : undefined, + }; + return this.callZome('create_thing', input); + } + /** + * Update the content of a thing without changing any of + * the links that point to or from it. + * + * @param thingId + * @param updatedContent + * @returns + */ + async updateThing(thingId, updatedContent) { + let input = { + thing_id: thingId, + updated_content: updatedContent, + }; + return this.callZome('udpate_thing', input); + } + /** + * Deletes a Thing as well as optionally any backlinks of + * 'bidirectional' links that were created with this Thing + * as the source. A Thing is unaware of 'from' links + * pointing to it from elsewhere (including bidirectional links * that were created from another node as the src). + * Such links (or any other links) need to be explicitly deleted * by passing them with the 'links' argument or using the + * `deleteLink` function. + * + * @param thingId + * @param deleteBacklinks + * @param deleteLinksFromCreator + * @param deleteLinks + * @returns + */ + async deleteThing(thingId, deleteBacklinks, deleteLinksFromCreator, deleteLinks) { + let input = { + thing_id: thingId, + delete_backlinks: deleteBacklinks, + delete_links_from_creator: deleteLinksFromCreator, + delete_links: deleteLinks + ? deleteLinks.map(link => linkInputToRustFormat(link)) + : undefined, + }; + return this.callZome('delete_thing', input); + } + /** + * Gets the latest known version of a thing (it's possible that other peers + * have updated it but they are now offline and we don't know about it) + * + * @param thingId + * @returns + */ + async getThing(thingId) { + return this.callZome('get_thing', thingId); + } + /** + * Get all the nodes that are linked from the specified source node + * + * @param src + * @returns + */ + async getAllLinkedNodes(src) { + return this.callZome('get_all_linked_nodes', src); + } + /** + * Get all the agents that are linked from the specified source node + * + * @param src + * @returns + */ + async getLinkedAgents(src) { + return this.callZome('get_linked_agents', src); + } + /** + * Get all the anchors that are linked from the specified source node + * + * @param src + * @returns + */ + async getLinkedAnchors(src) { + return this.callZome('get_linked_anchors', src); + } + /** + * Get the latest versions of all Things that are linked from the + * specified source node + * + * @param src + * @returns + */ + async getLinkedThings(src) { + return this.callZome('get_linked_things', src); + } + /** + * Creates links from a specified source node + * + * @param src + * @param links + * @returns + */ + async createLinks(src, links) { + const input = { + src, + links: links.map(link => linkInputToRustFormat(link)), + }; + return this.callZome('create_links_from_node', input); + } + /** + * Will delete the specified links. + * If a tag is provided in the LinkInput, only links + * with this same tag will be deleted. Otherwise only + * links without tag will be deleted. + * + * @param src + * @param links + * @returns + */ + async deleteLinks(src, links) { + const input = { + src, + links: links.map(link => linkInputToRustFormat(link)), + }; + return this.callZome('delete_links_from_node', input); + } + callZome(fn_name, payload) { + const req = { + role_name: this.roleName, + zome_name: this.zomeName, + fn_name, + payload, + }; + return this.client.callZome(req); + } +} +function linkInputToRustFormat(linkInput) { + let linkDirection; + switch (linkInput.direction) { + case LinkDirection.From: + linkDirection = { + type: 'From', + }; + case LinkDirection.To: + linkDirection = { type: 'To' }; + case LinkDirection.Bidirectional: + linkDirection = { type: 'Bidirectional' }; + } + return { + direction: linkDirection, + nodeId: linkInput.nodeId, + tag: linkInput.tag, + }; +} +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/lib/dist/index.js.map b/lib/dist/index.js.map new file mode 100644 index 0000000..30e1b88 --- /dev/null +++ b/lib/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAIL,YAAY,GAEb,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAKL,aAAa,GASd,MAAM,SAAS,CAAC;AAEjB,cAAc,SAAS,CAAC;AAExB,MAAM,OAAO,eAAe;IAM1B,YACE,MAAiB,EACjB,UAAyC,EACzC,WAAmB,aAAa,EAChC,WAAmB,cAAc;QAEjC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,oEAAoE;IACtE,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,UAAyC,EAAE;QAC9D,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACnD,MAAM,UAAU,GAAG,IAAI,UAAU,CAC/B,MAAM,EACN,aAAa,EACb,cAAc,CACf,CAAC;QACF,OAAO,IAAI,eAAe,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACjD,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,WAAW,CAAC,OAAe,EAAE,KAAmB;QACpD,IAAI,KAAK,GAAqB;YAC5B,OAAO;YACP,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS;SAC1E,CAAC;QACF,OAAO,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IAC9C,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,WAAW,CAAC,OAAgB,EAAE,cAAsB;QACxD,IAAI,KAAK,GAAqB;YAC5B,QAAQ,EAAE,OAAO;YACjB,eAAe,EAAE,cAAc;SAChC,CAAC;QACF,OAAO,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IAC9C,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,KAAK,CAAC,WAAW,CACf,OAAgB,EAChB,eAAwB,EACxB,sBAA+B,EAC/B,WAAyB;QAEzB,IAAI,KAAK,GAAqB;YAC5B,QAAQ,EAAE,OAAO;YACjB,gBAAgB,EAAE,eAAe;YACjC,yBAAyB,EAAE,sBAAsB;YACjD,YAAY,EAAE,WAAW;gBACvB,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC;gBACtD,CAAC,CAAC,SAAS;SACd,CAAC;QACF,OAAO,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IAC9C,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,QAAQ,CAAC,OAAgB;QAC7B,OAAO,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC7C,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,iBAAiB,CAAC,GAAW;QACjC,OAAO,IAAI,CAAC,QAAQ,CAAC,sBAAsB,EAAE,GAAG,CAAC,CAAC;IACpD,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,eAAe,CAAC,GAAW;QAC/B,OAAO,IAAI,CAAC,QAAQ,CAAC,mBAAmB,EAAE,GAAG,CAAC,CAAC;IACjD,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,gBAAgB,CAAC,GAAW;QAChC,OAAO,IAAI,CAAC,QAAQ,CAAC,oBAAoB,EAAE,GAAG,CAAC,CAAC;IAClD,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,eAAe,CAAC,GAAW;QAC/B,OAAO,IAAI,CAAC,QAAQ,CAAC,mBAAmB,EAAE,GAAG,CAAC,CAAC;IACjD,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,WAAW,CAAC,GAAW,EAAE,KAAkB;QAC/C,MAAM,KAAK,GAA6B;YACtC,GAAG;YACH,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC;SACtD,CAAC;QACF,OAAO,IAAI,CAAC,QAAQ,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;IACxD,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,WAAW,CAAC,GAAW,EAAE,KAAkB;QAC/C,MAAM,KAAK,GAA6B;YACtC,GAAG;YACH,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC;SACtD,CAAC;QACF,OAAO,IAAI,CAAC,QAAQ,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;IACxD,CAAC;IAEO,QAAQ,CAAC,OAAe,EAAE,OAAY;QAC5C,MAAM,GAAG,GAAuB;YAC9B,SAAS,EAAE,IAAI,CAAC,QAAQ;YACxB,SAAS,EAAE,IAAI,CAAC,QAAQ;YACxB,OAAO;YACP,OAAO;SACR,CAAC;QACF,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IACnC,CAAC;CACF;AAED,SAAS,qBAAqB,CAAC,SAAoB;IACjD,IAAI,aAAgC,CAAC;IACrC,QAAQ,SAAS,CAAC,SAAS,EAAE,CAAC;QAC5B,KAAK,aAAa,CAAC,IAAI;YACrB,aAAa,GAAG;gBACd,IAAI,EAAE,MAAM;aACb,CAAC;QACJ,KAAK,aAAa,CAAC,EAAE;YACnB,aAAa,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QACjC,KAAK,aAAa,CAAC,aAAa;YAC9B,aAAa,GAAG,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC;IAC9C,CAAC;IACD,OAAO;QACL,SAAS,EAAE,aAAa;QACxB,MAAM,EAAE,SAAS,CAAC,MAAM;QACxB,GAAG,EAAE,SAAS,CAAC,GAAG;KACnB,CAAC;AACJ,CAAC","sourcesContent":["import { ZomeClient } from '@holochain-open-dev/utils';\nimport {\n AgentPubKey,\n AppCallZomeRequest,\n AppClient,\n AppWebsocket,\n AppWebsocketConnectionOptions,\n} from '@holochain/client';\nimport {\n CreateOrDeleteLinksInput,\n CreateThingInput,\n DeleteThingInput,\n GenericZomeSignal,\n LinkDirection,\n LinkDirectionRust,\n LinkInput,\n LinkInputRust,\n NodeContent,\n NodeId,\n Thing,\n ThingId,\n UpdateThingInput,\n} from './types';\n\nexport * from './types';\n\nexport class SimpleHolochain {\n private client: AppClient;\n private zomeClient: ZomeClient;\n private roleName: string;\n private zomeName: string;\n\n private constructor(\n client: AppClient,\n zomeClient: ZomeClient,\n roleName: string = 'generic_dna',\n zomeName: string = 'generic_zome'\n ) {\n this.client = client;\n this.zomeClient = zomeClient;\n this.roleName = roleName;\n this.zomeName = zomeName;\n // TODO set up signal listener. Potentially emit signal to conductor\n }\n\n static async connect(options: AppWebsocketConnectionOptions = {}) {\n const client = await AppWebsocket.connect(options);\n const zomeClient = new ZomeClient(\n client,\n 'generic_dna',\n 'generic_zome'\n );\n return new SimpleHolochain(client, zomeClient);\n }\n\n /**\n * Creates a \"Thing\", i.e. an arbitrary piece of content in the DHT. You are responsible\n * yourself for making sure that the content adheres to the format you want\n * it to adhere.\n *\n * @param content\n * @param links\n * @returns\n */\n async createThing(content: string, links?: LinkInput[]): Promise {\n let input: CreateThingInput = {\n content,\n links: links ? links.map(link => linkInputToRustFormat(link)) : undefined,\n };\n return this.callZome('create_thing', input);\n }\n\n /**\n * Update the content of a thing without changing any of\n * the links that point to or from it.\n *\n * @param thingId\n * @param updatedContent\n * @returns\n */\n async updateThing(thingId: ThingId, updatedContent: string): Promise {\n let input: UpdateThingInput = {\n thing_id: thingId,\n updated_content: updatedContent,\n };\n return this.callZome('udpate_thing', input);\n }\n\n /**\n * Deletes a Thing as well as optionally any backlinks of\n * 'bidirectional' links that were created with this Thing\n * as the source. A Thing is unaware of 'from' links\n * pointing to it from elsewhere (including bidirectional links * that were created from another node as the src).\n * Such links (or any other links) need to be explicitly deleted * by passing them with the 'links' argument or using the\n * `deleteLink` function.\n *\n * @param thingId\n * @param deleteBacklinks\n * @param deleteLinksFromCreator\n * @param deleteLinks\n * @returns\n */\n async deleteThing(\n thingId: ThingId,\n deleteBacklinks: boolean,\n deleteLinksFromCreator: boolean,\n deleteLinks?: LinkInput[]\n ): Promise {\n let input: DeleteThingInput = {\n thing_id: thingId,\n delete_backlinks: deleteBacklinks,\n delete_links_from_creator: deleteLinksFromCreator,\n delete_links: deleteLinks\n ? deleteLinks.map(link => linkInputToRustFormat(link))\n : undefined,\n };\n return this.callZome('delete_thing', input);\n }\n\n /**\n * Gets the latest known version of a thing (it's possible that other peers\n * have updated it but they are now offline and we don't know about it)\n *\n * @param thingId\n * @returns\n */\n async getThing(thingId: ThingId): Promise {\n return this.callZome('get_thing', thingId);\n }\n\n /**\n * Get all the nodes that are linked from the specified source node\n *\n * @param src\n * @returns\n */\n async getAllLinkedNodes(src: NodeId): Promise {\n return this.callZome('get_all_linked_nodes', src);\n }\n\n /**\n * Get all the agents that are linked from the specified source node\n *\n * @param src\n * @returns\n */\n async getLinkedAgents(src: NodeId): Promise {\n return this.callZome('get_linked_agents', src);\n }\n\n /**\n * Get all the anchors that are linked from the specified source node\n *\n * @param src\n * @returns\n */\n async getLinkedAnchors(src: NodeId): Promise {\n return this.callZome('get_linked_anchors', src);\n }\n\n /**\n * Get the latest versions of all Things that are linked from the\n * specified source node\n *\n * @param src\n * @returns\n */\n async getLinkedThings(src: NodeId): Promise {\n return this.callZome('get_linked_things', src);\n }\n\n /**\n * Creates links from a specified source node\n *\n * @param src\n * @param links\n * @returns\n */\n async createLinks(src: NodeId, links: LinkInput[]): Promise {\n const input: CreateOrDeleteLinksInput = {\n src,\n links: links.map(link => linkInputToRustFormat(link)),\n };\n return this.callZome('create_links_from_node', input);\n }\n\n /**\n * Will delete the specified links.\n * If a tag is provided in the LinkInput, only links\n * with this same tag will be deleted. Otherwise only\n * links without tag will be deleted.\n *\n * @param src\n * @param links\n * @returns\n */\n async deleteLinks(src: NodeId, links: LinkInput[]): Promise {\n const input: CreateOrDeleteLinksInput = {\n src,\n links: links.map(link => linkInputToRustFormat(link)),\n };\n return this.callZome('delete_links_from_node', input);\n }\n\n private callZome(fn_name: string, payload: any) {\n const req: AppCallZomeRequest = {\n role_name: this.roleName,\n zome_name: this.zomeName,\n fn_name,\n payload,\n };\n return this.client.callZome(req);\n }\n}\n\nfunction linkInputToRustFormat(linkInput: LinkInput): LinkInputRust {\n let linkDirection: LinkDirectionRust;\n switch (linkInput.direction) {\n case LinkDirection.From:\n linkDirection = {\n type: 'From',\n };\n case LinkDirection.To:\n linkDirection = { type: 'To' };\n case LinkDirection.Bidirectional:\n linkDirection = { type: 'Bidirectional' };\n }\n return {\n direction: linkDirection,\n nodeId: linkInput.nodeId,\n tag: linkInput.tag,\n };\n}\n"]} \ No newline at end of file diff --git a/lib/dist/types.d.ts b/lib/dist/types.d.ts new file mode 100644 index 0000000..5dcea32 --- /dev/null +++ b/lib/dist/types.d.ts @@ -0,0 +1,109 @@ +import { ActionHash, AgentPubKey, Create, CreateLink, Delete, DeleteLink, SignedActionHashed, Update } from '@holochain/client'; +export type GenericZomeSignal = { + type: 'EntryCreated'; + action: SignedActionHashed; + app_entry: EntryTypes; +} | { + type: 'EntryUpdated'; + action: SignedActionHashed; + app_entry: EntryTypes; + original_app_entry: EntryTypes; +} | { + type: 'EntryDeleted'; + action: SignedActionHashed; + original_app_entry: EntryTypes; +} | { + type: 'LinkCreated'; + action: SignedActionHashed; + link_type: string; +} | { + type: 'LinkDeleted'; + action: SignedActionHashed; + link_type: string; +}; +export type EntryTypes = { + type: 'Thing'; +} & ThingEntry; +export interface ThingEntry { + content: string; +} +/** + * A node in the graph can be of three distinct types, identified in different ways + */ +export type NodeId = { + type: 'anchor'; + id: string; +} | { + type: 'thing'; + id: ThingId; +} | { + type: 'agent'; + id: AgentPubKey; +}; +export type NodeContent = { + type: 'anchor'; + content: string; +} | { + type: 'thing'; + content: Thing; +} | { + type: 'agent'; + content: AgentPubKey; +}; +/** + * An anchor is a known location identified by a string to + * or from which things can be linked + */ +export type Anchor = string; +/** + * A thing is a piece of arbitrary content identified by a + * ThingHash + */ +export type Thing = { + id: ThingId; + content: string; + creator: AgentPubKey; + created_at: number; + updated_at: number; +}; +export type ThingId = ActionHash; +export declare enum LinkDirection { + From = 0, + To = 1, + Bidirectional = 2 +} +export type LinkInput = { + direction: LinkDirection; + nodeId: NodeId; + tag?: Uint8Array; +}; +export type LinkDirectionRust = { + type: 'From'; +} | { + type: 'To'; +} | { + type: 'Bidirectional'; +}; +export type LinkInputRust = { + direction: LinkDirectionRust; + nodeId: NodeId; + tag?: Uint8Array; +}; +export type CreateThingInput = { + content: string; + links?: LinkInputRust[]; +}; +export type UpdateThingInput = { + thing_id: ActionHash; + updated_content: string; +}; +export type DeleteThingInput = { + thing_id: ActionHash; + delete_backlinks: boolean; + delete_links_from_creator: boolean; + delete_links?: LinkInputRust[]; +}; +export type CreateOrDeleteLinksInput = { + src: NodeId; + links: LinkInputRust[]; +}; diff --git a/lib/dist/types.js b/lib/dist/types.js new file mode 100644 index 0000000..26b63cb --- /dev/null +++ b/lib/dist/types.js @@ -0,0 +1,7 @@ +export var LinkDirection; +(function (LinkDirection) { + LinkDirection[LinkDirection["From"] = 0] = "From"; + LinkDirection[LinkDirection["To"] = 1] = "To"; + LinkDirection[LinkDirection["Bidirectional"] = 2] = "Bidirectional"; +})(LinkDirection || (LinkDirection = {})); +//# sourceMappingURL=types.js.map \ No newline at end of file diff --git a/lib/dist/types.js.map b/lib/dist/types.js.map new file mode 100644 index 0000000..8f6ee65 --- /dev/null +++ b/lib/dist/types.js.map @@ -0,0 +1 @@ +{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAkGA,MAAM,CAAN,IAAY,aAIX;AAJD,WAAY,aAAa;IACvB,iDAAI,CAAA;IACJ,6CAAE,CAAA;IACF,mEAAa,CAAA;AACf,CAAC,EAJW,aAAa,KAAb,aAAa,QAIxB","sourcesContent":["import {\n ActionHash,\n AgentPubKey,\n Create,\n CreateLink,\n Delete,\n DeleteLink,\n SignedActionHashed,\n Update,\n} from '@holochain/client';\n\nexport type GenericZomeSignal =\n | {\n type: 'EntryCreated';\n action: SignedActionHashed;\n app_entry: EntryTypes;\n }\n | {\n type: 'EntryUpdated';\n action: SignedActionHashed;\n app_entry: EntryTypes;\n original_app_entry: EntryTypes;\n }\n | {\n type: 'EntryDeleted';\n action: SignedActionHashed;\n original_app_entry: EntryTypes;\n }\n | {\n type: 'LinkCreated';\n action: SignedActionHashed;\n link_type: string;\n }\n | {\n type: 'LinkDeleted';\n action: SignedActionHashed;\n link_type: string;\n };\n\n/* dprint-ignore-start */\nexport type EntryTypes = { type: 'Thing' } & ThingEntry;\n/* dprint-ignore-end */\n\nexport interface ThingEntry {\n content: string;\n}\n\n/**\n * A node in the graph can be of three distinct types, identified in different ways\n */\nexport type NodeId =\n | {\n type: 'anchor';\n id: string;\n }\n | {\n type: 'thing';\n id: ThingId; // \"id\" --> original action hash\n }\n | {\n type: 'agent';\n id: AgentPubKey;\n };\n\nexport type NodeContent =\n | {\n type: 'anchor';\n content: string;\n }\n | {\n type: 'thing';\n content: Thing;\n }\n | {\n type: 'agent';\n content: AgentPubKey;\n };\n\n/**\n * An anchor is a known location identified by a string to\n * or from which things can be linked\n */\nexport type Anchor = string;\n\n/**\n * A thing is a piece of arbitrary content identified by a\n * ThingHash\n */\nexport type Thing = {\n id: ThingId;\n content: string;\n creator: AgentPubKey;\n created_at: number;\n updated_at: number;\n};\n\nexport type ThingId = ActionHash;\n\nexport enum LinkDirection {\n From,\n To,\n Bidirectional,\n}\n\nexport type LinkInput = {\n direction: LinkDirection;\n nodeId: NodeId;\n tag?: Uint8Array;\n};\n\nexport type LinkDirectionRust =\n | {\n type: 'From';\n }\n | {\n type: 'To';\n }\n | {\n type: 'Bidirectional';\n };\n\nexport type LinkInputRust = {\n direction: LinkDirectionRust;\n nodeId: NodeId;\n tag?: Uint8Array;\n};\n\nexport type CreateThingInput = {\n content: string;\n links?: LinkInputRust[];\n};\n\nexport type UpdateThingInput = {\n thing_id: ActionHash;\n updated_content: string;\n};\n\nexport type DeleteThingInput = {\n thing_id: ActionHash,\n delete_backlinks: boolean,\n delete_links_from_creator: boolean,\n delete_links?: LinkInputRust[],\n}\n\nexport type CreateOrDeleteLinksInput = {\n src: NodeId,\n links: LinkInputRust[],\n};"]} \ No newline at end of file diff --git a/lib/package.json b/lib/package.json new file mode 100644 index 0000000..f310cf7 --- /dev/null +++ b/lib/package.json @@ -0,0 +1,30 @@ +{ + "name": "@holochain/simple-holochain", + "version": "0.1.0", + "main": "./dist/index.js", + "module": "./dist/index.js", + "license": "MIT", + "exports": { + ".": "./dist/index.js", + "./dist/*": "./dist/*" + }, + "files": [ + "dist" + ], + "scripts": { + "build": "tsc", + "build:watch": "tsc --watch --preserveWatchOutput" + }, + "type": "module", + "dependencies": { + "@holochain/client": "0.18.0-rc.0", + "@holochain-open-dev/utils": "0.400.0-dev.4" + }, + "devDependencies": { + "rimraf": "^3.0.2", + "typescript": "^5.2.2" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/ui/src/simpleHolochain.ts b/lib/src/index.ts similarity index 99% rename from ui/src/simpleHolochain.ts rename to lib/src/index.ts index 7fe12ba..d86e50c 100644 --- a/ui/src/simpleHolochain.ts +++ b/lib/src/index.ts @@ -22,6 +22,8 @@ import { UpdateThingInput, } from './types'; +export * from './types'; + export class SimpleHolochain { private client: AppClient; private zomeClient: ZomeClient; diff --git a/ui/src/types.ts b/lib/src/types.ts similarity index 98% rename from ui/src/types.ts rename to lib/src/types.ts index cc9fcf1..f4709a8 100644 --- a/ui/src/types.ts +++ b/lib/src/types.ts @@ -1,8 +1,6 @@ import { ActionHash, - ActionHashB64, AgentPubKey, - AgentPubKeyB64, Create, CreateLink, Delete, diff --git a/lib/tsconfig.json b/lib/tsconfig.json new file mode 100644 index 0000000..76b2a61 --- /dev/null +++ b/lib/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "outDir": "dist", + "declarationDir": "dist", + "rootDir": "./src", + "target": "es2018", + "module": "esnext", + "moduleResolution": "node", + "noEmitOnError": true, + "lib": ["es2021", "dom"], + "strict": true, + "esModuleInterop": false, + "allowSyntheticDefaultImports": true, + "experimentalDecorators": true, + "importHelpers": true, + "noImplicitAny": false, + "sourceMap": true, + "inlineSources": true, + "declaration": true, + "skipLibCheck": true + }, + "include": ["src/**/*.ts"] +} diff --git a/package-lock.json b/package-lock.json index 34b94da..2eb83a3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,6 +6,7 @@ "": { "name": "generic-dna-dev", "workspaces": [ + "lib", "ui", "tests" ], @@ -19,6 +20,66 @@ "node": ">=16.0.0" } }, + "lib": { + "version": "0.1.0", + "license": "MIT", + "dependencies": { + "@holochain-open-dev/utils": "0.400.0-dev.4", + "@holochain/client": "0.18.0-rc.0" + }, + "devDependencies": { + "rimraf": "^3.0.2", + "typescript": "^5.2.2" + } + }, + "lib/node_modules/@holochain/client": { + "version": "0.18.0-rc.0", + "resolved": "https://registry.npmjs.org/@holochain/client/-/client-0.18.0-rc.0.tgz", + "integrity": "sha512-y9dfvrnUL4OeIhW+yHUnsjsBMoWvL1HnvUKGjfoBQDBsqJGpanmysV6ALScNErF5axPVZ30/m0nmQ9NgpFzUGg==", + "dependencies": { + "@bitgo/blake2b": "^3.2.4", + "@holochain/serialization": "^0.1.0-beta-rc.3", + "@msgpack/msgpack": "^2.8.0", + "emittery": "^1.0.1", + "isomorphic-ws": "^5.0.0", + "js-base64": "^3.7.5", + "libsodium-wrappers": "^0.7.13", + "lodash-es": "^4.17.21", + "ws": "^8.14.2" + }, + "engines": { + "node": ">=18.0.0 || >=20.0.0" + } + }, + "lib/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "lib/node_modules/typescript": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/@babel/code-frame": { "version": "7.26.2", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", @@ -737,6 +798,10 @@ "integrity": "sha512-DJx4V2KXHVLciyOGjOYKTM/JLBpBEZ3RsPIRCgf7qmwhQdxXvhi2p+oFFRD51yUT5uC1/MzIVeJCl/R60PwFbw==", "license": "CAL-1.0" }, + "node_modules/@holochain/simple-holochain": { + "resolved": "lib", + "link": true + }, "node_modules/@holochain/tryorama": { "version": "0.18.0-dev.0", "resolved": "https://registry.npmjs.org/@holochain/tryorama/-/tryorama-0.18.0-dev.0.tgz", diff --git a/package.json b/package.json index fab6ec1..0cefce3 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,7 @@ "name": "generic-dna-dev", "private": true, "workspaces": [ + "lib", "ui", "tests" ], @@ -15,7 +16,8 @@ "launch:tauri": "concurrently \"hc run-local-services --bootstrap-port $BOOTSTRAP_PORT --signal-port $SIGNAL_PORT\" \"echo pass | RUST_LOG=warn hc launch --piped -n $AGENTS workdir/generic-dna.happ --ui-port $UI_PORT network --bootstrap http://127.0.0.1:\"$BOOTSTRAP_PORT\" webrtc ws://127.0.0.1:\"$SIGNAL_PORT\"\"", "package": "npm run build:happ && npm run package --workspace ui && hc web-app pack workdir --recursive", "build:happ": "npm run build:zomes && hc app pack workdir --recursive", - "build:zomes": "cargo build --release --target wasm32-unknown-unknown" + "build:zomes": "cargo build --release --target wasm32-unknown-unknown", + "build:lib": "npm run build -w lib" }, "devDependencies": { "@holochain-playground/cli": "^0.300.1", diff --git a/ui/package.json b/ui/package.json index c4d8d19..721dc73 100644 --- a/ui/package.json +++ b/ui/package.json @@ -9,6 +9,7 @@ }, "dependencies": { "@holochain/client": "^0.18.0-rc.0", + "@holochain/simple-holochain": "file:../lib", "@holochain-open-dev/utils": "0.400.0-dev.4", "@lit/context": "^1.1.3", "@lit/task": "^1.0.1", diff --git a/ui/src/contexts.ts b/ui/src/contexts.ts index a5af1e2..a8822fe 100644 --- a/ui/src/contexts.ts +++ b/ui/src/contexts.ts @@ -1,4 +1,4 @@ -import { AppClient } from "@holochain/client"; import { createContext } from "@lit/context"; +import { SimpleHolochain } from "@holochain/simple-holochain"; -export const clientContext = createContext("AppClient"); +export const simpleHolochainContext = createContext("SimpleHolochain"); diff --git a/ui/src/elements/create-thing.ts b/ui/src/elements/create-thing.ts new file mode 100644 index 0000000..4c98b16 --- /dev/null +++ b/ui/src/elements/create-thing.ts @@ -0,0 +1,73 @@ +import { + AppClient, + HolochainError, + Record, +} from "@holochain/client"; +import { consume } from "@lit/context"; +import { html, LitElement } from "lit"; +import { customElement, state } from "lit/decorators.js"; + +import { simpleHolochainContext } from "../contexts"; +import { sharedStyles } from "../shared-styles"; +import { LinkDirection, Thing } from "@holochain/simple-holochain"; +import { SimpleHolochain } from "@holochain/simple-holochain"; + +@customElement("create-post") +export class CreatePost extends LitElement { + @consume({ context: simpleHolochainContext }) + client!: SimpleHolochain; + + @state() + _content: string = ""; + + firstUpdated() { + } + + isThingValid() { + return true && this._content !== ""; + } + + async createPost() { + try { + await this.client.createThing(this._content, [ + { + direction: LinkDirection.From, + nodeId: { + type: "anchor", + id: "ALL_POSTS" + } + } + ]); + } catch (e) { + alert((e as HolochainError).message); + } + } + + render() { + return html` +
+

Create Post

+
+ + { + this._content = (e.target as any).value; + }} + required +> +
+ + +
+ `; + } + + static styles = sharedStyles; +} diff --git a/ui/src/generic_dna/generic_zome/edit-thing.ts b/ui/src/elements/edit-thing.ts similarity index 58% rename from ui/src/generic_dna/generic_zome/edit-thing.ts rename to ui/src/elements/edit-thing.ts index 04ae05b..fa89465 100644 --- a/ui/src/generic_dna/generic_zome/edit-thing.ts +++ b/ui/src/elements/edit-thing.ts @@ -1,16 +1,17 @@ -import { ActionHash, AgentPubKey, AppClient, DnaHash, EntryHash, HolochainError, Record } from "@holochain/client"; +import { ActionHash, HolochainError, Record } from "@holochain/client"; import { consume } from "@lit/context"; import { decode } from "@msgpack/msgpack"; import { html, LitElement } from "lit"; import { customElement, property, state } from "lit/decorators.js"; -import { clientContext } from "../../contexts"; -import { Thing } from "./types"; +import { simpleHolochainContext } from "../contexts"; +import { Thing } from "@holochain/simple-holochain"; +import { SimpleHolochain } from "@holochain/simple-holochain"; -@customElement("edit-thing") -export class EditThing extends LitElement { - @consume({ context: clientContext }) - client!: AppClient; +@customElement("edit-post") +export class EditPost extends LitElement { + @consume({ context: simpleHolochainContext }) + client!: SimpleHolochain; @property({ hasChanged: (newVal: ActionHash, oldVal: ActionHash) => newVal?.toString() !== oldVal?.toString(), @@ -44,35 +45,9 @@ export class EditThing extends LitElement { this._content = this.currentThing.content; } - async updateThing() { - const thing: Thing = { - content: this._content!, - }; - + async updatePost() { try { - const updateRecord: Record = await this.client.callZome({ - cap_secret: null, - role_name: "generic_dna", - zome_name: "generic_zome", - fn_name: "update_thing", - payload: { - original_thing_hash: this.originalThingHash, - previous_thing_hash: this.currentRecord.signed_action.hashed.hash, - updated_thing: thing, - }, - }); - - this.dispatchEvent( - new CustomEvent("thing-updated", { - composed: true, - bubbles: true, - detail: { - originalThingHash: this.originalThingHash, - previousThingHash: this.currentRecord.signed_action.hashed.hash, - updatedThingHash: updateRecord.signed_action.hashed.hash, - }, - }), - ); + await this.client.updateThing(this.originalThingHash, this._content); } catch (e) { alert((e as HolochainError).message); } @@ -105,7 +80,7 @@ export class EditThing extends LitElement { > Cancel - diff --git a/ui/src/elements/thing-detail.ts b/ui/src/elements/thing-detail.ts new file mode 100644 index 0000000..e2560d0 --- /dev/null +++ b/ui/src/elements/thing-detail.ts @@ -0,0 +1,111 @@ +import { + ActionHash, + AppClient, + DnaHash, + EntryHash, + HolochainError, + Record, +} from '@holochain/client'; +import { consume } from '@lit/context'; +import { Task } from '@lit/task'; +import { decode } from '@msgpack/msgpack'; +import { html, LitElement } from 'lit'; +import { customElement, property, state } from 'lit/decorators.js'; + +import '../../elements/edit-thing'; + +import { simpleHolochainContext } from '../contexts'; +import { LinkDirection, SimpleHolochain, Thing } from '@holochain/simple-holochain'; + +@customElement('thing-detail') +export class ThingDetail extends LitElement { + @consume({ context: simpleHolochainContext }) + client!: SimpleHolochain; + + @property({ + hasChanged: (newVal: ActionHash, oldVal: ActionHash) => + newVal?.toString() !== oldVal?.toString(), + }) + thingHash!: ActionHash; + + @state() + _editing = false; + + firstUpdated() { + if (!this.thingHash) { + throw new Error( + `The thingHash property is required for the thing-detail element` + ); + } + } + + async deleteThing() { + try { + await this.client.deleteThing(this.thingHash, true, true, [ + { + direction: LinkDirection.From, + nodeId: { + type: 'anchor', + id: 'ALL_POSTS', + }, + }, + ]); + } catch (e) { + alert((e as HolochainError).message); + } + } + + renderDetail(record: Record) { + const thing = decode((record.entry as any).Present.entry) as Thing; + + return html` +
+
+ Content: + ${thing.content} +
+ +
+ + +
+
+ `; + } + + renderThing(record: Record | undefined) { + if (!record) + return html`
The requested thing was not found.
`; + if (this._editing) { + return html` + { + this._editing = false; + await this._fetchRecord.run(); + }} + @edit-canceled=${() => { + this._editing = false; + }} + > + `; + } + return this.renderDetail(record); + } + + render() { + return this._fetchRecord.render({ + pending: () => html``, + complete: record => this.renderThing(record), + error: (e: any) => + html`
Error fetching the thing: ${e.message}
`, + }); + } +} diff --git a/ui/src/generic_dna/generic_zome/create-thing.ts b/ui/src/generic_dna/generic_zome/create-thing.ts deleted file mode 100644 index 83b3c46..0000000 --- a/ui/src/generic_dna/generic_zome/create-thing.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { - ActionHash, - AgentPubKey, - AppClient, - DnaHash, - EntryHash, - HolochainError, - InstalledCell, - Record, -} from "@holochain/client"; -import { consume } from "@lit/context"; -import { html, LitElement } from "lit"; -import { customElement, property, state } from "lit/decorators.js"; - -import { clientContext } from "../../contexts"; -import { sharedStyles } from "../../shared-styles"; -import { Thing } from "./types"; - -@customElement("create-thing") -export class CreateThing extends LitElement { - @consume({ context: clientContext }) - client!: AppClient; - - @state() - _content: string = ""; - - firstUpdated() { - } - - isThingValid() { - return true && this._content !== ""; - } - - async createThing() { - const thing: Thing = { - content: this._content, - }; - - try { - const record: Record = await this.client.callZome({ - cap_secret: null, - role_name: "generic_dna", - zome_name: "generic_zome", - fn_name: "create_thing", - payload: thing, - }); - - this.dispatchEvent( - new CustomEvent("thing-created", { - composed: true, - bubbles: true, - detail: { - thingHash: record.signed_action.hashed.hash, - }, - }), - ); - } catch (e) { - alert((e as HolochainError).message); - } - } - - render() { - return html` -
-

Create Thing

-
- - { - this._content = (e.target as any).value; - }} - required -> -
- - -
- `; - } - - static styles = sharedStyles; -} diff --git a/ui/src/generic_dna/generic_zome/thing-detail.ts b/ui/src/generic_dna/generic_zome/thing-detail.ts deleted file mode 100644 index 06ef86d..0000000 --- a/ui/src/generic_dna/generic_zome/thing-detail.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { ActionHash, AppClient, DnaHash, EntryHash, HolochainError, Record } from "@holochain/client"; -import { consume } from "@lit/context"; -import { Task } from "@lit/task"; -import { decode } from "@msgpack/msgpack"; -import { html, LitElement } from "lit"; -import { customElement, property, state } from "lit/decorators.js"; - -import "./edit-thing"; - -import { clientContext } from "../../contexts"; -import { Thing } from "./types"; - -@customElement("thing-detail") -export class ThingDetail extends LitElement { - @consume({ context: clientContext }) - client!: AppClient; - - @property({ - hasChanged: (newVal: ActionHash, oldVal: ActionHash) => newVal?.toString() !== oldVal?.toString(), - }) - thingHash!: ActionHash; - - _fetchRecord = new Task(this, ([thingHash]: Array) => - this.client.callZome({ - cap_secret: null, - role_name: "generic_dna", - zome_name: "generic_zome", - fn_name: "get_latest_thing", - payload: thingHash, - }) as Promise, () => [this.thingHash]); - - @state() - _editing = false; - - firstUpdated() { - if (!this.thingHash) { - throw new Error(`The thingHash property is required for the thing-detail element`); - } - } - - async deleteThing() { - try { - await this.client.callZome({ - cap_secret: null, - role_name: "generic_dna", - zome_name: "generic_zome", - fn_name: "delete_thing", - payload: this.thingHash, - }); - this.dispatchEvent( - new CustomEvent("thing-deleted", { - bubbles: true, - composed: true, - detail: { - thingHash: this.thingHash, - }, - }), - ); - this._fetchRecord.run(); - } catch (e) { - alert((e as HolochainError).message); - } - } - - renderDetail(record: Record) { - const thing = decode((record.entry as any).Present.entry) as Thing; - - return html` -
-
- Content: - ${thing.content} -
- -
- - -
-
- `; - } - - renderThing(record: Record | undefined) { - if (!record) return html`
The requested thing was not found.
`; - if (this._editing) { - return html` - { - this._editing = false; - await this._fetchRecord.run(); - }} - @edit-canceled=${() => { - this._editing = false; - }} - > - `; - } - return this.renderDetail(record); - } - - render() { - return this._fetchRecord.render({ - pending: () => html``, - complete: (record) => this.renderThing(record), - error: (e: any) => html`
Error fetching the thing: ${e.message}
`, - }); - } -} diff --git a/ui/src/generic_dna/generic_zome/types.ts b/ui/src/generic_dna/generic_zome/types.ts deleted file mode 100644 index 7324045..0000000 --- a/ui/src/generic_dna/generic_zome/types.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { - ActionHash, - AgentPubKey, - Create, - CreateLink, - Delete, - DeleteLink, - DnaHash, - EntryHash, - ExternalHash, - Record, - SignedActionHashed, - Update, -} from "@holochain/client"; - -export type GenericZomeSignal = { - type: "EntryCreated"; - action: SignedActionHashed; - app_entry: EntryTypes; -} | { - type: "EntryUpdated"; - action: SignedActionHashed; - app_entry: EntryTypes; - original_app_entry: EntryTypes; -} | { - type: "EntryDeleted"; - action: SignedActionHashed; - original_app_entry: EntryTypes; -} | { - type: "LinkCreated"; - action: SignedActionHashed; - link_type: string; -} | { - type: "LinkDeleted"; - action: SignedActionHashed; - link_type: string; -}; - -/* dprint-ignore-start */ -export type EntryTypes = - | ({ type: 'Thing'; } & Thing); -/* dprint-ignore-end */ - -export interface Thing { - content: string; -} diff --git a/ui/src/holochain-app.ts b/ui/src/holochain-app.ts index 66c052c..e8ccc3d 100644 --- a/ui/src/holochain-app.ts +++ b/ui/src/holochain-app.ts @@ -4,8 +4,9 @@ import { css, html, LitElement } from "lit"; import { customElement, property, state } from "lit/decorators.js"; import HolochainLogo from "./assets/holochainLogo.svg"; -import { clientContext } from "./contexts"; +import { simpleHolochainContext } from "./contexts"; import { sharedStyles } from "./shared-styles"; +import { SimpleHolochain } from "@holochain/simple-holochain"; @customElement("holochain-app") export class HolochainApp extends LitElement { @@ -15,14 +16,14 @@ export class HolochainApp extends LitElement { @state() error: HolochainError | undefined; - @provide({ context: clientContext }) + @provide({ context: simpleHolochainContext }) @property({ type: Object }) - client!: AppClient; + client!: SimpleHolochain; async firstUpdated() { this.loading = true; try { - this.client = await AppWebsocket.connect(); + this.client = await SimpleHolochain.connect(); } catch (e) { this.error = e as HolochainError; } finally {