From 839d4e98f8612a6add6c498923a1b52c61de6b1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Zieli=C5=84ski?= Date: Thu, 13 May 2021 11:43:51 +0200 Subject: [PATCH 01/98] Initial commit --- .gitignore | 10 ++++++++++ LICENSE | 21 +++++++++++++++++++++ README.md | 1 + 3 files changed, 32 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..088ba6b --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +# Generated by Cargo +# will have compiled files and executables +/target/ + +# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries +# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html +Cargo.lock + +# These are backup files generated by rustfmt +**/*.rs.bk diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d603ca8 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Casper Ecosystem + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..b201a8e --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# casper-nft-cep46 \ No newline at end of file From d286da4f1683a6b4be2454a30fd04d022afda450 Mon Sep 17 00:00:00 2001 From: astro019 Date: Fri, 14 May 2021 21:47:56 +1000 Subject: [PATCH 02/98] initial version of cep45 --- Cargo.toml | 9 +++ Makefile | 26 ++++++ contract/Cargo.toml | 21 +++++ contract/src/main.rs | 187 +++++++++++++++++++++++++++++++++++++++++++ contract/src/todo | 42 ++++++++++ tests/Cargo.toml | 15 ++++ tests/src/main.rs | 3 + 7 files changed, 303 insertions(+) create mode 100644 Cargo.toml create mode 100644 Makefile create mode 100644 contract/Cargo.toml create mode 100644 contract/src/main.rs create mode 100644 contract/src/todo create mode 100644 tests/Cargo.toml create mode 100644 tests/src/main.rs diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..0c25af4 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,9 @@ +[workspace] + +members = [ + "contract", + "tests" +] + +[profile.release] +lto = true diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..607acb7 --- /dev/null +++ b/Makefile @@ -0,0 +1,26 @@ +prepare: + rustup target add wasm32-unknown-unknown + +build-contract: + cargo build --release -p contract --target wasm32-unknown-unknown + +test-only: + cargo test -p tests + +copy-wasm-file-to-test: + cp target/wasm32-unknown-unknown/release/contract.wasm tests/wasm + +test: build-contract copy-wasm-file-to-test test-only + +clippy: + cargo clippy --all-targets --all -- -D warnings -A renamed_and_removed_lints + +check-lint: clippy + cargo fmt --all -- --check + +lint: clippy + cargo fmt --all + +clean: + cargo clean + rm -rf tests/wasm/contract.wasm diff --git a/contract/Cargo.toml b/contract/Cargo.toml new file mode 100644 index 0000000..2caf990 --- /dev/null +++ b/contract/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "contract" +version = "0.1.0" +authors = ["astro019 "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +contract = { package = "casper-contract", version="1.1.1" } +types = { package = "casper-types", version="1.1.1" } + +[[bin]] +name = "contract" +path = "src/main.rs" +bench = false +doctest = false +test = false + +[features] +default = ["contract/std", "types/std"] diff --git a/contract/src/main.rs b/contract/src/main.rs new file mode 100644 index 0000000..d7314f0 --- /dev/null +++ b/contract/src/main.rs @@ -0,0 +1,187 @@ +#![no_main] +#![allow(unused_imports)] +#![allow(unused_parens)] +#![allow(non_snake_case)] + +extern crate alloc; +use alloc::{ + collections::{BTreeMap, BTreeSet}, + string::String, +}; +use contract::{ + contract_api::{runtime, storage}, + unwrap_or_revert::UnwrapOrRevert, +}; +use core::convert::TryInto; +use std::{ + collections::hash_map::DefaultHasher, + hash::{Hash, Hasher}, +}; +use types::{ + account::AccountHash, + bytesrepr::{FromBytes, ToBytes}, + ApiError, AsymmetricType, CLTyped, CLValue, PublicKey, URef, U256, +}; + +/** + * ApiError::User(1) - The number of piece is out or range. + * ApiError::User(2) - The piece of NFT is already minted and owned by someone. + * ApiError::User(3) - The piece of NFT is not minted yet. + */ + +#[derive(Hash)] +pub struct TokenId { + seed: URef, + piece_number: u64, +} + +#[no_mangle] +pub extern "C" fn name() { + let val: String = get_key("name"); + ret(val) +} + +#[no_mangle] +pub extern "C" fn ipfs_hash() { + let val: String = get_key("ipfs_hash"); + ret(val) +} + +#[no_mangle] +pub extern "C" fn balance_of() { + let account: AccountHash = runtime::get_named_arg("account"); + let val: U256 = get_key(&balance_key(&account)); + ret(val) +} + +#[no_mangle] +pub extern "C" fn transfer() { + let sender: AccountHash = runtime::get_named_arg("sender"); + let recipient: AccountHash = runtime::get_named_arg("recipient"); + let piece_number: u64 = runtime::get_named_arg("piece_number"); + if sender != runtime::get_caller() { + runtime::revert(ApiError::PermissionDenied); + } + + let total_number = number_of_pieces(); + if piece_number > total_number || piece_number == 0 { + runtime::revert(ApiError::User(1)); + } + + let owner = owner_of(piece_number); + if owner.is_none() { + runtime::revert(ApiError::User(3)); + } + if sender != owner.unwrap() { + runtime::revert(ApiError::PermissionDenied); + } + + let mut owners = owners(); + let token_id = to_token_id(piece_number); + owners.insert(token_id, Some(recipient)); + set_key("owners", owners); + + let sender_key: String = get_key(&balance_key(&sender)); + let recipient_key: String = get_key(&balance_key(&recipient)); + let new_sender_balance: U256 = get_key::(&sender_key) - 1; + set_key(&sender_key, new_sender_balance); + let new_recipient_balance: U256 = get_key::(&recipient_key) + 1; + set_key(&recipient_key, new_recipient_balance); +} + +#[no_mangle] +pub extern "C" fn mint() { + let recipient: AccountHash = runtime::get_named_arg("recipient"); + let piece_number: u64 = runtime::get_named_arg("piece_number"); + let minter: AccountHash = minter(); + if minter != runtime::get_caller() { + runtime::revert(ApiError::PermissionDenied); + } + let token_id = to_token_id(piece_number); + let owner = owner_of(token_id); + if owner.is_some() { + runtime::revert(ApiError::User(2)); + } + let mut owners = owners(); + owners.insert(token_id, Some(recipient)); + set_key("owners", owners); + + let recipient_key = balance_key(&recipient); + let recipient_balance = get_key::(&recipient_key); + set_key(&recipient_key, recipient_balance + 1); +} + +#[no_mangle] +pub extern "C" fn call() {} + +fn ret(value: T) { + runtime::ret(CLValue::from_t(value).unwrap_or_revert()) +} + +fn get_key(name: &str) -> T { + match runtime::get_key(name) { + None => Default::default(), + Some(value) => { + let key = value.try_into().unwrap_or_revert(); + storage::read(key).unwrap_or_revert().unwrap_or_revert() + } + } +} + +fn set_key(name: &str, value: T) { + match runtime::get_key(name) { + Some(key) => { + let key_ref = key.try_into().unwrap_or_revert(); + storage::write(key_ref, value); + } + None => { + let key = storage::new_uref(value).into(); + runtime::put_key(name, key); + } + } +} + +fn seed() -> URef { + let val: URef = get_key("seed"); + return val; +} + +fn minter() -> AccountHash { + let val: AccountHash = get_key("minter"); + return val; +} + +fn number_of_pieces() -> u64 { + let val: u64 = get_key("number_of_pieces"); + return val; +} + +fn owners() -> BTreeMap> { + let val: BTreeMap> = get_key("owners"); + return val; +} + +fn owner_of(token_id: u64) -> Option { + let owners = owners(); + let owner = owners.get(&token_id).unwrap(); + owner.clone() +} + +fn to_token_id(piece_number: u64) -> u64 { + let total_pieces: u64 = number_of_pieces(); + if piece_number > total_pieces || piece_number == 0 { + runtime::revert(ApiError::User(1)); + } + + let mut hasher = DefaultHasher::new(); + let token_id = TokenId { + seed: seed(), + piece_number, + }; + Hash::hash(&token_id, &mut hasher); + hasher.finish() +} + +fn balance_key(account: &AccountHash) -> String { + format!("balances_{}", account) +} diff --git a/contract/src/todo b/contract/src/todo new file mode 100644 index 0000000..009725e --- /dev/null +++ b/contract/src/todo @@ -0,0 +1,42 @@ +MonaLisaNFT +Data: + - seed: URef + - number_of_pieces: u64 + - minter: PublicKey + - owners: Map + - balances: Map + - name: String + - IPFS Hash: String +CEP47 - Endpoints: + - owner_of(token_id: TokenId) -> Option; + - balance_of(account: PublicKey) -> u64; + - transfer(from: PublicKey, to: PublicKey, token_id: TokenId) { + if from.to_account_hash() != runtime::get_caller() { + revert(); + } + } +MonaLisa - Endpoints: +mint(to: PublicKey, piece_number: u64) { + if minter.to_account_hash() != runtime::get_caller() { + revert(); + } + let token_id = to_token_id(piece_number); + let owner = owner_of(token_id); + if owner.is_none() { + owners[token_id] = to; + balances[to] += 1; + } +} +MonaLisa internal functions: +to_token_id(piece_number) -> TokenId { + if piece_number > number_of_pieces { + revert(); + } + hash(seed, piece_number) +} +Initial named keys: + - seed, + - number_of_pieces, + - name + - IPFS Hash + - minter: PublicKey \ No newline at end of file diff --git a/tests/Cargo.toml b/tests/Cargo.toml new file mode 100644 index 0000000..07bf930 --- /dev/null +++ b/tests/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "tests" +version = "0.1.0" +authors = ["astro019 "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +casper-contract = "1.1.1" +casper-types = "1.1.1" +casper-engine-test-support = "1.1.1" + +[features] +default = ["casper-contract/std", "casper-types/std", "casper-contract/test-support"] diff --git a/tests/src/main.rs b/tests/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/tests/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} From 18c3e069ea23562980a9d8e86fb8a3af82d5ff54 Mon Sep 17 00:00:00 2001 From: astro019 Date: Fri, 14 May 2021 22:13:35 +1000 Subject: [PATCH 03/98] change AccountHash into PublicKey --- contract/src/main.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/contract/src/main.rs b/contract/src/main.rs index d7314f0..cc5caba 100644 --- a/contract/src/main.rs +++ b/contract/src/main.rs @@ -49,17 +49,17 @@ pub extern "C" fn ipfs_hash() { #[no_mangle] pub extern "C" fn balance_of() { - let account: AccountHash = runtime::get_named_arg("account"); - let val: U256 = get_key(&balance_key(&account)); + let account: PublicKey = runtime::get_named_arg("account"); + let val: U256 = get_key(&balance_key(&account.to_account_hash())); ret(val) } #[no_mangle] pub extern "C" fn transfer() { - let sender: AccountHash = runtime::get_named_arg("sender"); - let recipient: AccountHash = runtime::get_named_arg("recipient"); + let sender: PublicKey = runtime::get_named_arg("sender"); + let recipient: PublicKey = runtime::get_named_arg("recipient"); let piece_number: u64 = runtime::get_named_arg("piece_number"); - if sender != runtime::get_caller() { + if sender.to_account_hash() != runtime::get_caller() { runtime::revert(ApiError::PermissionDenied); } @@ -81,8 +81,8 @@ pub extern "C" fn transfer() { owners.insert(token_id, Some(recipient)); set_key("owners", owners); - let sender_key: String = get_key(&balance_key(&sender)); - let recipient_key: String = get_key(&balance_key(&recipient)); + let sender_key: String = get_key(&balance_key(&sender.to_account_hash())); + let recipient_key: String = get_key(&balance_key(&recipient.to_account_hash())); let new_sender_balance: U256 = get_key::(&sender_key) - 1; set_key(&sender_key, new_sender_balance); let new_recipient_balance: U256 = get_key::(&recipient_key) + 1; @@ -91,7 +91,7 @@ pub extern "C" fn transfer() { #[no_mangle] pub extern "C" fn mint() { - let recipient: AccountHash = runtime::get_named_arg("recipient"); + let recipient: PublicKey = runtime::get_named_arg("recipient"); let piece_number: u64 = runtime::get_named_arg("piece_number"); let minter: AccountHash = minter(); if minter != runtime::get_caller() { @@ -106,7 +106,7 @@ pub extern "C" fn mint() { owners.insert(token_id, Some(recipient)); set_key("owners", owners); - let recipient_key = balance_key(&recipient); + let recipient_key = balance_key(&recipient.to_account_hash()); let recipient_balance = get_key::(&recipient_key); set_key(&recipient_key, recipient_balance + 1); } @@ -156,12 +156,12 @@ fn number_of_pieces() -> u64 { return val; } -fn owners() -> BTreeMap> { - let val: BTreeMap> = get_key("owners"); +fn owners() -> BTreeMap> { + let val: BTreeMap> = get_key("owners"); return val; } -fn owner_of(token_id: u64) -> Option { +fn owner_of(token_id: u64) -> Option { let owners = owners(); let owner = owners.get(&token_id).unwrap(); owner.clone() From 2f8079a34aca195bf04ed0c536b91e2b93f8a6b8 Mon Sep 17 00:00:00 2001 From: astro019 Date: Fri, 14 May 2021 22:44:35 +1000 Subject: [PATCH 04/98] remove mapping for token owners --- contract/src/main.rs | 79 +++++++++++++++++--------------------------- 1 file changed, 31 insertions(+), 48 deletions(-) diff --git a/contract/src/main.rs b/contract/src/main.rs index cc5caba..a42764c 100644 --- a/contract/src/main.rs +++ b/contract/src/main.rs @@ -37,20 +37,20 @@ pub struct TokenId { #[no_mangle] pub extern "C" fn name() { - let val: String = get_key("name"); + let val: String = get_key("name").unwrap(); ret(val) } #[no_mangle] pub extern "C" fn ipfs_hash() { - let val: String = get_key("ipfs_hash"); + let val: String = get_key("ipfs_hash").unwrap(); ret(val) } #[no_mangle] pub extern "C" fn balance_of() { let account: PublicKey = runtime::get_named_arg("account"); - let val: U256 = get_key(&balance_key(&account.to_account_hash())); + let val: U256 = get_key(&balance_key(&account.to_account_hash())).unwrap(); ret(val) } @@ -62,12 +62,6 @@ pub extern "C" fn transfer() { if sender.to_account_hash() != runtime::get_caller() { runtime::revert(ApiError::PermissionDenied); } - - let total_number = number_of_pieces(); - if piece_number > total_number || piece_number == 0 { - runtime::revert(ApiError::User(1)); - } - let owner = owner_of(piece_number); if owner.is_none() { runtime::revert(ApiError::User(3)); @@ -75,17 +69,13 @@ pub extern "C" fn transfer() { if sender != owner.unwrap() { runtime::revert(ApiError::PermissionDenied); } + set_key(&token_key(piece_number), Some(recipient)); - let mut owners = owners(); - let token_id = to_token_id(piece_number); - owners.insert(token_id, Some(recipient)); - set_key("owners", owners); - - let sender_key: String = get_key(&balance_key(&sender.to_account_hash())); - let recipient_key: String = get_key(&balance_key(&recipient.to_account_hash())); - let new_sender_balance: U256 = get_key::(&sender_key) - 1; + let sender_key: String = get_key(&balance_key(&sender.to_account_hash())).unwrap(); + let recipient_key: String = get_key(&balance_key(&recipient.to_account_hash())).unwrap(); + let new_sender_balance: U256 = get_key::(&sender_key).unwrap() - 1; set_key(&sender_key, new_sender_balance); - let new_recipient_balance: U256 = get_key::(&recipient_key) + 1; + let new_recipient_balance: U256 = get_key::(&recipient_key).unwrap() + 1; set_key(&recipient_key, new_recipient_balance); } @@ -93,21 +83,19 @@ pub extern "C" fn transfer() { pub extern "C" fn mint() { let recipient: PublicKey = runtime::get_named_arg("recipient"); let piece_number: u64 = runtime::get_named_arg("piece_number"); - let minter: AccountHash = minter(); - if minter != runtime::get_caller() { + let minter: PublicKey = minter(); + if minter.to_account_hash() != runtime::get_caller() { runtime::revert(ApiError::PermissionDenied); } - let token_id = to_token_id(piece_number); - let owner = owner_of(token_id); + let owner = owner_of(piece_number); if owner.is_some() { runtime::revert(ApiError::User(2)); } - let mut owners = owners(); - owners.insert(token_id, Some(recipient)); - set_key("owners", owners); + + set_key(&token_key(piece_number), Some(recipient)); let recipient_key = balance_key(&recipient.to_account_hash()); - let recipient_balance = get_key::(&recipient_key); + let recipient_balance = get_key::(&recipient_key).unwrap(); set_key(&recipient_key, recipient_balance + 1); } @@ -118,12 +106,13 @@ fn ret(value: T) { runtime::ret(CLValue::from_t(value).unwrap_or_revert()) } -fn get_key(name: &str) -> T { +fn get_key(name: &str) -> Option { match runtime::get_key(name) { - None => Default::default(), + None => None, Some(value) => { let key = value.try_into().unwrap_or_revert(); - storage::read(key).unwrap_or_revert().unwrap_or_revert() + let value = storage::read(key).unwrap_or_revert().unwrap_or_revert(); + Some(value) } } } @@ -142,29 +131,28 @@ fn set_key(name: &str, value: T) { } fn seed() -> URef { - let val: URef = get_key("seed"); - return val; + get_key::("seed").unwrap() } -fn minter() -> AccountHash { - let val: AccountHash = get_key("minter"); - return val; +fn minter() -> PublicKey { + get_key::("minter").unwrap() } fn number_of_pieces() -> u64 { - let val: u64 = get_key("number_of_pieces"); - return val; + get_key::("number_of_pieces").unwrap() } -fn owners() -> BTreeMap> { - let val: BTreeMap> = get_key("owners"); - return val; +fn owner_of(piece_number: u64) -> Option { + let token_id = to_token_id(piece_number); + get_key::(&token_key(token_id)) } -fn owner_of(token_id: u64) -> Option { - let owners = owners(); - let owner = owners.get(&token_id).unwrap(); - owner.clone() +fn balance_key(account: &AccountHash) -> String { + format!("balances_{}", account) +} + +fn token_key(token_id: u64) -> String { + format!("tokens_{}", to_token_id(token_id)) } fn to_token_id(piece_number: u64) -> u64 { @@ -172,7 +160,6 @@ fn to_token_id(piece_number: u64) -> u64 { if piece_number > total_pieces || piece_number == 0 { runtime::revert(ApiError::User(1)); } - let mut hasher = DefaultHasher::new(); let token_id = TokenId { seed: seed(), @@ -181,7 +168,3 @@ fn to_token_id(piece_number: u64) -> u64 { Hash::hash(&token_id, &mut hasher); hasher.finish() } - -fn balance_key(account: &AccountHash) -> String { - format!("balances_{}", account) -} From 951940e5f21ae8e8ee701775b76bfed5bd3e0730 Mon Sep 17 00:00:00 2001 From: Maciej Zielinski Date: Tue, 18 May 2021 16:15:40 +0200 Subject: [PATCH 05/98] wip --- Cargo.toml | 2 +- Makefile | 6 +- {contract => cep47}/Cargo.toml | 6 +- cep47/src/lib.rs | 1 + cep47/src/logic.rs | 205 ++++++++++++++++++++++++++++++++ {contract => cep47}/src/main.rs | 1 + {contract => cep47}/src/todo | 0 7 files changed, 213 insertions(+), 8 deletions(-) rename {contract => cep47}/Cargo.toml (72%) create mode 100644 cep47/src/lib.rs create mode 100644 cep47/src/logic.rs rename {contract => cep47}/src/main.rs (99%) rename {contract => cep47}/src/todo (100%) diff --git a/Cargo.toml b/Cargo.toml index 0c25af4..b6e8c8b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [workspace] members = [ - "contract", + "cep47", "tests" ] diff --git a/Makefile b/Makefile index 607acb7..59d81b7 100644 --- a/Makefile +++ b/Makefile @@ -2,13 +2,13 @@ prepare: rustup target add wasm32-unknown-unknown build-contract: - cargo build --release -p contract --target wasm32-unknown-unknown + cargo build --release -p cep47 --target wasm32-unknown-unknown test-only: cargo test -p tests copy-wasm-file-to-test: - cp target/wasm32-unknown-unknown/release/contract.wasm tests/wasm + cp target/wasm32-unknown-unknown/release/cep47.wasm tests/wasm test: build-contract copy-wasm-file-to-test test-only @@ -23,4 +23,4 @@ lint: clippy clean: cargo clean - rm -rf tests/wasm/contract.wasm + rm -rf tests/wasm/cep47.wasm diff --git a/contract/Cargo.toml b/cep47/Cargo.toml similarity index 72% rename from contract/Cargo.toml rename to cep47/Cargo.toml index 2caf990..2154079 100644 --- a/contract/Cargo.toml +++ b/cep47/Cargo.toml @@ -1,17 +1,15 @@ [package] -name = "contract" +name = "cep47" version = "0.1.0" authors = ["astro019 "] edition = "2018" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] contract = { package = "casper-contract", version="1.1.1" } types = { package = "casper-types", version="1.1.1" } [[bin]] -name = "contract" +name = "cep47" path = "src/main.rs" bench = false doctest = false diff --git a/cep47/src/lib.rs b/cep47/src/lib.rs new file mode 100644 index 0000000..45a2c47 --- /dev/null +++ b/cep47/src/lib.rs @@ -0,0 +1 @@ +pub mod logic; \ No newline at end of file diff --git a/cep47/src/logic.rs b/cep47/src/logic.rs new file mode 100644 index 0000000..f17d803 --- /dev/null +++ b/cep47/src/logic.rs @@ -0,0 +1,205 @@ +use std::marker::PhantomData; + +use contract::contract_api::{runtime, storage}; +use types::{U256, PublicKey, URef}; + +type TokenId = String; +type URI = String; + +trait WithStorage { + fn storage(&self) -> Storage; +} + +trait CEP47Contract: WithStorage { + // Metadata + fn name(&self) -> String { + self.storage().name() + } + + fn symbol(&self) -> String { + self.storage().symbol() + } + + fn uri(&self) -> URI { + self.storage().uri() + } + + // Getters + fn balance_of(&self, owner: PublicKey) -> U256 { + self.storage().balance_of(owner) + } + + fn owner_of(&self, token_id: TokenId) -> Option { + self.storage().onwer_of(token_id) + } + + fn total_supply(&self) -> U256 { + self.storage().total_supply() + } + + fn token_uri(&self, token_id: TokenId) -> Option { + self.storage().token_uri(token_id) + } + + fn tokens(&self, owner: PublicKey) -> Vec { + todo!(); + } + + // Minter function. + // Guarded by the entrypoint group. + fn mint_one(&mut self, recipient: PublicKey, token_uri: URI) { + self.storage().mint_copies(recipient, token_uri, U256::one()); + } + + fn mint_many(&mut self, recipient: PublicKey, token_uris: Vec) { + self.storage().mint_many(recipient, token_uris); + } + + fn mint_copies(&mut self, recipient: PublicKey, token_uri: URI, count: U256) { + self.storage().mint_copies(recipient, token_uri, count); + } + + // Transfer functions. + fn transfer_token(&mut self, sender: PublicKey, recipient: PublicKey, token_id: TokenId) { + // 1. Load tokens owned by the sender. + let sender_tokens = self.storage().get_tokens(sender); + // 2. Assert that token_id is in sender_tokens. + + // 3. Remove token_id from sender_tokens. + let updated_sender_tokens = sender_tokens; // Modify + self.storage().set_tokens(sender, updated_sender_tokens); + + // 4. Add token_id to the recipient tokens + let recipient_tokens = self.storage().get_tokens(recipient); + let updated_recipient_tokens = recipient_tokens; + self.storage().set_tokens(recipient, updated_recipient_tokens); + } + + fn transfer_many_tokens(&mut self, sender: PublicKey, recipient: PublicKey, token_ids: Vec) { + todo!() + } + fn transfer_all_tokens(&mut self, sender: PublicKey, recipient: PublicKey) { + todo!() + } + + // URef releated function. + fn detach(&mut self, owner: PublicKey, token_id: TokenId) -> URef { + todo!(); + } + fn attach(&mut self, token_uref: URef, recipient: PublicKey) {} + fn token_id(&self, token_uref: URef) -> TokenId { todo!(); } +} + +trait CEP47Storage { + + // Metadata. + fn name(&self) -> String; + fn symbol(&self) -> String; + fn uri(&self) -> URI; + + // Getters + fn balance_of(&self, owner: PublicKey) -> U256; + fn onwer_of(&self, token_id: TokenId) -> Option; + fn total_supply(&self) -> U256; + fn token_uri(&self, token_id: TokenId) -> Option; + + // Setters + fn get_tokens(&self, owner: PublicKey) -> Vec; + fn set_tokens(&mut self, owner: PublicKey, token_ids: Vec); + fn mint_many(&mut self, recipient: PublicKey, token_uris: Vec); + fn mint_copies(&mut self, recipient: PublicKey, token_uri: URI, count: U256); + fn new_uref(&mut self, token_id: TokenId) -> URef; + fn del_uref(&mut self, token_uref: URef); +} + +#[cfg(test)] +mod tests { + use std::collections::BTreeMap; + use super::{PublicKey, TokenId}; + use super::{WithStorage, CEP47Storage, CEP47Contract}; + + struct TestStorage { + name: String, + tokens: BTreeMap> + } + + impl TestStorage { + pub fn new() -> TestStorage { + TestStorage { + name: String::from("asd"), + tokens: BTreeMap::new() + } + } + } + + impl CEP47Storage for TestStorage { + fn name(&self) -> String { + self.name.clone() + } + + fn symbol(&self) -> String { + todo!() + } + + fn uri(&self) -> super::URI { + todo!() + } + + fn balance_of(&self, owner: types::PublicKey) -> types::U256 { + todo!() + } + + fn onwer_of(&self, token_id: super::TokenId) -> Option { + todo!() + } + + fn total_supply(&self) -> types::U256 { + todo!() + } + + fn token_uri(&self, token_id: super::TokenId) -> Option { + todo!() + } + + fn get_tokens(&self, owner: types::PublicKey) -> Vec { + todo!() + } + + fn set_tokens(&mut self, owner: types::PublicKey, token_ids: Vec) { + todo!() + } + + fn mint_many(&mut self, recipient: types::PublicKey, token_uris: Vec) { + todo!() + } + + fn mint_copies(&mut self, recipient: types::PublicKey, token_uri: super::URI, count: types::U256) { + todo!() + } + + fn new_uref(&mut self, token_id: super::TokenId) -> types::URef { + todo!() + } + + fn del_uref(&mut self, token_uref: types::URef) { + todo!() + } + } + + struct TestContract {} + + impl WithStorage for TestContract { + fn storage(&self) -> TestStorage { + TestStorage::new() + } + } + + impl CEP47Contract for TestContract{} + + #[test] + fn test_name() { + let contract = TestContract {}; + assert_eq!(contract.name(), String::from("asd")) + } + +} \ No newline at end of file diff --git a/contract/src/main.rs b/cep47/src/main.rs similarity index 99% rename from contract/src/main.rs rename to cep47/src/main.rs index a42764c..a955da4 100644 --- a/contract/src/main.rs +++ b/cep47/src/main.rs @@ -4,6 +4,7 @@ #![allow(non_snake_case)] extern crate alloc; + use alloc::{ collections::{BTreeMap, BTreeSet}, string::String, diff --git a/contract/src/todo b/cep47/src/todo similarity index 100% rename from contract/src/todo rename to cep47/src/todo From b7e8f77e3861a459bd09c217f434497d300ee94c Mon Sep 17 00:00:00 2001 From: astro019 Date: Thu, 20 May 2021 23:19:09 +1000 Subject: [PATCH 06/98] added mock TestStorage --- cep47/src/logic.rs | 249 +++++++++++++++++++++++++++++++-------------- 1 file changed, 173 insertions(+), 76 deletions(-) diff --git a/cep47/src/logic.rs b/cep47/src/logic.rs index f17d803..168ae1a 100644 --- a/cep47/src/logic.rs +++ b/cep47/src/logic.rs @@ -1,7 +1,6 @@ -use std::marker::PhantomData; - -use contract::contract_api::{runtime, storage}; -use types::{U256, PublicKey, URef}; +#![allow(dead_code)] +#![allow(unused_imports)] +use types::{PublicKey, URef, U256}; type TokenId = String; type URI = String; @@ -15,11 +14,11 @@ trait CEP47Contract: WithStorage { fn name(&self) -> String { self.storage().name() } - + fn symbol(&self) -> String { self.storage().symbol() } - + fn uri(&self) -> URI { self.storage().uri() } @@ -28,33 +27,34 @@ trait CEP47Contract: WithStorage { fn balance_of(&self, owner: PublicKey) -> U256 { self.storage().balance_of(owner) } - + fn owner_of(&self, token_id: TokenId) -> Option { self.storage().onwer_of(token_id) } - + fn total_supply(&self) -> U256 { self.storage().total_supply() } - + fn token_uri(&self, token_id: TokenId) -> Option { self.storage().token_uri(token_id) } fn tokens(&self, owner: PublicKey) -> Vec { - todo!(); + self.storage().get_tokens(owner) } - + // Minter function. // Guarded by the entrypoint group. fn mint_one(&mut self, recipient: PublicKey, token_uri: URI) { - self.storage().mint_copies(recipient, token_uri, U256::one()); + self.storage() + .mint_copies(recipient, token_uri, U256::one()); } - + fn mint_many(&mut self, recipient: PublicKey, token_uris: Vec) { self.storage().mint_many(recipient, token_uris); } - + fn mint_copies(&mut self, recipient: PublicKey, token_uri: URI, count: U256) { self.storage().mint_copies(recipient, token_uri, count); } @@ -62,36 +62,60 @@ trait CEP47Contract: WithStorage { // Transfer functions. fn transfer_token(&mut self, sender: PublicKey, recipient: PublicKey, token_id: TokenId) { // 1. Load tokens owned by the sender. - let sender_tokens = self.storage().get_tokens(sender); + let mut sender_tokens = self.storage().get_tokens(sender); // 2. Assert that token_id is in sender_tokens. - + assert!( + sender_tokens.contains(&token_id), + "wrong owner of token {}", + token_id + ); // 3. Remove token_id from sender_tokens. - let updated_sender_tokens = sender_tokens; // Modify - self.storage().set_tokens(sender, updated_sender_tokens); - - // 4. Add token_id to the recipient tokens - let recipient_tokens = self.storage().get_tokens(recipient); - let updated_recipient_tokens = recipient_tokens; - self.storage().set_tokens(recipient, updated_recipient_tokens); - } - - fn transfer_many_tokens(&mut self, sender: PublicKey, recipient: PublicKey, token_ids: Vec) { - todo!() + sender_tokens.retain(|x| x.clone() != token_id); + self.storage().set_tokens(sender, sender_tokens); + + // 4. Add token_id to the recipient tokens + let mut recipient_tokens = self.storage().get_tokens(recipient); + recipient_tokens.push(token_id); + self.storage().set_tokens(recipient, recipient_tokens); + } + + fn transfer_many_tokens( + &mut self, + sender: PublicKey, + recipient: PublicKey, + token_ids: Vec, + ) { + let mut sender_tokens = self.storage().get_tokens(sender); + for token_id in token_ids.iter() { + assert!(sender_tokens.contains(token_id), "wrong token {}", token_id); + sender_tokens.retain(|x| x.clone() != token_id.clone()); + } + let mut recipient_tokens = self.storage().get_tokens(recipient); + recipient_tokens.append(&mut token_ids.clone()); + self.storage().set_tokens(sender, sender_tokens); + self.storage().set_tokens(recipient, recipient_tokens); } + fn transfer_all_tokens(&mut self, sender: PublicKey, recipient: PublicKey) { - todo!() + let mut sender_tokens = self.storage().get_tokens(sender); + let mut recipient_tokens = self.storage().get_tokens(recipient); + recipient_tokens.append(&mut sender_tokens); + + self.storage().set_tokens(sender, sender_tokens); + self.storage().set_tokens(recipient, recipient_tokens); } - // URef releated function. + // URef releated function. fn detach(&mut self, owner: PublicKey, token_id: TokenId) -> URef { todo!(); } fn attach(&mut self, token_uref: URef, recipient: PublicKey) {} - fn token_id(&self, token_uref: URef) -> TokenId { todo!(); } + fn token_id(&self, token_uref: URef) -> TokenId { + todo!(); + } } trait CEP47Storage { - // Metadata. fn name(&self) -> String; fn symbol(&self) -> String; @@ -102,7 +126,7 @@ trait CEP47Storage { fn onwer_of(&self, token_id: TokenId) -> Option; fn total_supply(&self) -> U256; fn token_uri(&self, token_id: TokenId) -> Option; - + // Setters fn get_tokens(&self, owner: PublicKey) -> Vec; fn set_tokens(&mut self, owner: PublicKey, token_ids: Vec); @@ -114,20 +138,35 @@ trait CEP47Storage { #[cfg(test)] mod tests { - use std::collections::BTreeMap; - use super::{PublicKey, TokenId}; - use super::{WithStorage, CEP47Storage, CEP47Contract}; + use super::{CEP47Contract, CEP47Storage, WithStorage}; + use super::{PublicKey, TokenId, U256, URI}; + use std::{ + collections::{hash_map::DefaultHasher, BTreeMap}, + hash::{Hash, Hasher}, + }; struct TestStorage { name: String, - tokens: BTreeMap> + symbol: String, + uri: URI, + total_supply: U256, + tokens: BTreeMap>, + token_uris: BTreeMap, + balances: BTreeMap, + belongs_to: BTreeMap, } impl TestStorage { pub fn new() -> TestStorage { TestStorage { - name: String::from("asd"), - tokens: BTreeMap::new() + name: String::from("Casper Enhancement Proposal 47"), + symbol: String::from("CEP47"), + uri: URI::from("https://github.com/casper-ecosystem/casper-nft-cep47"), + total_supply: U256::from(0), + tokens: BTreeMap::new(), + balances: BTreeMap::new(), + belongs_to: BTreeMap::new(), + token_uris: BTreeMap::new(), } } } @@ -138,52 +177,103 @@ mod tests { } fn symbol(&self) -> String { - todo!() - } + self.symbol.clone() + } - fn uri(&self) -> super::URI { - todo!() - } + fn uri(&self) -> URI { + self.uri.clone() + } - fn balance_of(&self, owner: types::PublicKey) -> types::U256 { - todo!() - } + fn balance_of(&self, owner: PublicKey) -> U256 { + self.balances.get(&owner).unwrap().clone() + } - fn onwer_of(&self, token_id: super::TokenId) -> Option { - todo!() - } + fn onwer_of(&self, token_id: TokenId) -> Option { + let owner = self.belongs_to.get(&token_id); + if owner.is_some() { + Some(owner.unwrap().clone()) + } else { + None + } + } - fn total_supply(&self) -> types::U256 { - todo!() - } + fn total_supply(&self) -> U256 { + self.total_supply + } - fn token_uri(&self, token_id: super::TokenId) -> Option { - todo!() - } + fn token_uri(&self, token_id: TokenId) -> Option { + let uri = self.token_uris.get(&token_id); + if uri.is_some() { + Some(uri.unwrap().clone()) + } else { + None + } + } - fn get_tokens(&self, owner: types::PublicKey) -> Vec { - todo!() - } + fn get_tokens(&self, owner: PublicKey) -> Vec { + self.tokens.get(&owner).unwrap().clone() + } - fn set_tokens(&mut self, owner: types::PublicKey, token_ids: Vec) { - todo!() - } + fn set_tokens(&mut self, owner: PublicKey, token_ids: Vec) { + let owner_balance = self.balances.get(&owner); + let mut owner_new_balance = if owner_balance.is_none() { + U256::from(0) + } else { + owner_balance.unwrap().clone() + }; + + for token_id in token_ids.clone() { + let prev_owner = self.belongs_to.get(&token_id).unwrap().clone(); + let prev_owner_balance = self.balances.get(&prev_owner).unwrap().clone(); + self.balances.insert(prev_owner, prev_owner_balance - 1); + self.belongs_to.insert(token_id, owner); + owner_new_balance = owner_new_balance + 1; + self.balances.insert(owner, owner_new_balance); + } + } - fn mint_many(&mut self, recipient: types::PublicKey, token_uris: Vec) { - todo!() - } + fn mint_many(&mut self, recipient: PublicKey, token_uris: Vec) { + let recipient_balance = self.balances.get(&recipient); + let recipient_tokens = self.tokens.get(&recipient); + let mut recipient_new_balance = if recipient_balance.is_none() { + U256::from(0) + } else { + recipient_balance.unwrap().clone() + }; + let mut recipient_new_tokens = if recipient_tokens.is_none() { + Vec::::new() + } else { + recipient_tokens.unwrap().clone() + }; + + let mut hasher = DefaultHasher::new(); + + for token_uri in token_uris.clone() { + let token_info = (self.total_supply, self.uri.clone(), token_uri.clone()); + Hash::hash(&token_info, &mut hasher); + let token_id: TokenId = TokenId::from(hasher.finish().to_string()); + self.token_uris.insert(token_id.clone(), token_uri); + recipient_new_tokens.push(token_id.clone()); + self.belongs_to.insert(token_id, recipient); + recipient_new_balance = recipient_new_balance + 1; + self.total_supply = self.total_supply + 1; + } + self.balances.insert(recipient, recipient_new_balance); + self.tokens.insert(recipient, recipient_new_tokens); + } - fn mint_copies(&mut self, recipient: types::PublicKey, token_uri: super::URI, count: types::U256) { - todo!() - } + fn mint_copies(&mut self, recipient: PublicKey, token_uri: URI, count: U256) { + let token_uris: Vec = vec![token_uri; count.as_usize()]; + self.mint_many(recipient, token_uris); + } fn new_uref(&mut self, token_id: super::TokenId) -> types::URef { - todo!() - } + todo!() + } fn del_uref(&mut self, token_uref: types::URef) { - todo!() - } + todo!() + } } struct TestContract {} @@ -194,12 +284,19 @@ mod tests { } } - impl CEP47Contract for TestContract{} + impl CEP47Contract for TestContract {} #[test] - fn test_name() { + fn test_metadata() { let contract = TestContract {}; - assert_eq!(contract.name(), String::from("asd")) + assert_eq!( + contract.name(), + String::from("Casper Enhancement Proposal 47") + ); + assert_eq!(contract.symbol(), String::from("CEP47")); + assert_eq!( + contract.uri(), + String::from("https://github.com/casper-ecosystem/casper-nft-cep47") + ); } - -} \ No newline at end of file +} From ae04b620ee491fdd257655ba94a1ae05d9be5bf5 Mon Sep 17 00:00:00 2001 From: astro019 Date: Fri, 21 May 2021 20:04:40 +1000 Subject: [PATCH 07/98] added tests into logics --- cep47/src/logic.rs | 192 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 176 insertions(+), 16 deletions(-) diff --git a/cep47/src/logic.rs b/cep47/src/logic.rs index 168ae1a..19c4cb5 100644 --- a/cep47/src/logic.rs +++ b/cep47/src/logic.rs @@ -1,6 +1,6 @@ #![allow(dead_code)] #![allow(unused_imports)] -use types::{PublicKey, URef, U256}; +use types::{AsymmetricType, PublicKey, URef, U256}; type TokenId = String; type URI = String; @@ -138,8 +138,9 @@ trait CEP47Storage { #[cfg(test)] mod tests { - use super::{CEP47Contract, CEP47Storage, WithStorage}; - use super::{PublicKey, TokenId, U256, URI}; + use super::{ + AsymmetricType, CEP47Contract, CEP47Storage, PublicKey, TokenId, WithStorage, U256, URI, + }; use std::{ collections::{hash_map::DefaultHasher, BTreeMap}, hash::{Hash, Hasher}, @@ -185,7 +186,12 @@ mod tests { } fn balance_of(&self, owner: PublicKey) -> U256 { - self.balances.get(&owner).unwrap().clone() + let owner_balance = self.balances.get(&owner); + if owner_balance.is_none() { + U256::from(0) + } else { + owner_balance.unwrap().clone() + } } fn onwer_of(&self, token_id: TokenId) -> Option { @@ -211,25 +217,29 @@ mod tests { } fn get_tokens(&self, owner: PublicKey) -> Vec { - self.tokens.get(&owner).unwrap().clone() + let owner_tokens = self.tokens.get(&owner); + if owner_tokens.is_none() { + Vec::::new() + } else { + owner_tokens.unwrap().clone() + } } fn set_tokens(&mut self, owner: PublicKey, token_ids: Vec) { - let owner_balance = self.balances.get(&owner); - let mut owner_new_balance = if owner_balance.is_none() { - U256::from(0) - } else { - owner_balance.unwrap().clone() - }; + let owner_prev_balance = self.balance_of(owner); + let owner_new_balance = U256::from(token_ids.len() as u64); + let owner_tokens = self.get_tokens(owner); + for token_id in owner_tokens.clone() { + self.belongs_to.remove(&token_id); + } for token_id in token_ids.clone() { - let prev_owner = self.belongs_to.get(&token_id).unwrap().clone(); - let prev_owner_balance = self.balances.get(&prev_owner).unwrap().clone(); - self.balances.insert(prev_owner, prev_owner_balance - 1); self.belongs_to.insert(token_id, owner); - owner_new_balance = owner_new_balance + 1; - self.balances.insert(owner, owner_new_balance); } + + self.tokens.insert(owner, token_ids.clone()); + self.balances.insert(owner, owner_new_balance); + self.total_supply = self.total_supply - owner_prev_balance + owner_new_balance; } fn mint_many(&mut self, recipient: PublicKey, token_uris: Vec) { @@ -299,4 +309,154 @@ mod tests { String::from("https://github.com/casper-ecosystem/casper-nft-cep47") ); } + #[test] + fn test_mint_many() { + let mut contract = TestContract {}; + let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); + + assert_eq!(contract.total_supply(), U256::from(0)); + contract.mint_many(ali, vec![URI::from("Apple URI")]); + contract.mint_many(bob, vec![URI::from("Banana URI"), URI::from("Orange URI")]); + assert_eq!(contract.total_supply(), U256::from(3)); + + let ali_balance = contract.balance_of(ali); + assert_eq!(ali_balance, U256::from(1)); + let bob_balance = contract.balance_of(bob); + assert_eq!(bob_balance, U256::from(2)); + + let ali_tokens: Vec = contract.tokens(ali); + let ali_first_token_uri: URI = contract + .token_uri(ali_tokens.get(0).unwrap().clone()) + .unwrap(); + assert_eq!(ali_first_token_uri, URI::from("Apple URI")); + + let bob_tokens: Vec = contract.tokens(bob); + let bob_first_token_uri: URI = contract + .token_uri(bob_tokens.get(1).unwrap().clone()) + .unwrap(); + assert_eq!(bob_first_token_uri, URI::from("Orange URI")); + } + #[test] + fn test_mint_copies() { + let mut contract = TestContract {}; + let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + + assert_eq!(contract.total_supply(), U256::from(0)); + contract.mint_copies(ali, URI::from("Casper Fan URI"), U256::from(7)); + assert_eq!(contract.total_supply(), U256::from(7)); + + let ali_balance = contract.balance_of(ali); + assert_eq!(ali_balance, U256::from(7)); + + let ali_tokens: Vec = contract.tokens(ali); + let ali_first_token_uri: URI = contract + .token_uri(ali_tokens.get(0).unwrap().clone()) + .unwrap(); + let ali_third_token_uri: URI = contract + .token_uri(ali_tokens.get(2).unwrap().clone()) + .unwrap(); + assert_eq!(ali_first_token_uri, URI::from("Casper Fan URI")); + assert_eq!(ali_third_token_uri, URI::from("Casper Fan URI")); + } + #[test] + fn test_transfer_token() { + let mut contract = TestContract {}; + let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); + + assert_eq!(contract.total_supply(), U256::from(0)); + contract.mint_one(ali, URI::from("Casper Fan URI")); + assert_eq!(contract.total_supply(), U256::from(1)); + + let mut ali_balance = contract.balance_of(ali); + let mut bob_balance = contract.balance_of(bob); + assert_eq!(ali_balance, U256::from(1)); + assert_eq!(bob_balance, U256::from(0)); + + let ali_tokens: Vec = contract.tokens(ali); + let ali_first_token_id: TokenId = ali_tokens.get(0).unwrap().clone(); + let ali_first_token_uri: URI = contract.token_uri(ali_first_token_id.clone()).unwrap(); + assert_eq!(ali_first_token_uri, URI::from("Casper Fan URI")); + + contract.transfer_token(ali, bob, ali_first_token_id.clone()); + ali_balance = contract.balance_of(ali); + bob_balance = contract.balance_of(bob); + assert_eq!(ali_balance, U256::from(0)); + assert_eq!(bob_balance, U256::from(1)); + + let owner_of_first_token_id = contract.owner_of(ali_first_token_id); + assert_eq!(owner_of_first_token_id.unwrap(), bob); + } + #[test] + fn test_transfer_all_tokens() { + let mut contract = TestContract {}; + let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); + + assert_eq!(contract.total_supply(), U256::from(0)); + contract.mint_many(ali, vec![URI::from("Apple URI"), URI::from("Banana URI")]); + contract.mint_one(ali, URI::from("Casper Fan URI")); + assert_eq!(contract.total_supply(), U256::from(3)); + + let mut ali_balance = contract.balance_of(ali); + let mut bob_balance = contract.balance_of(bob); + assert_eq!(ali_balance, U256::from(3)); + assert_eq!(bob_balance, U256::from(0)); + + let ali_tokens: Vec = contract.tokens(ali); + let ali_second_token_id: TokenId = ali_tokens.get(1).unwrap().clone(); + let ali_second_token_uri: URI = contract.token_uri(ali_second_token_id.clone()).unwrap(); + assert_eq!(ali_second_token_uri, URI::from("Banana URI")); + + contract.transfer_all_tokens(ali, bob); + + ali_balance = contract.balance_of(ali); + bob_balance = contract.balance_of(bob); + assert_eq!(ali_balance, U256::from(0)); + assert_eq!(bob_balance, U256::from(3)); + + let owner_of_second_token_id = contract.owner_of(ali_second_token_id); + assert_eq!(owner_of_second_token_id.unwrap(), bob); + } + #[test] + fn test_transfer_many_tokens() { + let mut contract = TestContract {}; + let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); + + assert_eq!(contract.total_supply(), U256::from(0)); + contract.mint_many(ali, vec![URI::from("Apple URI"), URI::from("Banana URI")]); + contract.mint_copies(ali, URI::from("Casper Fan URI"), U256::from(3)); + assert_eq!(contract.total_supply(), U256::from(5)); + + let mut ali_balance = contract.balance_of(ali); + let mut bob_balance = contract.balance_of(bob); + assert_eq!(ali_balance, U256::from(5)); + assert_eq!(bob_balance, U256::from(0)); + + let ali_tokens: Vec = contract.tokens(ali); + let ali_second_token_id: TokenId = ali_tokens.get(1).unwrap().clone(); + let ali_second_token_uri: URI = contract.token_uri(ali_second_token_id.clone()).unwrap(); + let ali_third_token_id: TokenId = ali_tokens.get(2).unwrap().clone(); + let ali_third_token_uri: URI = contract.token_uri(ali_third_token_id.clone()).unwrap(); + assert_eq!(ali_second_token_uri, URI::from("Banana URI")); + assert_eq!(ali_third_token_uri, URI::from("Casper Fan URI")); + + contract.transfer_many_tokens( + ali, + bob, + vec![ali_second_token_id.clone(), ali_third_token_id.clone()], + ); + + ali_balance = contract.balance_of(ali); + bob_balance = contract.balance_of(bob); + assert_eq!(ali_balance, U256::from(3)); + assert_eq!(bob_balance, U256::from(2)); + + let owner_of_second_token_id = contract.owner_of(ali_second_token_id); + let owner_of_third_token_id = contract.owner_of(ali_third_token_id); + assert_eq!(owner_of_second_token_id.unwrap(), bob); + assert_eq!(owner_of_third_token_id.unwrap(), bob); + } } From a3d84cb23fba0a4553247d4e277d62bb1f856985 Mon Sep 17 00:00:00 2001 From: Maciej Zielinski Date: Fri, 21 May 2021 15:56:36 +0200 Subject: [PATCH 08/98] Update storage --- cep47/src/logic.rs | 58 ++++++++++++++++++++++++++++------------------ tests/Cargo.toml | 2 ++ 2 files changed, 37 insertions(+), 23 deletions(-) diff --git a/cep47/src/logic.rs b/cep47/src/logic.rs index 19c4cb5..030b519 100644 --- a/cep47/src/logic.rs +++ b/cep47/src/logic.rs @@ -6,7 +6,8 @@ type TokenId = String; type URI = String; trait WithStorage { - fn storage(&self) -> Storage; + fn storage(&self) -> &Storage; + fn storage_mut(&mut self) -> &mut Storage; } trait CEP47Contract: WithStorage { @@ -47,16 +48,16 @@ trait CEP47Contract: WithStorage { // Minter function. // Guarded by the entrypoint group. fn mint_one(&mut self, recipient: PublicKey, token_uri: URI) { - self.storage() + self.storage_mut() .mint_copies(recipient, token_uri, U256::one()); } fn mint_many(&mut self, recipient: PublicKey, token_uris: Vec) { - self.storage().mint_many(recipient, token_uris); + self.storage_mut().mint_many(recipient, token_uris); } fn mint_copies(&mut self, recipient: PublicKey, token_uri: URI, count: U256) { - self.storage().mint_copies(recipient, token_uri, count); + self.storage_mut().mint_copies(recipient, token_uri, count); } // Transfer functions. @@ -71,12 +72,12 @@ trait CEP47Contract: WithStorage { ); // 3. Remove token_id from sender_tokens. sender_tokens.retain(|x| x.clone() != token_id); - self.storage().set_tokens(sender, sender_tokens); + self.storage_mut().set_tokens(sender, sender_tokens); // 4. Add token_id to the recipient tokens let mut recipient_tokens = self.storage().get_tokens(recipient); recipient_tokens.push(token_id); - self.storage().set_tokens(recipient, recipient_tokens); + self.storage_mut().set_tokens(recipient, recipient_tokens); } fn transfer_many_tokens( @@ -92,8 +93,8 @@ trait CEP47Contract: WithStorage { } let mut recipient_tokens = self.storage().get_tokens(recipient); recipient_tokens.append(&mut token_ids.clone()); - self.storage().set_tokens(sender, sender_tokens); - self.storage().set_tokens(recipient, recipient_tokens); + self.storage_mut().set_tokens(sender, sender_tokens); + self.storage_mut().set_tokens(recipient, recipient_tokens); } fn transfer_all_tokens(&mut self, sender: PublicKey, recipient: PublicKey) { @@ -101,8 +102,8 @@ trait CEP47Contract: WithStorage { let mut recipient_tokens = self.storage().get_tokens(recipient); recipient_tokens.append(&mut sender_tokens); - self.storage().set_tokens(sender, sender_tokens); - self.storage().set_tokens(recipient, recipient_tokens); + self.storage_mut().set_tokens(sender, sender_tokens); + self.storage_mut().set_tokens(recipient, recipient_tokens); } // URef releated function. @@ -141,10 +142,7 @@ mod tests { use super::{ AsymmetricType, CEP47Contract, CEP47Storage, PublicKey, TokenId, WithStorage, U256, URI, }; - use std::{ - collections::{hash_map::DefaultHasher, BTreeMap}, - hash::{Hash, Hasher}, - }; + use std::{collections::{hash_map::DefaultHasher, BTreeMap}, hash::{Hash, Hasher}, sync::Mutex}; struct TestStorage { name: String, @@ -286,11 +284,25 @@ mod tests { } } - struct TestContract {} + struct TestContract { + storage: TestStorage + } + + impl TestContract { + pub fn new() -> TestContract { + TestContract { + storage: TestStorage::new() + } + } + } impl WithStorage for TestContract { - fn storage(&self) -> TestStorage { - TestStorage::new() + fn storage(&self) -> &TestStorage { + &self.storage + } + + fn storage_mut(&mut self) -> &mut TestStorage { + &mut self.storage } } @@ -298,7 +310,7 @@ mod tests { #[test] fn test_metadata() { - let contract = TestContract {}; + let contract = TestContract::new(); assert_eq!( contract.name(), String::from("Casper Enhancement Proposal 47") @@ -311,7 +323,7 @@ mod tests { } #[test] fn test_mint_many() { - let mut contract = TestContract {}; + let mut contract = TestContract::new(); let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); @@ -339,7 +351,7 @@ mod tests { } #[test] fn test_mint_copies() { - let mut contract = TestContract {}; + let mut contract = TestContract::new(); let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); assert_eq!(contract.total_supply(), U256::from(0)); @@ -361,7 +373,7 @@ mod tests { } #[test] fn test_transfer_token() { - let mut contract = TestContract {}; + let mut contract = TestContract::new(); let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); @@ -390,7 +402,7 @@ mod tests { } #[test] fn test_transfer_all_tokens() { - let mut contract = TestContract {}; + let mut contract = TestContract::new(); let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); @@ -421,7 +433,7 @@ mod tests { } #[test] fn test_transfer_many_tokens() { - let mut contract = TestContract {}; + let mut contract = TestContract::new(); let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); diff --git a/tests/Cargo.toml b/tests/Cargo.toml index 07bf930..54c675b 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -10,6 +10,8 @@ edition = "2018" casper-contract = "1.1.1" casper-types = "1.1.1" casper-engine-test-support = "1.1.1" +lazy_static = "1.4.0" + [features] default = ["casper-contract/std", "casper-types/std", "casper-contract/test-support"] From 574eb7b5ad17928e4f7555e3df722878a2adc8a5 Mon Sep 17 00:00:00 2001 From: astro019 Date: Mon, 24 May 2021 22:14:23 +1000 Subject: [PATCH 09/98] updated caspercep47 to interact with runtime storage --- cep47/src/main.rs | 510 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 435 insertions(+), 75 deletions(-) diff --git a/cep47/src/main.rs b/cep47/src/main.rs index a955da4..d459fcd 100644 --- a/cep47/src/main.rs +++ b/cep47/src/main.rs @@ -21,87 +21,451 @@ use std::{ use types::{ account::AccountHash, bytesrepr::{FromBytes, ToBytes}, - ApiError, AsymmetricType, CLTyped, CLValue, PublicKey, URef, U256, + contracts::NamedKeys, + ApiError, AsymmetricType, CLType, CLTyped, CLValue, EntryPoint, EntryPointAccess, + EntryPointType, EntryPoints, Parameter, PublicKey, URef, U256, }; +type TokenId = String; +type URI = String; + +trait WithStorage { + fn storage(&self) -> &Storage; + fn storage_mut(&mut self) -> &mut Storage; +} + +trait CEP47Contract: WithStorage { + // Metadata + fn name(&self) -> String { + self.storage().name() + } + + fn symbol(&self) -> String { + self.storage().symbol() + } + + fn uri(&self) -> URI { + self.storage().uri() + } + + // Getters + fn balance_of(&self, owner: PublicKey) -> U256 { + self.storage().balance_of(owner) + } + + fn owner_of(&self, token_id: TokenId) -> Option { + self.storage().onwer_of(token_id) + } + + fn total_supply(&self) -> U256 { + self.storage().total_supply() + } + + fn token_uri(&self, token_id: TokenId) -> Option { + self.storage().token_uri(token_id) + } + + fn tokens(&self, owner: PublicKey) -> Vec { + self.storage().get_tokens(owner) + } + + // Minter function. + // Guarded by the entrypoint group. + fn mint_one(&mut self, recipient: PublicKey, token_uri: URI) { + self.storage_mut() + .mint_copies(recipient, token_uri, U256::one()); + } + + fn mint_many(&mut self, recipient: PublicKey, token_uris: Vec) { + self.storage_mut().mint_many(recipient, token_uris); + } + + fn mint_copies(&mut self, recipient: PublicKey, token_uri: URI, count: U256) { + self.storage_mut().mint_copies(recipient, token_uri, count); + } + + // Transfer functions. + fn transfer_token(&mut self, sender: PublicKey, recipient: PublicKey, token_id: TokenId) { + // 1. Load tokens owned by the sender. + let mut sender_tokens = self.storage().get_tokens(sender); + // 2. Assert that token_id is in sender_tokens. + assert!( + sender_tokens.contains(&token_id), + "wrong owner of token {}", + token_id + ); + // 3. Remove token_id from sender_tokens. + sender_tokens.retain(|x| x.clone() != token_id); + self.storage_mut().set_tokens(sender, sender_tokens); + + // 4. Add token_id to the recipient tokens + let mut recipient_tokens = self.storage().get_tokens(recipient); + recipient_tokens.push(token_id); + self.storage_mut().set_tokens(recipient, recipient_tokens); + } + + fn transfer_many_tokens( + &mut self, + sender: PublicKey, + recipient: PublicKey, + token_ids: Vec, + ) { + let mut sender_tokens = self.storage().get_tokens(sender); + for token_id in token_ids.iter() { + assert!(sender_tokens.contains(token_id), "wrong token {}", token_id); + sender_tokens.retain(|x| x.clone() != token_id.clone()); + } + let mut recipient_tokens = self.storage().get_tokens(recipient); + recipient_tokens.append(&mut token_ids.clone()); + self.storage_mut().set_tokens(sender, sender_tokens); + self.storage_mut().set_tokens(recipient, recipient_tokens); + } + + fn transfer_all_tokens(&mut self, sender: PublicKey, recipient: PublicKey) { + let mut sender_tokens = self.storage().get_tokens(sender); + let mut recipient_tokens = self.storage().get_tokens(recipient); + recipient_tokens.append(&mut sender_tokens); + + self.storage_mut().set_tokens(sender, sender_tokens); + self.storage_mut().set_tokens(recipient, recipient_tokens); + } + + // URef releated function. + fn detach(&mut self, owner: PublicKey, token_id: TokenId) -> URef { + todo!(); + } + fn attach(&mut self, token_uref: URef, recipient: PublicKey) {} + fn token_id(&self, token_uref: URef) -> TokenId { + todo!(); + } +} + +trait CEP47Storage { + // Metadata. + fn name(&self) -> String { + get_key::("name").unwrap() + } + fn symbol(&self) -> String { + get_key::("symbol").unwrap() + } + fn uri(&self) -> URI { + get_key::("uri").unwrap() + } + + // Getters + fn balance_of(&self, owner: PublicKey) -> U256 { + let owner_balance = get_key::(&balance_key(&owner.to_account_hash())); + if owner_balance.is_none() { + U256::from(0) + } else { + owner_balance.unwrap() + } + } + fn onwer_of(&self, token_id: TokenId) -> Option { + get_key::(&owner_key(&token_id)) + } + fn total_supply(&self) -> U256 { + get_key::("total_supply").unwrap() + } + fn token_uri(&self, token_id: TokenId) -> Option { + get_key::(&uri_key(&token_id)) + } + + // Setters + fn get_tokens(&self, owner: PublicKey) -> Vec { + let owner_tokens = get_key::>(&token_key(&owner.to_account_hash())); + if owner_tokens.is_none() { + Vec::::new() + } else { + owner_tokens.unwrap() + } + } + fn set_tokens(&mut self, owner: PublicKey, token_ids: Vec) { + let owner_prev_balance = self.balance_of(owner); + let owner_new_balance = U256::from(token_ids.len() as u64); + let prev_total_supply = self.total_supply(); + + let owner_tokens = self.get_tokens(owner); + for token_id in owner_tokens.clone() { + remove_key(&owner_key(&token_id)); + } + for token_id in token_ids.clone() { + set_key(&owner_key(&token_id), owner); + } + set_key(&token_key(&owner.to_account_hash()), token_ids); + set_key(&balance_key(&owner.to_account_hash()), owner_new_balance); + set_key( + "total_supply", + prev_total_supply - owner_prev_balance + owner_new_balance, + ); + } + fn mint_many(&mut self, recipient: PublicKey, token_uris: Vec) { + let mut recipient_tokens = self.get_tokens(recipient); + let mut recipient_balance = self.balance_of(recipient); + let mut total_supply = self.total_supply(); + let uri = self.uri(); + + let mut hasher = DefaultHasher::new(); + for token_uri in token_uris.clone() { + let token_info = (total_supply, uri.clone(), token_uri.clone()); + Hash::hash(&token_info, &mut hasher); + + let token_id = TokenId::from(hasher.finish().to_string()); + recipient_tokens.push(token_id.clone()); + total_supply = total_supply + 1; + set_key(&uri_key(&token_id), token_uri); + set_key(&owner_key(&token_id), recipient); + } + set_key( + &balance_key(&recipient.to_account_hash()), + recipient_balance, + ); + set_key(&token_key(&recipient.to_account_hash()), recipient_tokens); + } + fn mint_copies(&mut self, recipient: PublicKey, token_uri: URI, count: U256) { + let token_uris: Vec = vec![token_uri; count.as_usize()]; + self.mint_many(recipient, token_uris); + } + // fn new_uref(&mut self, token_id: TokenId) -> URef; + // fn del_uref(&mut self, token_uref: URef); +} + +struct CasperCEP47Storage {} +impl CasperCEP47Storage { + pub fn new() -> CasperCEP47Storage { + CasperCEP47Storage {} + } +} +impl CEP47Storage for CasperCEP47Storage {} +struct CasperCEP47Contract { + storage: CasperCEP47Storage, +} +impl CasperCEP47Contract { + pub fn new() -> CasperCEP47Contract { + CasperCEP47Contract { + storage: CasperCEP47Storage::new(), + } + } +} +impl WithStorage for CasperCEP47Contract { + fn storage(&self) -> &CasperCEP47Storage { + &self.storage + } + fn storage_mut(&mut self) -> &mut CasperCEP47Storage { + &mut self.storage + } +} +impl CEP47Contract for CasperCEP47Contract {} /** * ApiError::User(1) - The number of piece is out or range. * ApiError::User(2) - The piece of NFT is already minted and owned by someone. * ApiError::User(3) - The piece of NFT is not minted yet. */ -#[derive(Hash)] -pub struct TokenId { - seed: URef, - piece_number: u64, +#[no_mangle] +pub extern "C" fn name() { + let contract = CasperCEP47Contract::new(); + ret(contract.name()) } #[no_mangle] -pub extern "C" fn name() { - let val: String = get_key("name").unwrap(); - ret(val) +pub extern "C" fn symbol() { + let contract = CasperCEP47Contract::new(); + ret(contract.symbol()) } #[no_mangle] -pub extern "C" fn ipfs_hash() { - let val: String = get_key("ipfs_hash").unwrap(); - ret(val) +pub extern "C" fn uri() { + let contract = CasperCEP47Contract::new(); + ret(contract.uri()) } #[no_mangle] pub extern "C" fn balance_of() { let account: PublicKey = runtime::get_named_arg("account"); - let val: U256 = get_key(&balance_key(&account.to_account_hash())).unwrap(); - ret(val) + let contract = CasperCEP47Contract::new(); + ret(contract.balance_of(account)) } #[no_mangle] -pub extern "C" fn transfer() { - let sender: PublicKey = runtime::get_named_arg("sender"); +pub extern "C" fn owner_of() { + let token_id: TokenId = runtime::get_named_arg("token_id"); + let contract = CasperCEP47Contract::new(); + ret(contract.owner_of(token_id)) +} + +#[no_mangle] +pub extern "C" fn total_supply() { + let contract = CasperCEP47Contract::new(); + ret(contract.total_supply()) +} + +#[no_mangle] +pub extern "C" fn token_uri() { + let token_id: TokenId = runtime::get_named_arg("token_id"); + let contract = CasperCEP47Contract::new(); + ret(contract.token_uri(token_id)) +} + +#[no_mangle] +pub extern "C" fn tokens() { + let owner: PublicKey = runtime::get_named_arg("owner"); + let contract = CasperCEP47Contract::new(); + ret(contract.tokens(owner)) +} + +#[no_mangle] +pub extern "C" fn mint_one() { let recipient: PublicKey = runtime::get_named_arg("recipient"); - let piece_number: u64 = runtime::get_named_arg("piece_number"); - if sender.to_account_hash() != runtime::get_caller() { - runtime::revert(ApiError::PermissionDenied); - } - let owner = owner_of(piece_number); - if owner.is_none() { - runtime::revert(ApiError::User(3)); - } - if sender != owner.unwrap() { - runtime::revert(ApiError::PermissionDenied); - } - set_key(&token_key(piece_number), Some(recipient)); + let token_uri: URI = runtime::get_named_arg("token_uri"); + let mut contract = CasperCEP47Contract::new(); + contract.mint_one(recipient, token_uri); +} - let sender_key: String = get_key(&balance_key(&sender.to_account_hash())).unwrap(); - let recipient_key: String = get_key(&balance_key(&recipient.to_account_hash())).unwrap(); - let new_sender_balance: U256 = get_key::(&sender_key).unwrap() - 1; - set_key(&sender_key, new_sender_balance); - let new_recipient_balance: U256 = get_key::(&recipient_key).unwrap() + 1; - set_key(&recipient_key, new_recipient_balance); +#[no_mangle] +pub extern "C" fn mint_many() { + let recipient: PublicKey = runtime::get_named_arg("recipient"); + let token_uris: Vec = runtime::get_named_arg("token_uris"); + let mut contract = CasperCEP47Contract::new(); + contract.mint_many(recipient, token_uris); } #[no_mangle] -pub extern "C" fn mint() { +pub extern "C" fn mint_copies() { let recipient: PublicKey = runtime::get_named_arg("recipient"); - let piece_number: u64 = runtime::get_named_arg("piece_number"); - let minter: PublicKey = minter(); - if minter.to_account_hash() != runtime::get_caller() { - runtime::revert(ApiError::PermissionDenied); - } - let owner = owner_of(piece_number); - if owner.is_some() { - runtime::revert(ApiError::User(2)); - } + let token_uri: URI = runtime::get_named_arg("token_uri"); + let count: U256 = runtime::get_named_arg("count"); + let mut contract = CasperCEP47Contract::new(); + contract.mint_copies(recipient, token_uri, count); +} - set_key(&token_key(piece_number), Some(recipient)); +#[no_mangle] +pub extern "C" fn transfer_token() { + let sender: PublicKey = runtime::get_named_arg("sender"); + let recipient: PublicKey = runtime::get_named_arg("recipient"); + let token_id: TokenId = runtime::get_named_arg("token_id"); + let mut contract = CasperCEP47Contract::new(); + contract.transfer_token(sender, recipient, token_id); +} - let recipient_key = balance_key(&recipient.to_account_hash()); - let recipient_balance = get_key::(&recipient_key).unwrap(); - set_key(&recipient_key, recipient_balance + 1); +#[no_mangle] +pub extern "C" fn transfer_many_tokens() { + let sender: PublicKey = runtime::get_named_arg("sender"); + let recipient: PublicKey = runtime::get_named_arg("recipient"); + let token_ids: Vec = runtime::get_named_arg("token_ids"); + let mut contract = CasperCEP47Contract::new(); + contract.transfer_many_tokens(sender, recipient, token_ids); +} + +#[no_mangle] +pub extern "C" fn transfer_all_tokens() { + let sender: PublicKey = runtime::get_named_arg("sender"); + let recipient: PublicKey = runtime::get_named_arg("recipient"); + let mut contract = CasperCEP47Contract::new(); + contract.transfer_all_tokens(sender, recipient); } #[no_mangle] -pub extern "C" fn call() {} +pub extern "C" fn call() { + let tokenName: String = runtime::get_named_arg("token_name"); + let tokenSymbol: String = runtime::get_named_arg("token_symbol"); + let tokenURI: URI = runtime::get_named_arg("token_uri"); + + let mut entry_points = EntryPoints::new(); + entry_points.add_entry_point(endpoint("name", vec![], CLType::String)); + entry_points.add_entry_point(endpoint("symbol", vec![], CLType::String)); + entry_points.add_entry_point(endpoint("uri", vec![], CLType::String)); + entry_points.add_entry_point(endpoint("total_supply", vec![], CLType::U256)); + entry_points.add_entry_point(endpoint( + "balance_of", + vec![Parameter::new("account", CLType::PublicKey)], + CLType::U256, + )); + entry_points.add_entry_point(endpoint( + "owner_of", + vec![Parameter::new("token_id", CLType::String)], + CLType::Option(Box::new(CLType::PublicKey)), + )); + entry_points.add_entry_point(endpoint( + "token_uri", + vec![Parameter::new("token_id", CLType::String)], + CLType::Option(Box::new(CLType::String)), + )); + entry_points.add_entry_point(endpoint( + "tokens", + vec![Parameter::new("owner", CLType::PublicKey)], + CLType::List(Box::new(CLType::String)), + )); + entry_points.add_entry_point(endpoint( + "tokens", + vec![Parameter::new("owner", CLType::PublicKey)], + CLType::List(Box::new(CLType::String)), + )); + entry_points.add_entry_point(endpoint( + "mint_one", + vec![ + Parameter::new("recipient", CLType::PublicKey), + Parameter::new("token_uri", CLType::String), + ], + CLType::Unit, + )); + entry_points.add_entry_point(endpoint( + "mint_many", + vec![ + Parameter::new("recipient", CLType::PublicKey), + Parameter::new("token_uris", CLType::List(Box::new(CLType::String))), + ], + CLType::Unit, + )); + entry_points.add_entry_point(endpoint( + "mint_copies", + vec![ + Parameter::new("recipient", CLType::PublicKey), + Parameter::new("token_uri", CLType::String), + Parameter::new("count", CLType::U256), + ], + CLType::Unit, + )); + entry_points.add_entry_point(endpoint( + "transfer_token", + vec![ + Parameter::new("sender", CLType::PublicKey), + Parameter::new("recipient", CLType::PublicKey), + Parameter::new("token_id", CLType::String), + ], + CLType::Unit, + )); + entry_points.add_entry_point(endpoint( + "transfer_many_tokens", + vec![ + Parameter::new("sender", CLType::PublicKey), + Parameter::new("recipient", CLType::PublicKey), + Parameter::new("token_ids", CLType::List(Box::new(CLType::String))), + ], + CLType::Unit, + )); + entry_points.add_entry_point(endpoint( + "transfer_all_tokens", + vec![ + Parameter::new("sender", CLType::PublicKey), + Parameter::new("recipient", CLType::PublicKey), + ], + CLType::Unit, + )); + + let mut named_keys = NamedKeys::new(); + named_keys.insert("name".to_string(), storage::new_uref(tokenName).into()); + named_keys.insert("symbol".to_string(), storage::new_uref(tokenSymbol).into()); + named_keys.insert("uri".to_string(), storage::new_uref(tokenURI).into()); + named_keys.insert("total_supply".to_string(), storage::new_uref(0u8).into()); + + let (contract_package_hash, _) = storage::create_contract_package_at_hash(); + let (contract_hash, _) = + storage::add_contract_version(contract_package_hash, entry_points, named_keys); + runtime::put_key("caspercep47_contract", contract_hash.into()); + let contract_hash_pack = storage::new_uref(contract_hash); + runtime::put_key("caspercep47_contract_hash", contract_hash_pack.into()); +} fn ret(value: T) { runtime::ret(CLValue::from_t(value).unwrap_or_revert()) @@ -131,41 +495,37 @@ fn set_key(name: &str, value: T) { } } -fn seed() -> URef { - get_key::("seed").unwrap() -} - -fn minter() -> PublicKey { - get_key::("minter").unwrap() +fn remove_key(name: &str) { + match runtime::get_key(name) { + Some(key) => { + runtime::remove_key(name); + } + None => {} + } } -fn number_of_pieces() -> u64 { - get_key::("number_of_pieces").unwrap() +fn balance_key(account: &AccountHash) -> String { + format!("balances_{}", account) } -fn owner_of(piece_number: u64) -> Option { - let token_id = to_token_id(piece_number); - get_key::(&token_key(token_id)) +fn owner_key(token_id: &TokenId) -> String { + format!("owners_{}", token_id) } -fn balance_key(account: &AccountHash) -> String { - format!("balances_{}", account) +fn uri_key(token_id: &TokenId) -> String { + format!("uris_{}", token_id) } -fn token_key(token_id: u64) -> String { - format!("tokens_{}", to_token_id(token_id)) +fn token_key(account: &AccountHash) -> String { + format!("tokens_{}", account) } -fn to_token_id(piece_number: u64) -> u64 { - let total_pieces: u64 = number_of_pieces(); - if piece_number > total_pieces || piece_number == 0 { - runtime::revert(ApiError::User(1)); - } - let mut hasher = DefaultHasher::new(); - let token_id = TokenId { - seed: seed(), - piece_number, - }; - Hash::hash(&token_id, &mut hasher); - hasher.finish() +fn endpoint(name: &str, param: Vec, ret: CLType) -> EntryPoint { + EntryPoint::new( + String::from(name), + param, + ret, + EntryPointAccess::Public, + EntryPointType::Contract, + ) } From 8bf7b7a03eff316e621dcde982387d0d612d59d5 Mon Sep 17 00:00:00 2001 From: Maciej Zielinski Date: Tue, 25 May 2021 16:26:34 +0200 Subject: [PATCH 10/98] attach, detach wip --- cep47/Cargo.toml | 3 ++ cep47/src/logic.rs | 91 ++++++++++++++++++++++++++++++++++++++++------ tests/Cargo.toml | 2 - 3 files changed, 82 insertions(+), 14 deletions(-) diff --git a/cep47/Cargo.toml b/cep47/Cargo.toml index 2154079..3be30b9 100644 --- a/cep47/Cargo.toml +++ b/cep47/Cargo.toml @@ -8,6 +8,9 @@ edition = "2018" contract = { package = "casper-contract", version="1.1.1" } types = { package = "casper-types", version="1.1.1" } +[dev-dependencies] +rand = "0.8.3" + [[bin]] name = "cep47" path = "src/main.rs" diff --git a/cep47/src/logic.rs b/cep47/src/logic.rs index 030b519..4dc4996 100644 --- a/cep47/src/logic.rs +++ b/cep47/src/logic.rs @@ -107,12 +107,26 @@ trait CEP47Contract: WithStorage { } // URef releated function. - fn detach(&mut self, owner: PublicKey, token_id: TokenId) -> URef { - todo!(); + fn detach(&mut self, owner: PublicKey, token_id: TokenId) -> Option { + let mut tokens = self.storage().get_tokens(owner); + if !tokens.contains(&token_id) { + None + } else { + tokens.retain(|x| x != &token_id); + self.storage_mut().set_tokens(owner, tokens); + self.storage_mut().new_uref(token_id) + } + } + + fn attach(&mut self, token_uref: URef, recipient: PublicKey) { + let token_id = self.storage_mut().del_uref(token_uref).unwrap(); + // load tokens of recipient + // add token to list + // save tokens } - fn attach(&mut self, token_uref: URef, recipient: PublicKey) {} + fn token_id(&self, token_uref: URef) -> TokenId { - todo!(); + self.storage().token_id(token_uref).unwrap() } } @@ -133,16 +147,21 @@ trait CEP47Storage { fn set_tokens(&mut self, owner: PublicKey, token_ids: Vec); fn mint_many(&mut self, recipient: PublicKey, token_uris: Vec); fn mint_copies(&mut self, recipient: PublicKey, token_uri: URI, count: U256); - fn new_uref(&mut self, token_id: TokenId) -> URef; - fn del_uref(&mut self, token_uref: URef); + + fn new_uref(&mut self, token_id: TokenId) -> Option; + fn del_uref(&mut self, token_uref: URef) -> Option; + fn token_id(&self, token_uref: URef) -> Option; } #[cfg(test)] mod tests { + use rand::Rng; + use types::AccessRights; + use super::{ - AsymmetricType, CEP47Contract, CEP47Storage, PublicKey, TokenId, WithStorage, U256, URI, + AsymmetricType, CEP47Contract, CEP47Storage, PublicKey, TokenId, WithStorage, U256, URI, URef }; - use std::{collections::{hash_map::DefaultHasher, BTreeMap}, hash::{Hash, Hasher}, sync::Mutex}; + use std::{collections::{BTreeMap, hash_map::DefaultHasher}, hash::{Hash, Hasher}, sync::Mutex}; struct TestStorage { name: String, @@ -153,6 +172,7 @@ mod tests { token_uris: BTreeMap, balances: BTreeMap, belongs_to: BTreeMap, + urefs: BTreeMap, } impl TestStorage { @@ -166,6 +186,7 @@ mod tests { balances: BTreeMap::new(), belongs_to: BTreeMap::new(), token_uris: BTreeMap::new(), + urefs: BTreeMap::new() } } } @@ -275,12 +296,34 @@ mod tests { self.mint_many(recipient, token_uris); } - fn new_uref(&mut self, token_id: super::TokenId) -> types::URef { - todo!() + fn new_uref(&mut self, token_id: super::TokenId) -> Option { + let mut rng = rand::thread_rng(); + let val: [u8; 32] = rng.gen(); + let uref = URef::new( + val, + AccessRights::READ_ADD_WRITE + ); + if self.urefs.contains_key(&uref) { + None + } else { + self.urefs.insert(uref, token_id); + Some(uref) + } } - fn del_uref(&mut self, token_uref: types::URef) { - todo!() + fn del_uref(&mut self, token_uref: URef) -> Option { + let token_id = self.token_id(token_uref); + if token_id.is_none() { + None + } else { + let token_id = token_id.unwrap(); + self.urefs.remove(&token_uref); + Some(token_id) + } + } + + fn token_id(&self, token_uref: URef) -> Option { + self.urefs.get(&token_uref).map(|x| x.clone()) } } @@ -431,6 +474,7 @@ mod tests { let owner_of_second_token_id = contract.owner_of(ali_second_token_id); assert_eq!(owner_of_second_token_id.unwrap(), bob); } + #[test] fn test_transfer_many_tokens() { let mut contract = TestContract::new(); @@ -471,4 +515,27 @@ mod tests { assert_eq!(owner_of_second_token_id.unwrap(), bob); assert_eq!(owner_of_third_token_id.unwrap(), bob); } + + #[test] + fn test_attach_and_detach() { + let mut contract = TestContract::new(); + let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); + + contract.mint_one(ali, URI::from("0x12af")); + let token_id: TokenId = contract.tokens(ali)[0].clone(); + + let token_uref: URef = contract.detach(ali, token_id.clone()).unwrap(); + assert_eq!(contract.balance_of(ali), U256::zero()); + assert_eq!(contract.total_supply(), U256::one()); + assert!(contract.tokens(ali).is_empty()); + + assert_eq!(contract.token_id(token_uref.clone()), token_id.clone()); + assert_eq!(contract.token_uri(token_id.clone()).unwrap(), URI::from("0x12af")); + + contract.attach(token_uref, bob); + assert_eq!(contract.balance_of(bob), U256::one()); + assert_eq!(contract.total_supply(), U256::one()); + assert_eq!(contract.tokens(bob), vec![token_id]); + } } diff --git a/tests/Cargo.toml b/tests/Cargo.toml index 54c675b..07bf930 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -10,8 +10,6 @@ edition = "2018" casper-contract = "1.1.1" casper-types = "1.1.1" casper-engine-test-support = "1.1.1" -lazy_static = "1.4.0" - [features] default = ["casper-contract/std", "casper-types/std", "casper-contract/test-support"] From ba3e16b7c388de2e982eb98a0b7b789a92048b0a Mon Sep 17 00:00:00 2001 From: astro019 Date: Wed, 26 May 2021 22:25:54 +1000 Subject: [PATCH 11/98] added set_token for attach fn in logic --- cep47/src/logic.rs | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/cep47/src/logic.rs b/cep47/src/logic.rs index 4dc4996..819e078 100644 --- a/cep47/src/logic.rs +++ b/cep47/src/logic.rs @@ -120,11 +120,11 @@ trait CEP47Contract: WithStorage { fn attach(&mut self, token_uref: URef, recipient: PublicKey) { let token_id = self.storage_mut().del_uref(token_uref).unwrap(); - // load tokens of recipient - // add token to list - // save tokens + let mut tokens = self.storage().get_tokens(recipient); + tokens.push(token_id); + self.storage_mut().set_tokens(recipient, tokens); } - + fn token_id(&self, token_uref: URef) -> TokenId { self.storage().token_id(token_uref).unwrap() } @@ -147,7 +147,7 @@ trait CEP47Storage { fn set_tokens(&mut self, owner: PublicKey, token_ids: Vec); fn mint_many(&mut self, recipient: PublicKey, token_uris: Vec); fn mint_copies(&mut self, recipient: PublicKey, token_uri: URI, count: U256); - + fn new_uref(&mut self, token_id: TokenId) -> Option; fn del_uref(&mut self, token_uref: URef) -> Option; fn token_id(&self, token_uref: URef) -> Option; @@ -159,9 +159,14 @@ mod tests { use types::AccessRights; use super::{ - AsymmetricType, CEP47Contract, CEP47Storage, PublicKey, TokenId, WithStorage, U256, URI, URef + AsymmetricType, CEP47Contract, CEP47Storage, PublicKey, TokenId, URef, WithStorage, U256, + URI, + }; + use std::{ + collections::{hash_map::DefaultHasher, BTreeMap}, + hash::{Hash, Hasher}, + sync::Mutex, }; - use std::{collections::{BTreeMap, hash_map::DefaultHasher}, hash::{Hash, Hasher}, sync::Mutex}; struct TestStorage { name: String, @@ -186,7 +191,7 @@ mod tests { balances: BTreeMap::new(), belongs_to: BTreeMap::new(), token_uris: BTreeMap::new(), - urefs: BTreeMap::new() + urefs: BTreeMap::new(), } } } @@ -245,7 +250,6 @@ mod tests { } fn set_tokens(&mut self, owner: PublicKey, token_ids: Vec) { - let owner_prev_balance = self.balance_of(owner); let owner_new_balance = U256::from(token_ids.len() as u64); let owner_tokens = self.get_tokens(owner); @@ -258,7 +262,6 @@ mod tests { self.tokens.insert(owner, token_ids.clone()); self.balances.insert(owner, owner_new_balance); - self.total_supply = self.total_supply - owner_prev_balance + owner_new_balance; } fn mint_many(&mut self, recipient: PublicKey, token_uris: Vec) { @@ -299,10 +302,7 @@ mod tests { fn new_uref(&mut self, token_id: super::TokenId) -> Option { let mut rng = rand::thread_rng(); let val: [u8; 32] = rng.gen(); - let uref = URef::new( - val, - AccessRights::READ_ADD_WRITE - ); + let uref = URef::new(val, AccessRights::READ_ADD_WRITE); if self.urefs.contains_key(&uref) { None } else { @@ -328,13 +328,13 @@ mod tests { } struct TestContract { - storage: TestStorage + storage: TestStorage, } impl TestContract { pub fn new() -> TestContract { TestContract { - storage: TestStorage::new() + storage: TestStorage::new(), } } } @@ -474,7 +474,7 @@ mod tests { let owner_of_second_token_id = contract.owner_of(ali_second_token_id); assert_eq!(owner_of_second_token_id.unwrap(), bob); } - + #[test] fn test_transfer_many_tokens() { let mut contract = TestContract::new(); @@ -524,14 +524,17 @@ mod tests { contract.mint_one(ali, URI::from("0x12af")); let token_id: TokenId = contract.tokens(ali)[0].clone(); - + let token_uref: URef = contract.detach(ali, token_id.clone()).unwrap(); assert_eq!(contract.balance_of(ali), U256::zero()); assert_eq!(contract.total_supply(), U256::one()); assert!(contract.tokens(ali).is_empty()); assert_eq!(contract.token_id(token_uref.clone()), token_id.clone()); - assert_eq!(contract.token_uri(token_id.clone()).unwrap(), URI::from("0x12af")); + assert_eq!( + contract.token_uri(token_id.clone()).unwrap(), + URI::from("0x12af") + ); contract.attach(token_uref, bob); assert_eq!(contract.balance_of(bob), U256::one()); From e64e18d6734bb8e1ec99c0a5b1fec2034ab20265 Mon Sep 17 00:00:00 2001 From: astro019 Date: Thu, 27 May 2021 13:23:31 +1000 Subject: [PATCH 12/98] push tests for main cep47 --- .gitignore | 11 +-- cep47/Cargo.toml | 3 - cep47/src/logic.rs | 9 +-- cep47/src/main.rs | 46 ++++++++--- cep47/src/todo | 42 ---------- tests/src/cep47.rs | 195 +++++++++++++++++++++++++++++++++++++++++++++ tests/src/lib.rs | 5 ++ tests/src/main.rs | 3 - tests/src/tests.rs | 126 +++++++++++++++++++++++++++++ 9 files changed, 365 insertions(+), 75 deletions(-) delete mode 100644 cep47/src/todo create mode 100644 tests/src/cep47.rs create mode 100644 tests/src/lib.rs delete mode 100644 tests/src/main.rs create mode 100644 tests/src/tests.rs diff --git a/.gitignore b/.gitignore index 088ba6b..9b160a5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,3 @@ -# Generated by Cargo -# will have compiled files and executables -/target/ - -# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries -# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html +target Cargo.lock - -# These are backup files generated by rustfmt -**/*.rs.bk +tests/wasm/cep47.wasm \ No newline at end of file diff --git a/cep47/Cargo.toml b/cep47/Cargo.toml index 3be30b9..2154079 100644 --- a/cep47/Cargo.toml +++ b/cep47/Cargo.toml @@ -8,9 +8,6 @@ edition = "2018" contract = { package = "casper-contract", version="1.1.1" } types = { package = "casper-types", version="1.1.1" } -[dev-dependencies] -rand = "0.8.3" - [[bin]] name = "cep47" path = "src/main.rs" diff --git a/cep47/src/logic.rs b/cep47/src/logic.rs index 819e078..ffb239b 100644 --- a/cep47/src/logic.rs +++ b/cep47/src/logic.rs @@ -155,7 +155,7 @@ trait CEP47Storage { #[cfg(test)] mod tests { - use rand::Rng; + use contract::contract_api::storage; use types::AccessRights; use super::{ @@ -299,10 +299,9 @@ mod tests { self.mint_many(recipient, token_uris); } - fn new_uref(&mut self, token_id: super::TokenId) -> Option { - let mut rng = rand::thread_rng(); - let val: [u8; 32] = rng.gen(); - let uref = URef::new(val, AccessRights::READ_ADD_WRITE); + fn new_uref(&mut self, token_id: TokenId) -> Option { + let uref = storage::new_uref(token_id.clone()); + uref.with_access_rights(AccessRights::READ_ADD_WRITE); if self.urefs.contains_key(&uref) { None } else { diff --git a/cep47/src/main.rs b/cep47/src/main.rs index d459fcd..ee69d4d 100644 --- a/cep47/src/main.rs +++ b/cep47/src/main.rs @@ -22,8 +22,8 @@ use types::{ account::AccountHash, bytesrepr::{FromBytes, ToBytes}, contracts::NamedKeys, - ApiError, AsymmetricType, CLType, CLTyped, CLValue, EntryPoint, EntryPointAccess, - EntryPointType, EntryPoints, Parameter, PublicKey, URef, U256, + AccessRights, ApiError, AsymmetricType, CLType, CLTyped, CLValue, EntryPoint, EntryPointAccess, + EntryPointType, EntryPoints, Key, Parameter, PublicKey, URef, U256, }; type TokenId = String; @@ -131,13 +131,27 @@ trait CEP47Contract: WithStorage { } // URef releated function. - fn detach(&mut self, owner: PublicKey, token_id: TokenId) -> URef { - todo!(); - } - fn attach(&mut self, token_uref: URef, recipient: PublicKey) {} - fn token_id(&self, token_uref: URef) -> TokenId { - todo!(); - } + // fn detach(&mut self, owner: PublicKey, token_id: TokenId) -> Option { + // let mut tokens = self.storage().get_tokens(owner); + // if !tokens.contains(&token_id) { + // None + // } else { + // tokens.retain(|x| x != &token_id); + // self.storage_mut().set_tokens(owner, tokens); + // self.storage_mut().new_uref(token_id) + // } + // } + + // fn attach(&mut self, token_uref: URef, recipient: PublicKey) { + // let token_id = self.storage_mut().del_uref(token_uref).unwrap(); + // let mut tokens = self.storage().get_tokens(recipient); + // tokens.push(token_id); + // self.storage_mut().set_tokens(recipient, tokens); + // } + + // fn token_id(&self, token_uref: URef) -> TokenId { + // self.storage().token_id(token_uref).unwrap() + // } } trait CEP47Storage { @@ -216,18 +230,21 @@ trait CEP47Storage { set_key(&uri_key(&token_id), token_uri); set_key(&owner_key(&token_id), recipient); } + recipient_balance = recipient_balance + U256::from(token_uris.len() as u64); set_key( &balance_key(&recipient.to_account_hash()), recipient_balance, ); set_key(&token_key(&recipient.to_account_hash()), recipient_tokens); + set_key("total_supply", total_supply); } fn mint_copies(&mut self, recipient: PublicKey, token_uri: URI, count: U256) { let token_uris: Vec = vec![token_uri; count.as_usize()]; self.mint_many(recipient, token_uris); } - // fn new_uref(&mut self, token_id: TokenId) -> URef; - // fn del_uref(&mut self, token_uref: URef); + // fn new_uref(&mut self, token_id: TokenId) -> Option {} + // fn del_uref(&mut self, token_uref: URef) -> Option {} + // fn token_id(&self, token_uref: URef) -> Option {} } struct CasperCEP47Storage {} @@ -457,7 +474,10 @@ pub extern "C" fn call() { named_keys.insert("name".to_string(), storage::new_uref(tokenName).into()); named_keys.insert("symbol".to_string(), storage::new_uref(tokenSymbol).into()); named_keys.insert("uri".to_string(), storage::new_uref(tokenURI).into()); - named_keys.insert("total_supply".to_string(), storage::new_uref(0u8).into()); + named_keys.insert( + "total_supply".to_string(), + storage::new_uref(U256::zero()).into(), + ); let (contract_package_hash, _) = storage::create_contract_package_at_hash(); let (contract_hash, _) = @@ -497,7 +517,7 @@ fn set_key(name: &str, value: T) { fn remove_key(name: &str) { match runtime::get_key(name) { - Some(key) => { + Some(_) => { runtime::remove_key(name); } None => {} diff --git a/cep47/src/todo b/cep47/src/todo deleted file mode 100644 index 009725e..0000000 --- a/cep47/src/todo +++ /dev/null @@ -1,42 +0,0 @@ -MonaLisaNFT -Data: - - seed: URef - - number_of_pieces: u64 - - minter: PublicKey - - owners: Map - - balances: Map - - name: String - - IPFS Hash: String -CEP47 - Endpoints: - - owner_of(token_id: TokenId) -> Option; - - balance_of(account: PublicKey) -> u64; - - transfer(from: PublicKey, to: PublicKey, token_id: TokenId) { - if from.to_account_hash() != runtime::get_caller() { - revert(); - } - } -MonaLisa - Endpoints: -mint(to: PublicKey, piece_number: u64) { - if minter.to_account_hash() != runtime::get_caller() { - revert(); - } - let token_id = to_token_id(piece_number); - let owner = owner_of(token_id); - if owner.is_none() { - owners[token_id] = to; - balances[to] += 1; - } -} -MonaLisa internal functions: -to_token_id(piece_number) -> TokenId { - if piece_number > number_of_pieces { - revert(); - } - hash(seed, piece_number) -} -Initial named keys: - - seed, - - number_of_pieces, - - name - - IPFS Hash - - minter: PublicKey \ No newline at end of file diff --git a/tests/src/cep47.rs b/tests/src/cep47.rs new file mode 100644 index 0000000..c472bae --- /dev/null +++ b/tests/src/cep47.rs @@ -0,0 +1,195 @@ +use casper_engine_test_support::{Code, Hash, SessionBuilder, TestContext, TestContextBuilder}; +use casper_types::{ + account::AccountHash, bytesrepr::FromBytes, runtime_args, AsymmetricType, CLTyped, PublicKey, + RuntimeArgs, U256, U512, +}; + +pub mod token_cfg { + pub const NAME: &str = "CasperNFT"; + pub const SYMBOL: &str = "CNFT"; + pub const URI: &str = "https://casper.network/network"; +} + +pub const CASPERCEP47_CONTRACT: &str = "caspercep47_contract"; +pub const CASPERCEP47_CONTRACT_HASH: &str = "caspercep47_contract_hash"; + +pub struct CasperCEP47Contract { + pub context: TestContext, + pub caspercep47_hash: Hash, + pub account: AccountHash, +} + +pub type TokenId = String; +pub type URI = String; + +impl CasperCEP47Contract { + pub fn deploy() -> Self { + let account = PublicKey::ed25519_from_bytes([1u8; 32]).unwrap(); + let mut context = TestContextBuilder::new() + .with_public_key(account, U512::from(500_000_000_000_000_000u64)) + .build(); + let session_code = Code::from("cep47.wasm"); + let session_args = runtime_args! { + "token_name" => token_cfg::NAME, + "token_symbol" => token_cfg::SYMBOL, + "token_uri" => token_cfg::URI + }; + let session = SessionBuilder::new(session_code, session_args) + .with_address(account.to_account_hash()) + .with_authorization_keys(&[account.to_account_hash()]) + .build(); + context.run(session); + let caspercep47_hash = context + .query( + account.to_account_hash(), + &[CASPERCEP47_CONTRACT_HASH.to_string()], + ) + .unwrap() + .into_t() + .unwrap(); + + Self { + context, + caspercep47_hash, + account: account.to_account_hash(), + } + } + + fn call(&mut self, method: &str, args: RuntimeArgs) { + let code = Code::Hash(self.caspercep47_hash, method.to_string()); + let session = SessionBuilder::new(code, args) + .with_address(self.account) + .with_authorization_keys(&[self.account]) + .build(); + self.context.run(session); + } + + fn query_contract(&self, name: &str) -> Option { + match self.context.query( + self.account, + &[CASPERCEP47_CONTRACT.to_string(), name.to_string()], + ) { + Err(_) => None, + Ok(maybe_value) => { + let value = maybe_value + .into_t() + .unwrap_or_else(|_| panic!("{} is not expected type.", name)); + Some(value) + } + } + } + + pub fn name(&self) -> String { + self.query_contract("name").unwrap() + } + + pub fn symbol(&self) -> String { + self.query_contract("symbol").unwrap() + } + + pub fn uri(&self) -> URI { + self.query_contract("uri").unwrap() + } + + pub fn total_supply(&self) -> U256 { + self.query_contract("total_supply").unwrap_or_default() + } + + pub fn owner_of(&self, token_id: &TokenId) -> Option { + self.query_contract(owner_key(&token_id).as_str()) + } + + pub fn balance_of(&self, owner: PublicKey) -> U256 { + self.query_contract(balance_key(&owner.to_account_hash()).as_str()) + .unwrap_or_default() + } + + pub fn tokens(&self, owner: PublicKey) -> Vec { + self.query_contract::>(token_key(&owner.to_account_hash()).as_str()) + .unwrap_or_default() + } + + pub fn mint_one(&mut self, recipient: PublicKey, token_uri: URI) { + self.call( + "mint_one", + runtime_args! { + "recipient" => recipient, + "token_uri" => token_uri + }, + ); + } + + pub fn mint_copies(&mut self, recipient: PublicKey, token_uri: URI, count: U256) { + self.call( + "mint_copies", + runtime_args! { + "recipient" => recipient, + "token_uri" => token_uri, + "count" => count + }, + ); + } + + pub fn mint_many(&mut self, recipient: PublicKey, token_uris: Vec) { + self.call( + "mint_many", + runtime_args! { + "recipient" => recipient, + "token_uris" => token_uris + }, + ); + } + + pub fn transfer_token(&mut self, sender: PublicKey, recipient: PublicKey, token_id: TokenId) { + self.call( + "transfer_token", + runtime_args! { + "sender" => sender, + "recipient" => recipient, + "token_id" => token_id + }, + ); + } + + pub fn transfer_many_tokens( + &mut self, + sender: PublicKey, + recipient: PublicKey, + token_ids: Vec, + ) { + self.call( + "transfer_many_tokens", + runtime_args! { + "sender" => sender, + "recipient" => recipient, + "token_ids" => token_ids + }, + ); + } + + pub fn transfer_all_tokens(&mut self, sender: PublicKey, recipient: PublicKey) { + self.call( + "transfer_all_tokens", + runtime_args! { + "sender" => sender, + "recipient" => recipient + }, + ); + } +} + +fn balance_key(account: &AccountHash) -> String { + format!("balances_{}", account) +} + +fn owner_key(token_id: &TokenId) -> String { + format!("owners_{}", token_id) +} + +fn uri_key(token_id: &TokenId) -> String { + format!("uris_{}", token_id) +} + +fn token_key(account: &AccountHash) -> String { + format!("tokens_{}", account) +} diff --git a/tests/src/lib.rs b/tests/src/lib.rs new file mode 100644 index 0000000..bcb4c6c --- /dev/null +++ b/tests/src/lib.rs @@ -0,0 +1,5 @@ +#[cfg(test)] +pub mod cep47; + +#[cfg(test)] +pub mod tests; \ No newline at end of file diff --git a/tests/src/main.rs b/tests/src/main.rs deleted file mode 100644 index e7a11a9..0000000 --- a/tests/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - println!("Hello, world!"); -} diff --git a/tests/src/tests.rs b/tests/src/tests.rs new file mode 100644 index 0000000..7463cc0 --- /dev/null +++ b/tests/src/tests.rs @@ -0,0 +1,126 @@ +use crate::cep47::{token_cfg, CasperCEP47Contract, TokenId, URI}; +use casper_types::{AsymmetricType, PublicKey, SecretKey, U256}; + +#[test] +fn test_deploy() { + let contract = CasperCEP47Contract::deploy(); + + assert_eq!(contract.name(), token_cfg::NAME); + assert_eq!(contract.symbol(), token_cfg::SYMBOL); + assert_eq!(contract.uri(), token_cfg::URI); + assert_eq!(contract.total_supply(), U256::zero()); +} + +#[test] +fn test_mint_one() { + let mut contract = CasperCEP47Contract::deploy(); + let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + let token_uri = URI::from("MonaLisa"); + contract.mint_one(ali, token_uri); + + let ali_tokens: Vec = contract.tokens(ali); + + assert_eq!(contract.total_supply(), U256::one()); + assert_eq!(contract.balance_of(ali), U256::one()); + assert_eq!(U256::from(ali_tokens.len() as u64), U256::one()); + assert_eq!(contract.owner_of(&ali_tokens[0]), Some(ali)); +} + +#[test] +fn test_mint_copies() { + let mut contract = CasperCEP47Contract::deploy(); + let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + let token_uri = URI::from("Casper Golden Card"); + contract.mint_copies(ali, token_uri, U256::from(3)); + + let ali_tokens: Vec = contract.tokens(ali); + + assert_eq!(contract.total_supply(), U256::from(3)); + assert_eq!(contract.balance_of(ali), U256::from(3)); + assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(3)); + assert_eq!(contract.owner_of(&ali_tokens[0]), Some(ali)); + assert_eq!(contract.owner_of(&ali_tokens[1]), Some(ali)); + assert_eq!(contract.owner_of(&ali_tokens[2]), Some(ali)); +} + +#[test] +fn test_mint_many() { + let mut contract = CasperCEP47Contract::deploy(); + let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + let token_uris: Vec = vec![URI::from("Casper Golden Card"), URI::from("Mona Lisa")]; + contract.mint_many(ali, token_uris); + + let ali_tokens: Vec = contract.tokens(ali); + + assert_eq!(contract.total_supply(), U256::from(2)); + assert_eq!(contract.balance_of(ali), U256::from(2)); + assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(2)); + assert_eq!(contract.owner_of(&ali_tokens[0]), Some(ali)); + assert_eq!(contract.owner_of(&ali_tokens[1]), Some(ali)); +} + +#[test] +fn test_transfer_token() { + let mut contract = CasperCEP47Contract::deploy(); + let ali: PublicKey = SecretKey::ed25519([3u8; 32]).into(); + let bob: PublicKey = SecretKey::ed25519([5u8; 32]).into(); + let token_uris: Vec = vec![ + URI::from("Casper Golden Card"), + URI::from("Casper Silver Card"), + ]; + contract.mint_many(ali, token_uris); + let ali_tokens: Vec = contract.tokens(ali); + contract.transfer_token(ali, bob, ali_tokens[1].clone()); + + assert_eq!(contract.balance_of(ali), U256::from(1)); + assert_eq!(contract.balance_of(bob), U256::from(1)); + assert_eq!(contract.total_supply(), U256::from(2)); + assert_eq!(contract.owner_of(&ali_tokens[0]), Some(ali)); + assert_eq!(contract.owner_of(&ali_tokens[1]), Some(bob)); +} + +#[test] +fn test_transfer_many_tokens() { + let mut contract = CasperCEP47Contract::deploy(); + let ali: PublicKey = SecretKey::ed25519([3u8; 32]).into(); + let bob: PublicKey = SecretKey::ed25519([5u8; 32]).into(); + let token_uris: Vec = vec![ + URI::from("Casper Golden Card"), + URI::from("Casper Silver Card"), + URI::from("Casper Bronze Card"), + ]; + contract.mint_many(ali, token_uris); + let ali_tokens: Vec = contract.tokens(ali); + contract.transfer_many_tokens(ali, bob, ali_tokens[..2].to_vec()); + + assert_eq!(contract.balance_of(ali), U256::from(1)); + assert_eq!(contract.balance_of(bob), U256::from(2)); + assert_eq!(contract.total_supply(), U256::from(3)); + assert_eq!(contract.owner_of(&ali_tokens[0]), Some(bob)); + assert_eq!(contract.owner_of(&ali_tokens[1]), Some(bob)); + assert_eq!(contract.owner_of(&ali_tokens[2]), Some(ali)); +} + +#[test] +fn test_transfer_all_tokens() { + let mut contract = CasperCEP47Contract::deploy(); + let ali: PublicKey = SecretKey::ed25519([3u8; 32]).into(); + let bob: PublicKey = SecretKey::ed25519([5u8; 32]).into(); + let token_uris: Vec = vec![ + URI::from("Casper Golden Card"), + URI::from("Casper Silver Card"), + ]; + contract.mint_many(ali, token_uris); + let ali_tokens: Vec = contract.tokens(ali); + assert_eq!(contract.balance_of(ali), U256::from(2)); + assert_eq!(contract.balance_of(bob), U256::from(0)); + assert_eq!(contract.owner_of(&ali_tokens[0]), Some(ali)); + assert_eq!(contract.owner_of(&ali_tokens[1]), Some(ali)); + + contract.transfer_all_tokens(ali, bob); + assert_eq!(contract.balance_of(ali), U256::from(0)); + assert_eq!(contract.balance_of(bob), U256::from(2)); + assert_eq!(contract.total_supply(), U256::from(2)); + assert_eq!(contract.owner_of(&ali_tokens[0]), Some(bob)); + assert_eq!(contract.owner_of(&ali_tokens[1]), Some(bob)); +} From 672013fe1ff55fd6a009fe4b9e5d7dbbb63692f3 Mon Sep 17 00:00:00 2001 From: astro019 Date: Thu, 27 May 2021 19:24:03 +1000 Subject: [PATCH 13/98] add token_uri test --- tests/src/cep47.rs | 4 ++++ tests/src/tests.rs | 13 +++++++++++++ 2 files changed, 17 insertions(+) diff --git a/tests/src/cep47.rs b/tests/src/cep47.rs index c472bae..0570e11 100644 --- a/tests/src/cep47.rs +++ b/tests/src/cep47.rs @@ -109,6 +109,10 @@ impl CasperCEP47Contract { .unwrap_or_default() } + pub fn token_uri(&self, token_id: TokenId) -> Option { + self.query_contract(uri_key(&token_id).as_str()) + } + pub fn mint_one(&mut self, recipient: PublicKey, token_uri: URI) { self.call( "mint_one", diff --git a/tests/src/tests.rs b/tests/src/tests.rs index 7463cc0..32c44ee 100644 --- a/tests/src/tests.rs +++ b/tests/src/tests.rs @@ -11,6 +11,19 @@ fn test_deploy() { assert_eq!(contract.total_supply(), U256::zero()); } +#[test] +fn test_token_uri() { + let mut contract = CasperCEP47Contract::deploy(); + let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + let token_uri = URI::from("MonaLisa"); + contract.mint_one(ali, token_uri.clone()); + + let ali_tokens: Vec = contract.tokens(ali); + let ali_token_uri = contract.token_uri(ali_tokens[0].clone()); + + assert_eq!(ali_token_uri, Some(token_uri)); +} + #[test] fn test_mint_one() { let mut contract = CasperCEP47Contract::deploy(); From cfb444ddf9de692c7626b5aae9bbf37abb005438 Mon Sep 17 00:00:00 2001 From: astro019 Date: Thu, 27 May 2021 19:58:19 +1000 Subject: [PATCH 14/98] revert new_uref creation with rand in logics --- cep47/Cargo.toml | 1 + cep47/src/logic.rs | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/cep47/Cargo.toml b/cep47/Cargo.toml index 2154079..af99dc9 100644 --- a/cep47/Cargo.toml +++ b/cep47/Cargo.toml @@ -7,6 +7,7 @@ edition = "2018" [dependencies] contract = { package = "casper-contract", version="1.1.1" } types = { package = "casper-types", version="1.1.1" } +rand = { version="0.8", default-features=false } [[bin]] name = "cep47" diff --git a/cep47/src/logic.rs b/cep47/src/logic.rs index ffb239b..35c33c2 100644 --- a/cep47/src/logic.rs +++ b/cep47/src/logic.rs @@ -155,7 +155,7 @@ trait CEP47Storage { #[cfg(test)] mod tests { - use contract::contract_api::storage; + use rand::Rng; use types::AccessRights; use super::{ @@ -300,8 +300,9 @@ mod tests { } fn new_uref(&mut self, token_id: TokenId) -> Option { - let uref = storage::new_uref(token_id.clone()); - uref.with_access_rights(AccessRights::READ_ADD_WRITE); + let mut rng = rand::thread_rng(); + let val: [u8; 32] = rng.gen(); + let uref = URef::new(val, AccessRights::READ_ADD_WRITE); if self.urefs.contains_key(&uref) { None } else { From 0862df0cca419910465ecc3e9f80879ff00197ad Mon Sep 17 00:00:00 2001 From: astro019 Date: Thu, 27 May 2021 20:04:26 +1000 Subject: [PATCH 15/98] fix the Makefile command for test --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 59d81b7..9daeb91 100644 --- a/Makefile +++ b/Makefile @@ -8,6 +8,7 @@ test-only: cargo test -p tests copy-wasm-file-to-test: + mkdir -p tests/wasm cp target/wasm32-unknown-unknown/release/cep47.wasm tests/wasm test: build-contract copy-wasm-file-to-test test-only From 1c631e0e1213044050b96068a8040dae62142f66 Mon Sep 17 00:00:00 2001 From: Deusz Date: Thu, 27 May 2021 14:20:11 +0200 Subject: [PATCH 16/98] start --- Makefile | 5 +- cep47/src/lib.rs | 555 ++++++++++++++++++++++++++++++++++++++++++++- cep47/src/logic.rs | 399 +------------------------------- cep47/src/main.rs | 552 +------------------------------------------- cep47/src/tests.rs | 389 +++++++++++++++++++++++++++++++ 5 files changed, 956 insertions(+), 944 deletions(-) create mode 100644 cep47/src/tests.rs diff --git a/Makefile b/Makefile index 9daeb91..336eee0 100644 --- a/Makefile +++ b/Makefile @@ -2,13 +2,12 @@ prepare: rustup target add wasm32-unknown-unknown build-contract: - cargo build --release -p cep47 --target wasm32-unknown-unknown + cargo +nightly build --release -p cep47 --target wasm32-unknown-unknown test-only: - cargo test -p tests + cargo +nightly test --workspace copy-wasm-file-to-test: - mkdir -p tests/wasm cp target/wasm32-unknown-unknown/release/cep47.wasm tests/wasm test: build-contract copy-wasm-file-to-test test-only diff --git a/cep47/src/lib.rs b/cep47/src/lib.rs index 45a2c47..ec02745 100644 --- a/cep47/src/lib.rs +++ b/cep47/src/lib.rs @@ -1 +1,554 @@ -pub mod logic; \ No newline at end of file + +#![allow(unused_imports)] +#![allow(unused_parens)] +#![allow(non_snake_case)] + +extern crate alloc; + +pub mod tests; +pub mod logic; + +use alloc::{ + collections::{BTreeMap, BTreeSet}, + string::String, +}; +use contract::{ + contract_api::{runtime, storage}, + unwrap_or_revert::UnwrapOrRevert, +}; +use core::convert::TryInto; +use std::{ + collections::hash_map::DefaultHasher, + hash::{Hash, Hasher}, +}; +use types::{ + account::AccountHash, + bytesrepr::{FromBytes, ToBytes}, + contracts::NamedKeys, + AccessRights, ApiError, AsymmetricType, CLType, CLTyped, CLValue, EntryPoint, EntryPointAccess, + EntryPointType, EntryPoints, Key, Parameter, PublicKey, URef, U256, +}; + +type TokenId = String; +type URI = String; + +trait WithStorage { + fn storage(&self) -> &Storage; + fn storage_mut(&mut self) -> &mut Storage; +} + +trait CEP47Contract: WithStorage { + // Metadata + fn name(&self) -> String { + self.storage().name() + } + + fn symbol(&self) -> String { + self.storage().symbol() + } + + fn uri(&self) -> URI { + self.storage().uri() + } + + // Getters + fn balance_of(&self, owner: PublicKey) -> U256 { + self.storage().balance_of(owner) + } + + fn owner_of(&self, token_id: TokenId) -> Option { + self.storage().onwer_of(token_id) + } + + fn total_supply(&self) -> U256 { + self.storage().total_supply() + } + + fn token_uri(&self, token_id: TokenId) -> Option { + self.storage().token_uri(token_id) + } + + fn tokens(&self, owner: PublicKey) -> Vec { + self.storage().get_tokens(owner) + } + + // Minter function. + // Guarded by the entrypoint group. + fn mint_one(&mut self, recipient: PublicKey, token_uri: URI) { + self.storage_mut() + .mint_copies(recipient, token_uri, U256::one()); + } + + fn mint_many(&mut self, recipient: PublicKey, token_uris: Vec) { + self.storage_mut().mint_many(recipient, token_uris); + } + + fn mint_copies(&mut self, recipient: PublicKey, token_uri: URI, count: U256) { + self.storage_mut().mint_copies(recipient, token_uri, count); + } + + // Transfer functions. + fn transfer_token(&mut self, sender: PublicKey, recipient: PublicKey, token_id: TokenId) { + // 1. Load tokens owned by the sender. + let mut sender_tokens = self.storage().get_tokens(sender); + // 2. Assert that token_id is in sender_tokens. + assert!( + sender_tokens.contains(&token_id), + "wrong owner of token {}", + token_id + ); + // 3. Remove token_id from sender_tokens. + sender_tokens.retain(|x| x.clone() != token_id); + self.storage_mut().set_tokens(sender, sender_tokens); + + // 4. Add token_id to the recipient tokens + let mut recipient_tokens = self.storage().get_tokens(recipient); + recipient_tokens.push(token_id); + self.storage_mut().set_tokens(recipient, recipient_tokens); + } + + fn transfer_many_tokens( + &mut self, + sender: PublicKey, + recipient: PublicKey, + token_ids: Vec, + ) { + let mut sender_tokens = self.storage().get_tokens(sender); + for token_id in token_ids.iter() { + assert!(sender_tokens.contains(token_id), "wrong token {}", token_id); + sender_tokens.retain(|x| x.clone() != token_id.clone()); + } + let mut recipient_tokens = self.storage().get_tokens(recipient); + recipient_tokens.append(&mut token_ids.clone()); + self.storage_mut().set_tokens(sender, sender_tokens); + self.storage_mut().set_tokens(recipient, recipient_tokens); + } + + fn transfer_all_tokens(&mut self, sender: PublicKey, recipient: PublicKey) { + let mut sender_tokens = self.storage().get_tokens(sender); + let mut recipient_tokens = self.storage().get_tokens(recipient); + recipient_tokens.append(&mut sender_tokens); + + self.storage_mut().set_tokens(sender, sender_tokens); + self.storage_mut().set_tokens(recipient, recipient_tokens); + } + + // URef releated function. + fn detach(&mut self, owner: PublicKey, token_id: TokenId) -> Option { + let mut tokens = self.storage().get_tokens(owner); + if !tokens.contains(&token_id) { + None + } else { + tokens.retain(|x| x != &token_id); + self.storage_mut().set_tokens(owner, tokens); + self.storage_mut().new_uref(token_id) + } + } + + fn attach(&mut self, token_uref: URef, recipient: PublicKey) { + let token_id = self.storage_mut().del_uref(token_uref).unwrap(); + let mut tokens = self.storage().get_tokens(recipient); + tokens.push(token_id); + self.storage_mut().set_tokens(recipient, tokens); + } + + fn token_id(&self, token_uref: URef) -> TokenId { + self.storage().token_id(token_uref).unwrap() + } +} + +trait CEP47Storage { + // Metadata. + fn name(&self) -> String { + get_key::("name").unwrap() + } + fn symbol(&self) -> String { + get_key::("symbol").unwrap() + } + fn uri(&self) -> URI { + get_key::("uri").unwrap() + } + + // Getters + fn balance_of(&self, owner: PublicKey) -> U256 { + let owner_balance = get_key::(&balance_key(&owner.to_account_hash())); + if owner_balance.is_none() { + U256::from(0) + } else { + owner_balance.unwrap() + } + } + fn onwer_of(&self, token_id: TokenId) -> Option { + get_key::(&owner_key(&token_id)) + } + fn total_supply(&self) -> U256 { + get_key::("total_supply").unwrap() + } + fn token_uri(&self, token_id: TokenId) -> Option { + get_key::(&uri_key(&token_id)) + } + + // Setters + fn get_tokens(&self, owner: PublicKey) -> Vec { + let owner_tokens = get_key::>(&token_key(&owner.to_account_hash())); + if owner_tokens.is_none() { + Vec::::new() + } else { + owner_tokens.unwrap() + } + } + fn set_tokens(&mut self, owner: PublicKey, token_ids: Vec) { + let owner_prev_balance = self.balance_of(owner); + let owner_new_balance = U256::from(token_ids.len() as u64); + let prev_total_supply = self.total_supply(); + + let owner_tokens = self.get_tokens(owner); + for token_id in owner_tokens.clone() { + remove_key(&owner_key(&token_id)); + } + for token_id in token_ids.clone() { + set_key(&owner_key(&token_id), owner); + } + set_key(&token_key(&owner.to_account_hash()), token_ids); + set_key(&balance_key(&owner.to_account_hash()), owner_new_balance); + set_key( + "total_supply", + prev_total_supply - owner_prev_balance + owner_new_balance, + ); + } + fn mint_many(&mut self, recipient: PublicKey, token_uris: Vec) { + let mut recipient_tokens = self.get_tokens(recipient); + let mut recipient_balance = self.balance_of(recipient); + let mut total_supply = self.total_supply(); + let uri = self.uri(); + + let mut hasher = DefaultHasher::new(); + for token_uri in token_uris.clone() { + let token_info = (total_supply, uri.clone(), token_uri.clone()); + Hash::hash(&token_info, &mut hasher); + + let token_id = TokenId::from(hasher.finish().to_string()); + recipient_tokens.push(token_id.clone()); + total_supply = total_supply + 1; + set_key(&uri_key(&token_id), token_uri); + set_key(&owner_key(&token_id), recipient); + } + recipient_balance = recipient_balance + U256::from(token_uris.len() as u64); + set_key( + &balance_key(&recipient.to_account_hash()), + recipient_balance, + ); + set_key(&token_key(&recipient.to_account_hash()), recipient_tokens); + set_key("total_supply", total_supply); + } + fn mint_copies(&mut self, recipient: PublicKey, token_uri: URI, count: U256) { + let token_uris: Vec = vec![token_uri; count.as_usize()]; + self.mint_many(recipient, token_uris); + } + fn new_uref(&mut self, token_id: TokenId) -> Option {None} + fn del_uref(&mut self, token_uref: URef) -> Option {None} + fn token_id(&self, token_uref: URef) -> Option {None} +} + +struct CasperCEP47Storage {} +impl CasperCEP47Storage { + pub fn new() -> CasperCEP47Storage { + CasperCEP47Storage {} + } +} +impl CEP47Storage for CasperCEP47Storage {} +struct CasperCEP47Contract { + storage: CasperCEP47Storage, +} +impl CasperCEP47Contract { + pub fn new() -> CasperCEP47Contract { + CasperCEP47Contract { + storage: CasperCEP47Storage::new(), + } + } +} +impl WithStorage for CasperCEP47Contract { + fn storage(&self) -> &CasperCEP47Storage { + &self.storage + } + fn storage_mut(&mut self) -> &mut CasperCEP47Storage { + &mut self.storage + } +} +impl CEP47Contract for CasperCEP47Contract {} +/** + * ApiError::User(1) - The number of piece is out or range. + * ApiError::User(2) - The piece of NFT is already minted and owned by someone. + * ApiError::User(3) - The piece of NFT is not minted yet. + */ + +#[no_mangle] +pub extern "C" fn name() { + let contract = CasperCEP47Contract::new(); + ret(contract.name()) +} + +#[no_mangle] +pub extern "C" fn symbol() { + let contract = CasperCEP47Contract::new(); + ret(contract.symbol()) +} + +#[no_mangle] +pub extern "C" fn uri() { + let contract = CasperCEP47Contract::new(); + ret(contract.uri()) +} + +#[no_mangle] +pub extern "C" fn balance_of() { + let account: PublicKey = runtime::get_named_arg("account"); + let contract = CasperCEP47Contract::new(); + ret(contract.balance_of(account)) +} + +#[no_mangle] +pub extern "C" fn owner_of() { + let token_id: TokenId = runtime::get_named_arg("token_id"); + let contract = CasperCEP47Contract::new(); + ret(contract.owner_of(token_id)) +} + +#[no_mangle] +pub extern "C" fn total_supply() { + let contract = CasperCEP47Contract::new(); + ret(contract.total_supply()) +} + +#[no_mangle] +pub extern "C" fn token_uri() { + let token_id: TokenId = runtime::get_named_arg("token_id"); + let contract = CasperCEP47Contract::new(); + ret(contract.token_uri(token_id)) +} + +#[no_mangle] +pub extern "C" fn tokens() { + let owner: PublicKey = runtime::get_named_arg("owner"); + let contract = CasperCEP47Contract::new(); + ret(contract.tokens(owner)) +} + +#[no_mangle] +pub extern "C" fn mint_one() { + let recipient: PublicKey = runtime::get_named_arg("recipient"); + let token_uri: URI = runtime::get_named_arg("token_uri"); + let mut contract = CasperCEP47Contract::new(); + contract.mint_one(recipient, token_uri); +} + +#[no_mangle] +pub extern "C" fn mint_many() { + let recipient: PublicKey = runtime::get_named_arg("recipient"); + let token_uris: Vec = runtime::get_named_arg("token_uris"); + let mut contract = CasperCEP47Contract::new(); + contract.mint_many(recipient, token_uris); +} + +#[no_mangle] +pub extern "C" fn mint_copies() { + let recipient: PublicKey = runtime::get_named_arg("recipient"); + let token_uri: URI = runtime::get_named_arg("token_uri"); + let count: U256 = runtime::get_named_arg("count"); + let mut contract = CasperCEP47Contract::new(); + contract.mint_copies(recipient, token_uri, count); +} + +#[no_mangle] +pub extern "C" fn transfer_token() { + let sender: PublicKey = runtime::get_named_arg("sender"); + let recipient: PublicKey = runtime::get_named_arg("recipient"); + let token_id: TokenId = runtime::get_named_arg("token_id"); + let mut contract = CasperCEP47Contract::new(); + contract.transfer_token(sender, recipient, token_id); +} + +#[no_mangle] +pub extern "C" fn transfer_many_tokens() { + let sender: PublicKey = runtime::get_named_arg("sender"); + let recipient: PublicKey = runtime::get_named_arg("recipient"); + let token_ids: Vec = runtime::get_named_arg("token_ids"); + let mut contract = CasperCEP47Contract::new(); + contract.transfer_many_tokens(sender, recipient, token_ids); +} + +#[no_mangle] +pub extern "C" fn transfer_all_tokens() { + let sender: PublicKey = runtime::get_named_arg("sender"); + let recipient: PublicKey = runtime::get_named_arg("recipient"); + let mut contract = CasperCEP47Contract::new(); + contract.transfer_all_tokens(sender, recipient); +} + + +pub fn deploy(token_name: &str, token_symbol: &str, token_uri: &str) { + let tokenName: String = runtime::get_named_arg("token_name"); + let tokenSymbol: String = runtime::get_named_arg("token_symbol"); + let tokenURI: URI = runtime::get_named_arg("token_uri"); + + let mut entry_points = EntryPoints::new(); + entry_points.add_entry_point(endpoint("name", vec![], CLType::String)); + entry_points.add_entry_point(endpoint("symbol", vec![], CLType::String)); + entry_points.add_entry_point(endpoint("uri", vec![], CLType::String)); + entry_points.add_entry_point(endpoint("total_supply", vec![], CLType::U256)); + entry_points.add_entry_point(endpoint( + "balance_of", + vec![Parameter::new("account", CLType::PublicKey)], + CLType::U256, + )); + entry_points.add_entry_point(endpoint( + "owner_of", + vec![Parameter::new("token_id", CLType::String)], + CLType::Option(Box::new(CLType::PublicKey)), + )); + entry_points.add_entry_point(endpoint( + "token_uri", + vec![Parameter::new("token_id", CLType::String)], + CLType::Option(Box::new(CLType::String)), + )); + entry_points.add_entry_point(endpoint( + "tokens", + vec![Parameter::new("owner", CLType::PublicKey)], + CLType::List(Box::new(CLType::String)), + )); + entry_points.add_entry_point(endpoint( + "tokens", + vec![Parameter::new("owner", CLType::PublicKey)], + CLType::List(Box::new(CLType::String)), + )); + entry_points.add_entry_point(endpoint( + "mint_one", + vec![ + Parameter::new("recipient", CLType::PublicKey), + Parameter::new("token_uri", CLType::String), + ], + CLType::Unit, + )); + entry_points.add_entry_point(endpoint( + "mint_many", + vec![ + Parameter::new("recipient", CLType::PublicKey), + Parameter::new("token_uris", CLType::List(Box::new(CLType::String))), + ], + CLType::Unit, + )); + entry_points.add_entry_point(endpoint( + "mint_copies", + vec![ + Parameter::new("recipient", CLType::PublicKey), + Parameter::new("token_uri", CLType::String), + Parameter::new("count", CLType::U256), + ], + CLType::Unit, + )); + entry_points.add_entry_point(endpoint( + "transfer_token", + vec![ + Parameter::new("sender", CLType::PublicKey), + Parameter::new("recipient", CLType::PublicKey), + Parameter::new("token_id", CLType::String), + ], + CLType::Unit, + )); + entry_points.add_entry_point(endpoint( + "transfer_many_tokens", + vec![ + Parameter::new("sender", CLType::PublicKey), + Parameter::new("recipient", CLType::PublicKey), + Parameter::new("token_ids", CLType::List(Box::new(CLType::String))), + ], + CLType::Unit, + )); + entry_points.add_entry_point(endpoint( + "transfer_all_tokens", + vec![ + Parameter::new("sender", CLType::PublicKey), + Parameter::new("recipient", CLType::PublicKey), + ], + CLType::Unit, + )); + + let mut named_keys = NamedKeys::new(); + named_keys.insert("name".to_string(), storage::new_uref(tokenName).into()); + named_keys.insert("symbol".to_string(), storage::new_uref(tokenSymbol).into()); + named_keys.insert("uri".to_string(), storage::new_uref(tokenURI).into()); + named_keys.insert( + "total_supply".to_string(), + storage::new_uref(U256::zero()).into(), + ); + + let (contract_package_hash, _) = storage::create_contract_package_at_hash(); + let (contract_hash, _) = + storage::add_contract_version(contract_package_hash, entry_points, named_keys); + runtime::put_key("caspercep47_contract", contract_hash.into()); + let contract_hash_pack = storage::new_uref(contract_hash); + runtime::put_key("caspercep47_contract_hash", contract_hash_pack.into()); +} + +fn ret(value: T) { + runtime::ret(CLValue::from_t(value).unwrap_or_revert()) +} + +fn get_key(name: &str) -> Option { + match runtime::get_key(name) { + None => None, + Some(value) => { + let key = value.try_into().unwrap_or_revert(); + let value = storage::read(key).unwrap_or_revert().unwrap_or_revert(); + Some(value) + } + } +} + +fn set_key(name: &str, value: T) { + match runtime::get_key(name) { + Some(key) => { + let key_ref = key.try_into().unwrap_or_revert(); + storage::write(key_ref, value); + } + None => { + let key = storage::new_uref(value).into(); + runtime::put_key(name, key); + } + } +} + +fn remove_key(name: &str) { + match runtime::get_key(name) { + Some(_) => { + runtime::remove_key(name); + } + None => {} + } +} + +fn balance_key(account: &AccountHash) -> String { + format!("balances_{}", account) +} + +fn owner_key(token_id: &TokenId) -> String { + format!("owners_{}", token_id) +} + +fn uri_key(token_id: &TokenId) -> String { + format!("uris_{}", token_id) +} + +fn token_key(account: &AccountHash) -> String { + format!("tokens_{}", account) +} + +fn endpoint(name: &str, param: Vec, ret: CLType) -> EntryPoint { + EntryPoint::new( + String::from(name), + param, + ret, + EntryPointAccess::Public, + EntryPointType::Contract, + ) +} diff --git a/cep47/src/logic.rs b/cep47/src/logic.rs index 35c33c2..1790bf3 100644 --- a/cep47/src/logic.rs +++ b/cep47/src/logic.rs @@ -2,15 +2,15 @@ #![allow(unused_imports)] use types::{AsymmetricType, PublicKey, URef, U256}; -type TokenId = String; -type URI = String; +pub type TokenId = String; +pub type URI = String; -trait WithStorage { +pub trait WithStorage { fn storage(&self) -> &Storage; fn storage_mut(&mut self) -> &mut Storage; } -trait CEP47Contract: WithStorage { +pub trait CEP47Contract: WithStorage { // Metadata fn name(&self) -> String { self.storage().name() @@ -130,7 +130,7 @@ trait CEP47Contract: WithStorage { } } -trait CEP47Storage { +pub trait CEP47Storage { // Metadata. fn name(&self) -> String; fn symbol(&self) -> String; @@ -153,392 +153,3 @@ trait CEP47Storage { fn token_id(&self, token_uref: URef) -> Option; } -#[cfg(test)] -mod tests { - use rand::Rng; - use types::AccessRights; - - use super::{ - AsymmetricType, CEP47Contract, CEP47Storage, PublicKey, TokenId, URef, WithStorage, U256, - URI, - }; - use std::{ - collections::{hash_map::DefaultHasher, BTreeMap}, - hash::{Hash, Hasher}, - sync::Mutex, - }; - - struct TestStorage { - name: String, - symbol: String, - uri: URI, - total_supply: U256, - tokens: BTreeMap>, - token_uris: BTreeMap, - balances: BTreeMap, - belongs_to: BTreeMap, - urefs: BTreeMap, - } - - impl TestStorage { - pub fn new() -> TestStorage { - TestStorage { - name: String::from("Casper Enhancement Proposal 47"), - symbol: String::from("CEP47"), - uri: URI::from("https://github.com/casper-ecosystem/casper-nft-cep47"), - total_supply: U256::from(0), - tokens: BTreeMap::new(), - balances: BTreeMap::new(), - belongs_to: BTreeMap::new(), - token_uris: BTreeMap::new(), - urefs: BTreeMap::new(), - } - } - } - - impl CEP47Storage for TestStorage { - fn name(&self) -> String { - self.name.clone() - } - - fn symbol(&self) -> String { - self.symbol.clone() - } - - fn uri(&self) -> URI { - self.uri.clone() - } - - fn balance_of(&self, owner: PublicKey) -> U256 { - let owner_balance = self.balances.get(&owner); - if owner_balance.is_none() { - U256::from(0) - } else { - owner_balance.unwrap().clone() - } - } - - fn onwer_of(&self, token_id: TokenId) -> Option { - let owner = self.belongs_to.get(&token_id); - if owner.is_some() { - Some(owner.unwrap().clone()) - } else { - None - } - } - - fn total_supply(&self) -> U256 { - self.total_supply - } - - fn token_uri(&self, token_id: TokenId) -> Option { - let uri = self.token_uris.get(&token_id); - if uri.is_some() { - Some(uri.unwrap().clone()) - } else { - None - } - } - - fn get_tokens(&self, owner: PublicKey) -> Vec { - let owner_tokens = self.tokens.get(&owner); - if owner_tokens.is_none() { - Vec::::new() - } else { - owner_tokens.unwrap().clone() - } - } - - fn set_tokens(&mut self, owner: PublicKey, token_ids: Vec) { - let owner_new_balance = U256::from(token_ids.len() as u64); - - let owner_tokens = self.get_tokens(owner); - for token_id in owner_tokens.clone() { - self.belongs_to.remove(&token_id); - } - for token_id in token_ids.clone() { - self.belongs_to.insert(token_id, owner); - } - - self.tokens.insert(owner, token_ids.clone()); - self.balances.insert(owner, owner_new_balance); - } - - fn mint_many(&mut self, recipient: PublicKey, token_uris: Vec) { - let recipient_balance = self.balances.get(&recipient); - let recipient_tokens = self.tokens.get(&recipient); - let mut recipient_new_balance = if recipient_balance.is_none() { - U256::from(0) - } else { - recipient_balance.unwrap().clone() - }; - let mut recipient_new_tokens = if recipient_tokens.is_none() { - Vec::::new() - } else { - recipient_tokens.unwrap().clone() - }; - - let mut hasher = DefaultHasher::new(); - - for token_uri in token_uris.clone() { - let token_info = (self.total_supply, self.uri.clone(), token_uri.clone()); - Hash::hash(&token_info, &mut hasher); - let token_id: TokenId = TokenId::from(hasher.finish().to_string()); - self.token_uris.insert(token_id.clone(), token_uri); - recipient_new_tokens.push(token_id.clone()); - self.belongs_to.insert(token_id, recipient); - recipient_new_balance = recipient_new_balance + 1; - self.total_supply = self.total_supply + 1; - } - self.balances.insert(recipient, recipient_new_balance); - self.tokens.insert(recipient, recipient_new_tokens); - } - - fn mint_copies(&mut self, recipient: PublicKey, token_uri: URI, count: U256) { - let token_uris: Vec = vec![token_uri; count.as_usize()]; - self.mint_many(recipient, token_uris); - } - - fn new_uref(&mut self, token_id: TokenId) -> Option { - let mut rng = rand::thread_rng(); - let val: [u8; 32] = rng.gen(); - let uref = URef::new(val, AccessRights::READ_ADD_WRITE); - if self.urefs.contains_key(&uref) { - None - } else { - self.urefs.insert(uref, token_id); - Some(uref) - } - } - - fn del_uref(&mut self, token_uref: URef) -> Option { - let token_id = self.token_id(token_uref); - if token_id.is_none() { - None - } else { - let token_id = token_id.unwrap(); - self.urefs.remove(&token_uref); - Some(token_id) - } - } - - fn token_id(&self, token_uref: URef) -> Option { - self.urefs.get(&token_uref).map(|x| x.clone()) - } - } - - struct TestContract { - storage: TestStorage, - } - - impl TestContract { - pub fn new() -> TestContract { - TestContract { - storage: TestStorage::new(), - } - } - } - - impl WithStorage for TestContract { - fn storage(&self) -> &TestStorage { - &self.storage - } - - fn storage_mut(&mut self) -> &mut TestStorage { - &mut self.storage - } - } - - impl CEP47Contract for TestContract {} - - #[test] - fn test_metadata() { - let contract = TestContract::new(); - assert_eq!( - contract.name(), - String::from("Casper Enhancement Proposal 47") - ); - assert_eq!(contract.symbol(), String::from("CEP47")); - assert_eq!( - contract.uri(), - String::from("https://github.com/casper-ecosystem/casper-nft-cep47") - ); - } - #[test] - fn test_mint_many() { - let mut contract = TestContract::new(); - let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); - let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); - - assert_eq!(contract.total_supply(), U256::from(0)); - contract.mint_many(ali, vec![URI::from("Apple URI")]); - contract.mint_many(bob, vec![URI::from("Banana URI"), URI::from("Orange URI")]); - assert_eq!(contract.total_supply(), U256::from(3)); - - let ali_balance = contract.balance_of(ali); - assert_eq!(ali_balance, U256::from(1)); - let bob_balance = contract.balance_of(bob); - assert_eq!(bob_balance, U256::from(2)); - - let ali_tokens: Vec = contract.tokens(ali); - let ali_first_token_uri: URI = contract - .token_uri(ali_tokens.get(0).unwrap().clone()) - .unwrap(); - assert_eq!(ali_first_token_uri, URI::from("Apple URI")); - - let bob_tokens: Vec = contract.tokens(bob); - let bob_first_token_uri: URI = contract - .token_uri(bob_tokens.get(1).unwrap().clone()) - .unwrap(); - assert_eq!(bob_first_token_uri, URI::from("Orange URI")); - } - #[test] - fn test_mint_copies() { - let mut contract = TestContract::new(); - let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); - - assert_eq!(contract.total_supply(), U256::from(0)); - contract.mint_copies(ali, URI::from("Casper Fan URI"), U256::from(7)); - assert_eq!(contract.total_supply(), U256::from(7)); - - let ali_balance = contract.balance_of(ali); - assert_eq!(ali_balance, U256::from(7)); - - let ali_tokens: Vec = contract.tokens(ali); - let ali_first_token_uri: URI = contract - .token_uri(ali_tokens.get(0).unwrap().clone()) - .unwrap(); - let ali_third_token_uri: URI = contract - .token_uri(ali_tokens.get(2).unwrap().clone()) - .unwrap(); - assert_eq!(ali_first_token_uri, URI::from("Casper Fan URI")); - assert_eq!(ali_third_token_uri, URI::from("Casper Fan URI")); - } - #[test] - fn test_transfer_token() { - let mut contract = TestContract::new(); - let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); - let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); - - assert_eq!(contract.total_supply(), U256::from(0)); - contract.mint_one(ali, URI::from("Casper Fan URI")); - assert_eq!(contract.total_supply(), U256::from(1)); - - let mut ali_balance = contract.balance_of(ali); - let mut bob_balance = contract.balance_of(bob); - assert_eq!(ali_balance, U256::from(1)); - assert_eq!(bob_balance, U256::from(0)); - - let ali_tokens: Vec = contract.tokens(ali); - let ali_first_token_id: TokenId = ali_tokens.get(0).unwrap().clone(); - let ali_first_token_uri: URI = contract.token_uri(ali_first_token_id.clone()).unwrap(); - assert_eq!(ali_first_token_uri, URI::from("Casper Fan URI")); - - contract.transfer_token(ali, bob, ali_first_token_id.clone()); - ali_balance = contract.balance_of(ali); - bob_balance = contract.balance_of(bob); - assert_eq!(ali_balance, U256::from(0)); - assert_eq!(bob_balance, U256::from(1)); - - let owner_of_first_token_id = contract.owner_of(ali_first_token_id); - assert_eq!(owner_of_first_token_id.unwrap(), bob); - } - #[test] - fn test_transfer_all_tokens() { - let mut contract = TestContract::new(); - let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); - let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); - - assert_eq!(contract.total_supply(), U256::from(0)); - contract.mint_many(ali, vec![URI::from("Apple URI"), URI::from("Banana URI")]); - contract.mint_one(ali, URI::from("Casper Fan URI")); - assert_eq!(contract.total_supply(), U256::from(3)); - - let mut ali_balance = contract.balance_of(ali); - let mut bob_balance = contract.balance_of(bob); - assert_eq!(ali_balance, U256::from(3)); - assert_eq!(bob_balance, U256::from(0)); - - let ali_tokens: Vec = contract.tokens(ali); - let ali_second_token_id: TokenId = ali_tokens.get(1).unwrap().clone(); - let ali_second_token_uri: URI = contract.token_uri(ali_second_token_id.clone()).unwrap(); - assert_eq!(ali_second_token_uri, URI::from("Banana URI")); - - contract.transfer_all_tokens(ali, bob); - - ali_balance = contract.balance_of(ali); - bob_balance = contract.balance_of(bob); - assert_eq!(ali_balance, U256::from(0)); - assert_eq!(bob_balance, U256::from(3)); - - let owner_of_second_token_id = contract.owner_of(ali_second_token_id); - assert_eq!(owner_of_second_token_id.unwrap(), bob); - } - - #[test] - fn test_transfer_many_tokens() { - let mut contract = TestContract::new(); - let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); - let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); - - assert_eq!(contract.total_supply(), U256::from(0)); - contract.mint_many(ali, vec![URI::from("Apple URI"), URI::from("Banana URI")]); - contract.mint_copies(ali, URI::from("Casper Fan URI"), U256::from(3)); - assert_eq!(contract.total_supply(), U256::from(5)); - - let mut ali_balance = contract.balance_of(ali); - let mut bob_balance = contract.balance_of(bob); - assert_eq!(ali_balance, U256::from(5)); - assert_eq!(bob_balance, U256::from(0)); - - let ali_tokens: Vec = contract.tokens(ali); - let ali_second_token_id: TokenId = ali_tokens.get(1).unwrap().clone(); - let ali_second_token_uri: URI = contract.token_uri(ali_second_token_id.clone()).unwrap(); - let ali_third_token_id: TokenId = ali_tokens.get(2).unwrap().clone(); - let ali_third_token_uri: URI = contract.token_uri(ali_third_token_id.clone()).unwrap(); - assert_eq!(ali_second_token_uri, URI::from("Banana URI")); - assert_eq!(ali_third_token_uri, URI::from("Casper Fan URI")); - - contract.transfer_many_tokens( - ali, - bob, - vec![ali_second_token_id.clone(), ali_third_token_id.clone()], - ); - - ali_balance = contract.balance_of(ali); - bob_balance = contract.balance_of(bob); - assert_eq!(ali_balance, U256::from(3)); - assert_eq!(bob_balance, U256::from(2)); - - let owner_of_second_token_id = contract.owner_of(ali_second_token_id); - let owner_of_third_token_id = contract.owner_of(ali_third_token_id); - assert_eq!(owner_of_second_token_id.unwrap(), bob); - assert_eq!(owner_of_third_token_id.unwrap(), bob); - } - - #[test] - fn test_attach_and_detach() { - let mut contract = TestContract::new(); - let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); - let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); - - contract.mint_one(ali, URI::from("0x12af")); - let token_id: TokenId = contract.tokens(ali)[0].clone(); - - let token_uref: URef = contract.detach(ali, token_id.clone()).unwrap(); - assert_eq!(contract.balance_of(ali), U256::zero()); - assert_eq!(contract.total_supply(), U256::one()); - assert!(contract.tokens(ali).is_empty()); - - assert_eq!(contract.token_id(token_uref.clone()), token_id.clone()); - assert_eq!( - contract.token_uri(token_id.clone()).unwrap(), - URI::from("0x12af") - ); - - contract.attach(token_uref, bob); - assert_eq!(contract.balance_of(bob), U256::one()); - assert_eq!(contract.total_supply(), U256::one()); - assert_eq!(contract.tokens(bob), vec![token_id]); - } -} diff --git a/cep47/src/main.rs b/cep47/src/main.rs index ee69d4d..88d3484 100644 --- a/cep47/src/main.rs +++ b/cep47/src/main.rs @@ -1,551 +1,11 @@ #![no_main] -#![allow(unused_imports)] -#![allow(unused_parens)] -#![allow(non_snake_case)] - -extern crate alloc; - -use alloc::{ - collections::{BTreeMap, BTreeSet}, - string::String, -}; -use contract::{ - contract_api::{runtime, storage}, - unwrap_or_revert::UnwrapOrRevert, -}; -use core::convert::TryInto; -use std::{ - collections::hash_map::DefaultHasher, - hash::{Hash, Hasher}, -}; -use types::{ - account::AccountHash, - bytesrepr::{FromBytes, ToBytes}, - contracts::NamedKeys, - AccessRights, ApiError, AsymmetricType, CLType, CLTyped, CLValue, EntryPoint, EntryPointAccess, - EntryPointType, EntryPoints, Key, Parameter, PublicKey, URef, U256, -}; - -type TokenId = String; -type URI = String; - -trait WithStorage { - fn storage(&self) -> &Storage; - fn storage_mut(&mut self) -> &mut Storage; -} - -trait CEP47Contract: WithStorage { - // Metadata - fn name(&self) -> String { - self.storage().name() - } - - fn symbol(&self) -> String { - self.storage().symbol() - } - - fn uri(&self) -> URI { - self.storage().uri() - } - - // Getters - fn balance_of(&self, owner: PublicKey) -> U256 { - self.storage().balance_of(owner) - } - - fn owner_of(&self, token_id: TokenId) -> Option { - self.storage().onwer_of(token_id) - } - - fn total_supply(&self) -> U256 { - self.storage().total_supply() - } - - fn token_uri(&self, token_id: TokenId) -> Option { - self.storage().token_uri(token_id) - } - - fn tokens(&self, owner: PublicKey) -> Vec { - self.storage().get_tokens(owner) - } - - // Minter function. - // Guarded by the entrypoint group. - fn mint_one(&mut self, recipient: PublicKey, token_uri: URI) { - self.storage_mut() - .mint_copies(recipient, token_uri, U256::one()); - } - - fn mint_many(&mut self, recipient: PublicKey, token_uris: Vec) { - self.storage_mut().mint_many(recipient, token_uris); - } - - fn mint_copies(&mut self, recipient: PublicKey, token_uri: URI, count: U256) { - self.storage_mut().mint_copies(recipient, token_uri, count); - } - - // Transfer functions. - fn transfer_token(&mut self, sender: PublicKey, recipient: PublicKey, token_id: TokenId) { - // 1. Load tokens owned by the sender. - let mut sender_tokens = self.storage().get_tokens(sender); - // 2. Assert that token_id is in sender_tokens. - assert!( - sender_tokens.contains(&token_id), - "wrong owner of token {}", - token_id - ); - // 3. Remove token_id from sender_tokens. - sender_tokens.retain(|x| x.clone() != token_id); - self.storage_mut().set_tokens(sender, sender_tokens); - - // 4. Add token_id to the recipient tokens - let mut recipient_tokens = self.storage().get_tokens(recipient); - recipient_tokens.push(token_id); - self.storage_mut().set_tokens(recipient, recipient_tokens); - } - - fn transfer_many_tokens( - &mut self, - sender: PublicKey, - recipient: PublicKey, - token_ids: Vec, - ) { - let mut sender_tokens = self.storage().get_tokens(sender); - for token_id in token_ids.iter() { - assert!(sender_tokens.contains(token_id), "wrong token {}", token_id); - sender_tokens.retain(|x| x.clone() != token_id.clone()); - } - let mut recipient_tokens = self.storage().get_tokens(recipient); - recipient_tokens.append(&mut token_ids.clone()); - self.storage_mut().set_tokens(sender, sender_tokens); - self.storage_mut().set_tokens(recipient, recipient_tokens); - } - - fn transfer_all_tokens(&mut self, sender: PublicKey, recipient: PublicKey) { - let mut sender_tokens = self.storage().get_tokens(sender); - let mut recipient_tokens = self.storage().get_tokens(recipient); - recipient_tokens.append(&mut sender_tokens); - - self.storage_mut().set_tokens(sender, sender_tokens); - self.storage_mut().set_tokens(recipient, recipient_tokens); - } - - // URef releated function. - // fn detach(&mut self, owner: PublicKey, token_id: TokenId) -> Option { - // let mut tokens = self.storage().get_tokens(owner); - // if !tokens.contains(&token_id) { - // None - // } else { - // tokens.retain(|x| x != &token_id); - // self.storage_mut().set_tokens(owner, tokens); - // self.storage_mut().new_uref(token_id) - // } - // } - - // fn attach(&mut self, token_uref: URef, recipient: PublicKey) { - // let token_id = self.storage_mut().del_uref(token_uref).unwrap(); - // let mut tokens = self.storage().get_tokens(recipient); - // tokens.push(token_id); - // self.storage_mut().set_tokens(recipient, tokens); - // } - - // fn token_id(&self, token_uref: URef) -> TokenId { - // self.storage().token_id(token_uref).unwrap() - // } -} - -trait CEP47Storage { - // Metadata. - fn name(&self) -> String { - get_key::("name").unwrap() - } - fn symbol(&self) -> String { - get_key::("symbol").unwrap() - } - fn uri(&self) -> URI { - get_key::("uri").unwrap() - } - - // Getters - fn balance_of(&self, owner: PublicKey) -> U256 { - let owner_balance = get_key::(&balance_key(&owner.to_account_hash())); - if owner_balance.is_none() { - U256::from(0) - } else { - owner_balance.unwrap() - } - } - fn onwer_of(&self, token_id: TokenId) -> Option { - get_key::(&owner_key(&token_id)) - } - fn total_supply(&self) -> U256 { - get_key::("total_supply").unwrap() - } - fn token_uri(&self, token_id: TokenId) -> Option { - get_key::(&uri_key(&token_id)) - } - - // Setters - fn get_tokens(&self, owner: PublicKey) -> Vec { - let owner_tokens = get_key::>(&token_key(&owner.to_account_hash())); - if owner_tokens.is_none() { - Vec::::new() - } else { - owner_tokens.unwrap() - } - } - fn set_tokens(&mut self, owner: PublicKey, token_ids: Vec) { - let owner_prev_balance = self.balance_of(owner); - let owner_new_balance = U256::from(token_ids.len() as u64); - let prev_total_supply = self.total_supply(); - - let owner_tokens = self.get_tokens(owner); - for token_id in owner_tokens.clone() { - remove_key(&owner_key(&token_id)); - } - for token_id in token_ids.clone() { - set_key(&owner_key(&token_id), owner); - } - set_key(&token_key(&owner.to_account_hash()), token_ids); - set_key(&balance_key(&owner.to_account_hash()), owner_new_balance); - set_key( - "total_supply", - prev_total_supply - owner_prev_balance + owner_new_balance, - ); - } - fn mint_many(&mut self, recipient: PublicKey, token_uris: Vec) { - let mut recipient_tokens = self.get_tokens(recipient); - let mut recipient_balance = self.balance_of(recipient); - let mut total_supply = self.total_supply(); - let uri = self.uri(); - - let mut hasher = DefaultHasher::new(); - for token_uri in token_uris.clone() { - let token_info = (total_supply, uri.clone(), token_uri.clone()); - Hash::hash(&token_info, &mut hasher); - - let token_id = TokenId::from(hasher.finish().to_string()); - recipient_tokens.push(token_id.clone()); - total_supply = total_supply + 1; - set_key(&uri_key(&token_id), token_uri); - set_key(&owner_key(&token_id), recipient); - } - recipient_balance = recipient_balance + U256::from(token_uris.len() as u64); - set_key( - &balance_key(&recipient.to_account_hash()), - recipient_balance, - ); - set_key(&token_key(&recipient.to_account_hash()), recipient_tokens); - set_key("total_supply", total_supply); - } - fn mint_copies(&mut self, recipient: PublicKey, token_uri: URI, count: U256) { - let token_uris: Vec = vec![token_uri; count.as_usize()]; - self.mint_many(recipient, token_uris); - } - // fn new_uref(&mut self, token_id: TokenId) -> Option {} - // fn del_uref(&mut self, token_uref: URef) -> Option {} - // fn token_id(&self, token_uref: URef) -> Option {} -} - -struct CasperCEP47Storage {} -impl CasperCEP47Storage { - pub fn new() -> CasperCEP47Storage { - CasperCEP47Storage {} - } -} -impl CEP47Storage for CasperCEP47Storage {} -struct CasperCEP47Contract { - storage: CasperCEP47Storage, -} -impl CasperCEP47Contract { - pub fn new() -> CasperCEP47Contract { - CasperCEP47Contract { - storage: CasperCEP47Storage::new(), - } - } -} -impl WithStorage for CasperCEP47Contract { - fn storage(&self) -> &CasperCEP47Storage { - &self.storage - } - fn storage_mut(&mut self) -> &mut CasperCEP47Storage { - &mut self.storage - } -} -impl CEP47Contract for CasperCEP47Contract {} -/** - * ApiError::User(1) - The number of piece is out or range. - * ApiError::User(2) - The piece of NFT is already minted and owned by someone. - * ApiError::User(3) - The piece of NFT is not minted yet. - */ - -#[no_mangle] -pub extern "C" fn name() { - let contract = CasperCEP47Contract::new(); - ret(contract.name()) -} - -#[no_mangle] -pub extern "C" fn symbol() { - let contract = CasperCEP47Contract::new(); - ret(contract.symbol()) -} - -#[no_mangle] -pub extern "C" fn uri() { - let contract = CasperCEP47Contract::new(); - ret(contract.uri()) -} - -#[no_mangle] -pub extern "C" fn balance_of() { - let account: PublicKey = runtime::get_named_arg("account"); - let contract = CasperCEP47Contract::new(); - ret(contract.balance_of(account)) -} - -#[no_mangle] -pub extern "C" fn owner_of() { - let token_id: TokenId = runtime::get_named_arg("token_id"); - let contract = CasperCEP47Contract::new(); - ret(contract.owner_of(token_id)) -} - -#[no_mangle] -pub extern "C" fn total_supply() { - let contract = CasperCEP47Contract::new(); - ret(contract.total_supply()) -} - -#[no_mangle] -pub extern "C" fn token_uri() { - let token_id: TokenId = runtime::get_named_arg("token_id"); - let contract = CasperCEP47Contract::new(); - ret(contract.token_uri(token_id)) -} - -#[no_mangle] -pub extern "C" fn tokens() { - let owner: PublicKey = runtime::get_named_arg("owner"); - let contract = CasperCEP47Contract::new(); - ret(contract.tokens(owner)) -} - -#[no_mangle] -pub extern "C" fn mint_one() { - let recipient: PublicKey = runtime::get_named_arg("recipient"); - let token_uri: URI = runtime::get_named_arg("token_uri"); - let mut contract = CasperCEP47Contract::new(); - contract.mint_one(recipient, token_uri); -} - -#[no_mangle] -pub extern "C" fn mint_many() { - let recipient: PublicKey = runtime::get_named_arg("recipient"); - let token_uris: Vec = runtime::get_named_arg("token_uris"); - let mut contract = CasperCEP47Contract::new(); - contract.mint_many(recipient, token_uris); -} - -#[no_mangle] -pub extern "C" fn mint_copies() { - let recipient: PublicKey = runtime::get_named_arg("recipient"); - let token_uri: URI = runtime::get_named_arg("token_uri"); - let count: U256 = runtime::get_named_arg("count"); - let mut contract = CasperCEP47Contract::new(); - contract.mint_copies(recipient, token_uri, count); -} - -#[no_mangle] -pub extern "C" fn transfer_token() { - let sender: PublicKey = runtime::get_named_arg("sender"); - let recipient: PublicKey = runtime::get_named_arg("recipient"); - let token_id: TokenId = runtime::get_named_arg("token_id"); - let mut contract = CasperCEP47Contract::new(); - contract.transfer_token(sender, recipient, token_id); -} - -#[no_mangle] -pub extern "C" fn transfer_many_tokens() { - let sender: PublicKey = runtime::get_named_arg("sender"); - let recipient: PublicKey = runtime::get_named_arg("recipient"); - let token_ids: Vec = runtime::get_named_arg("token_ids"); - let mut contract = CasperCEP47Contract::new(); - contract.transfer_many_tokens(sender, recipient, token_ids); -} - -#[no_mangle] -pub extern "C" fn transfer_all_tokens() { - let sender: PublicKey = runtime::get_named_arg("sender"); - let recipient: PublicKey = runtime::get_named_arg("recipient"); - let mut contract = CasperCEP47Contract::new(); - contract.transfer_all_tokens(sender, recipient); -} +extern crate cep47; #[no_mangle] pub extern "C" fn call() { - let tokenName: String = runtime::get_named_arg("token_name"); - let tokenSymbol: String = runtime::get_named_arg("token_symbol"); - let tokenURI: URI = runtime::get_named_arg("token_uri"); - - let mut entry_points = EntryPoints::new(); - entry_points.add_entry_point(endpoint("name", vec![], CLType::String)); - entry_points.add_entry_point(endpoint("symbol", vec![], CLType::String)); - entry_points.add_entry_point(endpoint("uri", vec![], CLType::String)); - entry_points.add_entry_point(endpoint("total_supply", vec![], CLType::U256)); - entry_points.add_entry_point(endpoint( - "balance_of", - vec![Parameter::new("account", CLType::PublicKey)], - CLType::U256, - )); - entry_points.add_entry_point(endpoint( - "owner_of", - vec![Parameter::new("token_id", CLType::String)], - CLType::Option(Box::new(CLType::PublicKey)), - )); - entry_points.add_entry_point(endpoint( - "token_uri", - vec![Parameter::new("token_id", CLType::String)], - CLType::Option(Box::new(CLType::String)), - )); - entry_points.add_entry_point(endpoint( - "tokens", - vec![Parameter::new("owner", CLType::PublicKey)], - CLType::List(Box::new(CLType::String)), - )); - entry_points.add_entry_point(endpoint( - "tokens", - vec![Parameter::new("owner", CLType::PublicKey)], - CLType::List(Box::new(CLType::String)), - )); - entry_points.add_entry_point(endpoint( - "mint_one", - vec![ - Parameter::new("recipient", CLType::PublicKey), - Parameter::new("token_uri", CLType::String), - ], - CLType::Unit, - )); - entry_points.add_entry_point(endpoint( - "mint_many", - vec![ - Parameter::new("recipient", CLType::PublicKey), - Parameter::new("token_uris", CLType::List(Box::new(CLType::String))), - ], - CLType::Unit, - )); - entry_points.add_entry_point(endpoint( - "mint_copies", - vec![ - Parameter::new("recipient", CLType::PublicKey), - Parameter::new("token_uri", CLType::String), - Parameter::new("count", CLType::U256), - ], - CLType::Unit, - )); - entry_points.add_entry_point(endpoint( - "transfer_token", - vec![ - Parameter::new("sender", CLType::PublicKey), - Parameter::new("recipient", CLType::PublicKey), - Parameter::new("token_id", CLType::String), - ], - CLType::Unit, - )); - entry_points.add_entry_point(endpoint( - "transfer_many_tokens", - vec![ - Parameter::new("sender", CLType::PublicKey), - Parameter::new("recipient", CLType::PublicKey), - Parameter::new("token_ids", CLType::List(Box::new(CLType::String))), - ], - CLType::Unit, - )); - entry_points.add_entry_point(endpoint( - "transfer_all_tokens", - vec![ - Parameter::new("sender", CLType::PublicKey), - Parameter::new("recipient", CLType::PublicKey), - ], - CLType::Unit, - )); - - let mut named_keys = NamedKeys::new(); - named_keys.insert("name".to_string(), storage::new_uref(tokenName).into()); - named_keys.insert("symbol".to_string(), storage::new_uref(tokenSymbol).into()); - named_keys.insert("uri".to_string(), storage::new_uref(tokenURI).into()); - named_keys.insert( - "total_supply".to_string(), - storage::new_uref(U256::zero()).into(), + cep47::deploy( + &contract::contract_api::runtime::get_named_arg::("token_name"), + &contract::contract_api::runtime::get_named_arg::("token_symbol"), + &contract::contract_api::runtime::get_named_arg::("token_uri") ); - - let (contract_package_hash, _) = storage::create_contract_package_at_hash(); - let (contract_hash, _) = - storage::add_contract_version(contract_package_hash, entry_points, named_keys); - runtime::put_key("caspercep47_contract", contract_hash.into()); - let contract_hash_pack = storage::new_uref(contract_hash); - runtime::put_key("caspercep47_contract_hash", contract_hash_pack.into()); -} - -fn ret(value: T) { - runtime::ret(CLValue::from_t(value).unwrap_or_revert()) -} - -fn get_key(name: &str) -> Option { - match runtime::get_key(name) { - None => None, - Some(value) => { - let key = value.try_into().unwrap_or_revert(); - let value = storage::read(key).unwrap_or_revert().unwrap_or_revert(); - Some(value) - } - } -} - -fn set_key(name: &str, value: T) { - match runtime::get_key(name) { - Some(key) => { - let key_ref = key.try_into().unwrap_or_revert(); - storage::write(key_ref, value); - } - None => { - let key = storage::new_uref(value).into(); - runtime::put_key(name, key); - } - } -} - -fn remove_key(name: &str) { - match runtime::get_key(name) { - Some(_) => { - runtime::remove_key(name); - } - None => {} - } -} - -fn balance_key(account: &AccountHash) -> String { - format!("balances_{}", account) -} - -fn owner_key(token_id: &TokenId) -> String { - format!("owners_{}", token_id) -} - -fn uri_key(token_id: &TokenId) -> String { - format!("uris_{}", token_id) -} - -fn token_key(account: &AccountHash) -> String { - format!("tokens_{}", account) -} - -fn endpoint(name: &str, param: Vec, ret: CLType) -> EntryPoint { - EntryPoint::new( - String::from(name), - param, - ret, - EntryPointAccess::Public, - EntryPointType::Contract, - ) -} +} \ No newline at end of file diff --git a/cep47/src/tests.rs b/cep47/src/tests.rs new file mode 100644 index 0000000..2df3453 --- /dev/null +++ b/cep47/src/tests.rs @@ -0,0 +1,389 @@ +#[cfg(test)] +mod tests { + use rand::Rng; + use types::AccessRights; + + use crate::{ + AsymmetricType, CEP47Contract, CEP47Storage, PublicKey, TokenId, URef, WithStorage, U256, + URI, + }; + use std::{ + collections::{hash_map::DefaultHasher, BTreeMap}, + hash::{Hash, Hasher}, + sync::Mutex, + }; + + struct TestStorage { + name: String, + symbol: String, + uri: URI, + total_supply: U256, + tokens: BTreeMap>, + token_uris: BTreeMap, + balances: BTreeMap, + belongs_to: BTreeMap, + urefs: BTreeMap, + } + + impl TestStorage { + pub fn new() -> TestStorage { + TestStorage { + name: String::from("Casper Enhancement Proposal 47"), + symbol: String::from("CEP47"), + uri: URI::from("https://github.com/casper-ecosystem/casper-nft-cep47"), + total_supply: U256::from(0), + tokens: BTreeMap::new(), + balances: BTreeMap::new(), + belongs_to: BTreeMap::new(), + token_uris: BTreeMap::new(), + urefs: BTreeMap::new(), + } + } + } + + impl CEP47Storage for TestStorage { + fn name(&self) -> String { + self.name.clone() + } + + fn symbol(&self) -> String { + self.symbol.clone() + } + + fn uri(&self) -> URI { + self.uri.clone() + } + + fn balance_of(&self, owner: PublicKey) -> U256 { + let owner_balance = self.balances.get(&owner); + if owner_balance.is_none() { + U256::from(0) + } else { + owner_balance.unwrap().clone() + } + } + + fn onwer_of(&self, token_id: TokenId) -> Option { + let owner = self.belongs_to.get(&token_id); + if owner.is_some() { + Some(owner.unwrap().clone()) + } else { + None + } + } + + fn total_supply(&self) -> U256 { + self.total_supply + } + + fn token_uri(&self, token_id: TokenId) -> Option { + let uri = self.token_uris.get(&token_id); + if uri.is_some() { + Some(uri.unwrap().clone()) + } else { + None + } + } + + fn get_tokens(&self, owner: PublicKey) -> Vec { + let owner_tokens = self.tokens.get(&owner); + if owner_tokens.is_none() { + Vec::::new() + } else { + owner_tokens.unwrap().clone() + } + } + + fn set_tokens(&mut self, owner: PublicKey, token_ids: Vec) { + let owner_new_balance = U256::from(token_ids.len() as u64); + + let owner_tokens = self.get_tokens(owner); + for token_id in owner_tokens.clone() { + self.belongs_to.remove(&token_id); + } + for token_id in token_ids.clone() { + self.belongs_to.insert(token_id, owner); + } + + self.tokens.insert(owner, token_ids.clone()); + self.balances.insert(owner, owner_new_balance); + } + + fn mint_many(&mut self, recipient: PublicKey, token_uris: Vec) { + let recipient_balance = self.balances.get(&recipient); + let recipient_tokens = self.tokens.get(&recipient); + let mut recipient_new_balance = if recipient_balance.is_none() { + U256::from(0) + } else { + recipient_balance.unwrap().clone() + }; + let mut recipient_new_tokens = if recipient_tokens.is_none() { + Vec::::new() + } else { + recipient_tokens.unwrap().clone() + }; + + let mut hasher = DefaultHasher::new(); + + for token_uri in token_uris.clone() { + let token_info = (self.total_supply, self.uri.clone(), token_uri.clone()); + Hash::hash(&token_info, &mut hasher); + let token_id: TokenId = TokenId::from(hasher.finish().to_string()); + self.token_uris.insert(token_id.clone(), token_uri); + recipient_new_tokens.push(token_id.clone()); + self.belongs_to.insert(token_id, recipient); + recipient_new_balance = recipient_new_balance + 1; + self.total_supply = self.total_supply + 1; + } + self.balances.insert(recipient, recipient_new_balance); + self.tokens.insert(recipient, recipient_new_tokens); + } + + fn mint_copies(&mut self, recipient: PublicKey, token_uri: URI, count: U256) { + let token_uris: Vec = vec![token_uri; count.as_usize()]; + self.mint_many(recipient, token_uris); + } + + fn new_uref(&mut self, token_id: TokenId) -> Option { + let mut rng = rand::thread_rng(); + let val: [u8; 32] = rng.gen(); + let uref = URef::new(val, AccessRights::READ_ADD_WRITE); + if self.urefs.contains_key(&uref) { + None + } else { + self.urefs.insert(uref, token_id); + Some(uref) + } + } + + fn del_uref(&mut self, token_uref: URef) -> Option { + let token_id = self.token_id(token_uref); + if token_id.is_none() { + None + } else { + let token_id = token_id.unwrap(); + self.urefs.remove(&token_uref); + Some(token_id) + } + } + + fn token_id(&self, token_uref: URef) -> Option { + self.urefs.get(&token_uref).map(|x| x.clone()) + } + } + + struct TestContract { + storage: TestStorage, + } + + impl TestContract { + pub fn new() -> TestContract { + TestContract { + storage: TestStorage::new(), + } + } + } + + impl WithStorage for TestContract { + fn storage(&self) -> &TestStorage { + &self.storage + } + + fn storage_mut(&mut self) -> &mut TestStorage { + &mut self.storage + } + } + + impl CEP47Contract for TestContract {} + + #[test] + fn test_metadata() { + let contract = TestContract::new(); + assert_eq!( + contract.name(), + String::from("Casper Enhancement Proposal 47") + ); + assert_eq!(contract.symbol(), String::from("CEP47")); + assert_eq!( + contract.uri(), + String::from("https://github.com/casper-ecosystem/casper-nft-cep47") + ); + } + #[test] + fn test_mint_many() { + let mut contract = TestContract::new(); + let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); + + assert_eq!(contract.total_supply(), U256::from(0)); + contract.mint_many(ali, vec![URI::from("Apple URI")]); + contract.mint_many(bob, vec![URI::from("Banana URI"), URI::from("Orange URI")]); + assert_eq!(contract.total_supply(), U256::from(3)); + + let ali_balance = contract.balance_of(ali); + assert_eq!(ali_balance, U256::from(1)); + let bob_balance = contract.balance_of(bob); + assert_eq!(bob_balance, U256::from(2)); + + let ali_tokens: Vec = contract.tokens(ali); + let ali_first_token_uri: URI = contract + .token_uri(ali_tokens.get(0).unwrap().clone()) + .unwrap(); + assert_eq!(ali_first_token_uri, URI::from("Apple URI")); + + let bob_tokens: Vec = contract.tokens(bob); + let bob_first_token_uri: URI = contract + .token_uri(bob_tokens.get(1).unwrap().clone()) + .unwrap(); + assert_eq!(bob_first_token_uri, URI::from("Orange URI")); + } + #[test] + fn test_mint_copies() { + let mut contract = TestContract::new(); + let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + + assert_eq!(contract.total_supply(), U256::from(0)); + contract.mint_copies(ali, URI::from("Casper Fan URI"), U256::from(7)); + assert_eq!(contract.total_supply(), U256::from(7)); + + let ali_balance = contract.balance_of(ali); + assert_eq!(ali_balance, U256::from(7)); + + let ali_tokens: Vec = contract.tokens(ali); + let ali_first_token_uri: URI = contract + .token_uri(ali_tokens.get(0).unwrap().clone()) + .unwrap(); + let ali_third_token_uri: URI = contract + .token_uri(ali_tokens.get(2).unwrap().clone()) + .unwrap(); + assert_eq!(ali_first_token_uri, URI::from("Casper Fan URI")); + assert_eq!(ali_third_token_uri, URI::from("Casper Fan URI")); + } + #[test] + fn test_transfer_token() { + let mut contract = TestContract::new(); + let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); + + assert_eq!(contract.total_supply(), U256::from(0)); + contract.mint_one(ali, URI::from("Casper Fan URI")); + assert_eq!(contract.total_supply(), U256::from(1)); + + let mut ali_balance = contract.balance_of(ali); + let mut bob_balance = contract.balance_of(bob); + assert_eq!(ali_balance, U256::from(1)); + assert_eq!(bob_balance, U256::from(0)); + + let ali_tokens: Vec = contract.tokens(ali); + let ali_first_token_id: TokenId = ali_tokens.get(0).unwrap().clone(); + let ali_first_token_uri: URI = contract.token_uri(ali_first_token_id.clone()).unwrap(); + assert_eq!(ali_first_token_uri, URI::from("Casper Fan URI")); + + contract.transfer_token(ali, bob, ali_first_token_id.clone()); + ali_balance = contract.balance_of(ali); + bob_balance = contract.balance_of(bob); + assert_eq!(ali_balance, U256::from(0)); + assert_eq!(bob_balance, U256::from(1)); + + let owner_of_first_token_id = contract.owner_of(ali_first_token_id); + assert_eq!(owner_of_first_token_id.unwrap(), bob); + } + #[test] + fn test_transfer_all_tokens() { + let mut contract = TestContract::new(); + let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); + + assert_eq!(contract.total_supply(), U256::from(0)); + contract.mint_many(ali, vec![URI::from("Apple URI"), URI::from("Banana URI")]); + contract.mint_one(ali, URI::from("Casper Fan URI")); + assert_eq!(contract.total_supply(), U256::from(3)); + + let mut ali_balance = contract.balance_of(ali); + let mut bob_balance = contract.balance_of(bob); + assert_eq!(ali_balance, U256::from(3)); + assert_eq!(bob_balance, U256::from(0)); + + let ali_tokens: Vec = contract.tokens(ali); + let ali_second_token_id: TokenId = ali_tokens.get(1).unwrap().clone(); + let ali_second_token_uri: URI = contract.token_uri(ali_second_token_id.clone()).unwrap(); + assert_eq!(ali_second_token_uri, URI::from("Banana URI")); + + contract.transfer_all_tokens(ali, bob); + + ali_balance = contract.balance_of(ali); + bob_balance = contract.balance_of(bob); + assert_eq!(ali_balance, U256::from(0)); + assert_eq!(bob_balance, U256::from(3)); + + let owner_of_second_token_id = contract.owner_of(ali_second_token_id); + assert_eq!(owner_of_second_token_id.unwrap(), bob); + } + + #[test] + fn test_transfer_many_tokens() { + let mut contract = TestContract::new(); + let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); + + assert_eq!(contract.total_supply(), U256::from(0)); + contract.mint_many(ali, vec![URI::from("Apple URI"), URI::from("Banana URI")]); + contract.mint_copies(ali, URI::from("Casper Fan URI"), U256::from(3)); + assert_eq!(contract.total_supply(), U256::from(5)); + + let mut ali_balance = contract.balance_of(ali); + let mut bob_balance = contract.balance_of(bob); + assert_eq!(ali_balance, U256::from(5)); + assert_eq!(bob_balance, U256::from(0)); + + let ali_tokens: Vec = contract.tokens(ali); + let ali_second_token_id: TokenId = ali_tokens.get(1).unwrap().clone(); + let ali_second_token_uri: URI = contract.token_uri(ali_second_token_id.clone()).unwrap(); + let ali_third_token_id: TokenId = ali_tokens.get(2).unwrap().clone(); + let ali_third_token_uri: URI = contract.token_uri(ali_third_token_id.clone()).unwrap(); + assert_eq!(ali_second_token_uri, URI::from("Banana URI")); + assert_eq!(ali_third_token_uri, URI::from("Casper Fan URI")); + + contract.transfer_many_tokens( + ali, + bob, + vec![ali_second_token_id.clone(), ali_third_token_id.clone()], + ); + + ali_balance = contract.balance_of(ali); + bob_balance = contract.balance_of(bob); + assert_eq!(ali_balance, U256::from(3)); + assert_eq!(bob_balance, U256::from(2)); + + let owner_of_second_token_id = contract.owner_of(ali_second_token_id); + let owner_of_third_token_id = contract.owner_of(ali_third_token_id); + assert_eq!(owner_of_second_token_id.unwrap(), bob); + assert_eq!(owner_of_third_token_id.unwrap(), bob); + } + + #[test] + fn test_attach_and_detach() { + let mut contract = TestContract::new(); + let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); + + contract.mint_one(ali, URI::from("0x12af")); + let token_id: TokenId = contract.tokens(ali)[0].clone(); + + let token_uref: URef = contract.detach(ali, token_id.clone()).unwrap(); + assert_eq!(contract.balance_of(ali), U256::zero()); + assert_eq!(contract.total_supply(), U256::one()); + assert!(contract.tokens(ali).is_empty()); + + assert_eq!(contract.token_id(token_uref.clone()), token_id.clone()); + assert_eq!( + contract.token_uri(token_id.clone()).unwrap(), + URI::from("0x12af") + ); + + contract.attach(token_uref, bob); + assert_eq!(contract.balance_of(bob), U256::one()); + assert_eq!(contract.total_supply(), U256::one()); + assert_eq!(contract.tokens(bob), vec![token_id]); + } +} From 9980b890de0ca2620480ba2129ea3253d2e9e409 Mon Sep 17 00:00:00 2001 From: Deusz Date: Thu, 27 May 2021 14:40:03 +0200 Subject: [PATCH 17/98] group access to minting --- cep47/src/lib.rs | 37 +++++++++++++++++++++++++++---------- cep47/src/main.rs | 3 ++- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/cep47/src/lib.rs b/cep47/src/lib.rs index ec02745..ff69952 100644 --- a/cep47/src/lib.rs +++ b/cep47/src/lib.rs @@ -385,41 +385,49 @@ pub extern "C" fn transfer_all_tokens() { contract.transfer_all_tokens(sender, recipient); } - -pub fn deploy(token_name: &str, token_symbol: &str, token_uri: &str) { +pub fn deploy(token_name: &str, token_symbol: &str, token_uri: &str, secure: bool) { let tokenName: String = runtime::get_named_arg("token_name"); let tokenSymbol: String = runtime::get_named_arg("token_symbol"); let tokenURI: URI = runtime::get_named_arg("token_uri"); + let (contract_package_hash, _) = storage::create_contract_package_at_hash(); + + let deployer_group = storage::create_contract_user_group(contract_package_hash, "deployer", 1, BTreeSet::default()).unwrap_or_revert(); + runtime::put_key("deployer_access", types::Key::URef(deployer_group[0])); let mut entry_points = EntryPoints::new(); - entry_points.add_entry_point(endpoint("name", vec![], CLType::String)); - entry_points.add_entry_point(endpoint("symbol", vec![], CLType::String)); - entry_points.add_entry_point(endpoint("uri", vec![], CLType::String)); - entry_points.add_entry_point(endpoint("total_supply", vec![], CLType::U256)); + entry_points.add_entry_point(endpoint("name", vec![], CLType::String, None)); + entry_points.add_entry_point(endpoint("symbol", vec![], CLType::String, None)); + entry_points.add_entry_point(endpoint("uri", vec![], CLType::String, None)); + entry_points.add_entry_point(endpoint("total_supply", vec![], CLType::U256, None)); entry_points.add_entry_point(endpoint( "balance_of", vec![Parameter::new("account", CLType::PublicKey)], CLType::U256, + None, )); entry_points.add_entry_point(endpoint( "owner_of", vec![Parameter::new("token_id", CLType::String)], CLType::Option(Box::new(CLType::PublicKey)), + None, )); entry_points.add_entry_point(endpoint( "token_uri", vec![Parameter::new("token_id", CLType::String)], CLType::Option(Box::new(CLType::String)), + None, )); entry_points.add_entry_point(endpoint( "tokens", vec![Parameter::new("owner", CLType::PublicKey)], CLType::List(Box::new(CLType::String)), + None, )); entry_points.add_entry_point(endpoint( - "tokens", + "total_supply", vec![Parameter::new("owner", CLType::PublicKey)], CLType::List(Box::new(CLType::String)), + None, )); entry_points.add_entry_point(endpoint( "mint_one", @@ -428,6 +436,7 @@ pub fn deploy(token_name: &str, token_symbol: &str, token_uri: &str) { Parameter::new("token_uri", CLType::String), ], CLType::Unit, + if secure {Some("deployer_access")}else{None}, )); entry_points.add_entry_point(endpoint( "mint_many", @@ -436,6 +445,7 @@ pub fn deploy(token_name: &str, token_symbol: &str, token_uri: &str) { Parameter::new("token_uris", CLType::List(Box::new(CLType::String))), ], CLType::Unit, + if secure {Some("deployer_access")}else{None}, )); entry_points.add_entry_point(endpoint( "mint_copies", @@ -445,6 +455,7 @@ pub fn deploy(token_name: &str, token_symbol: &str, token_uri: &str) { Parameter::new("count", CLType::U256), ], CLType::Unit, + if secure {Some("deployer_access")}else{None}, )); entry_points.add_entry_point(endpoint( "transfer_token", @@ -454,6 +465,7 @@ pub fn deploy(token_name: &str, token_symbol: &str, token_uri: &str) { Parameter::new("token_id", CLType::String), ], CLType::Unit, + None, )); entry_points.add_entry_point(endpoint( "transfer_many_tokens", @@ -463,6 +475,7 @@ pub fn deploy(token_name: &str, token_symbol: &str, token_uri: &str) { Parameter::new("token_ids", CLType::List(Box::new(CLType::String))), ], CLType::Unit, + None, )); entry_points.add_entry_point(endpoint( "transfer_all_tokens", @@ -471,6 +484,7 @@ pub fn deploy(token_name: &str, token_symbol: &str, token_uri: &str) { Parameter::new("recipient", CLType::PublicKey), ], CLType::Unit, + None, )); let mut named_keys = NamedKeys::new(); @@ -482,7 +496,7 @@ pub fn deploy(token_name: &str, token_symbol: &str, token_uri: &str) { storage::new_uref(U256::zero()).into(), ); - let (contract_package_hash, _) = storage::create_contract_package_at_hash(); + let (contract_hash, _) = storage::add_contract_version(contract_package_hash, entry_points, named_keys); runtime::put_key("caspercep47_contract", contract_hash.into()); @@ -543,12 +557,15 @@ fn token_key(account: &AccountHash) -> String { format!("tokens_{}", account) } -fn endpoint(name: &str, param: Vec, ret: CLType) -> EntryPoint { +fn endpoint(name: &str, param: Vec, ret: CLType, access: Option<&str>) -> EntryPoint { EntryPoint::new( String::from(name), param, ret, - EntryPointAccess::Public, + match access{ + None => EntryPointAccess::Public, + Some(access_key) => EntryPointAccess::groups(&[access_key]) + }, EntryPointType::Contract, ) } diff --git a/cep47/src/main.rs b/cep47/src/main.rs index 88d3484..faf7548 100644 --- a/cep47/src/main.rs +++ b/cep47/src/main.rs @@ -6,6 +6,7 @@ pub extern "C" fn call() { cep47::deploy( &contract::contract_api::runtime::get_named_arg::("token_name"), &contract::contract_api::runtime::get_named_arg::("token_symbol"), - &contract::contract_api::runtime::get_named_arg::("token_uri") + &contract::contract_api::runtime::get_named_arg::("token_uri"), + false ); } \ No newline at end of file From aabec0432314e000507dfcda5fc29a18726ccff4 Mon Sep 17 00:00:00 2001 From: Deusz Date: Thu, 27 May 2021 15:01:28 +0200 Subject: [PATCH 18/98] format lib form --- Makefile | 6 ++-- cep47/src/lib.rs | 78 +++++++++++++++++++++++++++++++++------------- cep47/src/logic.rs | 1 - cep47/src/main.rs | 8 +++-- tests/src/lib.rs | 2 +- 5 files changed, 68 insertions(+), 27 deletions(-) diff --git a/Makefile b/Makefile index 336eee0..d156dd4 100644 --- a/Makefile +++ b/Makefile @@ -13,13 +13,15 @@ copy-wasm-file-to-test: test: build-contract copy-wasm-file-to-test test-only clippy: - cargo clippy --all-targets --all -- -D warnings -A renamed_and_removed_lints + cargo +nightly clippy --all-targets --all -- -D warnings -A renamed_and_removed_lints check-lint: clippy cargo fmt --all -- --check -lint: clippy +format: cargo fmt --all + +lint: clippy format clean: cargo clean diff --git a/cep47/src/lib.rs b/cep47/src/lib.rs index ff69952..8c00a9e 100644 --- a/cep47/src/lib.rs +++ b/cep47/src/lib.rs @@ -1,12 +1,11 @@ - #![allow(unused_imports)] #![allow(unused_parens)] #![allow(non_snake_case)] extern crate alloc; -pub mod tests; pub mod logic; +pub mod tests; use alloc::{ collections::{BTreeMap, BTreeSet}, @@ -25,8 +24,9 @@ use types::{ account::AccountHash, bytesrepr::{FromBytes, ToBytes}, contracts::NamedKeys, - AccessRights, ApiError, AsymmetricType, CLType, CLTyped, CLValue, EntryPoint, EntryPointAccess, - EntryPointType, EntryPoints, Key, Parameter, PublicKey, URef, U256, + AccessRights, ApiError, AsymmetricType, CLType, CLTyped, CLValue, ContractPackageHash, + EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Key, Parameter, PublicKey, URef, + U256, }; type TokenId = String; @@ -245,9 +245,15 @@ trait CEP47Storage { let token_uris: Vec = vec![token_uri; count.as_usize()]; self.mint_many(recipient, token_uris); } - fn new_uref(&mut self, token_id: TokenId) -> Option {None} - fn del_uref(&mut self, token_uref: URef) -> Option {None} - fn token_id(&self, token_uref: URef) -> Option {None} + fn new_uref(&mut self, token_id: TokenId) -> Option { + None + } + fn del_uref(&mut self, token_uref: URef) -> Option { + None + } + fn token_id(&self, token_uref: URef) -> Option { + None + } } struct CasperCEP47Storage {} @@ -385,14 +391,20 @@ pub extern "C" fn transfer_all_tokens() { contract.transfer_all_tokens(sender, recipient); } -pub fn deploy(token_name: &str, token_symbol: &str, token_uri: &str, secure: bool) { - let tokenName: String = runtime::get_named_arg("token_name"); - let tokenSymbol: String = runtime::get_named_arg("token_symbol"); - let tokenURI: URI = runtime::get_named_arg("token_uri"); - let (contract_package_hash, _) = storage::create_contract_package_at_hash(); - - let deployer_group = storage::create_contract_user_group(contract_package_hash, "deployer", 1, BTreeSet::default()).unwrap_or_revert(); - runtime::put_key("deployer_access", types::Key::URef(deployer_group[0])); +pub fn get_entrypoints(package_hash: Option) -> EntryPoints { + let secure = if let Some(contract_package_hash) = package_hash { + let deployer_group = storage::create_contract_user_group( + contract_package_hash, + "deployer", + 1, + BTreeSet::default(), + ) + .unwrap_or_revert(); + runtime::put_key("deployer_access", types::Key::URef(deployer_group[0])); + true + } else { + false + }; let mut entry_points = EntryPoints::new(); entry_points.add_entry_point(endpoint("name", vec![], CLType::String, None)); @@ -436,7 +448,11 @@ pub fn deploy(token_name: &str, token_symbol: &str, token_uri: &str, secure: boo Parameter::new("token_uri", CLType::String), ], CLType::Unit, - if secure {Some("deployer_access")}else{None}, + if secure { + Some("deployer_access") + } else { + None + }, )); entry_points.add_entry_point(endpoint( "mint_many", @@ -445,7 +461,11 @@ pub fn deploy(token_name: &str, token_symbol: &str, token_uri: &str, secure: boo Parameter::new("token_uris", CLType::List(Box::new(CLType::String))), ], CLType::Unit, - if secure {Some("deployer_access")}else{None}, + if secure { + Some("deployer_access") + } else { + None + }, )); entry_points.add_entry_point(endpoint( "mint_copies", @@ -455,7 +475,11 @@ pub fn deploy(token_name: &str, token_symbol: &str, token_uri: &str, secure: boo Parameter::new("count", CLType::U256), ], CLType::Unit, - if secure {Some("deployer_access")}else{None}, + if secure { + Some("deployer_access") + } else { + None + }, )); entry_points.add_entry_point(endpoint( "transfer_token", @@ -486,6 +510,19 @@ pub fn deploy(token_name: &str, token_symbol: &str, token_uri: &str, secure: boo CLType::Unit, None, )); + entry_points +} + +pub fn deploy( + token_name: &str, + token_symbol: &str, + token_uri: &str, + entry_points: EntryPoints, + contract_package_hash: ContractPackageHash, +) { + let tokenName: String = runtime::get_named_arg("token_name"); + let tokenSymbol: String = runtime::get_named_arg("token_symbol"); + let tokenURI: URI = runtime::get_named_arg("token_uri"); let mut named_keys = NamedKeys::new(); named_keys.insert("name".to_string(), storage::new_uref(tokenName).into()); @@ -496,7 +533,6 @@ pub fn deploy(token_name: &str, token_symbol: &str, token_uri: &str, secure: boo storage::new_uref(U256::zero()).into(), ); - let (contract_hash, _) = storage::add_contract_version(contract_package_hash, entry_points, named_keys); runtime::put_key("caspercep47_contract", contract_hash.into()); @@ -562,9 +598,9 @@ fn endpoint(name: &str, param: Vec, ret: CLType, access: Option<&str> String::from(name), param, ret, - match access{ + match access { None => EntryPointAccess::Public, - Some(access_key) => EntryPointAccess::groups(&[access_key]) + Some(access_key) => EntryPointAccess::groups(&[access_key]), }, EntryPointType::Contract, ) diff --git a/cep47/src/logic.rs b/cep47/src/logic.rs index 1790bf3..9f7ec7a 100644 --- a/cep47/src/logic.rs +++ b/cep47/src/logic.rs @@ -152,4 +152,3 @@ pub trait CEP47Storage { fn del_uref(&mut self, token_uref: URef) -> Option; fn token_id(&self, token_uref: URef) -> Option; } - diff --git a/cep47/src/main.rs b/cep47/src/main.rs index faf7548..0f6ad43 100644 --- a/cep47/src/main.rs +++ b/cep47/src/main.rs @@ -3,10 +3,14 @@ extern crate cep47; #[no_mangle] pub extern "C" fn call() { + let (contract_package_hash, _) = + contract::contract_api::storage::create_contract_package_at_hash(); + let entry_points = cep47::get_entrypoints(None); cep47::deploy( &contract::contract_api::runtime::get_named_arg::("token_name"), &contract::contract_api::runtime::get_named_arg::("token_symbol"), &contract::contract_api::runtime::get_named_arg::("token_uri"), - false + entry_points, + contract_package_hash, ); -} \ No newline at end of file +} diff --git a/tests/src/lib.rs b/tests/src/lib.rs index bcb4c6c..8114a14 100644 --- a/tests/src/lib.rs +++ b/tests/src/lib.rs @@ -2,4 +2,4 @@ pub mod cep47; #[cfg(test)] -pub mod tests; \ No newline at end of file +pub mod tests; From 3e09997f53bcd343fe837e5f8f88fbb95ebec267 Mon Sep 17 00:00:00 2001 From: astro019 Date: Thu, 27 May 2021 23:32:13 +1000 Subject: [PATCH 19/98] import traits and types from logic --- cep47/src/lib.rs | 151 +++-------------------------------------------- 1 file changed, 9 insertions(+), 142 deletions(-) diff --git a/cep47/src/lib.rs b/cep47/src/lib.rs index 8c00a9e..4d4ea5f 100644 --- a/cep47/src/lib.rs +++ b/cep47/src/lib.rs @@ -16,6 +16,7 @@ use contract::{ unwrap_or_revert::UnwrapOrRevert, }; use core::convert::TryInto; +use logic::{CEP47Contract, CEP47Storage, TokenId, WithStorage, URI}; use std::{ collections::hash_map::DefaultHasher, hash::{Hash, Hasher}, @@ -29,135 +30,13 @@ use types::{ U256, }; -type TokenId = String; -type URI = String; - -trait WithStorage { - fn storage(&self) -> &Storage; - fn storage_mut(&mut self) -> &mut Storage; -} - -trait CEP47Contract: WithStorage { - // Metadata - fn name(&self) -> String { - self.storage().name() - } - - fn symbol(&self) -> String { - self.storage().symbol() - } - - fn uri(&self) -> URI { - self.storage().uri() - } - - // Getters - fn balance_of(&self, owner: PublicKey) -> U256 { - self.storage().balance_of(owner) - } - - fn owner_of(&self, token_id: TokenId) -> Option { - self.storage().onwer_of(token_id) - } - - fn total_supply(&self) -> U256 { - self.storage().total_supply() - } - - fn token_uri(&self, token_id: TokenId) -> Option { - self.storage().token_uri(token_id) - } - - fn tokens(&self, owner: PublicKey) -> Vec { - self.storage().get_tokens(owner) - } - - // Minter function. - // Guarded by the entrypoint group. - fn mint_one(&mut self, recipient: PublicKey, token_uri: URI) { - self.storage_mut() - .mint_copies(recipient, token_uri, U256::one()); - } - - fn mint_many(&mut self, recipient: PublicKey, token_uris: Vec) { - self.storage_mut().mint_many(recipient, token_uris); - } - - fn mint_copies(&mut self, recipient: PublicKey, token_uri: URI, count: U256) { - self.storage_mut().mint_copies(recipient, token_uri, count); - } - - // Transfer functions. - fn transfer_token(&mut self, sender: PublicKey, recipient: PublicKey, token_id: TokenId) { - // 1. Load tokens owned by the sender. - let mut sender_tokens = self.storage().get_tokens(sender); - // 2. Assert that token_id is in sender_tokens. - assert!( - sender_tokens.contains(&token_id), - "wrong owner of token {}", - token_id - ); - // 3. Remove token_id from sender_tokens. - sender_tokens.retain(|x| x.clone() != token_id); - self.storage_mut().set_tokens(sender, sender_tokens); - - // 4. Add token_id to the recipient tokens - let mut recipient_tokens = self.storage().get_tokens(recipient); - recipient_tokens.push(token_id); - self.storage_mut().set_tokens(recipient, recipient_tokens); - } - - fn transfer_many_tokens( - &mut self, - sender: PublicKey, - recipient: PublicKey, - token_ids: Vec, - ) { - let mut sender_tokens = self.storage().get_tokens(sender); - for token_id in token_ids.iter() { - assert!(sender_tokens.contains(token_id), "wrong token {}", token_id); - sender_tokens.retain(|x| x.clone() != token_id.clone()); - } - let mut recipient_tokens = self.storage().get_tokens(recipient); - recipient_tokens.append(&mut token_ids.clone()); - self.storage_mut().set_tokens(sender, sender_tokens); - self.storage_mut().set_tokens(recipient, recipient_tokens); - } - - fn transfer_all_tokens(&mut self, sender: PublicKey, recipient: PublicKey) { - let mut sender_tokens = self.storage().get_tokens(sender); - let mut recipient_tokens = self.storage().get_tokens(recipient); - recipient_tokens.append(&mut sender_tokens); - - self.storage_mut().set_tokens(sender, sender_tokens); - self.storage_mut().set_tokens(recipient, recipient_tokens); - } - - // URef releated function. - fn detach(&mut self, owner: PublicKey, token_id: TokenId) -> Option { - let mut tokens = self.storage().get_tokens(owner); - if !tokens.contains(&token_id) { - None - } else { - tokens.retain(|x| x != &token_id); - self.storage_mut().set_tokens(owner, tokens); - self.storage_mut().new_uref(token_id) - } - } - - fn attach(&mut self, token_uref: URef, recipient: PublicKey) { - let token_id = self.storage_mut().del_uref(token_uref).unwrap(); - let mut tokens = self.storage().get_tokens(recipient); - tokens.push(token_id); - self.storage_mut().set_tokens(recipient, tokens); - } - - fn token_id(&self, token_uref: URef) -> TokenId { - self.storage().token_id(token_uref).unwrap() +struct CasperCEP47Storage {} +impl CasperCEP47Storage { + pub fn new() -> CasperCEP47Storage { + CasperCEP47Storage {} } } - -trait CEP47Storage { +impl CEP47Storage for CasperCEP47Storage { // Metadata. fn name(&self) -> String { get_key::("name").unwrap() @@ -255,14 +134,6 @@ trait CEP47Storage { None } } - -struct CasperCEP47Storage {} -impl CasperCEP47Storage { - pub fn new() -> CasperCEP47Storage { - CasperCEP47Storage {} - } -} -impl CEP47Storage for CasperCEP47Storage {} struct CasperCEP47Contract { storage: CasperCEP47Storage, } @@ -520,14 +391,10 @@ pub fn deploy( entry_points: EntryPoints, contract_package_hash: ContractPackageHash, ) { - let tokenName: String = runtime::get_named_arg("token_name"); - let tokenSymbol: String = runtime::get_named_arg("token_symbol"); - let tokenURI: URI = runtime::get_named_arg("token_uri"); - let mut named_keys = NamedKeys::new(); - named_keys.insert("name".to_string(), storage::new_uref(tokenName).into()); - named_keys.insert("symbol".to_string(), storage::new_uref(tokenSymbol).into()); - named_keys.insert("uri".to_string(), storage::new_uref(tokenURI).into()); + named_keys.insert("name".to_string(), storage::new_uref(token_name).into()); + named_keys.insert("symbol".to_string(), storage::new_uref(token_symbol).into()); + named_keys.insert("uri".to_string(), storage::new_uref(token_uri).into()); named_keys.insert( "total_supply".to_string(), storage::new_uref(U256::zero()).into(), From 5cd9c6abd35ae4ba1c82c433e98fe91bad555f86 Mon Sep 17 00:00:00 2001 From: Deusz Date: Thu, 27 May 2021 15:58:19 +0200 Subject: [PATCH 20/98] attach detach entrypoints --- cep47/src/lib.rs | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/cep47/src/lib.rs b/cep47/src/lib.rs index 4d4ea5f..e5364d7 100644 --- a/cep47/src/lib.rs +++ b/cep47/src/lib.rs @@ -262,6 +262,22 @@ pub extern "C" fn transfer_all_tokens() { contract.transfer_all_tokens(sender, recipient); } +#[no_mangle] +pub extern "C" fn attach() { + let token_uref: URef = runtime::get_named_arg("token_uref"); + let recipient: PublicKey = runtime::get_named_arg("recipient"); + let mut contract = CasperCEP47Contract::new(); + contract.attach(token_uref, recipient); +} + +#[no_mangle] +pub extern "C" fn detach() { + let owner: PublicKey = runtime::get_named_arg("owner"); + let token_id: TokenId = runtime::get_named_arg("token_id"); + let mut contract = CasperCEP47Contract::new(); + contract.detach(owner, token_id); +} + pub fn get_entrypoints(package_hash: Option) -> EntryPoints { let secure = if let Some(contract_package_hash) = package_hash { let deployer_group = storage::create_contract_user_group( @@ -381,6 +397,24 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints CLType::Unit, None, )); + entry_points.add_entry_point(endpoint( + "attach", + vec![ + Parameter::new("token_uref", CLType::URef), + Parameter::new("recipient", CLType::PublicKey), + ], + CLType::Unit, + None, + )); + entry_points.add_entry_point(endpoint( + "detach", + vec![ + Parameter::new("owner", CLType::PublicKey), + Parameter::new("token_id", CLType::String), + ], + CLType::Unit, + None, + )); entry_points } From a41360cc4a6d6689bfa9d9a6a1ad0c6fbf5a62d9 Mon Sep 17 00:00:00 2001 From: Deusz Date: Thu, 27 May 2021 16:01:15 +0200 Subject: [PATCH 21/98] attach detach call in test --- tests/src/cep47.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/src/cep47.rs b/tests/src/cep47.rs index 0570e11..84209ed 100644 --- a/tests/src/cep47.rs +++ b/tests/src/cep47.rs @@ -180,6 +180,26 @@ impl CasperCEP47Contract { }, ); } + + pub fn attach(&mut self, token_uref: URef, recipient: PublicKey) { + self.call( + "attach", + runtime_args! { + "token_uref" => token_uref, + "recipient" => recipient + }, + ); + } + + pub fn detach(&mut self, owner: PublicKey, recipient: String) { + self.call( + "detach", + runtime_args! { + "owner" => owner, + "token_id" => token_id + }, + ); + } } fn balance_key(account: &AccountHash) -> String { From 74095ce457cca07ffe2fdedb535c0b66c6cc9669 Mon Sep 17 00:00:00 2001 From: Deusz Date: Thu, 27 May 2021 16:02:09 +0200 Subject: [PATCH 22/98] fix --- tests/src/cep47.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/src/cep47.rs b/tests/src/cep47.rs index 84209ed..0bfe903 100644 --- a/tests/src/cep47.rs +++ b/tests/src/cep47.rs @@ -1,7 +1,7 @@ use casper_engine_test_support::{Code, Hash, SessionBuilder, TestContext, TestContextBuilder}; use casper_types::{ account::AccountHash, bytesrepr::FromBytes, runtime_args, AsymmetricType, CLTyped, PublicKey, - RuntimeArgs, U256, U512, + RuntimeArgs, U256, U512, URef }; pub mod token_cfg { @@ -191,7 +191,7 @@ impl CasperCEP47Contract { ); } - pub fn detach(&mut self, owner: PublicKey, recipient: String) { + pub fn detach(&mut self, owner: PublicKey, token_id: String) { self.call( "detach", runtime_args! { From 5da524b5d6cad47a8729cbdb335329798d49fdd8 Mon Sep 17 00:00:00 2001 From: Deusz Date: Thu, 27 May 2021 16:02:41 +0200 Subject: [PATCH 23/98] format --- tests/src/cep47.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/cep47.rs b/tests/src/cep47.rs index 0bfe903..36871a2 100644 --- a/tests/src/cep47.rs +++ b/tests/src/cep47.rs @@ -1,7 +1,7 @@ use casper_engine_test_support::{Code, Hash, SessionBuilder, TestContext, TestContextBuilder}; use casper_types::{ account::AccountHash, bytesrepr::FromBytes, runtime_args, AsymmetricType, CLTyped, PublicKey, - RuntimeArgs, U256, U512, URef + RuntimeArgs, URef, U256, U512, }; pub mod token_cfg { From 17614a6a595d98862faf93ce66251ba1db88ca78 Mon Sep 17 00:00:00 2001 From: Deusz Date: Wed, 2 Jun 2021 11:17:58 +0200 Subject: [PATCH 24/98] updated to versions 1.2.0 --- .gitignore | 2 +- cep47/Cargo.toml | 4 +-- cep47/src/lib.rs | 12 +++---- cep47/src/logic.rs | 16 ++++----- cep47/src/tests.rs | 86 ++++++++++++++++++++++++++-------------------- tests/Cargo.toml | 6 ++-- tests/src/cep47.rs | 2 +- tests/src/tests.rs | 84 ++++++++++++++++++++++---------------------- 8 files changed, 111 insertions(+), 101 deletions(-) diff --git a/.gitignore b/.gitignore index 9b160a5..0564e6c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ target Cargo.lock -tests/wasm/cep47.wasm \ No newline at end of file +tests/wasm/*.wasm \ No newline at end of file diff --git a/cep47/Cargo.toml b/cep47/Cargo.toml index af99dc9..570c6bd 100644 --- a/cep47/Cargo.toml +++ b/cep47/Cargo.toml @@ -5,8 +5,8 @@ authors = ["astro019 "] edition = "2018" [dependencies] -contract = { package = "casper-contract", version="1.1.1" } -types = { package = "casper-types", version="1.1.1" } +contract = { package = "casper-contract", version="1.2.0" } +types = { package = "casper-types", version="1.2.0" } rand = { version="0.8", default-features=false } [[bin]] diff --git a/cep47/src/lib.rs b/cep47/src/lib.rs index e5364d7..5dd28ff 100644 --- a/cep47/src/lib.rs +++ b/cep47/src/lib.rs @@ -77,16 +77,16 @@ impl CEP47Storage for CasperCEP47Storage { } } fn set_tokens(&mut self, owner: PublicKey, token_ids: Vec) { - let owner_prev_balance = self.balance_of(owner); + let owner_prev_balance = self.balance_of(owner.clone()); let owner_new_balance = U256::from(token_ids.len() as u64); let prev_total_supply = self.total_supply(); - let owner_tokens = self.get_tokens(owner); + let owner_tokens = self.get_tokens(owner.clone()); for token_id in owner_tokens.clone() { remove_key(&owner_key(&token_id)); } for token_id in token_ids.clone() { - set_key(&owner_key(&token_id), owner); + set_key(&owner_key(&token_id), owner.clone()); } set_key(&token_key(&owner.to_account_hash()), token_ids); set_key(&balance_key(&owner.to_account_hash()), owner_new_balance); @@ -96,8 +96,8 @@ impl CEP47Storage for CasperCEP47Storage { ); } fn mint_many(&mut self, recipient: PublicKey, token_uris: Vec) { - let mut recipient_tokens = self.get_tokens(recipient); - let mut recipient_balance = self.balance_of(recipient); + let mut recipient_tokens = self.get_tokens(recipient.clone()); + let mut recipient_balance = self.balance_of(recipient.clone()); let mut total_supply = self.total_supply(); let uri = self.uri(); @@ -110,7 +110,7 @@ impl CEP47Storage for CasperCEP47Storage { recipient_tokens.push(token_id.clone()); total_supply = total_supply + 1; set_key(&uri_key(&token_id), token_uri); - set_key(&owner_key(&token_id), recipient); + set_key(&owner_key(&token_id), recipient.clone()); } recipient_balance = recipient_balance + U256::from(token_uris.len() as u64); set_key( diff --git a/cep47/src/logic.rs b/cep47/src/logic.rs index 9f7ec7a..b871677 100644 --- a/cep47/src/logic.rs +++ b/cep47/src/logic.rs @@ -63,7 +63,7 @@ pub trait CEP47Contract: WithStorage { // Transfer functions. fn transfer_token(&mut self, sender: PublicKey, recipient: PublicKey, token_id: TokenId) { // 1. Load tokens owned by the sender. - let mut sender_tokens = self.storage().get_tokens(sender); + let mut sender_tokens = self.storage().get_tokens(sender.clone()); // 2. Assert that token_id is in sender_tokens. assert!( sender_tokens.contains(&token_id), @@ -75,7 +75,7 @@ pub trait CEP47Contract: WithStorage { self.storage_mut().set_tokens(sender, sender_tokens); // 4. Add token_id to the recipient tokens - let mut recipient_tokens = self.storage().get_tokens(recipient); + let mut recipient_tokens = self.storage().get_tokens(recipient.clone()); recipient_tokens.push(token_id); self.storage_mut().set_tokens(recipient, recipient_tokens); } @@ -86,20 +86,20 @@ pub trait CEP47Contract: WithStorage { recipient: PublicKey, token_ids: Vec, ) { - let mut sender_tokens = self.storage().get_tokens(sender); + let mut sender_tokens = self.storage().get_tokens(sender.clone()); for token_id in token_ids.iter() { assert!(sender_tokens.contains(token_id), "wrong token {}", token_id); sender_tokens.retain(|x| x.clone() != token_id.clone()); } - let mut recipient_tokens = self.storage().get_tokens(recipient); + let mut recipient_tokens = self.storage().get_tokens(recipient.clone()); recipient_tokens.append(&mut token_ids.clone()); self.storage_mut().set_tokens(sender, sender_tokens); self.storage_mut().set_tokens(recipient, recipient_tokens); } fn transfer_all_tokens(&mut self, sender: PublicKey, recipient: PublicKey) { - let mut sender_tokens = self.storage().get_tokens(sender); - let mut recipient_tokens = self.storage().get_tokens(recipient); + let mut sender_tokens = self.storage().get_tokens(sender.clone()); + let mut recipient_tokens = self.storage().get_tokens(recipient.clone()); recipient_tokens.append(&mut sender_tokens); self.storage_mut().set_tokens(sender, sender_tokens); @@ -108,7 +108,7 @@ pub trait CEP47Contract: WithStorage { // URef releated function. fn detach(&mut self, owner: PublicKey, token_id: TokenId) -> Option { - let mut tokens = self.storage().get_tokens(owner); + let mut tokens = self.storage().get_tokens(owner.clone()); if !tokens.contains(&token_id) { None } else { @@ -120,7 +120,7 @@ pub trait CEP47Contract: WithStorage { fn attach(&mut self, token_uref: URef, recipient: PublicKey) { let token_id = self.storage_mut().del_uref(token_uref).unwrap(); - let mut tokens = self.storage().get_tokens(recipient); + let mut tokens = self.storage().get_tokens(recipient.clone()); tokens.push(token_id); self.storage_mut().set_tokens(recipient, tokens); } diff --git a/cep47/src/tests.rs b/cep47/src/tests.rs index 2df3453..5654106 100644 --- a/cep47/src/tests.rs +++ b/cep47/src/tests.rs @@ -97,15 +97,15 @@ mod tests { fn set_tokens(&mut self, owner: PublicKey, token_ids: Vec) { let owner_new_balance = U256::from(token_ids.len() as u64); - let owner_tokens = self.get_tokens(owner); + let owner_tokens = self.get_tokens(owner.clone()); for token_id in owner_tokens.clone() { self.belongs_to.remove(&token_id); } for token_id in token_ids.clone() { - self.belongs_to.insert(token_id, owner); + self.belongs_to.insert(token_id, owner.clone()); } - self.tokens.insert(owner, token_ids.clone()); + self.tokens.insert(owner.clone(), token_ids.clone()); self.balances.insert(owner, owner_new_balance); } @@ -131,11 +131,12 @@ mod tests { let token_id: TokenId = TokenId::from(hasher.finish().to_string()); self.token_uris.insert(token_id.clone(), token_uri); recipient_new_tokens.push(token_id.clone()); - self.belongs_to.insert(token_id, recipient); + self.belongs_to.insert(token_id, recipient.clone()); recipient_new_balance = recipient_new_balance + 1; self.total_supply = self.total_supply + 1; } - self.balances.insert(recipient, recipient_new_balance); + self.balances + .insert(recipient.clone(), recipient_new_balance); self.tokens.insert(recipient, recipient_new_tokens); } @@ -216,13 +217,16 @@ mod tests { let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); assert_eq!(contract.total_supply(), U256::from(0)); - contract.mint_many(ali, vec![URI::from("Apple URI")]); - contract.mint_many(bob, vec![URI::from("Banana URI"), URI::from("Orange URI")]); + contract.mint_many(ali.clone(), vec![URI::from("Apple URI")]); + contract.mint_many( + bob.clone(), + vec![URI::from("Banana URI"), URI::from("Orange URI")], + ); assert_eq!(contract.total_supply(), U256::from(3)); - let ali_balance = contract.balance_of(ali); + let ali_balance = contract.balance_of(ali.clone()); assert_eq!(ali_balance, U256::from(1)); - let bob_balance = contract.balance_of(bob); + let bob_balance = contract.balance_of(bob.clone()); assert_eq!(bob_balance, U256::from(2)); let ali_tokens: Vec = contract.tokens(ali); @@ -243,10 +247,10 @@ mod tests { let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); assert_eq!(contract.total_supply(), U256::from(0)); - contract.mint_copies(ali, URI::from("Casper Fan URI"), U256::from(7)); + contract.mint_copies(ali.clone(), URI::from("Casper Fan URI"), U256::from(7)); assert_eq!(contract.total_supply(), U256::from(7)); - let ali_balance = contract.balance_of(ali); + let ali_balance = contract.balance_of(ali.clone()); assert_eq!(ali_balance, U256::from(7)); let ali_tokens: Vec = contract.tokens(ali); @@ -266,22 +270,22 @@ mod tests { let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); assert_eq!(contract.total_supply(), U256::from(0)); - contract.mint_one(ali, URI::from("Casper Fan URI")); + contract.mint_one(ali.clone(), URI::from("Casper Fan URI")); assert_eq!(contract.total_supply(), U256::from(1)); - let mut ali_balance = contract.balance_of(ali); - let mut bob_balance = contract.balance_of(bob); + let mut ali_balance = contract.balance_of(ali.clone()); + let mut bob_balance = contract.balance_of(bob.clone()); assert_eq!(ali_balance, U256::from(1)); assert_eq!(bob_balance, U256::from(0)); - let ali_tokens: Vec = contract.tokens(ali); + let ali_tokens: Vec = contract.tokens(ali.clone()); let ali_first_token_id: TokenId = ali_tokens.get(0).unwrap().clone(); let ali_first_token_uri: URI = contract.token_uri(ali_first_token_id.clone()).unwrap(); assert_eq!(ali_first_token_uri, URI::from("Casper Fan URI")); - contract.transfer_token(ali, bob, ali_first_token_id.clone()); + contract.transfer_token(ali.clone(), bob.clone(), ali_first_token_id.clone()); ali_balance = contract.balance_of(ali); - bob_balance = contract.balance_of(bob); + bob_balance = contract.balance_of(bob.clone()); assert_eq!(ali_balance, U256::from(0)); assert_eq!(bob_balance, U256::from(1)); @@ -295,24 +299,27 @@ mod tests { let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); assert_eq!(contract.total_supply(), U256::from(0)); - contract.mint_many(ali, vec![URI::from("Apple URI"), URI::from("Banana URI")]); - contract.mint_one(ali, URI::from("Casper Fan URI")); + contract.mint_many( + ali.clone(), + vec![URI::from("Apple URI"), URI::from("Banana URI")], + ); + contract.mint_one(ali.clone(), URI::from("Casper Fan URI")); assert_eq!(contract.total_supply(), U256::from(3)); - let mut ali_balance = contract.balance_of(ali); - let mut bob_balance = contract.balance_of(bob); + let mut ali_balance = contract.balance_of(ali.clone()); + let mut bob_balance = contract.balance_of(bob.clone()); assert_eq!(ali_balance, U256::from(3)); assert_eq!(bob_balance, U256::from(0)); - let ali_tokens: Vec = contract.tokens(ali); + let ali_tokens: Vec = contract.tokens(ali.clone()); let ali_second_token_id: TokenId = ali_tokens.get(1).unwrap().clone(); let ali_second_token_uri: URI = contract.token_uri(ali_second_token_id.clone()).unwrap(); assert_eq!(ali_second_token_uri, URI::from("Banana URI")); - contract.transfer_all_tokens(ali, bob); + contract.transfer_all_tokens(ali.clone(), bob.clone()); ali_balance = contract.balance_of(ali); - bob_balance = contract.balance_of(bob); + bob_balance = contract.balance_of(bob.clone()); assert_eq!(ali_balance, U256::from(0)); assert_eq!(bob_balance, U256::from(3)); @@ -327,16 +334,19 @@ mod tests { let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); assert_eq!(contract.total_supply(), U256::from(0)); - contract.mint_many(ali, vec![URI::from("Apple URI"), URI::from("Banana URI")]); - contract.mint_copies(ali, URI::from("Casper Fan URI"), U256::from(3)); + contract.mint_many( + ali.clone(), + vec![URI::from("Apple URI"), URI::from("Banana URI")], + ); + contract.mint_copies(ali.clone(), URI::from("Casper Fan URI"), U256::from(3)); assert_eq!(contract.total_supply(), U256::from(5)); - let mut ali_balance = contract.balance_of(ali); - let mut bob_balance = contract.balance_of(bob); + let mut ali_balance = contract.balance_of(ali.clone()); + let mut bob_balance = contract.balance_of(bob.clone()); assert_eq!(ali_balance, U256::from(5)); assert_eq!(bob_balance, U256::from(0)); - let ali_tokens: Vec = contract.tokens(ali); + let ali_tokens: Vec = contract.tokens(ali.clone()); let ali_second_token_id: TokenId = ali_tokens.get(1).unwrap().clone(); let ali_second_token_uri: URI = contract.token_uri(ali_second_token_id.clone()).unwrap(); let ali_third_token_id: TokenId = ali_tokens.get(2).unwrap().clone(); @@ -345,13 +355,13 @@ mod tests { assert_eq!(ali_third_token_uri, URI::from("Casper Fan URI")); contract.transfer_many_tokens( - ali, - bob, + ali.clone(), + bob.clone(), vec![ali_second_token_id.clone(), ali_third_token_id.clone()], ); ali_balance = contract.balance_of(ali); - bob_balance = contract.balance_of(bob); + bob_balance = contract.balance_of(bob.clone()); assert_eq!(ali_balance, U256::from(3)); assert_eq!(bob_balance, U256::from(2)); @@ -367,11 +377,11 @@ mod tests { let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); - contract.mint_one(ali, URI::from("0x12af")); - let token_id: TokenId = contract.tokens(ali)[0].clone(); + contract.mint_one(ali.clone(), URI::from("0x12af")); + let token_id: TokenId = contract.tokens(ali.clone())[0].clone(); - let token_uref: URef = contract.detach(ali, token_id.clone()).unwrap(); - assert_eq!(contract.balance_of(ali), U256::zero()); + let token_uref: URef = contract.detach(ali.clone(), token_id.clone()).unwrap(); + assert_eq!(contract.balance_of(ali.clone()), U256::zero()); assert_eq!(contract.total_supply(), U256::one()); assert!(contract.tokens(ali).is_empty()); @@ -381,8 +391,8 @@ mod tests { URI::from("0x12af") ); - contract.attach(token_uref, bob); - assert_eq!(contract.balance_of(bob), U256::one()); + contract.attach(token_uref, bob.clone()); + assert_eq!(contract.balance_of(bob.clone()), U256::one()); assert_eq!(contract.total_supply(), U256::one()); assert_eq!(contract.tokens(bob), vec![token_id]); } diff --git a/tests/Cargo.toml b/tests/Cargo.toml index 07bf930..7969a10 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -7,9 +7,9 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -casper-contract = "1.1.1" -casper-types = "1.1.1" -casper-engine-test-support = "1.1.1" +casper-contract = "1.2.0" +casper-types = "1.2.0" +casper-engine-test-support = "1.2.0" [features] default = ["casper-contract/std", "casper-types/std", "casper-contract/test-support"] diff --git a/tests/src/cep47.rs b/tests/src/cep47.rs index 36871a2..ccb3662 100644 --- a/tests/src/cep47.rs +++ b/tests/src/cep47.rs @@ -26,7 +26,7 @@ impl CasperCEP47Contract { pub fn deploy() -> Self { let account = PublicKey::ed25519_from_bytes([1u8; 32]).unwrap(); let mut context = TestContextBuilder::new() - .with_public_key(account, U512::from(500_000_000_000_000_000u64)) + .with_public_key(account.clone(), U512::from(500_000_000_000_000_000u64)) .build(); let session_code = Code::from("cep47.wasm"); let session_args = runtime_args! { diff --git a/tests/src/tests.rs b/tests/src/tests.rs index 32c44ee..73cdd93 100644 --- a/tests/src/tests.rs +++ b/tests/src/tests.rs @@ -16,9 +16,9 @@ fn test_token_uri() { let mut contract = CasperCEP47Contract::deploy(); let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); let token_uri = URI::from("MonaLisa"); - contract.mint_one(ali, token_uri.clone()); + contract.mint_one(ali.clone(), token_uri.clone()); - let ali_tokens: Vec = contract.tokens(ali); + let ali_tokens: Vec = contract.tokens(ali.clone()); let ali_token_uri = contract.token_uri(ali_tokens[0].clone()); assert_eq!(ali_token_uri, Some(token_uri)); @@ -29,12 +29,12 @@ fn test_mint_one() { let mut contract = CasperCEP47Contract::deploy(); let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); let token_uri = URI::from("MonaLisa"); - contract.mint_one(ali, token_uri); + contract.mint_one(ali.clone(), token_uri); - let ali_tokens: Vec = contract.tokens(ali); + let ali_tokens: Vec = contract.tokens(ali.clone()); assert_eq!(contract.total_supply(), U256::one()); - assert_eq!(contract.balance_of(ali), U256::one()); + assert_eq!(contract.balance_of(ali.clone()), U256::one()); assert_eq!(U256::from(ali_tokens.len() as u64), U256::one()); assert_eq!(contract.owner_of(&ali_tokens[0]), Some(ali)); } @@ -44,15 +44,15 @@ fn test_mint_copies() { let mut contract = CasperCEP47Contract::deploy(); let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); let token_uri = URI::from("Casper Golden Card"); - contract.mint_copies(ali, token_uri, U256::from(3)); + contract.mint_copies(ali.clone(), token_uri, U256::from(3)); - let ali_tokens: Vec = contract.tokens(ali); + let ali_tokens: Vec = contract.tokens(ali.clone()); assert_eq!(contract.total_supply(), U256::from(3)); - assert_eq!(contract.balance_of(ali), U256::from(3)); + assert_eq!(contract.balance_of(ali.clone()), U256::from(3)); assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(3)); - assert_eq!(contract.owner_of(&ali_tokens[0]), Some(ali)); - assert_eq!(contract.owner_of(&ali_tokens[1]), Some(ali)); + assert_eq!(contract.owner_of(&ali_tokens[0]), Some(ali.clone())); + assert_eq!(contract.owner_of(&ali_tokens[1]), Some(ali.clone())); assert_eq!(contract.owner_of(&ali_tokens[2]), Some(ali)); } @@ -61,32 +61,32 @@ fn test_mint_many() { let mut contract = CasperCEP47Contract::deploy(); let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); let token_uris: Vec = vec![URI::from("Casper Golden Card"), URI::from("Mona Lisa")]; - contract.mint_many(ali, token_uris); + contract.mint_many(ali.clone(), token_uris); - let ali_tokens: Vec = contract.tokens(ali); + let ali_tokens: Vec = contract.tokens(ali.clone()); assert_eq!(contract.total_supply(), U256::from(2)); - assert_eq!(contract.balance_of(ali), U256::from(2)); + assert_eq!(contract.balance_of(ali.clone()), U256::from(2)); assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(2)); - assert_eq!(contract.owner_of(&ali_tokens[0]), Some(ali)); + assert_eq!(contract.owner_of(&ali_tokens[0]), Some(ali.clone())); assert_eq!(contract.owner_of(&ali_tokens[1]), Some(ali)); } #[test] fn test_transfer_token() { let mut contract = CasperCEP47Contract::deploy(); - let ali: PublicKey = SecretKey::ed25519([3u8; 32]).into(); - let bob: PublicKey = SecretKey::ed25519([5u8; 32]).into(); + let ali: PublicKey = SecretKey::ed25519_from_bytes([3u8; 32]).unwrap().into(); + let bob: PublicKey = SecretKey::ed25519_from_bytes([5u8; 32]).unwrap().into(); let token_uris: Vec = vec![ URI::from("Casper Golden Card"), URI::from("Casper Silver Card"), ]; - contract.mint_many(ali, token_uris); - let ali_tokens: Vec = contract.tokens(ali); - contract.transfer_token(ali, bob, ali_tokens[1].clone()); + contract.mint_many(ali.clone(), token_uris); + let ali_tokens: Vec = contract.tokens(ali.clone()); + contract.transfer_token(ali.clone(), bob.clone(), ali_tokens[1].clone()); - assert_eq!(contract.balance_of(ali), U256::from(1)); - assert_eq!(contract.balance_of(bob), U256::from(1)); + assert_eq!(contract.balance_of(ali.clone()), U256::from(1)); + assert_eq!(contract.balance_of(bob.clone()), U256::from(1)); assert_eq!(contract.total_supply(), U256::from(2)); assert_eq!(contract.owner_of(&ali_tokens[0]), Some(ali)); assert_eq!(contract.owner_of(&ali_tokens[1]), Some(bob)); @@ -95,21 +95,21 @@ fn test_transfer_token() { #[test] fn test_transfer_many_tokens() { let mut contract = CasperCEP47Contract::deploy(); - let ali: PublicKey = SecretKey::ed25519([3u8; 32]).into(); - let bob: PublicKey = SecretKey::ed25519([5u8; 32]).into(); + let ali: PublicKey = SecretKey::ed25519_from_bytes([3u8; 32]).unwrap().into(); + let bob: PublicKey = SecretKey::ed25519_from_bytes([5u8; 32]).unwrap().into(); let token_uris: Vec = vec![ URI::from("Casper Golden Card"), URI::from("Casper Silver Card"), URI::from("Casper Bronze Card"), ]; - contract.mint_many(ali, token_uris); - let ali_tokens: Vec = contract.tokens(ali); - contract.transfer_many_tokens(ali, bob, ali_tokens[..2].to_vec()); + contract.mint_many(ali.clone(), token_uris); + let ali_tokens: Vec = contract.tokens(ali.clone()); + contract.transfer_many_tokens(ali.clone(), bob.clone(), ali_tokens[..2].to_vec()); - assert_eq!(contract.balance_of(ali), U256::from(1)); - assert_eq!(contract.balance_of(bob), U256::from(2)); + assert_eq!(contract.balance_of(ali.clone()), U256::from(1)); + assert_eq!(contract.balance_of(bob.clone()), U256::from(2)); assert_eq!(contract.total_supply(), U256::from(3)); - assert_eq!(contract.owner_of(&ali_tokens[0]), Some(bob)); + assert_eq!(contract.owner_of(&ali_tokens[0]), Some(bob.clone())); assert_eq!(contract.owner_of(&ali_tokens[1]), Some(bob)); assert_eq!(contract.owner_of(&ali_tokens[2]), Some(ali)); } @@ -117,23 +117,23 @@ fn test_transfer_many_tokens() { #[test] fn test_transfer_all_tokens() { let mut contract = CasperCEP47Contract::deploy(); - let ali: PublicKey = SecretKey::ed25519([3u8; 32]).into(); - let bob: PublicKey = SecretKey::ed25519([5u8; 32]).into(); + let ali: PublicKey = SecretKey::ed25519_from_bytes([3u8; 32]).unwrap().into(); + let bob: PublicKey = SecretKey::ed25519_from_bytes([5u8; 32]).unwrap().into(); let token_uris: Vec = vec![ URI::from("Casper Golden Card"), URI::from("Casper Silver Card"), ]; - contract.mint_many(ali, token_uris); - let ali_tokens: Vec = contract.tokens(ali); - assert_eq!(contract.balance_of(ali), U256::from(2)); - assert_eq!(contract.balance_of(bob), U256::from(0)); - assert_eq!(contract.owner_of(&ali_tokens[0]), Some(ali)); - assert_eq!(contract.owner_of(&ali_tokens[1]), Some(ali)); - - contract.transfer_all_tokens(ali, bob); - assert_eq!(contract.balance_of(ali), U256::from(0)); - assert_eq!(contract.balance_of(bob), U256::from(2)); + contract.mint_many(ali.clone(), token_uris); + let ali_tokens: Vec = contract.tokens(ali.clone()); + assert_eq!(contract.balance_of(ali.clone()), U256::from(2)); + assert_eq!(contract.balance_of(bob.clone()), U256::from(0)); + assert_eq!(contract.owner_of(&ali_tokens[0]), Some(ali.clone())); + assert_eq!(contract.owner_of(&ali_tokens[1]), Some(ali.clone())); + + contract.transfer_all_tokens(ali.clone(), bob.clone()); + assert_eq!(contract.balance_of(ali.clone()), U256::from(0)); + assert_eq!(contract.balance_of(bob.clone()), U256::from(2)); assert_eq!(contract.total_supply(), U256::from(2)); - assert_eq!(contract.owner_of(&ali_tokens[0]), Some(bob)); + assert_eq!(contract.owner_of(&ali_tokens[0]), Some(bob.clone())); assert_eq!(contract.owner_of(&ali_tokens[1]), Some(bob)); } From f911ba4862ee27fb225becbbc0d384ea1c51bd6a Mon Sep 17 00:00:00 2001 From: Deusz Date: Fri, 4 Jun 2021 11:30:27 +0200 Subject: [PATCH 25/98] marketplace iter1, next better tests --- Cargo.toml | 3 +- Makefile | 5 + marketplace/Cargo.toml | 26 +++++ marketplace/src/lib.rs | 193 +++++++++++++++++++++++++++++++++ marketplace/src/main.rs | 10 ++ marketplace/src/offer.rs | 111 +++++++++++++++++++ marketplace/src/send_tokens.rs | 28 +++++ tests/src/lib.rs | 2 +- tests/src/market.rs | 60 ++++++++++ tests/src/tests.rs | 14 +++ 10 files changed, 450 insertions(+), 2 deletions(-) create mode 100644 marketplace/Cargo.toml create mode 100644 marketplace/src/lib.rs create mode 100644 marketplace/src/main.rs create mode 100644 marketplace/src/offer.rs create mode 100644 marketplace/src/send_tokens.rs create mode 100644 tests/src/market.rs diff --git a/Cargo.toml b/Cargo.toml index b6e8c8b..0897697 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,8 @@ members = [ "cep47", - "tests" + "tests", + "marketplace", ] [profile.release] diff --git a/Makefile b/Makefile index d156dd4..1218248 100644 --- a/Makefile +++ b/Makefile @@ -3,12 +3,15 @@ prepare: build-contract: cargo +nightly build --release -p cep47 --target wasm32-unknown-unknown + cargo +nightly build --release -p marketplace --target wasm32-unknown-unknown test-only: cargo +nightly test --workspace copy-wasm-file-to-test: cp target/wasm32-unknown-unknown/release/cep47.wasm tests/wasm + cp target/wasm32-unknown-unknown/release/marketplace.wasm tests/wasm + cp target/wasm32-unknown-unknown/release/send_tokens.wasm tests/wasm test: build-contract copy-wasm-file-to-test test-only @@ -26,3 +29,5 @@ lint: clippy format clean: cargo clean rm -rf tests/wasm/cep47.wasm + rm -rf tests/wasm/marketplace.wasm + rm -rf tests/wasm/send_tokens.wasm diff --git a/marketplace/Cargo.toml b/marketplace/Cargo.toml new file mode 100644 index 0000000..ccb5ed2 --- /dev/null +++ b/marketplace/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "marketplace" +version = "0.1.0" +authors = ["deusz "] +edition = "2018" + +[dependencies] +contract = { package = "casper-contract", version="1.2.0" } +types = { package = "casper-types", version="1.2.0" } + +[[bin]] +name = "marketplace" +path = "src/main.rs" +bench = false +doctest = false +test = false + +[[bin]] +name = "send_tokens" +path = "src/send_tokens.rs" +bench = false +doctest = false +test = false + +[features] +default = ["contract/std", "types/std"] diff --git a/marketplace/src/lib.rs b/marketplace/src/lib.rs new file mode 100644 index 0000000..e047629 --- /dev/null +++ b/marketplace/src/lib.rs @@ -0,0 +1,193 @@ +#![allow(unused_imports)] +#![allow(unused_parens)] +#![allow(non_snake_case)] + +extern crate alloc; + +pub mod offer; + +use alloc::{ + collections::{BTreeMap, BTreeSet}, + string::String, +}; +use contract::contract_api::runtime::revert; +use contract::{ + contract_api::{runtime, storage, system}, + unwrap_or_revert::UnwrapOrRevert, +}; +use core::convert::TryInto; +use offer::Offer; +use std::{ + collections::hash_map::DefaultHasher, + hash::{Hash, Hasher}, +}; +use types::bytesrepr::Error; +use types::{ + account::AccountHash, + bytesrepr::{FromBytes, ToBytes}, + contracts::NamedKeys, + AccessRights, ApiError, AsymmetricType, CLType, CLTyped, CLValue, ContractPackageHash, + EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Key, Parameter, PublicKey, URef, + U256, U512, +}; + +#[no_mangle] +pub extern "C" fn put_on_sale_test() { + let sel = runtime::get_named_arg("seller"); + let purse: URef = runtime::get_named_arg("purse"); + let offer = Offer::test_struct(sel); + let rets = offer.store(); + + let i_want_to_buy = Offer::load(&rets); + system::transfer_from_purse_to_account( + purse, + i_want_to_buy.seller.to_account_hash(), + system::get_purse_balance(purse).unwrap_or_revert(), + None, + ) + .unwrap_or_revert(); + remove_key(&i_want_to_buy.offer_key("")); +} + +#[no_mangle] +pub extern "C" fn put_on_sale() { + let offer = Offer::new( + runtime::get_named_arg("seller"), + runtime::get_named_arg("price"), + runtime::get_named_arg("item"), + runtime::get_named_arg("designation"), + ); + ret(offer.store()) +} + +#[no_mangle] +pub extern "C" fn buy() { + let offer_key: String = runtime::get_named_arg("offer_key"); + let payment: U512 = runtime::get_named_arg("payment"); + let offer: Offer = Offer::load(&offer_key); + if payment == offer.price { + system::transfer_to_account(offer.seller.to_account_hash(), payment, None) + .unwrap_or_revert(); + remove_key(&offer_key); + ret(offer.item) + } +} + +#[no_mangle] +pub extern "C" fn cancel() { + let offer_key: String = runtime::get_named_arg("offer_key"); + // let offer: Offer = Offer::load(&offer_key); + remove_key(&offer_key); +} + +pub fn get_entrypoints(package_hash: Option) -> EntryPoints { + let _secure = if let Some(contract_package_hash) = package_hash { + let deployer_group = storage::create_contract_user_group( + contract_package_hash, + "deployer", + 1, + BTreeSet::default(), + ) + .unwrap_or_revert(); + runtime::put_key("deployer_access", types::Key::URef(deployer_group[0])); + true + } else { + false + }; + + let mut entry_points = EntryPoints::new(); + entry_points.add_entry_point(endpoint( + "put_on_sale", + vec![ + Parameter::new("seller", CLType::PublicKey), + Parameter::new("designation", CLType::String), + Parameter::new("item", CLType::URef), + Parameter::new("price", CLType::U512), + ], + CLType::Unit, + None, + )); + entry_points.add_entry_point(endpoint( + "put_on_sale_test", + vec![ + Parameter::new("seller", CLType::PublicKey), + Parameter::new("purse", CLType::URef), + ], + CLType::Unit, + None, + )); + entry_points.add_entry_point(endpoint( + "buy", + vec![ + Parameter::new("offer_key", CLType::String), + Parameter::new("payment", CLType::U512), + ], + CLType::URef, + None, + )); + entry_points +} + +pub fn deploy(entry_points: EntryPoints, contract_package_hash: ContractPackageHash) { + let mut named_keys = NamedKeys::new(); + // named_keys.insert("name".to_string(), storage::new_uref(token_name).into()); + + let (contract_hash, _) = + storage::add_contract_version(contract_package_hash, entry_points, named_keys); + runtime::put_key("marketplace_contract_hash", contract_hash.into()); + let contract_hash_pack = storage::new_uref(contract_hash); + runtime::put_key( + "marketplace_contract_package_hash", + contract_hash_pack.into(), + ); +} + +fn ret(value: T) { + runtime::ret(CLValue::from_t(value).unwrap_or_revert()) +} + +fn get_key(name: &str) -> Option { + match runtime::get_key(name) { + None => None, + Some(value) => { + let key = value.try_into().unwrap_or_revert(); + let value = storage::read(key).unwrap_or_revert().unwrap_or_revert(); + Some(value) + } + } +} + +fn set_key(name: &str, value: T) { + match runtime::get_key(name) { + Some(key) => { + let key_ref = key.try_into().unwrap_or_revert(); + storage::write(key_ref, value); + } + None => { + let key = storage::new_uref(value).into(); + runtime::put_key(name, key); + } + } +} + +fn remove_key(name: &str) { + match runtime::get_key(name) { + Some(_) => { + runtime::remove_key(name); + } + None => {} + } +} + +fn endpoint(name: &str, param: Vec, ret: CLType, access: Option<&str>) -> EntryPoint { + EntryPoint::new( + String::from(name), + param, + ret, + match access { + None => EntryPointAccess::Public, + Some(access_key) => EntryPointAccess::groups(&[access_key]), + }, + EntryPointType::Contract, + ) +} diff --git a/marketplace/src/main.rs b/marketplace/src/main.rs new file mode 100644 index 0000000..f64792d --- /dev/null +++ b/marketplace/src/main.rs @@ -0,0 +1,10 @@ +#![no_main] +extern crate marketplace; + +#[no_mangle] +pub extern "C" fn call() { + let (contract_package_hash, _) = + contract::contract_api::storage::create_contract_package_at_hash(); + let entry_points = marketplace::get_entrypoints(None); + marketplace::deploy(entry_points, contract_package_hash); +} diff --git a/marketplace/src/offer.rs b/marketplace/src/offer.rs new file mode 100644 index 0000000..b5bc03d --- /dev/null +++ b/marketplace/src/offer.rs @@ -0,0 +1,111 @@ +use crate::{get_key, remove_key, set_key}; +use alloc::{ + collections::{BTreeMap, BTreeSet}, + string::String, +}; +use contract::contract_api::runtime::revert; +use contract::{ + contract_api::{runtime, storage, system}, + unwrap_or_revert::UnwrapOrRevert, +}; +use core::convert::TryInto; +use std::{ + collections::hash_map::DefaultHasher, + hash::{Hash, Hasher}, +}; +use types::bytesrepr::Error; +use types::{ + account::AccountHash, + bytesrepr::{FromBytes, ToBytes}, + contracts::NamedKeys, + AccessRights, ApiError, AsymmetricType, CLType, CLTyped, CLValue, ContractPackageHash, + EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Key, Parameter, PublicKey, URef, + U256, U512, +}; + +#[derive(Clone)] +pub struct Offer { + pub seller: PublicKey, + pub price: U512, + pub item: URef, + pub designation: String, +} + +impl ToBytes for Offer { + /// Serializes `&self` to a `Vec`. + fn to_bytes(&self) -> Result, Error> { + let mut ret = Vec::new(); + ret.extend(self.seller.to_bytes().unwrap()); + ret.extend(self.price.to_bytes().unwrap()); + ret.extend(self.item.to_bytes().unwrap()); + ret.extend(self.designation.to_bytes().unwrap()); + Ok(ret) + } + /// Consumes `self` and serializes to a `Vec`. + fn into_bytes(self) -> Result, Error> + where + Self: Sized, + { + self.to_bytes() + } + fn serialized_length(&self) -> usize { + self.seller.serialized_length() + + self.price.serialized_length() + + self.item.serialized_length() + + self.designation.serialized_length() + } +} + +impl FromBytes for Offer { + /// Deserializes the slice into `Self`. + fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), Error> { + let pk = PublicKey::from_bytes(&bytes[0..33]).unwrap().0; + let price = U512::from_bytes(&bytes[33..36]).unwrap().0; + let uref = URef::from_bytes(&bytes[36..69]).unwrap().0; + let name = String::from_bytes(&bytes[69..]).unwrap().0; + Ok((Offer::new(pk, price, uref, name), &[])) + } + /// Deserializes the `Vec` into `Self`. + fn from_vec(bytes: Vec) -> Result<(Self, Vec), Error> { + Self::from_bytes(bytes.as_slice()).map(|(x, remainder)| (x, Vec::from(remainder))) + } +} + +impl CLTyped for Offer { + fn cl_type() -> CLType { + CLType::Any + } +} + +impl Offer { + pub fn new(seller: PublicKey, price: U512, item: URef, designation: String) -> Self { + Self { + seller, + price, + item, + designation, + } + } + + pub fn store(&self) -> String { + let key = self.offer_key(""); + set_key(&key, self.clone()); + key + } + + pub fn load(key: &str) -> Offer { + get_key(key).unwrap_or_revert() + } + pub fn offer_key(&self, flag: &str) -> String { + format!("{}_{}{}", self.seller.to_hex(), self.designation, flag) + } + + pub fn test_struct(seller: PublicKey) -> Self { + Self { + seller: seller, + price: U512::from(1000), + item: storage::new_uref("test"), + designation: "test_order".to_string(), + } + } +} diff --git a/marketplace/src/send_tokens.rs b/marketplace/src/send_tokens.rs new file mode 100644 index 0000000..f0f95ca --- /dev/null +++ b/marketplace/src/send_tokens.rs @@ -0,0 +1,28 @@ +#![no_main] + +use contract::contract_api::{account, runtime, system}; +use types::{runtime_args, ContractHash, PublicKey, RuntimeArgs, U512}; + +#[no_mangle] +pub extern "C" fn call() { + let seller: PublicKey = runtime::get_named_arg("seller"); + let marketplace_contract: ContractHash = runtime::get_named_arg("marketplace_contract"); + + let transport_purse = system::create_purse(); + system::transfer_from_purse_to_purse( + account::get_main_purse(), + transport_purse, + U512::from(1000u128), + None, + ) + .unwrap(); + + let _: () = runtime::call_contract( + marketplace_contract, + "put_on_sale_test", + runtime_args! { + "seller" => seller, + "purse" => transport_purse + }, + ); +} diff --git a/tests/src/lib.rs b/tests/src/lib.rs index 8114a14..c774aca 100644 --- a/tests/src/lib.rs +++ b/tests/src/lib.rs @@ -1,5 +1,5 @@ -#[cfg(test)] pub mod cep47; +pub mod market; #[cfg(test)] pub mod tests; diff --git a/tests/src/market.rs b/tests/src/market.rs new file mode 100644 index 0000000..2ce642b --- /dev/null +++ b/tests/src/market.rs @@ -0,0 +1,60 @@ +use casper_engine_test_support::{Code, Hash, SessionBuilder, TestContext}; +use casper_types::{account::AccountHash, runtime_args, AsymmetricType, PublicKey, RuntimeArgs}; + +pub struct MarketTest { + pub market_hash: Hash, + pub account: PublicKey, +} + +impl MarketTest { + pub fn deploy(context: &mut TestContext) -> Self { + let admin = PublicKey::ed25519_from_bytes([1u8; 32]).unwrap(); + let session_code = Code::from("marketplace.wasm"); + let session_args = runtime_args! {}; + let session = SessionBuilder::new(session_code, session_args) + .with_address(admin.to_account_hash()) + .with_authorization_keys(&[admin.to_account_hash()]) + .build(); + context.run(session); + let market_hash = context + .query( + admin.to_account_hash(), + &["marketplace_contract_package_hash".to_string()], + ) + .unwrap() + .into_t() + .unwrap(); + Self { + market_hash, + account: admin, + } + } + + fn call( + &self, + context: &mut TestContext, + account: &AccountHash, + method: &str, + args: RuntimeArgs, + ) { + let code = Code::Hash(self.market_hash, method.to_string()); + let session = SessionBuilder::new(code, args) + .with_address(*account) + .with_authorization_keys(&[*account]) + .build(); + context.run(session); + } + + pub fn call_test(&self, context: &mut TestContext) { + let session_code = Code::from("send_tokens.wasm"); + let session_args = runtime_args! { + "marketplace_contract" => self.market_hash, + "seller" => self.account.clone(), + }; + let session = SessionBuilder::new(session_code, session_args) + .with_address(self.account.to_account_hash()) + .with_authorization_keys(&[self.account.to_account_hash()]) + .build(); + context.run(session); + } +} diff --git a/tests/src/tests.rs b/tests/src/tests.rs index 73cdd93..97e5829 100644 --- a/tests/src/tests.rs +++ b/tests/src/tests.rs @@ -1,4 +1,5 @@ use crate::cep47::{token_cfg, CasperCEP47Contract, TokenId, URI}; +use crate::market::MarketTest; use casper_types::{AsymmetricType, PublicKey, SecretKey, U256}; #[test] @@ -137,3 +138,16 @@ fn test_transfer_all_tokens() { assert_eq!(contract.owner_of(&ali_tokens[0]), Some(bob.clone())); assert_eq!(contract.owner_of(&ali_tokens[1]), Some(bob)); } + +#[test] +fn test_marketplace() { + let mut contract = CasperCEP47Contract::deploy(); + let ali: PublicKey = SecretKey::ed25519_from_bytes([3u8; 32]).unwrap().into(); + let bob: PublicKey = SecretKey::ed25519_from_bytes([5u8; 32]).unwrap().into(); + let token_uris: Vec = vec![ + URI::from("Casper Golden Card"), + URI::from("Casper Silver Card"), + ]; + let market = MarketTest::deploy(&mut contract.context); + market.call_test(&mut contract.context); +} From 3b67779c965f74ed512d506961fd35b810eeb6e9 Mon Sep 17 00:00:00 2001 From: Deusz Date: Fri, 4 Jun 2021 16:07:14 +0200 Subject: [PATCH 26/98] more test --- marketplace/src/lib.rs | 75 ++++++++++++++++++++++++++-------- marketplace/src/send_tokens.rs | 9 +++- tests/src/cep47.rs | 30 +++++++++----- tests/src/market.rs | 19 ++++----- tests/src/tests.rs | 7 ++-- 5 files changed, 96 insertions(+), 44 deletions(-) diff --git a/marketplace/src/lib.rs b/marketplace/src/lib.rs index e047629..0b50466 100644 --- a/marketplace/src/lib.rs +++ b/marketplace/src/lib.rs @@ -12,7 +12,7 @@ use alloc::{ }; use contract::contract_api::runtime::revert; use contract::{ - contract_api::{runtime, storage, system}, + contract_api::{runtime, storage, system, account}, unwrap_or_revert::UnwrapOrRevert, }; use core::convert::TryInto; @@ -34,21 +34,29 @@ use types::{ #[no_mangle] pub extern "C" fn put_on_sale_test() { let sel = runtime::get_named_arg("seller"); - let purse: URef = runtime::get_named_arg("purse"); let offer = Offer::test_struct(sel); let rets = offer.store(); + ret(rets) +} - let i_want_to_buy = Offer::load(&rets); - system::transfer_from_purse_to_account( - purse, - i_want_to_buy.seller.to_account_hash(), - system::get_purse_balance(purse).unwrap_or_revert(), - None, - ) - .unwrap_or_revert(); - remove_key(&i_want_to_buy.offer_key("")); +#[no_mangle] +pub extern "C" fn test_buy() { + let offer_key: String = "018a88e3dd7409f195fd52db2d3cba5d72ca6709bf1d94121bf3748801b40f6f5c_test_order".to_string(); + let purse: URef = runtime::get_named_arg("purse"); + let offer: Offer = Offer::load(&offer_key); + if system::get_purse_balance(purse).unwrap_or_revert() == offer.price && runtime::get_caller()!=offer.seller.to_account_hash(){ + system::transfer_from_purse_to_account( + purse, + offer.seller.to_account_hash(), + system::get_purse_balance(purse).unwrap_or_revert(), + None, + ) + .unwrap_or_revert(); + remove_key(&offer_key); + } } + #[no_mangle] pub extern "C" fn put_on_sale() { let offer = Offer::new( @@ -65,7 +73,7 @@ pub extern "C" fn buy() { let offer_key: String = runtime::get_named_arg("offer_key"); let payment: U512 = runtime::get_named_arg("payment"); let offer: Offer = Offer::load(&offer_key); - if payment == offer.price { + if payment == offer.price && runtime::get_caller()!=offer.seller.to_account_hash(){ system::transfer_to_account(offer.seller.to_account_hash(), payment, None) .unwrap_or_revert(); remove_key(&offer_key); @@ -73,11 +81,20 @@ pub extern "C" fn buy() { } } +#[no_mangle] +pub extern "C" fn get_price() { + let offer_key: String = runtime::get_named_arg("offer_key"); + let offer: Offer = Offer::load(&offer_key); + ret(offer.price) +} + #[no_mangle] pub extern "C" fn cancel() { let offer_key: String = runtime::get_named_arg("offer_key"); - // let offer: Offer = Offer::load(&offer_key); - remove_key(&offer_key); + let offer: Offer = Offer::load(&offer_key); + if runtime::get_caller()==offer.seller.to_account_hash(){ + remove_key(&offer_key); + } } pub fn get_entrypoints(package_hash: Option) -> EntryPoints { @@ -104,16 +121,15 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints Parameter::new("item", CLType::URef), Parameter::new("price", CLType::U512), ], - CLType::Unit, + CLType::String, None, )); entry_points.add_entry_point(endpoint( "put_on_sale_test", vec![ Parameter::new("seller", CLType::PublicKey), - Parameter::new("purse", CLType::URef), ], - CLType::Unit, + CLType::String, None, )); entry_points.add_entry_point(endpoint( @@ -125,6 +141,31 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints CLType::URef, None, )); + entry_points.add_entry_point(endpoint( + "test_buy", + vec![ + Parameter::new("payment", CLType::U512), + ], + CLType::URef, + None, + )); + entry_points.add_entry_point(endpoint( + "cancel", + vec![ + Parameter::new("offer_key", CLType::String), + ], + CLType::Unit, + None, + )); + entry_points.add_entry_point(endpoint( + "get_price", + vec![ + Parameter::new("offer_key", CLType::String), + ], + CLType::U512, + None, + )); + entry_points } diff --git a/marketplace/src/send_tokens.rs b/marketplace/src/send_tokens.rs index f0f95ca..afa926c 100644 --- a/marketplace/src/send_tokens.rs +++ b/marketplace/src/send_tokens.rs @@ -17,11 +17,18 @@ pub extern "C" fn call() { ) .unwrap(); - let _: () = runtime::call_contract( + let offer_key: String = runtime::call_contract( marketplace_contract, "put_on_sale_test", runtime_args! { "seller" => seller, + }, + ); + let _: () = runtime::call_contract( + marketplace_contract, + "test_buy", + runtime_args! { + // "offer_key" => offer_key, "purse" => transport_purse }, ); diff --git a/tests/src/cep47.rs b/tests/src/cep47.rs index ccb3662..4395efb 100644 --- a/tests/src/cep47.rs +++ b/tests/src/cep47.rs @@ -1,6 +1,6 @@ use casper_engine_test_support::{Code, Hash, SessionBuilder, TestContext, TestContextBuilder}; use casper_types::{ - account::AccountHash, bytesrepr::FromBytes, runtime_args, AsymmetricType, CLTyped, PublicKey, + account::AccountHash, bytesrepr::FromBytes, runtime_args, AsymmetricType, SecretKey, CLTyped, PublicKey, RuntimeArgs, URef, U256, U512, }; @@ -16,7 +16,9 @@ pub const CASPERCEP47_CONTRACT_HASH: &str = "caspercep47_contract_hash"; pub struct CasperCEP47Contract { pub context: TestContext, pub caspercep47_hash: Hash, - pub account: AccountHash, + pub admin: PublicKey, + pub ali: PublicKey, + pub bob: PublicKey, } pub type TokenId = String; @@ -24,9 +26,13 @@ pub type URI = String; impl CasperCEP47Contract { pub fn deploy() -> Self { - let account = PublicKey::ed25519_from_bytes([1u8; 32]).unwrap(); + let admin: PublicKey = SecretKey::ed25519_from_bytes([1u8; 32]).unwrap().into(); + let ali: PublicKey = SecretKey::ed25519_from_bytes([3u8; 32]).unwrap().into(); + let bob: PublicKey = SecretKey::ed25519_from_bytes([5u8; 32]).unwrap().into(); let mut context = TestContextBuilder::new() - .with_public_key(account.clone(), U512::from(500_000_000_000_000_000u64)) + .with_public_key(admin.clone(), U512::from(500_000_000_000_000_000u64)) + .with_public_key(ali.clone(), U512::from(500_000_000_000_000_000u64)) + .with_public_key(bob.clone(), U512::from(500_000_000_000_000_000u64)) .build(); let session_code = Code::from("cep47.wasm"); let session_args = runtime_args! { @@ -35,13 +41,13 @@ impl CasperCEP47Contract { "token_uri" => token_cfg::URI }; let session = SessionBuilder::new(session_code, session_args) - .with_address(account.to_account_hash()) - .with_authorization_keys(&[account.to_account_hash()]) + .with_address(admin.to_account_hash()) + .with_authorization_keys(&[admin.to_account_hash()]) .build(); context.run(session); let caspercep47_hash = context .query( - account.to_account_hash(), + admin.to_account_hash(), &[CASPERCEP47_CONTRACT_HASH.to_string()], ) .unwrap() @@ -51,22 +57,24 @@ impl CasperCEP47Contract { Self { context, caspercep47_hash, - account: account.to_account_hash(), + admin: admin, + ali: ali, + bob: bob } } fn call(&mut self, method: &str, args: RuntimeArgs) { let code = Code::Hash(self.caspercep47_hash, method.to_string()); let session = SessionBuilder::new(code, args) - .with_address(self.account) - .with_authorization_keys(&[self.account]) + .with_address(self.admin.to_account_hash()) + .with_authorization_keys(&[self.admin.to_account_hash()]) .build(); self.context.run(session); } fn query_contract(&self, name: &str) -> Option { match self.context.query( - self.account, + self.admin.to_account_hash(), &[CASPERCEP47_CONTRACT.to_string(), name.to_string()], ) { Err(_) => None, diff --git a/tests/src/market.rs b/tests/src/market.rs index 2ce642b..20b9719 100644 --- a/tests/src/market.rs +++ b/tests/src/market.rs @@ -3,22 +3,20 @@ use casper_types::{account::AccountHash, runtime_args, AsymmetricType, PublicKey pub struct MarketTest { pub market_hash: Hash, - pub account: PublicKey, } impl MarketTest { - pub fn deploy(context: &mut TestContext) -> Self { - let admin = PublicKey::ed25519_from_bytes([1u8; 32]).unwrap(); + pub fn deploy(context: &mut TestContext, deployer: AccountHash) -> Self { let session_code = Code::from("marketplace.wasm"); let session_args = runtime_args! {}; let session = SessionBuilder::new(session_code, session_args) - .with_address(admin.to_account_hash()) - .with_authorization_keys(&[admin.to_account_hash()]) + .with_address(deployer) + .with_authorization_keys(&[deployer]) .build(); context.run(session); let market_hash = context .query( - admin.to_account_hash(), + deployer, &["marketplace_contract_package_hash".to_string()], ) .unwrap() @@ -26,7 +24,6 @@ impl MarketTest { .unwrap(); Self { market_hash, - account: admin, } } @@ -45,15 +42,15 @@ impl MarketTest { context.run(session); } - pub fn call_test(&self, context: &mut TestContext) { + pub fn call_test(&self, context: &mut TestContext, account: &PublicKey, seller: &PublicKey) { let session_code = Code::from("send_tokens.wasm"); let session_args = runtime_args! { "marketplace_contract" => self.market_hash, - "seller" => self.account.clone(), + "seller" => seller.clone(), }; let session = SessionBuilder::new(session_code, session_args) - .with_address(self.account.to_account_hash()) - .with_authorization_keys(&[self.account.to_account_hash()]) + .with_address(account.to_account_hash()) + .with_authorization_keys(&[account.to_account_hash()]) .build(); context.run(session); } diff --git a/tests/src/tests.rs b/tests/src/tests.rs index 97e5829..ae58b04 100644 --- a/tests/src/tests.rs +++ b/tests/src/tests.rs @@ -142,12 +142,11 @@ fn test_transfer_all_tokens() { #[test] fn test_marketplace() { let mut contract = CasperCEP47Contract::deploy(); - let ali: PublicKey = SecretKey::ed25519_from_bytes([3u8; 32]).unwrap().into(); - let bob: PublicKey = SecretKey::ed25519_from_bytes([5u8; 32]).unwrap().into(); let token_uris: Vec = vec![ URI::from("Casper Golden Card"), URI::from("Casper Silver Card"), ]; - let market = MarketTest::deploy(&mut contract.context); - market.call_test(&mut contract.context); + let market = MarketTest::deploy(&mut contract.context, contract.admin.to_account_hash()); + market.call_test(&mut contract.context, &contract.ali, &contract.admin); + contract.mint_many(contract.ali.clone(), token_uris); } From e79f95c0e3d6d1878f7a3e3da311f57f9c555d3a Mon Sep 17 00:00:00 2001 From: astro019 Date: Tue, 8 Jun 2021 22:50:15 +1000 Subject: [PATCH 27/98] adding example token --- Cargo.toml | 3 +- Makefile | 10 ++--- cep47/Cargo.toml | 13 ++---- cep47/src/lib.rs | 92 +++++++++++++++++++++++++++------------ cep47/src/logic.rs | 36 +++++++++++---- cep47/src/main.rs | 16 ------- cep47/src/tests.rs | 9 ++-- example-token/Cargo.toml | 22 ++++++++++ example-token/src/main.rs | 46 ++++++++++++++++++++ tests/src/cep47.rs | 10 ++++- tests/src/tests.rs | 11 +++++ 11 files changed, 196 insertions(+), 72 deletions(-) delete mode 100644 cep47/src/main.rs create mode 100644 example-token/Cargo.toml create mode 100644 example-token/src/main.rs diff --git a/Cargo.toml b/Cargo.toml index b6e8c8b..e299197 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,8 @@ members = [ "cep47", - "tests" + "tests", + "example-token" ] [profile.release] diff --git a/Makefile b/Makefile index d156dd4..9ae2627 100644 --- a/Makefile +++ b/Makefile @@ -2,18 +2,18 @@ prepare: rustup target add wasm32-unknown-unknown build-contract: - cargo +nightly build --release -p cep47 --target wasm32-unknown-unknown + cargo build --release -p example-token --target wasm32-unknown-unknown test-only: - cargo +nightly test --workspace + cargo test --workspace copy-wasm-file-to-test: - cp target/wasm32-unknown-unknown/release/cep47.wasm tests/wasm + cp target/wasm32-unknown-unknown/release/example-token.wasm tests/wasm test: build-contract copy-wasm-file-to-test test-only clippy: - cargo +nightly clippy --all-targets --all -- -D warnings -A renamed_and_removed_lints + cargo clippy --all-targets --all -- -D warnings -A renamed_and_removed_lints check-lint: clippy cargo fmt --all -- --check @@ -25,4 +25,4 @@ lint: clippy format clean: cargo clean - rm -rf tests/wasm/cep47.wasm + rm -rf tests/wasm/example-token.wasm diff --git a/cep47/Cargo.toml b/cep47/Cargo.toml index 570c6bd..f2011e7 100644 --- a/cep47/Cargo.toml +++ b/cep47/Cargo.toml @@ -5,16 +5,9 @@ authors = ["astro019 "] edition = "2018" [dependencies] -contract = { package = "casper-contract", version="1.2.0" } -types = { package = "casper-types", version="1.2.0" } +casper-contract = "1.2.0" +casper-types = "1.2.0" rand = { version="0.8", default-features=false } -[[bin]] +[lib] name = "cep47" -path = "src/main.rs" -bench = false -doctest = false -test = false - -[features] -default = ["contract/std", "types/std"] diff --git a/cep47/src/lib.rs b/cep47/src/lib.rs index 5dd28ff..1103d32 100644 --- a/cep47/src/lib.rs +++ b/cep47/src/lib.rs @@ -11,17 +11,11 @@ use alloc::{ collections::{BTreeMap, BTreeSet}, string::String, }; -use contract::{ +use casper_contract::{ contract_api::{runtime, storage}, unwrap_or_revert::UnwrapOrRevert, }; -use core::convert::TryInto; -use logic::{CEP47Contract, CEP47Storage, TokenId, WithStorage, URI}; -use std::{ - collections::hash_map::DefaultHasher, - hash::{Hash, Hasher}, -}; -use types::{ +use casper_types::{ account::AccountHash, bytesrepr::{FromBytes, ToBytes}, contracts::NamedKeys, @@ -29,8 +23,14 @@ use types::{ EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Key, Parameter, PublicKey, URef, U256, }; +use core::convert::TryInto; +use logic::{CEP47Contract, CEP47Storage, TokenId, WithStorage, URI}; +use std::{ + collections::hash_map::DefaultHasher, + hash::{Hash, Hasher}, +}; -struct CasperCEP47Storage {} +pub struct CasperCEP47Storage {} impl CasperCEP47Storage { pub fn new() -> CasperCEP47Storage { CasperCEP47Storage {} @@ -125,16 +125,43 @@ impl CEP47Storage for CasperCEP47Storage { self.mint_many(recipient, token_uris); } fn new_uref(&mut self, token_id: TokenId) -> Option { - None + let value_ref = + storage::new_uref(token_id).with_access_rights(AccessRights::READ_ADD_WRITE); + let value_key = uref_key(&value_ref); + let prev_value_ref = get_key::(&value_key); + if prev_value_ref.is_some() { + None + } else { + set_key(&value_key, value_ref); + Some(value_ref) + } } fn del_uref(&mut self, token_uref: URef) -> Option { - None + let token_id = self.token_id(token_uref); + if token_id.is_some() { + let value_key = uref_key(&token_uref); + remove_key(&value_key); + token_id + } else { + None + } } fn token_id(&self, token_uref: URef) -> Option { - None + let value_key = uref_key(&token_uref); + let prev_value_ref = get_key::(&value_key); + if prev_value_ref.is_some() { + let res = storage::read::(prev_value_ref.unwrap()); + if res.is_err() { + None + } else { + res.unwrap() + } + } else { + None + } } } -struct CasperCEP47Contract { +pub struct CasperCEP47Contract { storage: CasperCEP47Storage, } impl CasperCEP47Contract { @@ -153,11 +180,6 @@ impl WithStorage for CasperCEP47Contract { } } impl CEP47Contract for CasperCEP47Contract {} -/** - * ApiError::User(1) - The number of piece is out or range. - * ApiError::User(2) - The piece of NFT is already minted and owned by someone. - * ApiError::User(3) - The piece of NFT is not minted yet. - */ #[no_mangle] pub extern "C" fn name() { @@ -242,7 +264,8 @@ pub extern "C" fn transfer_token() { let recipient: PublicKey = runtime::get_named_arg("recipient"); let token_id: TokenId = runtime::get_named_arg("token_id"); let mut contract = CasperCEP47Contract::new(); - contract.transfer_token(sender, recipient, token_id); + let res = contract.transfer_token(sender, recipient, token_id); + res.unwrap_or_revert(); } #[no_mangle] @@ -251,7 +274,8 @@ pub extern "C" fn transfer_many_tokens() { let recipient: PublicKey = runtime::get_named_arg("recipient"); let token_ids: Vec = runtime::get_named_arg("token_ids"); let mut contract = CasperCEP47Contract::new(); - contract.transfer_many_tokens(sender, recipient, token_ids); + let res = contract.transfer_many_tokens(sender, recipient, token_ids); + res.unwrap_or_revert(); } #[no_mangle] @@ -275,7 +299,8 @@ pub extern "C" fn detach() { let owner: PublicKey = runtime::get_named_arg("owner"); let token_id: TokenId = runtime::get_named_arg("token_id"); let mut contract = CasperCEP47Contract::new(); - contract.detach(owner, token_id); + let res = contract.detach(owner, token_id.clone()); // For test purpose + set_key(&test_uref_key(&token_id), res); } pub fn get_entrypoints(package_hash: Option) -> EntryPoints { @@ -287,7 +312,7 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints BTreeSet::default(), ) .unwrap_or_revert(); - runtime::put_key("deployer_access", types::Key::URef(deployer_group[0])); + runtime::put_key("deployer_access", Key::URef(deployer_group[0])); true } else { false @@ -441,10 +466,6 @@ pub fn deploy( runtime::put_key("caspercep47_contract_hash", contract_hash_pack.into()); } -fn ret(value: T) { - runtime::ret(CLValue::from_t(value).unwrap_or_revert()) -} - fn get_key(name: &str) -> Option { match runtime::get_key(name) { None => None, @@ -490,11 +511,24 @@ fn uri_key(token_id: &TokenId) -> String { format!("uris_{}", token_id) } +fn uref_key(uref: &URef) -> String { + format!("uref_{}", uref) +} + +fn test_uref_key(token_id: &TokenId) -> String { + format!("turef_{}", token_id) +} + fn token_key(account: &AccountHash) -> String { format!("tokens_{}", account) } -fn endpoint(name: &str, param: Vec, ret: CLType, access: Option<&str>) -> EntryPoint { +pub fn endpoint( + name: &str, + param: Vec, + ret: CLType, + access: Option<&str>, +) -> EntryPoint { EntryPoint::new( String::from(name), param, @@ -506,3 +540,7 @@ fn endpoint(name: &str, param: Vec, ret: CLType, access: Option<&str> EntryPointType::Contract, ) } + +pub fn ret(value: T) { + runtime::ret(CLValue::from_t(value).unwrap_or_revert()) +} diff --git a/cep47/src/logic.rs b/cep47/src/logic.rs index b871677..459e077 100644 --- a/cep47/src/logic.rs +++ b/cep47/src/logic.rs @@ -1,10 +1,21 @@ #![allow(dead_code)] #![allow(unused_imports)] -use types::{AsymmetricType, PublicKey, URef, U256}; +use casper_types::{ApiError, AsymmetricType, PublicKey, URef, U256}; pub type TokenId = String; pub type URI = String; +#[repr(u16)] +pub enum Error { + PermissionDenied = 2, // 65538 +} + +impl From for ApiError { + fn from(error: Error) -> ApiError { + ApiError::User(error as u16) + } +} + pub trait WithStorage { fn storage(&self) -> &Storage; fn storage_mut(&mut self) -> &mut Storage; @@ -61,15 +72,18 @@ pub trait CEP47Contract: WithStorage { } // Transfer functions. - fn transfer_token(&mut self, sender: PublicKey, recipient: PublicKey, token_id: TokenId) { + fn transfer_token( + &mut self, + sender: PublicKey, + recipient: PublicKey, + token_id: TokenId, + ) -> Result<(), Error> { // 1. Load tokens owned by the sender. let mut sender_tokens = self.storage().get_tokens(sender.clone()); // 2. Assert that token_id is in sender_tokens. - assert!( - sender_tokens.contains(&token_id), - "wrong owner of token {}", - token_id - ); + if !sender_tokens.contains(&token_id) { + return Err(Error::PermissionDenied); + } // 3. Remove token_id from sender_tokens. sender_tokens.retain(|x| x.clone() != token_id); self.storage_mut().set_tokens(sender, sender_tokens); @@ -78,6 +92,7 @@ pub trait CEP47Contract: WithStorage { let mut recipient_tokens = self.storage().get_tokens(recipient.clone()); recipient_tokens.push(token_id); self.storage_mut().set_tokens(recipient, recipient_tokens); + Ok(()) } fn transfer_many_tokens( @@ -85,16 +100,19 @@ pub trait CEP47Contract: WithStorage { sender: PublicKey, recipient: PublicKey, token_ids: Vec, - ) { + ) -> Result<(), Error> { let mut sender_tokens = self.storage().get_tokens(sender.clone()); for token_id in token_ids.iter() { - assert!(sender_tokens.contains(token_id), "wrong token {}", token_id); + if !sender_tokens.contains(token_id) { + return Err(Error::PermissionDenied); + } sender_tokens.retain(|x| x.clone() != token_id.clone()); } let mut recipient_tokens = self.storage().get_tokens(recipient.clone()); recipient_tokens.append(&mut token_ids.clone()); self.storage_mut().set_tokens(sender, sender_tokens); self.storage_mut().set_tokens(recipient, recipient_tokens); + Ok(()) } fn transfer_all_tokens(&mut self, sender: PublicKey, recipient: PublicKey) { diff --git a/cep47/src/main.rs b/cep47/src/main.rs deleted file mode 100644 index 0f6ad43..0000000 --- a/cep47/src/main.rs +++ /dev/null @@ -1,16 +0,0 @@ -#![no_main] -extern crate cep47; - -#[no_mangle] -pub extern "C" fn call() { - let (contract_package_hash, _) = - contract::contract_api::storage::create_contract_package_at_hash(); - let entry_points = cep47::get_entrypoints(None); - cep47::deploy( - &contract::contract_api::runtime::get_named_arg::("token_name"), - &contract::contract_api::runtime::get_named_arg::("token_symbol"), - &contract::contract_api::runtime::get_named_arg::("token_uri"), - entry_points, - contract_package_hash, - ); -} diff --git a/cep47/src/tests.rs b/cep47/src/tests.rs index 5654106..3b8e680 100644 --- a/cep47/src/tests.rs +++ b/cep47/src/tests.rs @@ -1,7 +1,7 @@ #[cfg(test)] mod tests { + use casper_types::AccessRights; use rand::Rng; - use types::AccessRights; use crate::{ AsymmetricType, CEP47Contract, CEP47Storage, PublicKey, TokenId, URef, WithStorage, U256, @@ -283,7 +283,9 @@ mod tests { let ali_first_token_uri: URI = contract.token_uri(ali_first_token_id.clone()).unwrap(); assert_eq!(ali_first_token_uri, URI::from("Casper Fan URI")); - contract.transfer_token(ali.clone(), bob.clone(), ali_first_token_id.clone()); + let transfer_res = + contract.transfer_token(ali.clone(), bob.clone(), ali_first_token_id.clone()); + assert!(transfer_res.is_ok()); ali_balance = contract.balance_of(ali); bob_balance = contract.balance_of(bob.clone()); assert_eq!(ali_balance, U256::from(0)); @@ -354,11 +356,12 @@ mod tests { assert_eq!(ali_second_token_uri, URI::from("Banana URI")); assert_eq!(ali_third_token_uri, URI::from("Casper Fan URI")); - contract.transfer_many_tokens( + let transfer_res = contract.transfer_many_tokens( ali.clone(), bob.clone(), vec![ali_second_token_id.clone(), ali_third_token_id.clone()], ); + assert!(transfer_res.is_ok()); ali_balance = contract.balance_of(ali); bob_balance = contract.balance_of(bob.clone()); diff --git a/example-token/Cargo.toml b/example-token/Cargo.toml new file mode 100644 index 0000000..060ee90 --- /dev/null +++ b/example-token/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "example-token" +version = "0.1.0" +authors = ["astro019 "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +contract = { package="casper-contract", version = "1.2.0" } +types = { package="casper-types", version = "1.2.0" } +cep47 = { path="../cep47" } + +[[bin]] +name = "example-token" +path = "src/main.rs" +bench = false +doctest = false +test = false + +[features] +default = ["contract/std", "types/std"] diff --git a/example-token/src/main.rs b/example-token/src/main.rs new file mode 100644 index 0000000..3617173 --- /dev/null +++ b/example-token/src/main.rs @@ -0,0 +1,46 @@ +#![no_main] +extern crate cep47; +use cep47::{endpoint, logic::CEP47Contract, ret, CasperCEP47Contract}; +use types::{CLType, EntryPoints}; + +#[no_mangle] +pub extern "C" fn new_name() { + let contract = CasperCEP47Contract::new(); + ret(String::from("[CEP47] ").push_str(contract.name().as_str())) +} + +#[no_mangle] +pub extern "C" fn change_name() { + // let contract = CasperCEP47Contract::new(); +} + +/** +It should present how to: + +- override one of the CEP47 endpoints. Override the name endpoint to always return a name in the format: +[CEP47] +- add a new endpoint. Add change_name that allows to change a name. +- show how to tests only the name and and change_name. If the name is changed to example-nft then name endpoint should return [CEP47] example-nft. This test should be implemented as a WASM file. + */ + +#[no_mangle] +pub extern "C" fn call() { + let (contract_package_hash, _) = + contract::contract_api::storage::create_contract_package_at_hash(); + let entry_points = cep47::get_entrypoints(None); + let mut new_entry_points = EntryPoints::new(); + for ep in entry_points.take_entry_points().iter() { + if ep.name().eq("name") { + new_entry_points.add_entry_point(endpoint("new_name", vec![], CLType::String, None)); + } else { + new_entry_points.add_entry_point(ep.to_owned()); + } + } + cep47::deploy( + &contract::contract_api::runtime::get_named_arg::("token_name"), + &contract::contract_api::runtime::get_named_arg::("token_symbol"), + &contract::contract_api::runtime::get_named_arg::("token_uri"), + new_entry_points, + contract_package_hash, + ); +} diff --git a/tests/src/cep47.rs b/tests/src/cep47.rs index ccb3662..423fe9b 100644 --- a/tests/src/cep47.rs +++ b/tests/src/cep47.rs @@ -28,7 +28,7 @@ impl CasperCEP47Contract { let mut context = TestContextBuilder::new() .with_public_key(account.clone(), U512::from(500_000_000_000_000_000u64)) .build(); - let session_code = Code::from("cep47.wasm"); + let session_code = Code::from("example-token.wasm"); let session_args = runtime_args! { "token_name" => token_cfg::NAME, "token_symbol" => token_cfg::SYMBOL, @@ -113,6 +113,10 @@ impl CasperCEP47Contract { self.query_contract(uri_key(&token_id).as_str()) } + pub fn token_uref(&self, token_id: &TokenId) -> Option { + self.query_contract(test_uref_key(&token_id).as_str()) + } + pub fn mint_one(&mut self, recipient: PublicKey, token_uri: URI) { self.call( "mint_one", @@ -217,3 +221,7 @@ fn uri_key(token_id: &TokenId) -> String { fn token_key(account: &AccountHash) -> String { format!("tokens_{}", account) } + +fn test_uref_key(token_id: &TokenId) -> String { + format!("turef_{}", token_id) +} diff --git a/tests/src/tests.rs b/tests/src/tests.rs index 73cdd93..5a17972 100644 --- a/tests/src/tests.rs +++ b/tests/src/tests.rs @@ -137,3 +137,14 @@ fn test_transfer_all_tokens() { assert_eq!(contract.owner_of(&ali_tokens[0]), Some(bob.clone())); assert_eq!(contract.owner_of(&ali_tokens[1]), Some(bob)); } + +#[test] +fn test_attach_and_detach() { + let mut contract = CasperCEP47Contract::deploy(); + let ali: PublicKey = SecretKey::ed25519_from_bytes([3u8; 32]).unwrap().into(); + // let bob: PublicKey = SecretKey::ed25519_from_bytes([5u8; 32]).unwrap().into(); + let token_uri = URI::from("0x12af"); + contract.mint_one(ali.clone(), token_uri); + let ali_token_id: TokenId = contract.tokens(ali.clone())[0].clone(); + contract.detach(ali.clone(), ali_token_id.clone()); +} From f10c0073ad8a6aca07fe02f758a52e46bcd57ab5 Mon Sep 17 00:00:00 2001 From: Maciej Zielinski Date: Tue, 8 Jun 2021 15:17:02 +0200 Subject: [PATCH 28/98] tests/wasm --- Makefile | 1 + tests/wasm/.gitkeep | 0 2 files changed, 1 insertion(+) create mode 100644 tests/wasm/.gitkeep diff --git a/Makefile b/Makefile index 2b77217..8f7d345 100644 --- a/Makefile +++ b/Makefile @@ -9,6 +9,7 @@ test-only: cargo test --workspace copy-wasm-file-to-test: + mkdir -p tests/wasm cp target/wasm32-unknown-unknown/release/example-token.wasm tests/wasm cp target/wasm32-unknown-unknown/release/marketplace.wasm tests/wasm cp target/wasm32-unknown-unknown/release/send_tokens.wasm tests/wasm diff --git a/tests/wasm/.gitkeep b/tests/wasm/.gitkeep new file mode 100644 index 0000000..e69de29 From 527fbbb14b729e4a64458108f7fa23831a5e8fe3 Mon Sep 17 00:00:00 2001 From: Maciej Zielinski Date: Tue, 8 Jun 2021 15:42:00 +0200 Subject: [PATCH 29/98] Dragons NFT + test reorg --- Cargo.toml | 2 +- Makefile | 10 ++--- cep47/Cargo.toml | 3 ++ cep47/src/lib.rs | 2 +- cep47/src/{tests.rs => logic_tests.rs} | 0 cep47/src/test_attach_detach.rs | 7 ++++ {example-token => dragons-nft}/Cargo.toml | 4 +- dragons-nft/src/main.rs | 16 ++++++++ example-token/src/main.rs | 46 ----------------------- marketplace/src/lib.rs | 32 +++++++--------- tests/src/cep47.rs | 30 +++------------ tests/src/{tests.rs => contract_tests.rs} | 24 ------------ tests/src/lib.rs | 2 +- tests/src/market.rs | 9 +---- 14 files changed, 54 insertions(+), 133 deletions(-) rename cep47/src/{tests.rs => logic_tests.rs} (100%) create mode 100644 cep47/src/test_attach_detach.rs rename {example-token => dragons-nft}/Cargo.toml (91%) create mode 100644 dragons-nft/src/main.rs delete mode 100644 example-token/src/main.rs rename tests/src/{tests.rs => contract_tests.rs} (85%) diff --git a/Cargo.toml b/Cargo.toml index 8d263a6..ae618a2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ members = [ "tests", - "example-token", + "dragons-nft", "marketplace" ] diff --git a/Makefile b/Makefile index 8f7d345..a3ac087 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ prepare: rustup target add wasm32-unknown-unknown build-contract: - cargo build --release -p example-token --target wasm32-unknown-unknown + cargo build --release -p dragons-nft --target wasm32-unknown-unknown cargo build --release -p marketplace --target wasm32-unknown-unknown test-only: @@ -10,9 +10,7 @@ test-only: copy-wasm-file-to-test: mkdir -p tests/wasm - cp target/wasm32-unknown-unknown/release/example-token.wasm tests/wasm - cp target/wasm32-unknown-unknown/release/marketplace.wasm tests/wasm - cp target/wasm32-unknown-unknown/release/send_tokens.wasm tests/wasm + cp target/wasm32-unknown-unknown/release/*.wasm tests/wasm test: build-contract copy-wasm-file-to-test test-only @@ -29,6 +27,4 @@ lint: clippy format clean: cargo clean - rm -rf tests/wasm/example-token.wasm - rm -rf tests/wasm/marketplace.wasm - rm -rf tests/wasm/send_tokens.wasm + rm -rf tests/wasm/*.wasm diff --git a/cep47/Cargo.toml b/cep47/Cargo.toml index f2011e7..f578f6f 100644 --- a/cep47/Cargo.toml +++ b/cep47/Cargo.toml @@ -11,3 +11,6 @@ rand = { version="0.8", default-features=false } [lib] name = "cep47" + +[features] +default = ["casper-contract/std", "casper-types/std"] diff --git a/cep47/src/lib.rs b/cep47/src/lib.rs index 1103d32..85a8a19 100644 --- a/cep47/src/lib.rs +++ b/cep47/src/lib.rs @@ -5,7 +5,7 @@ extern crate alloc; pub mod logic; -pub mod tests; +pub mod logic_tests; use alloc::{ collections::{BTreeMap, BTreeSet}, diff --git a/cep47/src/tests.rs b/cep47/src/logic_tests.rs similarity index 100% rename from cep47/src/tests.rs rename to cep47/src/logic_tests.rs diff --git a/cep47/src/test_attach_detach.rs b/cep47/src/test_attach_detach.rs new file mode 100644 index 0000000..8e18cc9 --- /dev/null +++ b/cep47/src/test_attach_detach.rs @@ -0,0 +1,7 @@ +fn call() { + // mint tokens. + // detach tokens. + // assert balances. + // attach token to another account. + // assert balances. +} \ No newline at end of file diff --git a/example-token/Cargo.toml b/dragons-nft/Cargo.toml similarity index 91% rename from example-token/Cargo.toml rename to dragons-nft/Cargo.toml index 060ee90..9ea9ff1 100644 --- a/example-token/Cargo.toml +++ b/dragons-nft/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "example-token" +name = "dragons-nft" version = "0.1.0" authors = ["astro019 "] edition = "2018" @@ -12,7 +12,7 @@ types = { package="casper-types", version = "1.2.0" } cep47 = { path="../cep47" } [[bin]] -name = "example-token" +name = "dragons-nft" path = "src/main.rs" bench = false doctest = false diff --git a/dragons-nft/src/main.rs b/dragons-nft/src/main.rs new file mode 100644 index 0000000..0f6ad43 --- /dev/null +++ b/dragons-nft/src/main.rs @@ -0,0 +1,16 @@ +#![no_main] +extern crate cep47; + +#[no_mangle] +pub extern "C" fn call() { + let (contract_package_hash, _) = + contract::contract_api::storage::create_contract_package_at_hash(); + let entry_points = cep47::get_entrypoints(None); + cep47::deploy( + &contract::contract_api::runtime::get_named_arg::("token_name"), + &contract::contract_api::runtime::get_named_arg::("token_symbol"), + &contract::contract_api::runtime::get_named_arg::("token_uri"), + entry_points, + contract_package_hash, + ); +} diff --git a/example-token/src/main.rs b/example-token/src/main.rs deleted file mode 100644 index 3617173..0000000 --- a/example-token/src/main.rs +++ /dev/null @@ -1,46 +0,0 @@ -#![no_main] -extern crate cep47; -use cep47::{endpoint, logic::CEP47Contract, ret, CasperCEP47Contract}; -use types::{CLType, EntryPoints}; - -#[no_mangle] -pub extern "C" fn new_name() { - let contract = CasperCEP47Contract::new(); - ret(String::from("[CEP47] ").push_str(contract.name().as_str())) -} - -#[no_mangle] -pub extern "C" fn change_name() { - // let contract = CasperCEP47Contract::new(); -} - -/** -It should present how to: - -- override one of the CEP47 endpoints. Override the name endpoint to always return a name in the format: -[CEP47] -- add a new endpoint. Add change_name that allows to change a name. -- show how to tests only the name and and change_name. If the name is changed to example-nft then name endpoint should return [CEP47] example-nft. This test should be implemented as a WASM file. - */ - -#[no_mangle] -pub extern "C" fn call() { - let (contract_package_hash, _) = - contract::contract_api::storage::create_contract_package_at_hash(); - let entry_points = cep47::get_entrypoints(None); - let mut new_entry_points = EntryPoints::new(); - for ep in entry_points.take_entry_points().iter() { - if ep.name().eq("name") { - new_entry_points.add_entry_point(endpoint("new_name", vec![], CLType::String, None)); - } else { - new_entry_points.add_entry_point(ep.to_owned()); - } - } - cep47::deploy( - &contract::contract_api::runtime::get_named_arg::("token_name"), - &contract::contract_api::runtime::get_named_arg::("token_symbol"), - &contract::contract_api::runtime::get_named_arg::("token_uri"), - new_entry_points, - contract_package_hash, - ); -} diff --git a/marketplace/src/lib.rs b/marketplace/src/lib.rs index 0b50466..35f1857 100644 --- a/marketplace/src/lib.rs +++ b/marketplace/src/lib.rs @@ -12,7 +12,7 @@ use alloc::{ }; use contract::contract_api::runtime::revert; use contract::{ - contract_api::{runtime, storage, system, account}, + contract_api::{account, runtime, storage, system}, unwrap_or_revert::UnwrapOrRevert, }; use core::convert::TryInto; @@ -41,10 +41,13 @@ pub extern "C" fn put_on_sale_test() { #[no_mangle] pub extern "C" fn test_buy() { - let offer_key: String = "018a88e3dd7409f195fd52db2d3cba5d72ca6709bf1d94121bf3748801b40f6f5c_test_order".to_string(); + let offer_key: String = + "018a88e3dd7409f195fd52db2d3cba5d72ca6709bf1d94121bf3748801b40f6f5c_test_order".to_string(); let purse: URef = runtime::get_named_arg("purse"); let offer: Offer = Offer::load(&offer_key); - if system::get_purse_balance(purse).unwrap_or_revert() == offer.price && runtime::get_caller()!=offer.seller.to_account_hash(){ + if system::get_purse_balance(purse).unwrap_or_revert() == offer.price + && runtime::get_caller() != offer.seller.to_account_hash() + { system::transfer_from_purse_to_account( purse, offer.seller.to_account_hash(), @@ -56,7 +59,6 @@ pub extern "C" fn test_buy() { } } - #[no_mangle] pub extern "C" fn put_on_sale() { let offer = Offer::new( @@ -73,7 +75,7 @@ pub extern "C" fn buy() { let offer_key: String = runtime::get_named_arg("offer_key"); let payment: U512 = runtime::get_named_arg("payment"); let offer: Offer = Offer::load(&offer_key); - if payment == offer.price && runtime::get_caller()!=offer.seller.to_account_hash(){ + if payment == offer.price && runtime::get_caller() != offer.seller.to_account_hash() { system::transfer_to_account(offer.seller.to_account_hash(), payment, None) .unwrap_or_revert(); remove_key(&offer_key); @@ -92,7 +94,7 @@ pub extern "C" fn get_price() { pub extern "C" fn cancel() { let offer_key: String = runtime::get_named_arg("offer_key"); let offer: Offer = Offer::load(&offer_key); - if runtime::get_caller()==offer.seller.to_account_hash(){ + if runtime::get_caller() == offer.seller.to_account_hash() { remove_key(&offer_key); } } @@ -126,9 +128,7 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints )); entry_points.add_entry_point(endpoint( "put_on_sale_test", - vec![ - Parameter::new("seller", CLType::PublicKey), - ], + vec![Parameter::new("seller", CLType::PublicKey)], CLType::String, None, )); @@ -143,29 +143,23 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints )); entry_points.add_entry_point(endpoint( "test_buy", - vec![ - Parameter::new("payment", CLType::U512), - ], + vec![Parameter::new("payment", CLType::U512)], CLType::URef, None, )); entry_points.add_entry_point(endpoint( "cancel", - vec![ - Parameter::new("offer_key", CLType::String), - ], + vec![Parameter::new("offer_key", CLType::String)], CLType::Unit, None, )); entry_points.add_entry_point(endpoint( "get_price", - vec![ - Parameter::new("offer_key", CLType::String), - ], + vec![Parameter::new("offer_key", CLType::String)], CLType::U512, None, )); - + entry_points } diff --git a/tests/src/cep47.rs b/tests/src/cep47.rs index f733e93..81ed355 100644 --- a/tests/src/cep47.rs +++ b/tests/src/cep47.rs @@ -1,7 +1,7 @@ use casper_engine_test_support::{Code, Hash, SessionBuilder, TestContext, TestContextBuilder}; use casper_types::{ - account::AccountHash, bytesrepr::FromBytes, runtime_args, AsymmetricType, SecretKey, CLTyped, PublicKey, - RuntimeArgs, URef, U256, U512, + account::AccountHash, bytesrepr::FromBytes, runtime_args, AsymmetricType, CLTyped, PublicKey, + RuntimeArgs, SecretKey, URef, U256, U512, }; pub mod token_cfg { @@ -18,7 +18,7 @@ pub struct CasperCEP47Contract { pub caspercep47_hash: Hash, pub admin: PublicKey, pub ali: PublicKey, - pub bob: PublicKey, + pub bob: PublicKey, } pub type TokenId = String; @@ -34,7 +34,7 @@ impl CasperCEP47Contract { .with_public_key(ali.clone(), U512::from(500_000_000_000_000_000u64)) .with_public_key(bob.clone(), U512::from(500_000_000_000_000_000u64)) .build(); - let session_code = Code::from("example-token.wasm"); + let session_code = Code::from("dragons-nft.wasm"); let session_args = runtime_args! { "token_name" => token_cfg::NAME, "token_symbol" => token_cfg::SYMBOL, @@ -59,7 +59,7 @@ impl CasperCEP47Contract { caspercep47_hash, admin: admin, ali: ali, - bob: bob + bob: bob, } } @@ -192,26 +192,6 @@ impl CasperCEP47Contract { }, ); } - - pub fn attach(&mut self, token_uref: URef, recipient: PublicKey) { - self.call( - "attach", - runtime_args! { - "token_uref" => token_uref, - "recipient" => recipient - }, - ); - } - - pub fn detach(&mut self, owner: PublicKey, token_id: String) { - self.call( - "detach", - runtime_args! { - "owner" => owner, - "token_id" => token_id - }, - ); - } } fn balance_key(account: &AccountHash) -> String { diff --git a/tests/src/tests.rs b/tests/src/contract_tests.rs similarity index 85% rename from tests/src/tests.rs rename to tests/src/contract_tests.rs index 78c3f6f..73cdd93 100644 --- a/tests/src/tests.rs +++ b/tests/src/contract_tests.rs @@ -1,5 +1,4 @@ use crate::cep47::{token_cfg, CasperCEP47Contract, TokenId, URI}; -use crate::market::MarketTest; use casper_types::{AsymmetricType, PublicKey, SecretKey, U256}; #[test] @@ -138,26 +137,3 @@ fn test_transfer_all_tokens() { assert_eq!(contract.owner_of(&ali_tokens[0]), Some(bob.clone())); assert_eq!(contract.owner_of(&ali_tokens[1]), Some(bob)); } - -#[test] -fn test_attach_and_detach() { - let mut contract = CasperCEP47Contract::deploy(); - let ali: PublicKey = SecretKey::ed25519_from_bytes([3u8; 32]).unwrap().into(); - // let bob: PublicKey = SecretKey::ed25519_from_bytes([5u8; 32]).unwrap().into(); - let token_uri = URI::from("0x12af"); - contract.mint_one(ali.clone(), token_uri); - let ali_token_id: TokenId = contract.tokens(ali.clone())[0].clone(); - contract.detach(ali.clone(), ali_token_id.clone()); -} - -#[test] -fn test_marketplace() { - let mut contract = CasperCEP47Contract::deploy(); - let token_uris: Vec = vec![ - URI::from("Casper Golden Card"), - URI::from("Casper Silver Card"), - ]; - let market = MarketTest::deploy(&mut contract.context, contract.admin.to_account_hash()); - market.call_test(&mut contract.context, &contract.ali, &contract.admin); - contract.mint_many(contract.ali.clone(), token_uris); -} diff --git a/tests/src/lib.rs b/tests/src/lib.rs index c774aca..6bfe26c 100644 --- a/tests/src/lib.rs +++ b/tests/src/lib.rs @@ -2,4 +2,4 @@ pub mod cep47; pub mod market; #[cfg(test)] -pub mod tests; +pub mod contract_tests; diff --git a/tests/src/market.rs b/tests/src/market.rs index 20b9719..a92624f 100644 --- a/tests/src/market.rs +++ b/tests/src/market.rs @@ -15,16 +15,11 @@ impl MarketTest { .build(); context.run(session); let market_hash = context - .query( - deployer, - &["marketplace_contract_package_hash".to_string()], - ) + .query(deployer, &["marketplace_contract_package_hash".to_string()]) .unwrap() .into_t() .unwrap(); - Self { - market_hash, - } + Self { market_hash } } fn call( From 81001cc1bd15fa30b5653ff1d7fa8a4e588f8c9e Mon Sep 17 00:00:00 2001 From: Maciej Zielinski Date: Tue, 8 Jun 2021 16:27:28 +0200 Subject: [PATCH 30/98] no attach, detach --- cep47/src/test_attach_detach.rs | 7 ------- dragons-nft/src/main.rs | 8 +++++++- 2 files changed, 7 insertions(+), 8 deletions(-) delete mode 100644 cep47/src/test_attach_detach.rs diff --git a/cep47/src/test_attach_detach.rs b/cep47/src/test_attach_detach.rs deleted file mode 100644 index 8e18cc9..0000000 --- a/cep47/src/test_attach_detach.rs +++ /dev/null @@ -1,7 +0,0 @@ -fn call() { - // mint tokens. - // detach tokens. - // assert balances. - // attach token to another account. - // assert balances. -} \ No newline at end of file diff --git a/dragons-nft/src/main.rs b/dragons-nft/src/main.rs index 0f6ad43..c421622 100644 --- a/dragons-nft/src/main.rs +++ b/dragons-nft/src/main.rs @@ -1,5 +1,11 @@ #![no_main] -extern crate cep47; +// extern crate cep47; +// use cep47::endpoints::aa as other_aa; + +// #[no_mangle] +// pub fn aa() { + +// } #[no_mangle] pub extern "C" fn call() { From 03288c11072e8d5c96604a08d9f175b37ef4ad9c Mon Sep 17 00:00:00 2001 From: Maciej Zielinski Date: Tue, 15 Jun 2021 16:52:53 +0200 Subject: [PATCH 31/98] Allow disable endpoints --- cep47/Cargo.toml | 16 ++++++++++++++++ cep47/src/lib.rs | 16 ++++++++++++++++ dragons-nft/Cargo.toml | 2 +- dragons-nft/src/main.rs | 8 +++----- 4 files changed, 36 insertions(+), 6 deletions(-) diff --git a/cep47/Cargo.toml b/cep47/Cargo.toml index f578f6f..a657624 100644 --- a/cep47/Cargo.toml +++ b/cep47/Cargo.toml @@ -14,3 +14,19 @@ name = "cep47" [features] default = ["casper-contract/std", "casper-types/std"] +no_name = [] +no_symbol = [] +no_uri = [] +no_balance_of = [] +no_owner_of = [] +no_total_supply = [] +no_token_uri = [] +no_tokens = [] +no_mint_one = [] +no_mint_many = [] +no_mint_copies = [] +no_transfer_token = [] +no_transfer_many_tokens = [] +no_transfer_all_tokens = [] +no_attach = [] +no_detach = [] \ No newline at end of file diff --git a/cep47/src/lib.rs b/cep47/src/lib.rs index 85a8a19..719163b 100644 --- a/cep47/src/lib.rs +++ b/cep47/src/lib.rs @@ -181,24 +181,28 @@ impl WithStorage for CasperCEP47Contract { } impl CEP47Contract for CasperCEP47Contract {} +#[cfg(not(feature = "no_name"))] #[no_mangle] pub extern "C" fn name() { let contract = CasperCEP47Contract::new(); ret(contract.name()) } +#[cfg(not(feature = "no_symbol"))] #[no_mangle] pub extern "C" fn symbol() { let contract = CasperCEP47Contract::new(); ret(contract.symbol()) } +#[cfg(not(feature = "no_uri"))] #[no_mangle] pub extern "C" fn uri() { let contract = CasperCEP47Contract::new(); ret(contract.uri()) } +#[cfg(not(feature = "no_balance_of"))] #[no_mangle] pub extern "C" fn balance_of() { let account: PublicKey = runtime::get_named_arg("account"); @@ -206,6 +210,7 @@ pub extern "C" fn balance_of() { ret(contract.balance_of(account)) } +#[cfg(not(feature = "no_owner_of"))] #[no_mangle] pub extern "C" fn owner_of() { let token_id: TokenId = runtime::get_named_arg("token_id"); @@ -213,12 +218,14 @@ pub extern "C" fn owner_of() { ret(contract.owner_of(token_id)) } +#[cfg(not(feature = "no_total_supply"))] #[no_mangle] pub extern "C" fn total_supply() { let contract = CasperCEP47Contract::new(); ret(contract.total_supply()) } +#[cfg(not(feature = "no_token_uri"))] #[no_mangle] pub extern "C" fn token_uri() { let token_id: TokenId = runtime::get_named_arg("token_id"); @@ -226,6 +233,7 @@ pub extern "C" fn token_uri() { ret(contract.token_uri(token_id)) } +#[cfg(not(feature = "no_tokens"))] #[no_mangle] pub extern "C" fn tokens() { let owner: PublicKey = runtime::get_named_arg("owner"); @@ -233,6 +241,7 @@ pub extern "C" fn tokens() { ret(contract.tokens(owner)) } +#[cfg(not(feature = "no_mint_one"))] #[no_mangle] pub extern "C" fn mint_one() { let recipient: PublicKey = runtime::get_named_arg("recipient"); @@ -241,6 +250,7 @@ pub extern "C" fn mint_one() { contract.mint_one(recipient, token_uri); } +#[cfg(not(feature = "no_mint_many"))] #[no_mangle] pub extern "C" fn mint_many() { let recipient: PublicKey = runtime::get_named_arg("recipient"); @@ -249,6 +259,7 @@ pub extern "C" fn mint_many() { contract.mint_many(recipient, token_uris); } +#[cfg(not(feature = "no_mint_copies"))] #[no_mangle] pub extern "C" fn mint_copies() { let recipient: PublicKey = runtime::get_named_arg("recipient"); @@ -258,6 +269,7 @@ pub extern "C" fn mint_copies() { contract.mint_copies(recipient, token_uri, count); } +#[cfg(not(feature = "no_transfer_token"))] #[no_mangle] pub extern "C" fn transfer_token() { let sender: PublicKey = runtime::get_named_arg("sender"); @@ -268,6 +280,7 @@ pub extern "C" fn transfer_token() { res.unwrap_or_revert(); } +#[cfg(not(feature = "no_transfer_many_tokens"))] #[no_mangle] pub extern "C" fn transfer_many_tokens() { let sender: PublicKey = runtime::get_named_arg("sender"); @@ -278,6 +291,7 @@ pub extern "C" fn transfer_many_tokens() { res.unwrap_or_revert(); } +#[cfg(not(feature = "no_transfer_all_tokens"))] #[no_mangle] pub extern "C" fn transfer_all_tokens() { let sender: PublicKey = runtime::get_named_arg("sender"); @@ -286,6 +300,7 @@ pub extern "C" fn transfer_all_tokens() { contract.transfer_all_tokens(sender, recipient); } +#[cfg(not(feature = "no_attach"))] #[no_mangle] pub extern "C" fn attach() { let token_uref: URef = runtime::get_named_arg("token_uref"); @@ -294,6 +309,7 @@ pub extern "C" fn attach() { contract.attach(token_uref, recipient); } +#[cfg(not(feature = "no_detach"))] #[no_mangle] pub extern "C" fn detach() { let owner: PublicKey = runtime::get_named_arg("owner"); diff --git a/dragons-nft/Cargo.toml b/dragons-nft/Cargo.toml index 9ea9ff1..9e0d58f 100644 --- a/dragons-nft/Cargo.toml +++ b/dragons-nft/Cargo.toml @@ -9,7 +9,7 @@ edition = "2018" [dependencies] contract = { package="casper-contract", version = "1.2.0" } types = { package="casper-types", version = "1.2.0" } -cep47 = { path="../cep47" } +cep47 = { path="../cep47", features = ["no_owner_of"]} [[bin]] name = "dragons-nft" diff --git a/dragons-nft/src/main.rs b/dragons-nft/src/main.rs index c421622..cda2485 100644 --- a/dragons-nft/src/main.rs +++ b/dragons-nft/src/main.rs @@ -1,11 +1,9 @@ #![no_main] -// extern crate cep47; -// use cep47::endpoints::aa as other_aa; -// #[no_mangle] -// pub fn aa() { +#[no_mangle] +pub extern "C" fn owner_of() { -// } +} #[no_mangle] pub extern "C" fn call() { From 5c6e9576c08ac4a600a2ea9a0edad717db27c34c Mon Sep 17 00:00:00 2001 From: astro019 Date: Wed, 16 Jun 2021 22:01:11 +1000 Subject: [PATCH 32/98] add github action --- .github/workflows/ci-casper-rust-contract.yml | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/workflows/ci-casper-rust-contract.yml diff --git a/.github/workflows/ci-casper-rust-contract.yml b/.github/workflows/ci-casper-rust-contract.yml new file mode 100644 index 0000000..0c9975d --- /dev/null +++ b/.github/workflows/ci-casper-rust-contract.yml @@ -0,0 +1,30 @@ +name: ci-casper-rust-contract + +on: + push: + branches: [ master ] + paths-ignore: + - '**.md' + + pull_request: + branches: [ master ] + paths-ignore: + - '**.md' + +jobs: + build: + + runs-on: ubuntu-18.04 + + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + components: rustfmt, clippy + # Needed for gcc install + - run: sudo apt update && sudo apt install -y build-essential + - run: make prepare + - run: make check-lint + # Tests will be added after NCTL interaction is possible. + # - run: make test \ No newline at end of file From 2341bcdcd085cb15fda02120a94ce1dd43e18f33 Mon Sep 17 00:00:00 2001 From: astro019 Date: Mon, 5 Jul 2021 21:59:45 +1000 Subject: [PATCH 33/98] added burn feature --- cep47/Cargo.toml | 2 + cep47/src/lib.rs | 81 ++++++++++++++++++++- cep47/src/logic.rs | 10 +++ cep47/src/logic_tests.rs | 128 ++++++++++++++++++++++++++++++++- marketplace/src/lib.rs | 2 +- marketplace/src/send_tokens.rs | 18 ++--- tests/src/cep47.rs | 22 +++++- tests/src/contract_tests.rs | 42 +++++++++++ tests/src/market.rs | 30 ++++---- 9 files changed, 307 insertions(+), 28 deletions(-) diff --git a/cep47/Cargo.toml b/cep47/Cargo.toml index a657624..eccddb1 100644 --- a/cep47/Cargo.toml +++ b/cep47/Cargo.toml @@ -25,6 +25,8 @@ no_tokens = [] no_mint_one = [] no_mint_many = [] no_mint_copies = [] +no_burn_many = [] +no_burn_one = [] no_transfer_token = [] no_transfer_many_tokens = [] no_transfer_all_tokens = [] diff --git a/cep47/src/lib.rs b/cep47/src/lib.rs index 719163b..679faf7 100644 --- a/cep47/src/lib.rs +++ b/cep47/src/lib.rs @@ -103,7 +103,7 @@ impl CEP47Storage for CasperCEP47Storage { let mut hasher = DefaultHasher::new(); for token_uri in token_uris.clone() { - let token_info = (total_supply, uri.clone(), token_uri.clone()); + let token_info = (uri.clone(), token_uri.clone()); Hash::hash(&token_info, &mut hasher); let token_id = TokenId::from(hasher.finish().to_string()); @@ -124,6 +124,41 @@ impl CEP47Storage for CasperCEP47Storage { let token_uris: Vec = vec![token_uri; count.as_usize()]; self.mint_many(recipient, token_uris); } + fn burn_many(&mut self, owner: PublicKey, token_ids: Vec) { + let mut owner_tokens = self.get_tokens(owner.clone()); + let mut owner_balance = self.balance_of(owner.clone()); + let mut total_supply = self.total_supply(); + + for token_id in token_ids.clone() { + let index = owner_tokens + .iter() + .position(|x| *x == token_id.clone()) + .unwrap_or_revert(); + owner_tokens.remove(index); + remove_key(&uri_key(&token_id)); + remove_key(&owner_key(&token_id)); + owner_balance = owner_balance - 1; + total_supply = total_supply - 1; + } + set_key(&balance_key(&owner.to_account_hash()), owner_balance); + set_key(&token_key(&owner.to_account_hash()), owner_tokens); + set_key("total_supply", total_supply); + } + fn burn_one(&mut self, owner: PublicKey, token_id: TokenId) { + let mut owner_tokens = self.get_tokens(owner.clone()); + let owner_balance = self.balance_of(owner.clone()); + let total_supply = self.total_supply(); + let index = owner_tokens + .iter() + .position(|x| *x == token_id.clone()) + .unwrap_or_revert(); + owner_tokens.remove(index); + remove_key(&uri_key(&token_id)); + remove_key(&owner_key(&token_id)); + set_key(&balance_key(&owner.to_account_hash()), owner_balance - 1); + set_key(&token_key(&owner.to_account_hash()), owner_tokens); + set_key("total_supply", total_supply - 1); + } fn new_uref(&mut self, token_id: TokenId) -> Option { let value_ref = storage::new_uref(token_id).with_access_rights(AccessRights::READ_ADD_WRITE); @@ -269,6 +304,24 @@ pub extern "C" fn mint_copies() { contract.mint_copies(recipient, token_uri, count); } +#[cfg(not(feature = "no_burn_many"))] +#[no_mangle] +pub extern "C" fn burn_many() { + let owner: PublicKey = runtime::get_named_arg("owner"); + let token_ids: Vec = runtime::get_named_arg("token_ids"); + let mut contract = CasperCEP47Contract::new(); + contract.burn_many(owner, token_ids); +} + +#[cfg(not(feature = "no_burn_one"))] +#[no_mangle] +pub extern "C" fn burn_one() { + let owner: PublicKey = runtime::get_named_arg("owner"); + let token_id: TokenId = runtime::get_named_arg("token_id"); + let mut contract = CasperCEP47Contract::new(); + contract.burn_one(owner, token_id); +} + #[cfg(not(feature = "no_transfer_token"))] #[no_mangle] pub extern "C" fn transfer_token() { @@ -395,6 +448,32 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints None }, )); + entry_points.add_entry_point(endpoint( + "burn_many", + vec![ + Parameter::new("owner", CLType::PublicKey), + Parameter::new("token_ids", CLType::List(Box::new(CLType::String))), + ], + CLType::Unit, + if secure { + Some("deployer_access") + } else { + None + }, + )); + entry_points.add_entry_point(endpoint( + "burn_one", + vec![ + Parameter::new("owner", CLType::PublicKey), + Parameter::new("token_id", CLType::List(Box::new(CLType::String))), + ], + CLType::Unit, + if secure { + Some("deployer_access") + } else { + None + }, + )); entry_points.add_entry_point(endpoint( "mint_copies", vec![ diff --git a/cep47/src/logic.rs b/cep47/src/logic.rs index 459e077..e4b1300 100644 --- a/cep47/src/logic.rs +++ b/cep47/src/logic.rs @@ -71,6 +71,14 @@ pub trait CEP47Contract: WithStorage { self.storage_mut().mint_copies(recipient, token_uri, count); } + fn burn_one(&mut self, owner: PublicKey, token_id: TokenId) { + self.storage_mut().burn_one(owner, token_id); + } + + fn burn_many(&mut self, owner: PublicKey, token_ids: Vec) { + self.storage_mut().burn_many(owner, token_ids); + } + // Transfer functions. fn transfer_token( &mut self, @@ -165,6 +173,8 @@ pub trait CEP47Storage { fn set_tokens(&mut self, owner: PublicKey, token_ids: Vec); fn mint_many(&mut self, recipient: PublicKey, token_uris: Vec); fn mint_copies(&mut self, recipient: PublicKey, token_uri: URI, count: U256); + fn burn_one(&mut self, owner: PublicKey, token_id: TokenId); + fn burn_many(&mut self, owner: PublicKey, token_ids: Vec); fn new_uref(&mut self, token_id: TokenId) -> Option; fn del_uref(&mut self, token_uref: URef) -> Option; diff --git a/cep47/src/logic_tests.rs b/cep47/src/logic_tests.rs index 3b8e680..a5d5f6e 100644 --- a/cep47/src/logic_tests.rs +++ b/cep47/src/logic_tests.rs @@ -126,7 +126,7 @@ mod tests { let mut hasher = DefaultHasher::new(); for token_uri in token_uris.clone() { - let token_info = (self.total_supply, self.uri.clone(), token_uri.clone()); + let token_info = (self.uri.clone(), token_uri.clone()); Hash::hash(&token_info, &mut hasher); let token_id: TokenId = TokenId::from(hasher.finish().to_string()); self.token_uris.insert(token_id.clone(), token_uri); @@ -145,6 +145,60 @@ mod tests { self.mint_many(recipient, token_uris); } + fn burn_many(&mut self, owner: PublicKey, token_ids: Vec) { + let owner_tokens = self.tokens.get(&owner); + let owner_balance = self.balances.get(&owner); + let mut owner_new_balance = if owner_balance.is_none() { + U256::from(0) + } else { + owner_balance.unwrap().clone() + }; + let mut owner_new_tokens = if owner_tokens.is_none() { + Vec::::new() + } else { + owner_tokens.unwrap().clone() + }; + + for token_id in token_ids.clone() { + let index = owner_new_tokens + .iter() + .position(|x| *x == token_id.clone()) + .unwrap(); + owner_new_tokens.remove(index); + self.token_uris.remove(&token_id.clone()); + self.belongs_to.remove(&token_id.clone()); + owner_new_balance = owner_new_balance - 1; + self.total_supply = self.total_supply - 1; + } + self.balances.insert(owner.clone(), owner_new_balance); + self.tokens.insert(owner, owner_new_tokens); + } + + fn burn_one(&mut self, owner: PublicKey, token_id: TokenId) { + let owner_tokens = self.tokens.get(&owner); + let owner_balance = self.balances.get(&owner); + let owner_new_balance = if owner_balance.is_none() { + U256::from(0) + } else { + owner_balance.unwrap().clone() + }; + let mut owner_new_tokens = if owner_tokens.is_none() { + Vec::::new() + } else { + owner_tokens.unwrap().clone() + }; + let index = owner_new_tokens + .iter() + .position(|x| *x == token_id.clone()) + .unwrap(); + owner_new_tokens.remove(index); + self.token_uris.remove(&token_id.clone()); + self.belongs_to.remove(&token_id.clone()); + self.total_supply = self.total_supply - 1; + self.balances.insert(owner.clone(), owner_new_balance - 1); + self.tokens.insert(owner, owner_new_tokens); + } + fn new_uref(&mut self, token_id: TokenId) -> Option { let mut rng = rand::thread_rng(); let val: [u8; 32] = rng.gen(); @@ -264,6 +318,78 @@ mod tests { assert_eq!(ali_third_token_uri, URI::from("Casper Fan URI")); } #[test] + fn test_burn_many() { + let mut contract = TestContract::new(); + let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + + assert_eq!(contract.total_supply(), U256::from(0)); + contract.mint_many( + ali.clone(), + vec![ + URI::from("Banana URI"), + URI::from("Orange URI"), + URI::from("Apple URI"), + URI::from("Grape URI"), + ], + ); + assert_eq!(contract.total_supply(), U256::from(4)); + + let mut ali_balance = contract.balance_of(ali.clone()); + assert_eq!(ali_balance, U256::from(4)); + + let mut ali_tokens: Vec = contract.tokens(ali.clone()); + contract.burn_many( + ali.clone(), + vec![ + ali_tokens.get(0).unwrap().clone(), + ali_tokens.get(3).unwrap().clone(), + ], + ); + let mut ali_first_token_uri = contract.token_uri(ali_tokens.first().unwrap().clone()); + assert_eq!(ali_first_token_uri, None); + let mut ali_last_token_uri = contract.token_uri(ali_tokens.last().unwrap().clone()); + assert_eq!(ali_first_token_uri, None); + assert_eq!(ali_last_token_uri, None); + + ali_tokens = contract.tokens(ali.clone()); + ali_first_token_uri = contract.token_uri(ali_tokens.first().unwrap().clone()); + ali_last_token_uri = contract.token_uri(ali_tokens.last().unwrap().clone()); + assert_eq!(ali_first_token_uri, Some(URI::from("Orange URI"))); + assert_eq!(ali_last_token_uri, Some(URI::from("Apple URI"))); + + assert_eq!(contract.total_supply(), U256::from(2)); + ali_balance = contract.balance_of(ali); + assert_eq!(ali_balance, U256::from(2)); + } + #[test] + fn test_burn_one() { + let mut contract = TestContract::new(); + let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + + assert_eq!(contract.total_supply(), U256::from(0)); + contract.mint_many( + ali.clone(), + vec![URI::from("Banana URI"), URI::from("Orange URI")], + ); + assert_eq!(contract.total_supply(), U256::from(2)); + + let mut ali_balance = contract.balance_of(ali.clone()); + assert_eq!(ali_balance, U256::from(2)); + + let mut ali_tokens: Vec = contract.tokens(ali.clone()); + contract.burn_one(ali.clone(), ali_tokens.get(0).unwrap().clone()); + let mut ali_first_token_uri = contract.token_uri(ali_tokens.get(0).unwrap().clone()); + assert_eq!(ali_first_token_uri, None); + + ali_tokens = contract.tokens(ali.clone()); + ali_first_token_uri = contract.token_uri(ali_tokens.get(0).unwrap().clone()); + assert_eq!(ali_first_token_uri, Some(URI::from("Orange URI"))); + + assert_eq!(contract.total_supply(), U256::from(1)); + ali_balance = contract.balance_of(ali); + assert_eq!(ali_balance, U256::from(1)); + } + #[test] fn test_transfer_token() { let mut contract = TestContract::new(); let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); diff --git a/marketplace/src/lib.rs b/marketplace/src/lib.rs index 35f1857..2629b6e 100644 --- a/marketplace/src/lib.rs +++ b/marketplace/src/lib.rs @@ -164,7 +164,7 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints } pub fn deploy(entry_points: EntryPoints, contract_package_hash: ContractPackageHash) { - let mut named_keys = NamedKeys::new(); + let named_keys = NamedKeys::new(); // named_keys.insert("name".to_string(), storage::new_uref(token_name).into()); let (contract_hash, _) = diff --git a/marketplace/src/send_tokens.rs b/marketplace/src/send_tokens.rs index afa926c..b1ec9c6 100644 --- a/marketplace/src/send_tokens.rs +++ b/marketplace/src/send_tokens.rs @@ -1,11 +1,11 @@ #![no_main] use contract::contract_api::{account, runtime, system}; -use types::{runtime_args, ContractHash, PublicKey, RuntimeArgs, U512}; +use types::{runtime_args, ContractHash, RuntimeArgs, U512}; #[no_mangle] pub extern "C" fn call() { - let seller: PublicKey = runtime::get_named_arg("seller"); + // let seller: PublicKey = runtime::get_named_arg("seller"); let marketplace_contract: ContractHash = runtime::get_named_arg("marketplace_contract"); let transport_purse = system::create_purse(); @@ -17,13 +17,13 @@ pub extern "C" fn call() { ) .unwrap(); - let offer_key: String = runtime::call_contract( - marketplace_contract, - "put_on_sale_test", - runtime_args! { - "seller" => seller, - }, - ); + // let offer_key: String = runtime::call_contract( + // marketplace_contract, + // "put_on_sale_test", + // runtime_args! { + // "seller" => seller, + // }, + // ); let _: () = runtime::call_contract( marketplace_contract, "test_buy", diff --git a/tests/src/cep47.rs b/tests/src/cep47.rs index 81ed355..6efe0ce 100644 --- a/tests/src/cep47.rs +++ b/tests/src/cep47.rs @@ -1,6 +1,6 @@ use casper_engine_test_support::{Code, Hash, SessionBuilder, TestContext, TestContextBuilder}; use casper_types::{ - account::AccountHash, bytesrepr::FromBytes, runtime_args, AsymmetricType, CLTyped, PublicKey, + account::AccountHash, bytesrepr::FromBytes, runtime_args, CLTyped, PublicKey, RuntimeArgs, SecretKey, URef, U256, U512, }; @@ -156,6 +156,26 @@ impl CasperCEP47Contract { ); } + pub fn burn_many(&mut self, owner: PublicKey, token_ids: Vec) { + self.call( + "burn_many", + runtime_args! { + "owner" => owner, + "token_ids" => token_ids + }, + ); + } + + pub fn burn_one(&mut self, owner: PublicKey, token_id: TokenId) { + self.call( + "burn_one", + runtime_args! { + "owner" => owner, + "token_id" => token_id + }, + ); + } + pub fn transfer_token(&mut self, sender: PublicKey, recipient: PublicKey, token_id: TokenId) { self.call( "transfer_token", diff --git a/tests/src/contract_tests.rs b/tests/src/contract_tests.rs index 73cdd93..8175b5d 100644 --- a/tests/src/contract_tests.rs +++ b/tests/src/contract_tests.rs @@ -72,6 +72,48 @@ fn test_mint_many() { assert_eq!(contract.owner_of(&ali_tokens[1]), Some(ali)); } +#[test] +fn test_burn_many() { + let mut contract = CasperCEP47Contract::deploy(); + let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + let token_uris: Vec = vec![URI::from("Casper Golden Card"), URI::from("Casper Siver Card"), URI::from("Casper Bronze Card"), URI::from("Mona Lisa")]; + contract.mint_many(ali.clone(), token_uris); + + let mut ali_tokens: Vec = contract.tokens(ali.clone()); + + assert_eq!(contract.total_supply(), U256::from(4)); + assert_eq!(contract.balance_of(ali.clone()), U256::from(4)); + assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(4)); + + contract.burn_many(ali.clone(), vec![ali_tokens.first().unwrap().clone(), ali_tokens.last().unwrap().clone()]); + assert_eq!(contract.total_supply(), U256::from(2)); + assert_eq!(contract.balance_of(ali.clone()), U256::from(2)); + + ali_tokens = contract.tokens(ali.clone()); + assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(2)); +} + +#[test] +fn test_burn_one() { + let mut contract = CasperCEP47Contract::deploy(); + let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + let token_uris: Vec = vec![URI::from("Casper Golden Card"), URI::from("Mona Lisa")]; + contract.mint_many(ali.clone(), token_uris); + + let mut ali_tokens: Vec = contract.tokens(ali.clone()); + + assert_eq!(contract.total_supply(), U256::from(2)); + assert_eq!(contract.balance_of(ali.clone()), U256::from(2)); + assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(2)); + + contract.burn_one(ali.clone(), ali_tokens.first().unwrap().clone()); + assert_eq!(contract.total_supply(), U256::from(1)); + assert_eq!(contract.balance_of(ali.clone()), U256::from(1)); + + ali_tokens = contract.tokens(ali.clone()); + assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(1)); +} + #[test] fn test_transfer_token() { let mut contract = CasperCEP47Contract::deploy(); diff --git a/tests/src/market.rs b/tests/src/market.rs index a92624f..fb8d420 100644 --- a/tests/src/market.rs +++ b/tests/src/market.rs @@ -1,5 +1,5 @@ use casper_engine_test_support::{Code, Hash, SessionBuilder, TestContext}; -use casper_types::{account::AccountHash, runtime_args, AsymmetricType, PublicKey, RuntimeArgs}; +use casper_types::{account::AccountHash, runtime_args, PublicKey, RuntimeArgs}; pub struct MarketTest { pub market_hash: Hash, @@ -22,20 +22,20 @@ impl MarketTest { Self { market_hash } } - fn call( - &self, - context: &mut TestContext, - account: &AccountHash, - method: &str, - args: RuntimeArgs, - ) { - let code = Code::Hash(self.market_hash, method.to_string()); - let session = SessionBuilder::new(code, args) - .with_address(*account) - .with_authorization_keys(&[*account]) - .build(); - context.run(session); - } + // fn call( + // &self, + // context: &mut TestContext, + // account: &AccountHash, + // method: &str, + // args: RuntimeArgs, + // ) { + // let code = Code::Hash(self.market_hash, method.to_string()); + // let session = SessionBuilder::new(code, args) + // .with_address(*account) + // .with_authorization_keys(&[*account]) + // .build(); + // context.run(session); + // } pub fn call_test(&self, context: &mut TestContext, account: &PublicKey, seller: &PublicKey) { let session_code = Code::from("send_tokens.wasm"); From 02484ba80a61507b5d37c84df29f2ef2e3de25a2 Mon Sep 17 00:00:00 2001 From: astro019 Date: Mon, 5 Jul 2021 22:31:43 +1000 Subject: [PATCH 34/98] update transfer functions based on paused status --- cep47/Cargo.toml | 3 +++ cep47/src/lib.rs | 55 +++++++++++++++++++++++++++++++++++++++- cep47/src/logic.rs | 36 +++++++++++++++++++++++++- cep47/src/logic_tests.rs | 17 ++++++++++++- 4 files changed, 108 insertions(+), 3 deletions(-) diff --git a/cep47/Cargo.toml b/cep47/Cargo.toml index eccddb1..f19fe36 100644 --- a/cep47/Cargo.toml +++ b/cep47/Cargo.toml @@ -22,6 +22,9 @@ no_owner_of = [] no_total_supply = [] no_token_uri = [] no_tokens = [] +no_is_paused = [] +no_pause = [] +no_unpause = [] no_mint_one = [] no_mint_many = [] no_mint_copies = [] diff --git a/cep47/src/lib.rs b/cep47/src/lib.rs index 679faf7..05b31b9 100644 --- a/cep47/src/lib.rs +++ b/cep47/src/lib.rs @@ -66,6 +66,15 @@ impl CEP47Storage for CasperCEP47Storage { fn token_uri(&self, token_id: TokenId) -> Option { get_key::(&uri_key(&token_id)) } + fn is_paused(&self) -> bool { + get_key::("paused").unwrap() + } + fn pause(&mut self) { + set_key("paused", true); + } + fn unpause(&mut self) { + set_key("paused", false); + } // Setters fn get_tokens(&self, owner: PublicKey) -> Vec { @@ -276,6 +285,27 @@ pub extern "C" fn tokens() { ret(contract.tokens(owner)) } +#[cfg(not(feature = "no_is_paused"))] +#[no_mangle] +pub extern "C" fn is_paused() { + let contract = CasperCEP47Contract::new(); + ret(contract.is_paused()) +} + +#[cfg(not(feature = "no_pause"))] +#[no_mangle] +pub extern "C" fn pause() { + let mut contract = CasperCEP47Contract::new(); + contract.pause(); +} + +#[cfg(not(feature = "no_unpause"))] +#[no_mangle] +pub extern "C" fn unpause() { + let mut contract = CasperCEP47Contract::new(); + contract.unpause(); +} + #[cfg(not(feature = "no_mint_one"))] #[no_mangle] pub extern "C" fn mint_one() { @@ -350,7 +380,8 @@ pub extern "C" fn transfer_all_tokens() { let sender: PublicKey = runtime::get_named_arg("sender"); let recipient: PublicKey = runtime::get_named_arg("recipient"); let mut contract = CasperCEP47Contract::new(); - contract.transfer_all_tokens(sender, recipient); + let res = contract.transfer_all_tokens(sender, recipient); + res.unwrap_or_revert(); } #[cfg(not(feature = "no_attach"))] @@ -392,6 +423,27 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints entry_points.add_entry_point(endpoint("symbol", vec![], CLType::String, None)); entry_points.add_entry_point(endpoint("uri", vec![], CLType::String, None)); entry_points.add_entry_point(endpoint("total_supply", vec![], CLType::U256, None)); + entry_points.add_entry_point(endpoint("is_paused", vec![], CLType::Bool, None)); + entry_points.add_entry_point(endpoint( + "pause", + vec![], + CLType::Unit, + if secure { + Some("deployer_access") + } else { + None + }, + )); + entry_points.add_entry_point(endpoint( + "unpause", + vec![], + CLType::Unit, + if secure { + Some("deployer_access") + } else { + None + }, + )); entry_points.add_entry_point(endpoint( "balance_of", vec![Parameter::new("account", CLType::PublicKey)], @@ -553,6 +605,7 @@ pub fn deploy( "total_supply".to_string(), storage::new_uref(U256::zero()).into(), ); + named_keys.insert("paused".to_string(), storage::new_uref(false).into()); let (contract_hash, _) = storage::add_contract_version(contract_package_hash, entry_points, named_keys); diff --git a/cep47/src/logic.rs b/cep47/src/logic.rs index e4b1300..ce04ab0 100644 --- a/cep47/src/logic.rs +++ b/cep47/src/logic.rs @@ -56,6 +56,18 @@ pub trait CEP47Contract: WithStorage { self.storage().get_tokens(owner) } + fn is_paused(&self) -> bool { + self.storage().is_paused() + } + + fn pause(&mut self) { + self.storage_mut().pause(); + } + + fn unpause(&mut self) { + self.storage_mut().unpause(); + } + // Minter function. // Guarded by the entrypoint group. fn mint_one(&mut self, recipient: PublicKey, token_uri: URI) { @@ -86,6 +98,10 @@ pub trait CEP47Contract: WithStorage { recipient: PublicKey, token_id: TokenId, ) -> Result<(), Error> { + let paused = self.storage().is_paused(); + if paused { + return Err(Error::PermissionDenied); + } // 1. Load tokens owned by the sender. let mut sender_tokens = self.storage().get_tokens(sender.clone()); // 2. Assert that token_id is in sender_tokens. @@ -109,6 +125,10 @@ pub trait CEP47Contract: WithStorage { recipient: PublicKey, token_ids: Vec, ) -> Result<(), Error> { + let paused = self.storage().is_paused(); + if paused { + return Err(Error::PermissionDenied); + } let mut sender_tokens = self.storage().get_tokens(sender.clone()); for token_id in token_ids.iter() { if !sender_tokens.contains(token_id) { @@ -123,13 +143,22 @@ pub trait CEP47Contract: WithStorage { Ok(()) } - fn transfer_all_tokens(&mut self, sender: PublicKey, recipient: PublicKey) { + fn transfer_all_tokens( + &mut self, + sender: PublicKey, + recipient: PublicKey, + ) -> Result<(), Error> { + let paused = self.storage().is_paused(); + if paused { + return Err(Error::PermissionDenied); + } let mut sender_tokens = self.storage().get_tokens(sender.clone()); let mut recipient_tokens = self.storage().get_tokens(recipient.clone()); recipient_tokens.append(&mut sender_tokens); self.storage_mut().set_tokens(sender, sender_tokens); self.storage_mut().set_tokens(recipient, recipient_tokens); + Ok(()) } // URef releated function. @@ -168,6 +197,11 @@ pub trait CEP47Storage { fn total_supply(&self) -> U256; fn token_uri(&self, token_id: TokenId) -> Option; + // Controls + fn is_paused(&self) -> bool; + fn pause(&mut self); + fn unpause(&mut self); + // Setters fn get_tokens(&self, owner: PublicKey) -> Vec; fn set_tokens(&mut self, owner: PublicKey, token_ids: Vec); diff --git a/cep47/src/logic_tests.rs b/cep47/src/logic_tests.rs index a5d5f6e..0729cbe 100644 --- a/cep47/src/logic_tests.rs +++ b/cep47/src/logic_tests.rs @@ -17,6 +17,7 @@ mod tests { name: String, symbol: String, uri: URI, + paused: bool, total_supply: U256, tokens: BTreeMap>, token_uris: BTreeMap, @@ -31,6 +32,7 @@ mod tests { name: String::from("Casper Enhancement Proposal 47"), symbol: String::from("CEP47"), uri: URI::from("https://github.com/casper-ecosystem/casper-nft-cep47"), + paused: false, total_supply: U256::from(0), tokens: BTreeMap::new(), balances: BTreeMap::new(), @@ -85,6 +87,18 @@ mod tests { } } + fn is_paused(&self) -> bool { + self.paused + } + + fn pause(&mut self) { + self.paused = true; + } + + fn unpause(&mut self) { + self.paused = false; + } + fn get_tokens(&self, owner: PublicKey) -> Vec { let owner_tokens = self.tokens.get(&owner); if owner_tokens.is_none() { @@ -444,7 +458,8 @@ mod tests { let ali_second_token_uri: URI = contract.token_uri(ali_second_token_id.clone()).unwrap(); assert_eq!(ali_second_token_uri, URI::from("Banana URI")); - contract.transfer_all_tokens(ali.clone(), bob.clone()); + let transfer_res = contract.transfer_all_tokens(ali.clone(), bob.clone()); + assert!(transfer_res.is_ok()); ali_balance = contract.balance_of(ali); bob_balance = contract.balance_of(bob.clone()); From a6e4bee21f61a4c9610ad1a8d59dc6888770dd28 Mon Sep 17 00:00:00 2001 From: astro019 Date: Tue, 6 Jul 2021 02:01:30 +1000 Subject: [PATCH 35/98] check if the sender is the owner of nft, add paused flag to deploy function --- .github/workflows/ci-casper-rust-contract.yml | 2 +- cep47/src/lib.rs | 25 +- dragons-nft/src/main.rs | 5 +- tests/src/cep47.rs | 74 ++++-- tests/src/contract_tests.rs | 233 ++++++++++++------ 5 files changed, 234 insertions(+), 105 deletions(-) diff --git a/.github/workflows/ci-casper-rust-contract.yml b/.github/workflows/ci-casper-rust-contract.yml index 0c9975d..80ec4f6 100644 --- a/.github/workflows/ci-casper-rust-contract.yml +++ b/.github/workflows/ci-casper-rust-contract.yml @@ -27,4 +27,4 @@ jobs: - run: make prepare - run: make check-lint # Tests will be added after NCTL interaction is possible. - # - run: make test \ No newline at end of file + - run: make test \ No newline at end of file diff --git a/cep47/src/lib.rs b/cep47/src/lib.rs index 05b31b9..596f4b4 100644 --- a/cep47/src/lib.rs +++ b/cep47/src/lib.rs @@ -355,7 +355,11 @@ pub extern "C" fn burn_one() { #[cfg(not(feature = "no_transfer_token"))] #[no_mangle] pub extern "C" fn transfer_token() { + let caller: AccountHash = runtime::get_caller(); let sender: PublicKey = runtime::get_named_arg("sender"); + if sender.to_account_hash() != caller { + runtime::revert(ApiError::PermissionDenied); + } let recipient: PublicKey = runtime::get_named_arg("recipient"); let token_id: TokenId = runtime::get_named_arg("token_id"); let mut contract = CasperCEP47Contract::new(); @@ -366,7 +370,11 @@ pub extern "C" fn transfer_token() { #[cfg(not(feature = "no_transfer_many_tokens"))] #[no_mangle] pub extern "C" fn transfer_many_tokens() { + let caller: AccountHash = runtime::get_caller(); let sender: PublicKey = runtime::get_named_arg("sender"); + if sender.to_account_hash() != caller { + runtime::revert(ApiError::PermissionDenied); + } let recipient: PublicKey = runtime::get_named_arg("recipient"); let token_ids: Vec = runtime::get_named_arg("token_ids"); let mut contract = CasperCEP47Contract::new(); @@ -377,7 +385,11 @@ pub extern "C" fn transfer_many_tokens() { #[cfg(not(feature = "no_transfer_all_tokens"))] #[no_mangle] pub extern "C" fn transfer_all_tokens() { + let caller: AccountHash = runtime::get_caller(); let sender: PublicKey = runtime::get_named_arg("sender"); + if sender.to_account_hash() != caller { + runtime::revert(ApiError::PermissionDenied); + } let recipient: PublicKey = runtime::get_named_arg("recipient"); let mut contract = CasperCEP47Contract::new(); let res = contract.transfer_all_tokens(sender, recipient); @@ -596,6 +608,7 @@ pub fn deploy( token_uri: &str, entry_points: EntryPoints, contract_package_hash: ContractPackageHash, + paused: bool, ) { let mut named_keys = NamedKeys::new(); named_keys.insert("name".to_string(), storage::new_uref(token_name).into()); @@ -605,13 +618,19 @@ pub fn deploy( "total_supply".to_string(), storage::new_uref(U256::zero()).into(), ); - named_keys.insert("paused".to_string(), storage::new_uref(false).into()); + named_keys.insert("paused".to_string(), storage::new_uref(paused).into()); let (contract_hash, _) = storage::add_contract_version(contract_package_hash, entry_points, named_keys); - runtime::put_key("caspercep47_contract", contract_hash.into()); + runtime::put_key( + format!("{}_contract", token_name).as_str(), + contract_hash.into(), + ); let contract_hash_pack = storage::new_uref(contract_hash); - runtime::put_key("caspercep47_contract_hash", contract_hash_pack.into()); + runtime::put_key( + format!("{}_contract_hash", token_name).as_str(), + contract_hash_pack.into(), + ); } fn get_key(name: &str) -> Option { diff --git a/dragons-nft/src/main.rs b/dragons-nft/src/main.rs index cda2485..4c01b0f 100644 --- a/dragons-nft/src/main.rs +++ b/dragons-nft/src/main.rs @@ -1,9 +1,7 @@ #![no_main] #[no_mangle] -pub extern "C" fn owner_of() { - -} +pub extern "C" fn owner_of() {} #[no_mangle] pub extern "C" fn call() { @@ -16,5 +14,6 @@ pub extern "C" fn call() { &contract::contract_api::runtime::get_named_arg::("token_uri"), entry_points, contract_package_hash, + false, ); } diff --git a/tests/src/cep47.rs b/tests/src/cep47.rs index 6efe0ce..b0990ab 100644 --- a/tests/src/cep47.rs +++ b/tests/src/cep47.rs @@ -1,7 +1,7 @@ use casper_engine_test_support::{Code, Hash, SessionBuilder, TestContext, TestContextBuilder}; use casper_types::{ - account::AccountHash, bytesrepr::FromBytes, runtime_args, CLTyped, PublicKey, - RuntimeArgs, SecretKey, URef, U256, U512, + account::AccountHash, bytesrepr::FromBytes, runtime_args, CLTyped, PublicKey, RuntimeArgs, + SecretKey, URef, U256, U512, }; pub mod token_cfg { @@ -10,12 +10,13 @@ pub mod token_cfg { pub const URI: &str = "https://casper.network/network"; } -pub const CASPERCEP47_CONTRACT: &str = "caspercep47_contract"; -pub const CASPERCEP47_CONTRACT_HASH: &str = "caspercep47_contract_hash"; +pub const CONTRACT_KEY: &str = "CasperNFT_contract"; +pub const CONTRACT_HASH_KEY: &str = "CasperNFT_contract_hash"; +pub struct Sender(pub AccountHash); pub struct CasperCEP47Contract { pub context: TestContext, - pub caspercep47_hash: Hash, + pub hash: Hash, pub admin: PublicKey, pub ali: PublicKey, pub bob: PublicKey, @@ -45,29 +46,27 @@ impl CasperCEP47Contract { .with_authorization_keys(&[admin.to_account_hash()]) .build(); context.run(session); - let caspercep47_hash = context - .query( - admin.to_account_hash(), - &[CASPERCEP47_CONTRACT_HASH.to_string()], - ) + let hash = context + .query(admin.to_account_hash(), &[CONTRACT_HASH_KEY.to_string()]) .unwrap() .into_t() .unwrap(); Self { context, - caspercep47_hash, + hash, admin: admin, ali: ali, bob: bob, } } - fn call(&mut self, method: &str, args: RuntimeArgs) { - let code = Code::Hash(self.caspercep47_hash, method.to_string()); + fn call(&mut self, sender: Sender, method: &str, args: RuntimeArgs) { + let Sender(address) = sender; + let code = Code::Hash(self.hash, method.to_string()); let session = SessionBuilder::new(code, args) - .with_address(self.admin.to_account_hash()) - .with_authorization_keys(&[self.admin.to_account_hash()]) + .with_address(address) + .with_authorization_keys(&[address]) .build(); self.context.run(session); } @@ -75,7 +74,7 @@ impl CasperCEP47Contract { fn query_contract(&self, name: &str) -> Option { match self.context.query( self.admin.to_account_hash(), - &[CASPERCEP47_CONTRACT.to_string(), name.to_string()], + &[CONTRACT_KEY.to_string(), name.to_string()], ) { Err(_) => None, Ok(maybe_value) => { @@ -125,8 +124,9 @@ impl CasperCEP47Contract { self.query_contract(test_uref_key(&token_id).as_str()) } - pub fn mint_one(&mut self, recipient: PublicKey, token_uri: URI) { + pub fn mint_one(&mut self, recipient: PublicKey, token_uri: URI, sender: Sender) { self.call( + sender, "mint_one", runtime_args! { "recipient" => recipient, @@ -135,8 +135,15 @@ impl CasperCEP47Contract { ); } - pub fn mint_copies(&mut self, recipient: PublicKey, token_uri: URI, count: U256) { + pub fn mint_copies( + &mut self, + recipient: PublicKey, + token_uri: URI, + count: U256, + sender: Sender, + ) { self.call( + sender, "mint_copies", runtime_args! { "recipient" => recipient, @@ -146,8 +153,9 @@ impl CasperCEP47Contract { ); } - pub fn mint_many(&mut self, recipient: PublicKey, token_uris: Vec) { + pub fn mint_many(&mut self, recipient: PublicKey, token_uris: Vec, sender: Sender) { self.call( + sender, "mint_many", runtime_args! { "recipient" => recipient, @@ -156,8 +164,9 @@ impl CasperCEP47Contract { ); } - pub fn burn_many(&mut self, owner: PublicKey, token_ids: Vec) { + pub fn burn_many(&mut self, owner: PublicKey, token_ids: Vec, sender: Sender) { self.call( + sender, "burn_many", runtime_args! { "owner" => owner, @@ -166,8 +175,9 @@ impl CasperCEP47Contract { ); } - pub fn burn_one(&mut self, owner: PublicKey, token_id: TokenId) { + pub fn burn_one(&mut self, owner: PublicKey, token_id: TokenId, sender: Sender) { self.call( + sender, "burn_one", runtime_args! { "owner" => owner, @@ -176,11 +186,18 @@ impl CasperCEP47Contract { ); } - pub fn transfer_token(&mut self, sender: PublicKey, recipient: PublicKey, token_id: TokenId) { + pub fn transfer_token( + &mut self, + owner: PublicKey, + recipient: PublicKey, + token_id: TokenId, + sender: Sender, + ) { self.call( + sender, "transfer_token", runtime_args! { - "sender" => sender, + "sender" => owner, "recipient" => recipient, "token_id" => token_id }, @@ -189,25 +206,28 @@ impl CasperCEP47Contract { pub fn transfer_many_tokens( &mut self, - sender: PublicKey, + owner: PublicKey, recipient: PublicKey, token_ids: Vec, + sender: Sender, ) { self.call( + sender, "transfer_many_tokens", runtime_args! { - "sender" => sender, + "sender" => owner, "recipient" => recipient, "token_ids" => token_ids }, ); } - pub fn transfer_all_tokens(&mut self, sender: PublicKey, recipient: PublicKey) { + pub fn transfer_all_tokens(&mut self, owner: PublicKey, recipient: PublicKey, sender: Sender) { self.call( + sender, "transfer_all_tokens", runtime_args! { - "sender" => sender, + "sender" => owner, "recipient" => recipient }, ); diff --git a/tests/src/contract_tests.rs b/tests/src/contract_tests.rs index 8175b5d..e9cf007 100644 --- a/tests/src/contract_tests.rs +++ b/tests/src/contract_tests.rs @@ -1,5 +1,5 @@ -use crate::cep47::{token_cfg, CasperCEP47Contract, TokenId, URI}; -use casper_types::{AsymmetricType, PublicKey, SecretKey, U256}; +use crate::cep47::{token_cfg, CasperCEP47Contract, Sender, TokenId, URI}; +use casper_types::U256; #[test] fn test_deploy() { @@ -14,11 +14,14 @@ fn test_deploy() { #[test] fn test_token_uri() { let mut contract = CasperCEP47Contract::deploy(); - let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); let token_uri = URI::from("MonaLisa"); - contract.mint_one(ali.clone(), token_uri.clone()); + contract.mint_one( + contract.ali.clone(), + token_uri.clone(), + Sender(contract.admin.clone().to_account_hash()), + ); - let ali_tokens: Vec = contract.tokens(ali.clone()); + let ali_tokens: Vec = contract.tokens(contract.ali.clone()); let ali_token_uri = contract.token_uri(ali_tokens[0].clone()); assert_eq!(ali_token_uri, Some(token_uri)); @@ -27,155 +30,243 @@ fn test_token_uri() { #[test] fn test_mint_one() { let mut contract = CasperCEP47Contract::deploy(); - let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); let token_uri = URI::from("MonaLisa"); - contract.mint_one(ali.clone(), token_uri); + contract.mint_one( + contract.ali.clone(), + token_uri, + Sender(contract.admin.clone().to_account_hash()), + ); - let ali_tokens: Vec = contract.tokens(ali.clone()); + let ali_tokens: Vec = contract.tokens(contract.ali.clone()); assert_eq!(contract.total_supply(), U256::one()); - assert_eq!(contract.balance_of(ali.clone()), U256::one()); + assert_eq!(contract.balance_of(contract.ali.clone()), U256::one()); assert_eq!(U256::from(ali_tokens.len() as u64), U256::one()); - assert_eq!(contract.owner_of(&ali_tokens[0]), Some(ali)); + assert_eq!(contract.owner_of(&ali_tokens[0]), Some(contract.ali)); } #[test] fn test_mint_copies() { let mut contract = CasperCEP47Contract::deploy(); - let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); let token_uri = URI::from("Casper Golden Card"); - contract.mint_copies(ali.clone(), token_uri, U256::from(3)); + contract.mint_copies( + contract.ali.clone(), + token_uri, + U256::from(3), + Sender(contract.admin.clone().to_account_hash()), + ); - let ali_tokens: Vec = contract.tokens(ali.clone()); + let ali_tokens: Vec = contract.tokens(contract.ali.clone()); assert_eq!(contract.total_supply(), U256::from(3)); - assert_eq!(contract.balance_of(ali.clone()), U256::from(3)); + assert_eq!(contract.balance_of(contract.ali.clone()), U256::from(3)); assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(3)); - assert_eq!(contract.owner_of(&ali_tokens[0]), Some(ali.clone())); - assert_eq!(contract.owner_of(&ali_tokens[1]), Some(ali.clone())); - assert_eq!(contract.owner_of(&ali_tokens[2]), Some(ali)); + assert_eq!( + contract.owner_of(&ali_tokens[0]), + Some(contract.ali.clone()) + ); + assert_eq!( + contract.owner_of(&ali_tokens[1]), + Some(contract.ali.clone()) + ); + assert_eq!(contract.owner_of(&ali_tokens[2]), Some(contract.ali)); } #[test] fn test_mint_many() { let mut contract = CasperCEP47Contract::deploy(); - let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); let token_uris: Vec = vec![URI::from("Casper Golden Card"), URI::from("Mona Lisa")]; - contract.mint_many(ali.clone(), token_uris); + contract.mint_many( + contract.ali.clone(), + token_uris, + Sender(contract.admin.clone().to_account_hash()), + ); - let ali_tokens: Vec = contract.tokens(ali.clone()); + let ali_tokens: Vec = contract.tokens(contract.ali.clone()); assert_eq!(contract.total_supply(), U256::from(2)); - assert_eq!(contract.balance_of(ali.clone()), U256::from(2)); + assert_eq!(contract.balance_of(contract.ali.clone()), U256::from(2)); assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(2)); - assert_eq!(contract.owner_of(&ali_tokens[0]), Some(ali.clone())); - assert_eq!(contract.owner_of(&ali_tokens[1]), Some(ali)); + assert_eq!( + contract.owner_of(&ali_tokens[0]), + Some(contract.ali.clone()) + ); + assert_eq!(contract.owner_of(&ali_tokens[1]), Some(contract.ali)); } #[test] fn test_burn_many() { let mut contract = CasperCEP47Contract::deploy(); - let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); - let token_uris: Vec = vec![URI::from("Casper Golden Card"), URI::from("Casper Siver Card"), URI::from("Casper Bronze Card"), URI::from("Mona Lisa")]; - contract.mint_many(ali.clone(), token_uris); + let token_uris: Vec = vec![ + URI::from("Casper Golden Card"), + URI::from("Casper Siver Card"), + URI::from("Casper Bronze Card"), + URI::from("Mona Lisa"), + ]; + contract.mint_many( + contract.ali.clone(), + token_uris, + Sender(contract.admin.clone().to_account_hash()), + ); - let mut ali_tokens: Vec = contract.tokens(ali.clone()); + let mut ali_tokens: Vec = contract.tokens(contract.ali.clone()); assert_eq!(contract.total_supply(), U256::from(4)); - assert_eq!(contract.balance_of(ali.clone()), U256::from(4)); + assert_eq!(contract.balance_of(contract.ali.clone()), U256::from(4)); assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(4)); - contract.burn_many(ali.clone(), vec![ali_tokens.first().unwrap().clone(), ali_tokens.last().unwrap().clone()]); + contract.burn_many( + contract.ali.clone(), + vec![ + ali_tokens.first().unwrap().clone(), + ali_tokens.last().unwrap().clone(), + ], + Sender(contract.admin.clone().to_account_hash()), + ); assert_eq!(contract.total_supply(), U256::from(2)); - assert_eq!(contract.balance_of(ali.clone()), U256::from(2)); + assert_eq!(contract.balance_of(contract.ali.clone()), U256::from(2)); - ali_tokens = contract.tokens(ali.clone()); + ali_tokens = contract.tokens(contract.ali.clone()); assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(2)); } #[test] fn test_burn_one() { let mut contract = CasperCEP47Contract::deploy(); - let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); let token_uris: Vec = vec![URI::from("Casper Golden Card"), URI::from("Mona Lisa")]; - contract.mint_many(ali.clone(), token_uris); + contract.mint_many( + contract.ali.clone(), + token_uris, + Sender(contract.admin.clone().to_account_hash()), + ); - let mut ali_tokens: Vec = contract.tokens(ali.clone()); + let mut ali_tokens: Vec = contract.tokens(contract.ali.clone()); assert_eq!(contract.total_supply(), U256::from(2)); - assert_eq!(contract.balance_of(ali.clone()), U256::from(2)); + assert_eq!(contract.balance_of(contract.ali.clone()), U256::from(2)); assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(2)); - contract.burn_one(ali.clone(), ali_tokens.first().unwrap().clone()); + contract.burn_one( + contract.ali.clone(), + ali_tokens.first().unwrap().clone(), + Sender(contract.admin.clone().to_account_hash()), + ); assert_eq!(contract.total_supply(), U256::from(1)); - assert_eq!(contract.balance_of(ali.clone()), U256::from(1)); + assert_eq!(contract.balance_of(contract.ali.clone()), U256::from(1)); - ali_tokens = contract.tokens(ali.clone()); + ali_tokens = contract.tokens(contract.ali.clone()); assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(1)); } #[test] fn test_transfer_token() { let mut contract = CasperCEP47Contract::deploy(); - let ali: PublicKey = SecretKey::ed25519_from_bytes([3u8; 32]).unwrap().into(); - let bob: PublicKey = SecretKey::ed25519_from_bytes([5u8; 32]).unwrap().into(); let token_uris: Vec = vec![ URI::from("Casper Golden Card"), URI::from("Casper Silver Card"), ]; - contract.mint_many(ali.clone(), token_uris); - let ali_tokens: Vec = contract.tokens(ali.clone()); - contract.transfer_token(ali.clone(), bob.clone(), ali_tokens[1].clone()); + contract.mint_many( + contract.ali.clone(), + token_uris, + Sender(contract.admin.clone().to_account_hash()), + ); + let ali_tokens: Vec = contract.tokens(contract.ali.clone()); + contract.transfer_token( + contract.ali.clone(), + contract.bob.clone(), + ali_tokens[1].clone(), + Sender(contract.ali.clone().to_account_hash()), + ); - assert_eq!(contract.balance_of(ali.clone()), U256::from(1)); - assert_eq!(contract.balance_of(bob.clone()), U256::from(1)); + assert_eq!(contract.balance_of(contract.ali.clone()), U256::from(1)); + assert_eq!(contract.balance_of(contract.bob.clone()), U256::from(1)); assert_eq!(contract.total_supply(), U256::from(2)); - assert_eq!(contract.owner_of(&ali_tokens[0]), Some(ali)); - assert_eq!(contract.owner_of(&ali_tokens[1]), Some(bob)); + assert_eq!( + contract.owner_of(&ali_tokens[0]), + Some(contract.ali.clone()) + ); + assert_eq!( + contract.owner_of(&ali_tokens[1]), + Some(contract.bob.clone()) + ); } #[test] fn test_transfer_many_tokens() { let mut contract = CasperCEP47Contract::deploy(); - let ali: PublicKey = SecretKey::ed25519_from_bytes([3u8; 32]).unwrap().into(); - let bob: PublicKey = SecretKey::ed25519_from_bytes([5u8; 32]).unwrap().into(); let token_uris: Vec = vec![ URI::from("Casper Golden Card"), URI::from("Casper Silver Card"), URI::from("Casper Bronze Card"), ]; - contract.mint_many(ali.clone(), token_uris); - let ali_tokens: Vec = contract.tokens(ali.clone()); - contract.transfer_many_tokens(ali.clone(), bob.clone(), ali_tokens[..2].to_vec()); + contract.mint_many( + contract.ali.clone(), + token_uris, + Sender(contract.admin.clone().to_account_hash()), + ); + let ali_tokens: Vec = contract.tokens(contract.ali.clone()); + contract.transfer_many_tokens( + contract.ali.clone(), + contract.bob.clone(), + ali_tokens[..2].to_vec(), + Sender(contract.ali.clone().to_account_hash()), + ); - assert_eq!(contract.balance_of(ali.clone()), U256::from(1)); - assert_eq!(contract.balance_of(bob.clone()), U256::from(2)); + assert_eq!(contract.balance_of(contract.ali.clone()), U256::from(1)); + assert_eq!(contract.balance_of(contract.bob.clone()), U256::from(2)); assert_eq!(contract.total_supply(), U256::from(3)); - assert_eq!(contract.owner_of(&ali_tokens[0]), Some(bob.clone())); - assert_eq!(contract.owner_of(&ali_tokens[1]), Some(bob)); - assert_eq!(contract.owner_of(&ali_tokens[2]), Some(ali)); + assert_eq!( + contract.owner_of(&ali_tokens[0]), + Some(contract.bob.clone()) + ); + assert_eq!( + contract.owner_of(&ali_tokens[1]), + Some(contract.bob.clone()) + ); + assert_eq!( + contract.owner_of(&ali_tokens[2]), + Some(contract.ali.clone()) + ); } #[test] fn test_transfer_all_tokens() { let mut contract = CasperCEP47Contract::deploy(); - let ali: PublicKey = SecretKey::ed25519_from_bytes([3u8; 32]).unwrap().into(); - let bob: PublicKey = SecretKey::ed25519_from_bytes([5u8; 32]).unwrap().into(); let token_uris: Vec = vec![ URI::from("Casper Golden Card"), URI::from("Casper Silver Card"), ]; - contract.mint_many(ali.clone(), token_uris); - let ali_tokens: Vec = contract.tokens(ali.clone()); - assert_eq!(contract.balance_of(ali.clone()), U256::from(2)); - assert_eq!(contract.balance_of(bob.clone()), U256::from(0)); - assert_eq!(contract.owner_of(&ali_tokens[0]), Some(ali.clone())); - assert_eq!(contract.owner_of(&ali_tokens[1]), Some(ali.clone())); - - contract.transfer_all_tokens(ali.clone(), bob.clone()); - assert_eq!(contract.balance_of(ali.clone()), U256::from(0)); - assert_eq!(contract.balance_of(bob.clone()), U256::from(2)); + contract.mint_many( + contract.ali.clone(), + token_uris, + Sender(contract.admin.clone().to_account_hash()), + ); + let ali_tokens: Vec = contract.tokens(contract.ali.clone()); + assert_eq!(contract.balance_of(contract.ali.clone()), U256::from(2)); + assert_eq!(contract.balance_of(contract.bob.clone()), U256::from(0)); + assert_eq!( + contract.owner_of(&ali_tokens[0]), + Some(contract.ali.clone()) + ); + assert_eq!( + contract.owner_of(&ali_tokens[1]), + Some(contract.ali.clone()) + ); + + contract.transfer_all_tokens( + contract.ali.clone(), + contract.bob.clone(), + Sender(contract.ali.clone().to_account_hash()), + ); + assert_eq!(contract.balance_of(contract.ali.clone()), U256::from(0)); + assert_eq!(contract.balance_of(contract.bob.clone()), U256::from(2)); assert_eq!(contract.total_supply(), U256::from(2)); - assert_eq!(contract.owner_of(&ali_tokens[0]), Some(bob.clone())); - assert_eq!(contract.owner_of(&ali_tokens[1]), Some(bob)); + assert_eq!( + contract.owner_of(&ali_tokens[0]), + Some(contract.bob.clone()) + ); + assert_eq!( + contract.owner_of(&ali_tokens[1]), + Some(contract.bob.clone()) + ); } From 63bdfd41d72cbed9240e2e909d06cd7dc5edf7bb Mon Sep 17 00:00:00 2001 From: astro019 Date: Tue, 6 Jul 2021 02:14:41 +1000 Subject: [PATCH 36/98] added cep47 lib to workspace --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index ae618a2..e23f16c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,7 @@ [workspace] members = [ + "cep47", "tests", "dragons-nft", "marketplace" From 1d3c88975510dc26f5da69fabefafc0b60caac76 Mon Sep 17 00:00:00 2001 From: Maciej Zielinski Date: Tue, 6 Jul 2021 13:17:15 +0200 Subject: [PATCH 37/98] Remove marketplace, split cep47 logic and contract, organise tests. --- .github/workflows/ci-casper-rust-contract.yml | 2 +- .gitignore | 2 +- Cargo.toml | 4 +- Makefile | 12 +- cep47-logic/Cargo.toml | 11 + cep47/src/logic.rs => cep47-logic/src/lib.rs | 4 + cep47-logic/src/tests.rs | 539 +++++++++++++++++ cep47/Cargo.toml | 4 +- cep47/src/lib.rs | 5 +- cep47/src/logic_tests.rs | 543 ------------------ {tests => dragons-nft-tests}/Cargo.toml | 2 +- {tests => dragons-nft-tests}/src/cep47.rs | 0 .../src/contract_tests.rs | 0 {tests => dragons-nft-tests}/src/lib.rs | 0 {tests => dragons-nft-tests}/src/market.rs | 0 {tests => dragons-nft-tests}/wasm/.gitkeep | 0 dragons-nft-tests/wasm/dragons-nft.wasm | Bin 0 -> 338879 bytes dragons-nft/Cargo.toml | 9 +- dragons-nft/src/main.rs | 12 +- marketplace/Cargo.toml | 26 - marketplace/src/lib.rs | 228 -------- marketplace/src/main.rs | 10 - marketplace/src/offer.rs | 111 ---- marketplace/src/send_tokens.rs | 35 -- rust-toolchain | 1 + 25 files changed, 580 insertions(+), 980 deletions(-) create mode 100644 cep47-logic/Cargo.toml rename cep47/src/logic.rs => cep47-logic/src/lib.rs (99%) create mode 100644 cep47-logic/src/tests.rs delete mode 100644 cep47/src/logic_tests.rs rename {tests => dragons-nft-tests}/Cargo.toml (93%) rename {tests => dragons-nft-tests}/src/cep47.rs (100%) rename {tests => dragons-nft-tests}/src/contract_tests.rs (100%) rename {tests => dragons-nft-tests}/src/lib.rs (100%) rename {tests => dragons-nft-tests}/src/market.rs (100%) rename {tests => dragons-nft-tests}/wasm/.gitkeep (100%) create mode 100755 dragons-nft-tests/wasm/dragons-nft.wasm delete mode 100644 marketplace/Cargo.toml delete mode 100644 marketplace/src/lib.rs delete mode 100644 marketplace/src/main.rs delete mode 100644 marketplace/src/offer.rs delete mode 100644 marketplace/src/send_tokens.rs create mode 100644 rust-toolchain diff --git a/.github/workflows/ci-casper-rust-contract.yml b/.github/workflows/ci-casper-rust-contract.yml index 80ec4f6..7bd0689 100644 --- a/.github/workflows/ci-casper-rust-contract.yml +++ b/.github/workflows/ci-casper-rust-contract.yml @@ -27,4 +27,4 @@ jobs: - run: make prepare - run: make check-lint # Tests will be added after NCTL interaction is possible. - - run: make test \ No newline at end of file + - run: make test diff --git a/.gitignore b/.gitignore index 0564e6c..08ee105 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ target Cargo.lock -tests/wasm/*.wasm \ No newline at end of file +dragons-nft-tests/wasm/*.wasm \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index e23f16c..284c799 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,10 +1,10 @@ [workspace] members = [ + "cep47-logic", "cep47", - "tests", "dragons-nft", - "marketplace" + "dragons-nft-tests" ] [profile.release] diff --git a/Makefile b/Makefile index a3ac087..b008ec7 100644 --- a/Makefile +++ b/Makefile @@ -3,19 +3,19 @@ prepare: build-contract: cargo build --release -p dragons-nft --target wasm32-unknown-unknown - cargo build --release -p marketplace --target wasm32-unknown-unknown test-only: - cargo test --workspace + cargo test -p cep47-logic + cargo test -p dragons-nft-tests copy-wasm-file-to-test: - mkdir -p tests/wasm - cp target/wasm32-unknown-unknown/release/*.wasm tests/wasm + mkdir -p dragons-nft-tests/wasm + cp target/wasm32-unknown-unknown/release/*.wasm dragons-nft-tests/wasm test: build-contract copy-wasm-file-to-test test-only clippy: - cargo clippy --all-targets --all -- -D warnings -A renamed_and_removed_lints + cargo clippy --all-targets --all check-lint: clippy cargo fmt --all -- --check @@ -27,4 +27,4 @@ lint: clippy format clean: cargo clean - rm -rf tests/wasm/*.wasm + rm -rf dragons-nft-tests/wasm/*.wasm diff --git a/cep47-logic/Cargo.toml b/cep47-logic/Cargo.toml new file mode 100644 index 0000000..eb1f628 --- /dev/null +++ b/cep47-logic/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "cep47-logic" +version = "0.1.0" +authors = ["Maciej Zielinski "] +edition = "2018" + +[dependencies] +casper-types = "1.2.0" + +[dev-dependencies] +rand = "0.7.3" \ No newline at end of file diff --git a/cep47/src/logic.rs b/cep47-logic/src/lib.rs similarity index 99% rename from cep47/src/logic.rs rename to cep47-logic/src/lib.rs index ce04ab0..4aad53c 100644 --- a/cep47/src/logic.rs +++ b/cep47-logic/src/lib.rs @@ -1,7 +1,11 @@ #![allow(dead_code)] #![allow(unused_imports)] + use casper_types::{ApiError, AsymmetricType, PublicKey, URef, U256}; +#[cfg(test)] +pub mod tests; + pub type TokenId = String; pub type URI = String; diff --git a/cep47-logic/src/tests.rs b/cep47-logic/src/tests.rs new file mode 100644 index 0000000..6017d7d --- /dev/null +++ b/cep47-logic/src/tests.rs @@ -0,0 +1,539 @@ +use casper_types::AccessRights; +use rand::Rng; + +use crate::{ + AsymmetricType, CEP47Contract, CEP47Storage, PublicKey, TokenId, URef, WithStorage, U256, URI, +}; +use std::{ + collections::{hash_map::DefaultHasher, BTreeMap}, + hash::{Hash, Hasher}, + sync::Mutex, +}; + +struct TestStorage { + name: String, + symbol: String, + uri: URI, + paused: bool, + total_supply: U256, + tokens: BTreeMap>, + token_uris: BTreeMap, + balances: BTreeMap, + belongs_to: BTreeMap, + urefs: BTreeMap, +} + +impl TestStorage { + pub fn new() -> TestStorage { + TestStorage { + name: String::from("Casper Enhancement Proposal 47"), + symbol: String::from("CEP47"), + uri: URI::from("https://github.com/casper-ecosystem/casper-nft-cep47"), + paused: false, + total_supply: U256::from(0), + tokens: BTreeMap::new(), + balances: BTreeMap::new(), + belongs_to: BTreeMap::new(), + token_uris: BTreeMap::new(), + urefs: BTreeMap::new(), + } + } +} + +impl CEP47Storage for TestStorage { + fn name(&self) -> String { + self.name.clone() + } + + fn symbol(&self) -> String { + self.symbol.clone() + } + + fn uri(&self) -> URI { + self.uri.clone() + } + + fn balance_of(&self, owner: PublicKey) -> U256 { + let owner_balance = self.balances.get(&owner); + if owner_balance.is_none() { + U256::from(0) + } else { + owner_balance.unwrap().clone() + } + } + + fn onwer_of(&self, token_id: TokenId) -> Option { + let owner = self.belongs_to.get(&token_id); + if owner.is_some() { + Some(owner.unwrap().clone()) + } else { + None + } + } + + fn total_supply(&self) -> U256 { + self.total_supply + } + + fn token_uri(&self, token_id: TokenId) -> Option { + let uri = self.token_uris.get(&token_id); + if uri.is_some() { + Some(uri.unwrap().clone()) + } else { + None + } + } + + fn is_paused(&self) -> bool { + self.paused + } + + fn pause(&mut self) { + self.paused = true; + } + + fn unpause(&mut self) { + self.paused = false; + } + + fn get_tokens(&self, owner: PublicKey) -> Vec { + let owner_tokens = self.tokens.get(&owner); + if owner_tokens.is_none() { + Vec::::new() + } else { + owner_tokens.unwrap().clone() + } + } + + fn set_tokens(&mut self, owner: PublicKey, token_ids: Vec) { + let owner_new_balance = U256::from(token_ids.len() as u64); + + let owner_tokens = self.get_tokens(owner.clone()); + for token_id in owner_tokens.clone() { + self.belongs_to.remove(&token_id); + } + for token_id in token_ids.clone() { + self.belongs_to.insert(token_id, owner.clone()); + } + + self.tokens.insert(owner.clone(), token_ids.clone()); + self.balances.insert(owner, owner_new_balance); + } + + fn mint_many(&mut self, recipient: PublicKey, token_uris: Vec) { + let recipient_balance = self.balances.get(&recipient); + let recipient_tokens = self.tokens.get(&recipient); + let mut recipient_new_balance = if recipient_balance.is_none() { + U256::from(0) + } else { + recipient_balance.unwrap().clone() + }; + let mut recipient_new_tokens = if recipient_tokens.is_none() { + Vec::::new() + } else { + recipient_tokens.unwrap().clone() + }; + + let mut hasher = DefaultHasher::new(); + + for token_uri in token_uris.clone() { + let token_info = (self.uri.clone(), token_uri.clone()); + Hash::hash(&token_info, &mut hasher); + let token_id: TokenId = TokenId::from(hasher.finish().to_string()); + self.token_uris.insert(token_id.clone(), token_uri); + recipient_new_tokens.push(token_id.clone()); + self.belongs_to.insert(token_id, recipient.clone()); + recipient_new_balance = recipient_new_balance + 1; + self.total_supply = self.total_supply + 1; + } + self.balances + .insert(recipient.clone(), recipient_new_balance); + self.tokens.insert(recipient, recipient_new_tokens); + } + + fn mint_copies(&mut self, recipient: PublicKey, token_uri: URI, count: U256) { + let token_uris: Vec = vec![token_uri; count.as_usize()]; + self.mint_many(recipient, token_uris); + } + + fn burn_many(&mut self, owner: PublicKey, token_ids: Vec) { + let owner_tokens = self.tokens.get(&owner); + let owner_balance = self.balances.get(&owner); + let mut owner_new_balance = if owner_balance.is_none() { + U256::from(0) + } else { + owner_balance.unwrap().clone() + }; + let mut owner_new_tokens = if owner_tokens.is_none() { + Vec::::new() + } else { + owner_tokens.unwrap().clone() + }; + + for token_id in token_ids.clone() { + let index = owner_new_tokens + .iter() + .position(|x| *x == token_id.clone()) + .unwrap(); + owner_new_tokens.remove(index); + self.token_uris.remove(&token_id.clone()); + self.belongs_to.remove(&token_id.clone()); + owner_new_balance = owner_new_balance - 1; + self.total_supply = self.total_supply - 1; + } + self.balances.insert(owner.clone(), owner_new_balance); + self.tokens.insert(owner, owner_new_tokens); + } + + fn burn_one(&mut self, owner: PublicKey, token_id: TokenId) { + let owner_tokens = self.tokens.get(&owner); + let owner_balance = self.balances.get(&owner); + let owner_new_balance = if owner_balance.is_none() { + U256::from(0) + } else { + owner_balance.unwrap().clone() + }; + let mut owner_new_tokens = if owner_tokens.is_none() { + Vec::::new() + } else { + owner_tokens.unwrap().clone() + }; + let index = owner_new_tokens + .iter() + .position(|x| *x == token_id.clone()) + .unwrap(); + owner_new_tokens.remove(index); + self.token_uris.remove(&token_id.clone()); + self.belongs_to.remove(&token_id.clone()); + self.total_supply = self.total_supply - 1; + self.balances.insert(owner.clone(), owner_new_balance - 1); + self.tokens.insert(owner, owner_new_tokens); + } + + fn new_uref(&mut self, token_id: TokenId) -> Option { + let mut rng = rand::thread_rng(); + let val: [u8; 32] = rng.gen(); + let uref = URef::new(val, AccessRights::READ_ADD_WRITE); + if self.urefs.contains_key(&uref) { + None + } else { + self.urefs.insert(uref, token_id); + Some(uref) + } + } + + fn del_uref(&mut self, token_uref: URef) -> Option { + let token_id = self.token_id(token_uref); + if token_id.is_none() { + None + } else { + let token_id = token_id.unwrap(); + self.urefs.remove(&token_uref); + Some(token_id) + } + } + + fn token_id(&self, token_uref: URef) -> Option { + self.urefs.get(&token_uref).map(|x| x.clone()) + } +} + +struct TestContract { + storage: TestStorage, +} + +impl TestContract { + pub fn new() -> TestContract { + TestContract { + storage: TestStorage::new(), + } + } +} + +impl WithStorage for TestContract { + fn storage(&self) -> &TestStorage { + &self.storage + } + + fn storage_mut(&mut self) -> &mut TestStorage { + &mut self.storage + } +} + +impl CEP47Contract for TestContract {} + +#[test] +fn test_metadata() { + let contract = TestContract::new(); + assert_eq!( + contract.name(), + String::from("Casper Enhancement Proposal 47") + ); + assert_eq!(contract.symbol(), String::from("CEP47")); + assert_eq!( + contract.uri(), + String::from("https://github.com/casper-ecosystem/casper-nft-cep47") + ); +} +#[test] +fn test_mint_many() { + let mut contract = TestContract::new(); + let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); + + assert_eq!(contract.total_supply(), U256::from(0)); + contract.mint_many(ali.clone(), vec![URI::from("Apple URI")]); + contract.mint_many( + bob.clone(), + vec![URI::from("Banana URI"), URI::from("Orange URI")], + ); + assert_eq!(contract.total_supply(), U256::from(3)); + + let ali_balance = contract.balance_of(ali.clone()); + assert_eq!(ali_balance, U256::from(1)); + let bob_balance = contract.balance_of(bob.clone()); + assert_eq!(bob_balance, U256::from(2)); + + let ali_tokens: Vec = contract.tokens(ali); + let ali_first_token_uri: URI = contract + .token_uri(ali_tokens.get(0).unwrap().clone()) + .unwrap(); + assert_eq!(ali_first_token_uri, URI::from("Apple URI")); + + let bob_tokens: Vec = contract.tokens(bob); + let bob_first_token_uri: URI = contract + .token_uri(bob_tokens.get(1).unwrap().clone()) + .unwrap(); + assert_eq!(bob_first_token_uri, URI::from("Orange URI")); +} +#[test] +fn test_mint_copies() { + let mut contract = TestContract::new(); + let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + + assert_eq!(contract.total_supply(), U256::from(0)); + contract.mint_copies(ali.clone(), URI::from("Casper Fan URI"), U256::from(7)); + assert_eq!(contract.total_supply(), U256::from(7)); + + let ali_balance = contract.balance_of(ali.clone()); + assert_eq!(ali_balance, U256::from(7)); + + let ali_tokens: Vec = contract.tokens(ali); + let ali_first_token_uri: URI = contract + .token_uri(ali_tokens.get(0).unwrap().clone()) + .unwrap(); + let ali_third_token_uri: URI = contract + .token_uri(ali_tokens.get(2).unwrap().clone()) + .unwrap(); + assert_eq!(ali_first_token_uri, URI::from("Casper Fan URI")); + assert_eq!(ali_third_token_uri, URI::from("Casper Fan URI")); +} +#[test] +fn test_burn_many() { + let mut contract = TestContract::new(); + let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + + assert_eq!(contract.total_supply(), U256::from(0)); + contract.mint_many( + ali.clone(), + vec![ + URI::from("Banana URI"), + URI::from("Orange URI"), + URI::from("Apple URI"), + URI::from("Grape URI"), + ], + ); + assert_eq!(contract.total_supply(), U256::from(4)); + + let mut ali_balance = contract.balance_of(ali.clone()); + assert_eq!(ali_balance, U256::from(4)); + + let mut ali_tokens: Vec = contract.tokens(ali.clone()); + contract.burn_many( + ali.clone(), + vec![ + ali_tokens.get(0).unwrap().clone(), + ali_tokens.get(3).unwrap().clone(), + ], + ); + let mut ali_first_token_uri = contract.token_uri(ali_tokens.first().unwrap().clone()); + assert_eq!(ali_first_token_uri, None); + let mut ali_last_token_uri = contract.token_uri(ali_tokens.last().unwrap().clone()); + assert_eq!(ali_first_token_uri, None); + assert_eq!(ali_last_token_uri, None); + + ali_tokens = contract.tokens(ali.clone()); + ali_first_token_uri = contract.token_uri(ali_tokens.first().unwrap().clone()); + ali_last_token_uri = contract.token_uri(ali_tokens.last().unwrap().clone()); + assert_eq!(ali_first_token_uri, Some(URI::from("Orange URI"))); + assert_eq!(ali_last_token_uri, Some(URI::from("Apple URI"))); + + assert_eq!(contract.total_supply(), U256::from(2)); + ali_balance = contract.balance_of(ali); + assert_eq!(ali_balance, U256::from(2)); +} +#[test] +fn test_burn_one() { + let mut contract = TestContract::new(); + let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + + assert_eq!(contract.total_supply(), U256::from(0)); + contract.mint_many( + ali.clone(), + vec![URI::from("Banana URI"), URI::from("Orange URI")], + ); + assert_eq!(contract.total_supply(), U256::from(2)); + + let mut ali_balance = contract.balance_of(ali.clone()); + assert_eq!(ali_balance, U256::from(2)); + + let mut ali_tokens: Vec = contract.tokens(ali.clone()); + contract.burn_one(ali.clone(), ali_tokens.get(0).unwrap().clone()); + let mut ali_first_token_uri = contract.token_uri(ali_tokens.get(0).unwrap().clone()); + assert_eq!(ali_first_token_uri, None); + + ali_tokens = contract.tokens(ali.clone()); + ali_first_token_uri = contract.token_uri(ali_tokens.get(0).unwrap().clone()); + assert_eq!(ali_first_token_uri, Some(URI::from("Orange URI"))); + + assert_eq!(contract.total_supply(), U256::from(1)); + ali_balance = contract.balance_of(ali); + assert_eq!(ali_balance, U256::from(1)); +} +#[test] +fn test_transfer_token() { + let mut contract = TestContract::new(); + let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); + + assert_eq!(contract.total_supply(), U256::from(0)); + contract.mint_one(ali.clone(), URI::from("Casper Fan URI")); + assert_eq!(contract.total_supply(), U256::from(1)); + + let mut ali_balance = contract.balance_of(ali.clone()); + let mut bob_balance = contract.balance_of(bob.clone()); + assert_eq!(ali_balance, U256::from(1)); + assert_eq!(bob_balance, U256::from(0)); + + let ali_tokens: Vec = contract.tokens(ali.clone()); + let ali_first_token_id: TokenId = ali_tokens.get(0).unwrap().clone(); + let ali_first_token_uri: URI = contract.token_uri(ali_first_token_id.clone()).unwrap(); + assert_eq!(ali_first_token_uri, URI::from("Casper Fan URI")); + + let transfer_res = + contract.transfer_token(ali.clone(), bob.clone(), ali_first_token_id.clone()); + assert!(transfer_res.is_ok()); + ali_balance = contract.balance_of(ali); + bob_balance = contract.balance_of(bob.clone()); + assert_eq!(ali_balance, U256::from(0)); + assert_eq!(bob_balance, U256::from(1)); + + let owner_of_first_token_id = contract.owner_of(ali_first_token_id); + assert_eq!(owner_of_first_token_id.unwrap(), bob); +} +#[test] +fn test_transfer_all_tokens() { + let mut contract = TestContract::new(); + let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); + + assert_eq!(contract.total_supply(), U256::from(0)); + contract.mint_many( + ali.clone(), + vec![URI::from("Apple URI"), URI::from("Banana URI")], + ); + contract.mint_one(ali.clone(), URI::from("Casper Fan URI")); + assert_eq!(contract.total_supply(), U256::from(3)); + + let mut ali_balance = contract.balance_of(ali.clone()); + let mut bob_balance = contract.balance_of(bob.clone()); + assert_eq!(ali_balance, U256::from(3)); + assert_eq!(bob_balance, U256::from(0)); + + let ali_tokens: Vec = contract.tokens(ali.clone()); + let ali_second_token_id: TokenId = ali_tokens.get(1).unwrap().clone(); + let ali_second_token_uri: URI = contract.token_uri(ali_second_token_id.clone()).unwrap(); + assert_eq!(ali_second_token_uri, URI::from("Banana URI")); + + let transfer_res = contract.transfer_all_tokens(ali.clone(), bob.clone()); + assert!(transfer_res.is_ok()); + + ali_balance = contract.balance_of(ali); + bob_balance = contract.balance_of(bob.clone()); + assert_eq!(ali_balance, U256::from(0)); + assert_eq!(bob_balance, U256::from(3)); + + let owner_of_second_token_id = contract.owner_of(ali_second_token_id); + assert_eq!(owner_of_second_token_id.unwrap(), bob); +} + +#[test] +fn test_transfer_many_tokens() { + let mut contract = TestContract::new(); + let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); + + assert_eq!(contract.total_supply(), U256::from(0)); + contract.mint_many( + ali.clone(), + vec![URI::from("Apple URI"), URI::from("Banana URI")], + ); + contract.mint_copies(ali.clone(), URI::from("Casper Fan URI"), U256::from(3)); + assert_eq!(contract.total_supply(), U256::from(5)); + + let mut ali_balance = contract.balance_of(ali.clone()); + let mut bob_balance = contract.balance_of(bob.clone()); + assert_eq!(ali_balance, U256::from(5)); + assert_eq!(bob_balance, U256::from(0)); + + let ali_tokens: Vec = contract.tokens(ali.clone()); + let ali_second_token_id: TokenId = ali_tokens.get(1).unwrap().clone(); + let ali_second_token_uri: URI = contract.token_uri(ali_second_token_id.clone()).unwrap(); + let ali_third_token_id: TokenId = ali_tokens.get(2).unwrap().clone(); + let ali_third_token_uri: URI = contract.token_uri(ali_third_token_id.clone()).unwrap(); + assert_eq!(ali_second_token_uri, URI::from("Banana URI")); + assert_eq!(ali_third_token_uri, URI::from("Casper Fan URI")); + + let transfer_res = contract.transfer_many_tokens( + ali.clone(), + bob.clone(), + vec![ali_second_token_id.clone(), ali_third_token_id.clone()], + ); + assert!(transfer_res.is_ok()); + + ali_balance = contract.balance_of(ali); + bob_balance = contract.balance_of(bob.clone()); + assert_eq!(ali_balance, U256::from(3)); + assert_eq!(bob_balance, U256::from(2)); + + let owner_of_second_token_id = contract.owner_of(ali_second_token_id); + let owner_of_third_token_id = contract.owner_of(ali_third_token_id); + assert_eq!(owner_of_second_token_id.unwrap(), bob); + assert_eq!(owner_of_third_token_id.unwrap(), bob); +} + +#[test] +fn test_attach_and_detach() { + let mut contract = TestContract::new(); + let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); + + contract.mint_one(ali.clone(), URI::from("0x12af")); + let token_id: TokenId = contract.tokens(ali.clone())[0].clone(); + + let token_uref: URef = contract.detach(ali.clone(), token_id.clone()).unwrap(); + assert_eq!(contract.balance_of(ali.clone()), U256::zero()); + assert_eq!(contract.total_supply(), U256::one()); + assert!(contract.tokens(ali).is_empty()); + + assert_eq!(contract.token_id(token_uref.clone()), token_id.clone()); + assert_eq!( + contract.token_uri(token_id.clone()).unwrap(), + URI::from("0x12af") + ); + + contract.attach(token_uref, bob.clone()); + assert_eq!(contract.balance_of(bob.clone()), U256::one()); + assert_eq!(contract.total_supply(), U256::one()); + assert_eq!(contract.tokens(bob), vec![token_id]); +} diff --git a/cep47/Cargo.toml b/cep47/Cargo.toml index f19fe36..7eacf6e 100644 --- a/cep47/Cargo.toml +++ b/cep47/Cargo.toml @@ -7,7 +7,7 @@ edition = "2018" [dependencies] casper-contract = "1.2.0" casper-types = "1.2.0" -rand = { version="0.8", default-features=false } +cep47-logic = { path = "../cep47-logic" } [lib] name = "cep47" @@ -34,4 +34,4 @@ no_transfer_token = [] no_transfer_many_tokens = [] no_transfer_all_tokens = [] no_attach = [] -no_detach = [] \ No newline at end of file +no_detach = [] diff --git a/cep47/src/lib.rs b/cep47/src/lib.rs index 596f4b4..19b9c40 100644 --- a/cep47/src/lib.rs +++ b/cep47/src/lib.rs @@ -4,9 +4,6 @@ extern crate alloc; -pub mod logic; -pub mod logic_tests; - use alloc::{ collections::{BTreeMap, BTreeSet}, string::String, @@ -23,8 +20,8 @@ use casper_types::{ EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Key, Parameter, PublicKey, URef, U256, }; +use cep47_logic::{CEP47Contract, CEP47Storage, TokenId, WithStorage, URI}; use core::convert::TryInto; -use logic::{CEP47Contract, CEP47Storage, TokenId, WithStorage, URI}; use std::{ collections::hash_map::DefaultHasher, hash::{Hash, Hasher}, diff --git a/cep47/src/logic_tests.rs b/cep47/src/logic_tests.rs deleted file mode 100644 index 0729cbe..0000000 --- a/cep47/src/logic_tests.rs +++ /dev/null @@ -1,543 +0,0 @@ -#[cfg(test)] -mod tests { - use casper_types::AccessRights; - use rand::Rng; - - use crate::{ - AsymmetricType, CEP47Contract, CEP47Storage, PublicKey, TokenId, URef, WithStorage, U256, - URI, - }; - use std::{ - collections::{hash_map::DefaultHasher, BTreeMap}, - hash::{Hash, Hasher}, - sync::Mutex, - }; - - struct TestStorage { - name: String, - symbol: String, - uri: URI, - paused: bool, - total_supply: U256, - tokens: BTreeMap>, - token_uris: BTreeMap, - balances: BTreeMap, - belongs_to: BTreeMap, - urefs: BTreeMap, - } - - impl TestStorage { - pub fn new() -> TestStorage { - TestStorage { - name: String::from("Casper Enhancement Proposal 47"), - symbol: String::from("CEP47"), - uri: URI::from("https://github.com/casper-ecosystem/casper-nft-cep47"), - paused: false, - total_supply: U256::from(0), - tokens: BTreeMap::new(), - balances: BTreeMap::new(), - belongs_to: BTreeMap::new(), - token_uris: BTreeMap::new(), - urefs: BTreeMap::new(), - } - } - } - - impl CEP47Storage for TestStorage { - fn name(&self) -> String { - self.name.clone() - } - - fn symbol(&self) -> String { - self.symbol.clone() - } - - fn uri(&self) -> URI { - self.uri.clone() - } - - fn balance_of(&self, owner: PublicKey) -> U256 { - let owner_balance = self.balances.get(&owner); - if owner_balance.is_none() { - U256::from(0) - } else { - owner_balance.unwrap().clone() - } - } - - fn onwer_of(&self, token_id: TokenId) -> Option { - let owner = self.belongs_to.get(&token_id); - if owner.is_some() { - Some(owner.unwrap().clone()) - } else { - None - } - } - - fn total_supply(&self) -> U256 { - self.total_supply - } - - fn token_uri(&self, token_id: TokenId) -> Option { - let uri = self.token_uris.get(&token_id); - if uri.is_some() { - Some(uri.unwrap().clone()) - } else { - None - } - } - - fn is_paused(&self) -> bool { - self.paused - } - - fn pause(&mut self) { - self.paused = true; - } - - fn unpause(&mut self) { - self.paused = false; - } - - fn get_tokens(&self, owner: PublicKey) -> Vec { - let owner_tokens = self.tokens.get(&owner); - if owner_tokens.is_none() { - Vec::::new() - } else { - owner_tokens.unwrap().clone() - } - } - - fn set_tokens(&mut self, owner: PublicKey, token_ids: Vec) { - let owner_new_balance = U256::from(token_ids.len() as u64); - - let owner_tokens = self.get_tokens(owner.clone()); - for token_id in owner_tokens.clone() { - self.belongs_to.remove(&token_id); - } - for token_id in token_ids.clone() { - self.belongs_to.insert(token_id, owner.clone()); - } - - self.tokens.insert(owner.clone(), token_ids.clone()); - self.balances.insert(owner, owner_new_balance); - } - - fn mint_many(&mut self, recipient: PublicKey, token_uris: Vec) { - let recipient_balance = self.balances.get(&recipient); - let recipient_tokens = self.tokens.get(&recipient); - let mut recipient_new_balance = if recipient_balance.is_none() { - U256::from(0) - } else { - recipient_balance.unwrap().clone() - }; - let mut recipient_new_tokens = if recipient_tokens.is_none() { - Vec::::new() - } else { - recipient_tokens.unwrap().clone() - }; - - let mut hasher = DefaultHasher::new(); - - for token_uri in token_uris.clone() { - let token_info = (self.uri.clone(), token_uri.clone()); - Hash::hash(&token_info, &mut hasher); - let token_id: TokenId = TokenId::from(hasher.finish().to_string()); - self.token_uris.insert(token_id.clone(), token_uri); - recipient_new_tokens.push(token_id.clone()); - self.belongs_to.insert(token_id, recipient.clone()); - recipient_new_balance = recipient_new_balance + 1; - self.total_supply = self.total_supply + 1; - } - self.balances - .insert(recipient.clone(), recipient_new_balance); - self.tokens.insert(recipient, recipient_new_tokens); - } - - fn mint_copies(&mut self, recipient: PublicKey, token_uri: URI, count: U256) { - let token_uris: Vec = vec![token_uri; count.as_usize()]; - self.mint_many(recipient, token_uris); - } - - fn burn_many(&mut self, owner: PublicKey, token_ids: Vec) { - let owner_tokens = self.tokens.get(&owner); - let owner_balance = self.balances.get(&owner); - let mut owner_new_balance = if owner_balance.is_none() { - U256::from(0) - } else { - owner_balance.unwrap().clone() - }; - let mut owner_new_tokens = if owner_tokens.is_none() { - Vec::::new() - } else { - owner_tokens.unwrap().clone() - }; - - for token_id in token_ids.clone() { - let index = owner_new_tokens - .iter() - .position(|x| *x == token_id.clone()) - .unwrap(); - owner_new_tokens.remove(index); - self.token_uris.remove(&token_id.clone()); - self.belongs_to.remove(&token_id.clone()); - owner_new_balance = owner_new_balance - 1; - self.total_supply = self.total_supply - 1; - } - self.balances.insert(owner.clone(), owner_new_balance); - self.tokens.insert(owner, owner_new_tokens); - } - - fn burn_one(&mut self, owner: PublicKey, token_id: TokenId) { - let owner_tokens = self.tokens.get(&owner); - let owner_balance = self.balances.get(&owner); - let owner_new_balance = if owner_balance.is_none() { - U256::from(0) - } else { - owner_balance.unwrap().clone() - }; - let mut owner_new_tokens = if owner_tokens.is_none() { - Vec::::new() - } else { - owner_tokens.unwrap().clone() - }; - let index = owner_new_tokens - .iter() - .position(|x| *x == token_id.clone()) - .unwrap(); - owner_new_tokens.remove(index); - self.token_uris.remove(&token_id.clone()); - self.belongs_to.remove(&token_id.clone()); - self.total_supply = self.total_supply - 1; - self.balances.insert(owner.clone(), owner_new_balance - 1); - self.tokens.insert(owner, owner_new_tokens); - } - - fn new_uref(&mut self, token_id: TokenId) -> Option { - let mut rng = rand::thread_rng(); - let val: [u8; 32] = rng.gen(); - let uref = URef::new(val, AccessRights::READ_ADD_WRITE); - if self.urefs.contains_key(&uref) { - None - } else { - self.urefs.insert(uref, token_id); - Some(uref) - } - } - - fn del_uref(&mut self, token_uref: URef) -> Option { - let token_id = self.token_id(token_uref); - if token_id.is_none() { - None - } else { - let token_id = token_id.unwrap(); - self.urefs.remove(&token_uref); - Some(token_id) - } - } - - fn token_id(&self, token_uref: URef) -> Option { - self.urefs.get(&token_uref).map(|x| x.clone()) - } - } - - struct TestContract { - storage: TestStorage, - } - - impl TestContract { - pub fn new() -> TestContract { - TestContract { - storage: TestStorage::new(), - } - } - } - - impl WithStorage for TestContract { - fn storage(&self) -> &TestStorage { - &self.storage - } - - fn storage_mut(&mut self) -> &mut TestStorage { - &mut self.storage - } - } - - impl CEP47Contract for TestContract {} - - #[test] - fn test_metadata() { - let contract = TestContract::new(); - assert_eq!( - contract.name(), - String::from("Casper Enhancement Proposal 47") - ); - assert_eq!(contract.symbol(), String::from("CEP47")); - assert_eq!( - contract.uri(), - String::from("https://github.com/casper-ecosystem/casper-nft-cep47") - ); - } - #[test] - fn test_mint_many() { - let mut contract = TestContract::new(); - let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); - let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); - - assert_eq!(contract.total_supply(), U256::from(0)); - contract.mint_many(ali.clone(), vec![URI::from("Apple URI")]); - contract.mint_many( - bob.clone(), - vec![URI::from("Banana URI"), URI::from("Orange URI")], - ); - assert_eq!(contract.total_supply(), U256::from(3)); - - let ali_balance = contract.balance_of(ali.clone()); - assert_eq!(ali_balance, U256::from(1)); - let bob_balance = contract.balance_of(bob.clone()); - assert_eq!(bob_balance, U256::from(2)); - - let ali_tokens: Vec = contract.tokens(ali); - let ali_first_token_uri: URI = contract - .token_uri(ali_tokens.get(0).unwrap().clone()) - .unwrap(); - assert_eq!(ali_first_token_uri, URI::from("Apple URI")); - - let bob_tokens: Vec = contract.tokens(bob); - let bob_first_token_uri: URI = contract - .token_uri(bob_tokens.get(1).unwrap().clone()) - .unwrap(); - assert_eq!(bob_first_token_uri, URI::from("Orange URI")); - } - #[test] - fn test_mint_copies() { - let mut contract = TestContract::new(); - let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); - - assert_eq!(contract.total_supply(), U256::from(0)); - contract.mint_copies(ali.clone(), URI::from("Casper Fan URI"), U256::from(7)); - assert_eq!(contract.total_supply(), U256::from(7)); - - let ali_balance = contract.balance_of(ali.clone()); - assert_eq!(ali_balance, U256::from(7)); - - let ali_tokens: Vec = contract.tokens(ali); - let ali_first_token_uri: URI = contract - .token_uri(ali_tokens.get(0).unwrap().clone()) - .unwrap(); - let ali_third_token_uri: URI = contract - .token_uri(ali_tokens.get(2).unwrap().clone()) - .unwrap(); - assert_eq!(ali_first_token_uri, URI::from("Casper Fan URI")); - assert_eq!(ali_third_token_uri, URI::from("Casper Fan URI")); - } - #[test] - fn test_burn_many() { - let mut contract = TestContract::new(); - let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); - - assert_eq!(contract.total_supply(), U256::from(0)); - contract.mint_many( - ali.clone(), - vec![ - URI::from("Banana URI"), - URI::from("Orange URI"), - URI::from("Apple URI"), - URI::from("Grape URI"), - ], - ); - assert_eq!(contract.total_supply(), U256::from(4)); - - let mut ali_balance = contract.balance_of(ali.clone()); - assert_eq!(ali_balance, U256::from(4)); - - let mut ali_tokens: Vec = contract.tokens(ali.clone()); - contract.burn_many( - ali.clone(), - vec![ - ali_tokens.get(0).unwrap().clone(), - ali_tokens.get(3).unwrap().clone(), - ], - ); - let mut ali_first_token_uri = contract.token_uri(ali_tokens.first().unwrap().clone()); - assert_eq!(ali_first_token_uri, None); - let mut ali_last_token_uri = contract.token_uri(ali_tokens.last().unwrap().clone()); - assert_eq!(ali_first_token_uri, None); - assert_eq!(ali_last_token_uri, None); - - ali_tokens = contract.tokens(ali.clone()); - ali_first_token_uri = contract.token_uri(ali_tokens.first().unwrap().clone()); - ali_last_token_uri = contract.token_uri(ali_tokens.last().unwrap().clone()); - assert_eq!(ali_first_token_uri, Some(URI::from("Orange URI"))); - assert_eq!(ali_last_token_uri, Some(URI::from("Apple URI"))); - - assert_eq!(contract.total_supply(), U256::from(2)); - ali_balance = contract.balance_of(ali); - assert_eq!(ali_balance, U256::from(2)); - } - #[test] - fn test_burn_one() { - let mut contract = TestContract::new(); - let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); - - assert_eq!(contract.total_supply(), U256::from(0)); - contract.mint_many( - ali.clone(), - vec![URI::from("Banana URI"), URI::from("Orange URI")], - ); - assert_eq!(contract.total_supply(), U256::from(2)); - - let mut ali_balance = contract.balance_of(ali.clone()); - assert_eq!(ali_balance, U256::from(2)); - - let mut ali_tokens: Vec = contract.tokens(ali.clone()); - contract.burn_one(ali.clone(), ali_tokens.get(0).unwrap().clone()); - let mut ali_first_token_uri = contract.token_uri(ali_tokens.get(0).unwrap().clone()); - assert_eq!(ali_first_token_uri, None); - - ali_tokens = contract.tokens(ali.clone()); - ali_first_token_uri = contract.token_uri(ali_tokens.get(0).unwrap().clone()); - assert_eq!(ali_first_token_uri, Some(URI::from("Orange URI"))); - - assert_eq!(contract.total_supply(), U256::from(1)); - ali_balance = contract.balance_of(ali); - assert_eq!(ali_balance, U256::from(1)); - } - #[test] - fn test_transfer_token() { - let mut contract = TestContract::new(); - let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); - let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); - - assert_eq!(contract.total_supply(), U256::from(0)); - contract.mint_one(ali.clone(), URI::from("Casper Fan URI")); - assert_eq!(contract.total_supply(), U256::from(1)); - - let mut ali_balance = contract.balance_of(ali.clone()); - let mut bob_balance = contract.balance_of(bob.clone()); - assert_eq!(ali_balance, U256::from(1)); - assert_eq!(bob_balance, U256::from(0)); - - let ali_tokens: Vec = contract.tokens(ali.clone()); - let ali_first_token_id: TokenId = ali_tokens.get(0).unwrap().clone(); - let ali_first_token_uri: URI = contract.token_uri(ali_first_token_id.clone()).unwrap(); - assert_eq!(ali_first_token_uri, URI::from("Casper Fan URI")); - - let transfer_res = - contract.transfer_token(ali.clone(), bob.clone(), ali_first_token_id.clone()); - assert!(transfer_res.is_ok()); - ali_balance = contract.balance_of(ali); - bob_balance = contract.balance_of(bob.clone()); - assert_eq!(ali_balance, U256::from(0)); - assert_eq!(bob_balance, U256::from(1)); - - let owner_of_first_token_id = contract.owner_of(ali_first_token_id); - assert_eq!(owner_of_first_token_id.unwrap(), bob); - } - #[test] - fn test_transfer_all_tokens() { - let mut contract = TestContract::new(); - let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); - let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); - - assert_eq!(contract.total_supply(), U256::from(0)); - contract.mint_many( - ali.clone(), - vec![URI::from("Apple URI"), URI::from("Banana URI")], - ); - contract.mint_one(ali.clone(), URI::from("Casper Fan URI")); - assert_eq!(contract.total_supply(), U256::from(3)); - - let mut ali_balance = contract.balance_of(ali.clone()); - let mut bob_balance = contract.balance_of(bob.clone()); - assert_eq!(ali_balance, U256::from(3)); - assert_eq!(bob_balance, U256::from(0)); - - let ali_tokens: Vec = contract.tokens(ali.clone()); - let ali_second_token_id: TokenId = ali_tokens.get(1).unwrap().clone(); - let ali_second_token_uri: URI = contract.token_uri(ali_second_token_id.clone()).unwrap(); - assert_eq!(ali_second_token_uri, URI::from("Banana URI")); - - let transfer_res = contract.transfer_all_tokens(ali.clone(), bob.clone()); - assert!(transfer_res.is_ok()); - - ali_balance = contract.balance_of(ali); - bob_balance = contract.balance_of(bob.clone()); - assert_eq!(ali_balance, U256::from(0)); - assert_eq!(bob_balance, U256::from(3)); - - let owner_of_second_token_id = contract.owner_of(ali_second_token_id); - assert_eq!(owner_of_second_token_id.unwrap(), bob); - } - - #[test] - fn test_transfer_many_tokens() { - let mut contract = TestContract::new(); - let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); - let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); - - assert_eq!(contract.total_supply(), U256::from(0)); - contract.mint_many( - ali.clone(), - vec![URI::from("Apple URI"), URI::from("Banana URI")], - ); - contract.mint_copies(ali.clone(), URI::from("Casper Fan URI"), U256::from(3)); - assert_eq!(contract.total_supply(), U256::from(5)); - - let mut ali_balance = contract.balance_of(ali.clone()); - let mut bob_balance = contract.balance_of(bob.clone()); - assert_eq!(ali_balance, U256::from(5)); - assert_eq!(bob_balance, U256::from(0)); - - let ali_tokens: Vec = contract.tokens(ali.clone()); - let ali_second_token_id: TokenId = ali_tokens.get(1).unwrap().clone(); - let ali_second_token_uri: URI = contract.token_uri(ali_second_token_id.clone()).unwrap(); - let ali_third_token_id: TokenId = ali_tokens.get(2).unwrap().clone(); - let ali_third_token_uri: URI = contract.token_uri(ali_third_token_id.clone()).unwrap(); - assert_eq!(ali_second_token_uri, URI::from("Banana URI")); - assert_eq!(ali_third_token_uri, URI::from("Casper Fan URI")); - - let transfer_res = contract.transfer_many_tokens( - ali.clone(), - bob.clone(), - vec![ali_second_token_id.clone(), ali_third_token_id.clone()], - ); - assert!(transfer_res.is_ok()); - - ali_balance = contract.balance_of(ali); - bob_balance = contract.balance_of(bob.clone()); - assert_eq!(ali_balance, U256::from(3)); - assert_eq!(bob_balance, U256::from(2)); - - let owner_of_second_token_id = contract.owner_of(ali_second_token_id); - let owner_of_third_token_id = contract.owner_of(ali_third_token_id); - assert_eq!(owner_of_second_token_id.unwrap(), bob); - assert_eq!(owner_of_third_token_id.unwrap(), bob); - } - - #[test] - fn test_attach_and_detach() { - let mut contract = TestContract::new(); - let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); - let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); - - contract.mint_one(ali.clone(), URI::from("0x12af")); - let token_id: TokenId = contract.tokens(ali.clone())[0].clone(); - - let token_uref: URef = contract.detach(ali.clone(), token_id.clone()).unwrap(); - assert_eq!(contract.balance_of(ali.clone()), U256::zero()); - assert_eq!(contract.total_supply(), U256::one()); - assert!(contract.tokens(ali).is_empty()); - - assert_eq!(contract.token_id(token_uref.clone()), token_id.clone()); - assert_eq!( - contract.token_uri(token_id.clone()).unwrap(), - URI::from("0x12af") - ); - - contract.attach(token_uref, bob.clone()); - assert_eq!(contract.balance_of(bob.clone()), U256::one()); - assert_eq!(contract.total_supply(), U256::one()); - assert_eq!(contract.tokens(bob), vec![token_id]); - } -} diff --git a/tests/Cargo.toml b/dragons-nft-tests/Cargo.toml similarity index 93% rename from tests/Cargo.toml rename to dragons-nft-tests/Cargo.toml index 7969a10..b3ee76a 100644 --- a/tests/Cargo.toml +++ b/dragons-nft-tests/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "tests" +name = "dragons-nft-tests" version = "0.1.0" authors = ["astro019 "] edition = "2018" diff --git a/tests/src/cep47.rs b/dragons-nft-tests/src/cep47.rs similarity index 100% rename from tests/src/cep47.rs rename to dragons-nft-tests/src/cep47.rs diff --git a/tests/src/contract_tests.rs b/dragons-nft-tests/src/contract_tests.rs similarity index 100% rename from tests/src/contract_tests.rs rename to dragons-nft-tests/src/contract_tests.rs diff --git a/tests/src/lib.rs b/dragons-nft-tests/src/lib.rs similarity index 100% rename from tests/src/lib.rs rename to dragons-nft-tests/src/lib.rs diff --git a/tests/src/market.rs b/dragons-nft-tests/src/market.rs similarity index 100% rename from tests/src/market.rs rename to dragons-nft-tests/src/market.rs diff --git a/tests/wasm/.gitkeep b/dragons-nft-tests/wasm/.gitkeep similarity index 100% rename from tests/wasm/.gitkeep rename to dragons-nft-tests/wasm/.gitkeep diff --git a/dragons-nft-tests/wasm/dragons-nft.wasm b/dragons-nft-tests/wasm/dragons-nft.wasm new file mode 100755 index 0000000000000000000000000000000000000000..8be51e6fe2dd21dec6599fe7d422bcf6f99c5c71 GIT binary patch literal 338879 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 RLHh(rO6>=f^MLa2`=2_^hI0S_ literal 0 HcmV?d00001 diff --git a/dragons-nft/Cargo.toml b/dragons-nft/Cargo.toml index 9e0d58f..8a2c3ea 100644 --- a/dragons-nft/Cargo.toml +++ b/dragons-nft/Cargo.toml @@ -4,11 +4,9 @@ version = "0.1.0" authors = ["astro019 "] edition = "2018" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] -contract = { package="casper-contract", version = "1.2.0" } -types = { package="casper-types", version = "1.2.0" } +casper-contract = "1.2.0" +casper-types = "1.2.0" cep47 = { path="../cep47", features = ["no_owner_of"]} [[bin]] @@ -19,4 +17,5 @@ doctest = false test = false [features] -default = ["contract/std", "types/std"] +default = ["casper-contract/std", "casper-types/std"] + diff --git a/dragons-nft/src/main.rs b/dragons-nft/src/main.rs index 4c01b0f..8628114 100644 --- a/dragons-nft/src/main.rs +++ b/dragons-nft/src/main.rs @@ -1,17 +1,19 @@ #![no_main] +use casper_contract::contract_api::runtime::get_named_arg; +use casper_contract::contract_api::storage::create_contract_package_at_hash; + #[no_mangle] pub extern "C" fn owner_of() {} #[no_mangle] pub extern "C" fn call() { - let (contract_package_hash, _) = - contract::contract_api::storage::create_contract_package_at_hash(); + let (contract_package_hash, _) = create_contract_package_at_hash(); let entry_points = cep47::get_entrypoints(None); cep47::deploy( - &contract::contract_api::runtime::get_named_arg::("token_name"), - &contract::contract_api::runtime::get_named_arg::("token_symbol"), - &contract::contract_api::runtime::get_named_arg::("token_uri"), + &get_named_arg::("token_name"), + &get_named_arg::("token_symbol"), + &get_named_arg::("token_uri"), entry_points, contract_package_hash, false, diff --git a/marketplace/Cargo.toml b/marketplace/Cargo.toml deleted file mode 100644 index ccb5ed2..0000000 --- a/marketplace/Cargo.toml +++ /dev/null @@ -1,26 +0,0 @@ -[package] -name = "marketplace" -version = "0.1.0" -authors = ["deusz "] -edition = "2018" - -[dependencies] -contract = { package = "casper-contract", version="1.2.0" } -types = { package = "casper-types", version="1.2.0" } - -[[bin]] -name = "marketplace" -path = "src/main.rs" -bench = false -doctest = false -test = false - -[[bin]] -name = "send_tokens" -path = "src/send_tokens.rs" -bench = false -doctest = false -test = false - -[features] -default = ["contract/std", "types/std"] diff --git a/marketplace/src/lib.rs b/marketplace/src/lib.rs deleted file mode 100644 index 2629b6e..0000000 --- a/marketplace/src/lib.rs +++ /dev/null @@ -1,228 +0,0 @@ -#![allow(unused_imports)] -#![allow(unused_parens)] -#![allow(non_snake_case)] - -extern crate alloc; - -pub mod offer; - -use alloc::{ - collections::{BTreeMap, BTreeSet}, - string::String, -}; -use contract::contract_api::runtime::revert; -use contract::{ - contract_api::{account, runtime, storage, system}, - unwrap_or_revert::UnwrapOrRevert, -}; -use core::convert::TryInto; -use offer::Offer; -use std::{ - collections::hash_map::DefaultHasher, - hash::{Hash, Hasher}, -}; -use types::bytesrepr::Error; -use types::{ - account::AccountHash, - bytesrepr::{FromBytes, ToBytes}, - contracts::NamedKeys, - AccessRights, ApiError, AsymmetricType, CLType, CLTyped, CLValue, ContractPackageHash, - EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Key, Parameter, PublicKey, URef, - U256, U512, -}; - -#[no_mangle] -pub extern "C" fn put_on_sale_test() { - let sel = runtime::get_named_arg("seller"); - let offer = Offer::test_struct(sel); - let rets = offer.store(); - ret(rets) -} - -#[no_mangle] -pub extern "C" fn test_buy() { - let offer_key: String = - "018a88e3dd7409f195fd52db2d3cba5d72ca6709bf1d94121bf3748801b40f6f5c_test_order".to_string(); - let purse: URef = runtime::get_named_arg("purse"); - let offer: Offer = Offer::load(&offer_key); - if system::get_purse_balance(purse).unwrap_or_revert() == offer.price - && runtime::get_caller() != offer.seller.to_account_hash() - { - system::transfer_from_purse_to_account( - purse, - offer.seller.to_account_hash(), - system::get_purse_balance(purse).unwrap_or_revert(), - None, - ) - .unwrap_or_revert(); - remove_key(&offer_key); - } -} - -#[no_mangle] -pub extern "C" fn put_on_sale() { - let offer = Offer::new( - runtime::get_named_arg("seller"), - runtime::get_named_arg("price"), - runtime::get_named_arg("item"), - runtime::get_named_arg("designation"), - ); - ret(offer.store()) -} - -#[no_mangle] -pub extern "C" fn buy() { - let offer_key: String = runtime::get_named_arg("offer_key"); - let payment: U512 = runtime::get_named_arg("payment"); - let offer: Offer = Offer::load(&offer_key); - if payment == offer.price && runtime::get_caller() != offer.seller.to_account_hash() { - system::transfer_to_account(offer.seller.to_account_hash(), payment, None) - .unwrap_or_revert(); - remove_key(&offer_key); - ret(offer.item) - } -} - -#[no_mangle] -pub extern "C" fn get_price() { - let offer_key: String = runtime::get_named_arg("offer_key"); - let offer: Offer = Offer::load(&offer_key); - ret(offer.price) -} - -#[no_mangle] -pub extern "C" fn cancel() { - let offer_key: String = runtime::get_named_arg("offer_key"); - let offer: Offer = Offer::load(&offer_key); - if runtime::get_caller() == offer.seller.to_account_hash() { - remove_key(&offer_key); - } -} - -pub fn get_entrypoints(package_hash: Option) -> EntryPoints { - let _secure = if let Some(contract_package_hash) = package_hash { - let deployer_group = storage::create_contract_user_group( - contract_package_hash, - "deployer", - 1, - BTreeSet::default(), - ) - .unwrap_or_revert(); - runtime::put_key("deployer_access", types::Key::URef(deployer_group[0])); - true - } else { - false - }; - - let mut entry_points = EntryPoints::new(); - entry_points.add_entry_point(endpoint( - "put_on_sale", - vec![ - Parameter::new("seller", CLType::PublicKey), - Parameter::new("designation", CLType::String), - Parameter::new("item", CLType::URef), - Parameter::new("price", CLType::U512), - ], - CLType::String, - None, - )); - entry_points.add_entry_point(endpoint( - "put_on_sale_test", - vec![Parameter::new("seller", CLType::PublicKey)], - CLType::String, - None, - )); - entry_points.add_entry_point(endpoint( - "buy", - vec![ - Parameter::new("offer_key", CLType::String), - Parameter::new("payment", CLType::U512), - ], - CLType::URef, - None, - )); - entry_points.add_entry_point(endpoint( - "test_buy", - vec![Parameter::new("payment", CLType::U512)], - CLType::URef, - None, - )); - entry_points.add_entry_point(endpoint( - "cancel", - vec![Parameter::new("offer_key", CLType::String)], - CLType::Unit, - None, - )); - entry_points.add_entry_point(endpoint( - "get_price", - vec![Parameter::new("offer_key", CLType::String)], - CLType::U512, - None, - )); - - entry_points -} - -pub fn deploy(entry_points: EntryPoints, contract_package_hash: ContractPackageHash) { - let named_keys = NamedKeys::new(); - // named_keys.insert("name".to_string(), storage::new_uref(token_name).into()); - - let (contract_hash, _) = - storage::add_contract_version(contract_package_hash, entry_points, named_keys); - runtime::put_key("marketplace_contract_hash", contract_hash.into()); - let contract_hash_pack = storage::new_uref(contract_hash); - runtime::put_key( - "marketplace_contract_package_hash", - contract_hash_pack.into(), - ); -} - -fn ret(value: T) { - runtime::ret(CLValue::from_t(value).unwrap_or_revert()) -} - -fn get_key(name: &str) -> Option { - match runtime::get_key(name) { - None => None, - Some(value) => { - let key = value.try_into().unwrap_or_revert(); - let value = storage::read(key).unwrap_or_revert().unwrap_or_revert(); - Some(value) - } - } -} - -fn set_key(name: &str, value: T) { - match runtime::get_key(name) { - Some(key) => { - let key_ref = key.try_into().unwrap_or_revert(); - storage::write(key_ref, value); - } - None => { - let key = storage::new_uref(value).into(); - runtime::put_key(name, key); - } - } -} - -fn remove_key(name: &str) { - match runtime::get_key(name) { - Some(_) => { - runtime::remove_key(name); - } - None => {} - } -} - -fn endpoint(name: &str, param: Vec, ret: CLType, access: Option<&str>) -> EntryPoint { - EntryPoint::new( - String::from(name), - param, - ret, - match access { - None => EntryPointAccess::Public, - Some(access_key) => EntryPointAccess::groups(&[access_key]), - }, - EntryPointType::Contract, - ) -} diff --git a/marketplace/src/main.rs b/marketplace/src/main.rs deleted file mode 100644 index f64792d..0000000 --- a/marketplace/src/main.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![no_main] -extern crate marketplace; - -#[no_mangle] -pub extern "C" fn call() { - let (contract_package_hash, _) = - contract::contract_api::storage::create_contract_package_at_hash(); - let entry_points = marketplace::get_entrypoints(None); - marketplace::deploy(entry_points, contract_package_hash); -} diff --git a/marketplace/src/offer.rs b/marketplace/src/offer.rs deleted file mode 100644 index b5bc03d..0000000 --- a/marketplace/src/offer.rs +++ /dev/null @@ -1,111 +0,0 @@ -use crate::{get_key, remove_key, set_key}; -use alloc::{ - collections::{BTreeMap, BTreeSet}, - string::String, -}; -use contract::contract_api::runtime::revert; -use contract::{ - contract_api::{runtime, storage, system}, - unwrap_or_revert::UnwrapOrRevert, -}; -use core::convert::TryInto; -use std::{ - collections::hash_map::DefaultHasher, - hash::{Hash, Hasher}, -}; -use types::bytesrepr::Error; -use types::{ - account::AccountHash, - bytesrepr::{FromBytes, ToBytes}, - contracts::NamedKeys, - AccessRights, ApiError, AsymmetricType, CLType, CLTyped, CLValue, ContractPackageHash, - EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Key, Parameter, PublicKey, URef, - U256, U512, -}; - -#[derive(Clone)] -pub struct Offer { - pub seller: PublicKey, - pub price: U512, - pub item: URef, - pub designation: String, -} - -impl ToBytes for Offer { - /// Serializes `&self` to a `Vec`. - fn to_bytes(&self) -> Result, Error> { - let mut ret = Vec::new(); - ret.extend(self.seller.to_bytes().unwrap()); - ret.extend(self.price.to_bytes().unwrap()); - ret.extend(self.item.to_bytes().unwrap()); - ret.extend(self.designation.to_bytes().unwrap()); - Ok(ret) - } - /// Consumes `self` and serializes to a `Vec`. - fn into_bytes(self) -> Result, Error> - where - Self: Sized, - { - self.to_bytes() - } - fn serialized_length(&self) -> usize { - self.seller.serialized_length() - + self.price.serialized_length() - + self.item.serialized_length() - + self.designation.serialized_length() - } -} - -impl FromBytes for Offer { - /// Deserializes the slice into `Self`. - fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), Error> { - let pk = PublicKey::from_bytes(&bytes[0..33]).unwrap().0; - let price = U512::from_bytes(&bytes[33..36]).unwrap().0; - let uref = URef::from_bytes(&bytes[36..69]).unwrap().0; - let name = String::from_bytes(&bytes[69..]).unwrap().0; - Ok((Offer::new(pk, price, uref, name), &[])) - } - /// Deserializes the `Vec` into `Self`. - fn from_vec(bytes: Vec) -> Result<(Self, Vec), Error> { - Self::from_bytes(bytes.as_slice()).map(|(x, remainder)| (x, Vec::from(remainder))) - } -} - -impl CLTyped for Offer { - fn cl_type() -> CLType { - CLType::Any - } -} - -impl Offer { - pub fn new(seller: PublicKey, price: U512, item: URef, designation: String) -> Self { - Self { - seller, - price, - item, - designation, - } - } - - pub fn store(&self) -> String { - let key = self.offer_key(""); - set_key(&key, self.clone()); - key - } - - pub fn load(key: &str) -> Offer { - get_key(key).unwrap_or_revert() - } - pub fn offer_key(&self, flag: &str) -> String { - format!("{}_{}{}", self.seller.to_hex(), self.designation, flag) - } - - pub fn test_struct(seller: PublicKey) -> Self { - Self { - seller: seller, - price: U512::from(1000), - item: storage::new_uref("test"), - designation: "test_order".to_string(), - } - } -} diff --git a/marketplace/src/send_tokens.rs b/marketplace/src/send_tokens.rs deleted file mode 100644 index b1ec9c6..0000000 --- a/marketplace/src/send_tokens.rs +++ /dev/null @@ -1,35 +0,0 @@ -#![no_main] - -use contract::contract_api::{account, runtime, system}; -use types::{runtime_args, ContractHash, RuntimeArgs, U512}; - -#[no_mangle] -pub extern "C" fn call() { - // let seller: PublicKey = runtime::get_named_arg("seller"); - let marketplace_contract: ContractHash = runtime::get_named_arg("marketplace_contract"); - - let transport_purse = system::create_purse(); - system::transfer_from_purse_to_purse( - account::get_main_purse(), - transport_purse, - U512::from(1000u128), - None, - ) - .unwrap(); - - // let offer_key: String = runtime::call_contract( - // marketplace_contract, - // "put_on_sale_test", - // runtime_args! { - // "seller" => seller, - // }, - // ); - let _: () = runtime::call_contract( - marketplace_contract, - "test_buy", - runtime_args! { - // "offer_key" => offer_key, - "purse" => transport_purse - }, - ); -} diff --git a/rust-toolchain b/rust-toolchain new file mode 100644 index 0000000..cfafc52 --- /dev/null +++ b/rust-toolchain @@ -0,0 +1 @@ +nightly-2020-12-16 \ No newline at end of file From 46d11ff300a59951a0425d599b1d298b9c2c7532 Mon Sep 17 00:00:00 2001 From: Maciej Zielinski Date: Tue, 6 Jul 2021 13:40:49 +0200 Subject: [PATCH 38/98] Remove dragons-nft.wasm --- dragons-nft-tests/wasm/dragons-nft.wasm | Bin 338879 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100755 dragons-nft-tests/wasm/dragons-nft.wasm diff --git a/dragons-nft-tests/wasm/dragons-nft.wasm b/dragons-nft-tests/wasm/dragons-nft.wasm deleted file mode 100755 index 8be51e6fe2dd21dec6599fe7d422bcf6f99c5c71..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 338879 zcmdqKdAwZ5b>G>yyWjpE&{&9t0Lj};EDs<+09*iY6LFseE+Q=}AA3H@UqjInZ0S)V zMG%tZeM->PMxY-xAOQi@5?HcO7@qwzN32aV&xsR zix)3u7nSDUc^>@#c*+EtvS$)?C0zN6djL4=ORHo?Zl&TYRA}*8o`F}Nb-CHII3hu%&FXgS1I@Y$KUzHD{%9S#jyomCC}!O7ZgFNPcI& zP~AQKzH{$;>ioA=D|HP<<=dv8`L_3c(^K!QJX`y~`S(;VW%J+k_Yp^1@?JJ$bJ3z1f_l-}m^F-&Xm)Y{4Gh`PBR0bMBeS z_h)n8^nvqFK4y8J&SvdFm3}DOgpNG<408RLA+7vywmm{r+<~8|{7AMf!qJid{u|l! z;}`IBWeblz z_U?0!zyGmsdij5r{u};I*1CD$7qXwp zem47j_Vd~NmwtZfm$Jo5Udgk@^Or7Nsx0`2U-_^e=E-S%m%%OBH)zAk=heK{_@w21 z$6Pjhv3jQbFRvDJ4=+{nT3&5fORefsR#Y}G6qP2`ir@UoUwUMzUNlH9tQH@7TE7qP zX=Zt)SX*t?m#dZ56yWA`(&SW8d-^PGR*Da;HfQqbJo|dJxm@l2jVqTbIgr)X>;p?x zfj(~_o@)8*az1Y_w^(zCtFDovl2=c|%eZPH!pGz8ic&RSF1+q6k0@5^oS*YaAV zk&&rsbQZI#^e^^C{euL=#&z@Ar|CF76N$!rN1~%jEQ8@sG{ws~<99{lva31g##axE zFmU!kD4i{~BN#xox2k(qB?>i-Gn7>q1fGR#uq=wrC#$ofmny6L(^$=`dz#ZVdfuD@ zRjpMeqc!c?fHq1rr}OG^wb86Cf|*`*p)Xn$`}y-Pm-OE2r?c!N$?OWlDJyTE!ibdBaQnQw-s(I_n zqHAcDlCGT}^z9(}A5=T`EH+eg=@z`tYme+{{JJFTdNkG4Qv_A>xs%mhu0M@dO=@Ep zP&kpg%NV)cXNY+=mOhVa3q?cfThFD68%4cF0VnFDB>Av3h&qr`)RPwGOUaubmpoIc zTH{yMi&iFDGj*?6D?ViS8O7SudlR$@^!w? zo;3~btQ1UWjQ^J6llpD^pv(G3n!DMm6*<;qpC#$$_Ei%>QdfS6;wO=?+Ddi`JHiN` ztnTFp;4Xe@#jaI}9plvatZVeM8LgVKL+0C-7^`L#UBM$j*t~KvIMN|{a(1aoce2J` zS7lT6>KPk5%=5%-p(+rw#&^3K@OUW`Ptf)vYtojfrG6FwBU*K7s!zjBWL$+S3xBni zO()&2`tD;Ru{*8X?CrsW9;>WR?kQqr=`L(w96cTJzrI6+z;z4 zo!c&*qBGOY8RJ1-N1&*W!EV;+?Q~)0Q0-C>rC-2IVhWi6m`>0wXaCMS;XO{t2Kwv(zjkR3W{1Q3P7a#${ol$JHWVbzEhN8JYy%?%Mjn4^z1Koc?Y6 zh@$C<^%VA(Y5aR=QeCTs%zY-NIbv!8 zd$PK0fI5JjQuHc{?thrd=7L0|BozCc$WXj?cZK>Z;JtLIeyRo@se&5f2L$?Q1UVOL zG&^X(m14}DY-91g(VdZ(@W`Il>{*lIDajN6)HR1KZZX}i;4(}>XVcnfH0Sc!<~*`j z%j<9h(_tj>P}kV3>L{iVqJt)^RWFWpCytwHS*40FX9#x_0mB8Fligg9)%>Wq z`XKc1grT941*cA?{o6sz2sA*^Fcf9eHjjj+F_9OV8O`E|nBNhbm4>NVBs*))__<0( zWkxKVa~8gK0n17$KSa>A#YVfbRL|#&i}*`u3N+-a%{tJpmq-K?DrG}jh1RI{42r}NpbL#V8eQ%u}qmtp50%=B2*CC0DPtYds+ zab&@cd$r8#3*ViUYImjbL~F{M!71t8Vm>AD#!c09yqzB#`6=n1Y2j3H?`rWe$&0jb zN?N!VmVEO2uL!b>F9!O+At0Gh@nlu&z=RYURyNncq-kSaI0KAL@oafpYedJ@U#ZY8r|=Eh|@O zc93?d$EY_gBJR%gDE@cV&}3Eq<_gNl$Wdvts&#F?*?~F|{L9X`RjXwDp6<%MK@dPh|!z$EIxMOTt zvL~2##n@6*%_&lGhWhS`WJN8}OD!TCJ2nV@Mze*$ zUns2>1|rCN7~QYhiJ|ccE=)7C&hJCZFI8~HpG$0IqGgDFbf2VF!9}T#xhU0@np~7> z@#06!IL?yv{)_l8F3VynCEsLODR~xEiSST$f_2=CoZN{e$r?Y6gHTymDS6RId0_?| zmdJoti{E#ikyzusdT4F@oLZ6f&TFWbkYR6mCYpt1;FMnzDsZadq&%XS7mFMt7TC*$v{*PW6{rG49bl1_cNL+4Z zYporYd`AmpJ888`tGm?dZXVh^T(5^cR;baMUu*4M`QgErf9Fe|_}!0u>Y|~zVdWQp z>nA=lc<~Q^_7~~WjrnfFaZ|q6>g;OmU2Em}4c4WmRcHzK74_#b?cc2S_X%_ zmDUYwtpm@k{FCQ?;NSi6KmO!*{1eB!gDdUt`u{%tmEZjG$Nr$Q)>_W@8KOh^0jo6I zIm#Tfrk?4j18iXAhA{ENUG&$s8-SzFiTxwZ9n)y&mVvJd77MWXT8>QSVmCEgv;^z;|8nd$J%TY-0#aSMqxp?Ff&v9M zihB$~Gj^5%JDlHW{h-jA*l3y7&%vX-L;hv>QM z=T4*ca1Om|t(K?_2w@z;%)j*ZR`SCbLkP0h6hp0_JM&{=2OJ8+O9}L=83fPD9S37F zvWWan-_Kk_axi5tdbcyrtsjglndx}mYC?DGF2?mo?Ao6I@GG4P)k3{ z@jSSegOGoXeW*+5sr6!~7;61I?bl{{qPEA<&J9H{dmF$WTdIC&_b>uDcMUV z!eE(gOTr=b<>BXe;u`ztFU9JWa5|cpemo zVENd1np~#+JYI5I)&@zjA+vt2A5Zk}s^dxH*D{{i8Z4dfr_;|@8Be5-@uasWkh)|% zjmj{d*gvrYT?leZKVW$@n3Kj68F}^b#DH9NJQ0>_8BbZ(Ya34li1B3f){Q6fTu1y)jVHSE>f;H*tB$7`jEVMkOh2V{*EXJvB;yIq>&DZlyy|!|URNE@Fk}<; zlkvLhc*6c`8Be6{8pjg}XFO?k-FTYzT~$Ak+pCTzI{)h9iMm{MJn6u-=qK#D#_@z2 z#uG7FH=c}eX>TX$r-@!_ht}C!ll)h+xAgO>;|ZIuWjx{aHI66J<*e?y@kE|qLqCy( ztB$A1b?E1MdmEJ3<`pbC|1bR^=1(&iudSc3;~K|Pmf7Z^b>j)AUSm9wfvf6g7_y1_ zNk6YTo(RLWjHj&Vwb@(bmhm)oh_i|uGcy!d)lbIjs^e*r|7zoD(-xVpHlB#twdg0j zyvFfl+!#+YZ)5YPN!?ZLEi!Y}@ie&({k%nt5AJ5-EWMgP1d}v@ct=NW%Hil!GH01A zg|^X&(#0bal`Cx=H7(QmiHz!P`ItwA;2;q;{~w&}Nufek0#aSMbsBD>86@Jc2n|j~ z5EpO6aQfxPACLa;Z6;t4WaG`a`b^P^H)9QvzRA`KTE8$JPytiWk)yEZkOptut3g0u z0lXLc67Lj-ngW@29hQGe&9Nm1JdG-57;d2jw}wQPO!AlGiU+nH5!+agSf(jf=;skK z(=iF_6*CZYV5bN-UrfD|R+;Wo9qL+QL%Dt=lOc)%fLSI?TF%{gmSe(rqDUvOh48KEd(kxUF4>3(8mEkn zaN?Gz{!otcLKc(D#pl4K(8w&C50Kr zF8YIAZE0L+0jnY&2Trw2`dX3@D!WWcl{Z#07(|jzgxJNH03w>k9GcI)wg`dx<7Gl* zg_fj3x+hg^nGsiAj6~c;RhrTkPp?S#^Mm!~7)1i7X4i6-yG?`? zi4N>yWLsfmWyyexNh-L$ggo6Iu@Ah7GWB3oQq@8&Bdq zYq^w^A0q@XCiOZ*D8DXWuud${WBPfWy1(5dm=Y~zLaHmml3c+(?4mJ{qC2s2=nUM2 z=cYR`vY>uaj>_bZTRII00@h-dh=V$-K|K(y3YZyj>7%nq7@3{rc#>%??_llZ;BGu` z5qY=39;gahhFROB@!h1zCsa-oi^Ci-L2b&3Xu>#3a0I{_bwMmLW zXNk`S+LrPe%bJl2E-@RY-fJZow^Z?Z{&Y8 z{gv$LP0I(fYOOvsJu^Euzp%KpX>()C)@|Fb+p%-k?(6sLz2QcD1rCtzKTtVH7mCIQ zwTXG2^CngPID%Ew`J3Wzn!g$TX8D`rZ=Sye{ucRL;%^gwoB3<-w}rp0{B7fJJAc>l zw}Zc({O#gzH-Fdjw}-#I{N2Fcjr`rjU(R2XzZQQta|A3?FN#Z}8bpPMKTaS1Yx?lt zYUg!Wsk*SGl2;l(rH!Y?-_pO8g`;fq6x*6v;IZdVy#jwK3EdjY%+>!%tN+(r{h$2v zwHfwywuO!LmpDOM_j_A)_SV?)WE(N#=TOB?{TQ%e2SSm?6v$pQhZNYD3P276sm}30 zTlGwl$3sY*ZQ;mb&UVr9Qx#I$>YrjG#62KR)A51RI5Yl%{nlB|y4V?w8MUiqy*2NT zJ2@RN`4^oWqnU5KppGK*zg#gfpC)<5B~gb%wbM<`kuF#7Xrh?Q)#FVphInP=^J(p= zTX`qvsPf6`Lu^+roT{DX2VJ~_pG6KUKuQJ`_2v>9Smke%wqdEDBOaTrme`4f+S6Lp zUa31{Kynrn$PZe4Ec*{rw$*MbT=U(lwA8TFng%%^wu&B8^yMiIm}QX7zrG?CWLo)l z)+nEX!Q`7U$Qw@8z0rZ#Dbb~q2C`Gj)mNry$-#6^4Rjo7U}I8tXi;YZDm*o`X_$fI z^m|veGX}Htw8#@jZ8CM5*35KRmu8y{U{$cuzwQ3aWU=?XbO692d%ISts!AMqgez=c z{%wsHX3pBw0fN0Un^VQR{1G}3f@}*^?OJt(n_Ep1Xp-$bSd|(30_?ayr#B@=OhK&J zhLjrWDMv4-R1BRYT||L{qchXu1XZShEMV%ZtNB)TqgV4S`KHy?Vs5p$iLPySr!_XO zA7=^G|FlC5FBkGn3`A>5M-FTG(pltZi38ACa~pDMiXM(TEJdZ?hDhqk=ah!Qr3wyf zxFmb~Omta`l(d2@%lG znkHsf&=M1{r3J}XCR6H+DrRk4E~hG<@j}uTg?q}0-a@`bGoT}C3({h9iJu^xsdx63 zVqdF$-J&^vr#G#eP1tE|gJ}i!hMLyRGOZZZ7Bl9fOLM|&xSd7!eGBG+Gm}BFyRcjO z@niaBzPjw#pKp0>F<~sF^oWTPKbA2O^V`i@St>AqE@vF`X7T_jIlhf%A|tvb^v3$2-GItZxbMI*f4nn}WC z&G1ttre1)ypTv+rKi2=3^~-c|MWd!MKsLX#q2|NxxSzn!>R% z8Sf+X59@Ucy|6H)cXF(xF-%2+*`c>{dBZ&|&Pfw^8DUDAzyU__oMXK#k#)Xs7n;By zn!uYq5Jpw-2itj7?(dqU1+T{aCD8%*nK9v|J0b|WO+vRA=$>k#o-9;Q?XA3Yr?st# zP~w58$K$&14hMU+XB2QhF|_LJJZz@387TStA4Ba$;8{_YsJ-cUgIU9$oHWyej!y+0 zw?Xmaxj+D`UR=&r*NaWvOXikhSWe_AB*P4UWh<54KQwzHy zhh3h$xzMpIA8fH|rp@(eXU)P;UK(P+|N z;1mE@r^LH8&L}Z`b*5BmvGeRwLv!%%qRLrY^$Jh2oKt1xWcI&?u9;=SR5Ul!C$;jr z3Ehmm(_RL#Iv8x{t0S8>dt(Xjg0Xz#OeM?LYc-V^Amj3SQ@KgL8FS_GMo&7KQ*4c9 z+-7Yt(NcOVY15!=<5uBYltUCv+V<9>{5uDqkb$ZwMFY|^q+(!`3>y~kid0iBiC z>PD};V!-e;gUQ{^@G(*Bw0W<%0yY%t0u~V?o@W>_bXI!%$ewG|o2v9?$rc=?W(qc) z@AmzgmQI0bb7_OV0d+0-JC19R0&+dn?G71@}v$F^3?2w$FTPG7HJ)myyP2)kZt&M5o%uLuTDLr zah_2M30Uu!pf{yV?ap^b`7&v+AilK3D;xbLIu*(=M_dm=>)tkx5Y{jaT`#l2D{_^5 zUTX>*(HS+xTcdhQbv~b095D?P&MTNlXppNH%;fO)xmY%+5M$(*cm+0AKIcCJvIh)k zP=SGA1*zB=2(ErPBl&a%J^r!7*!MsYGLXz8H6TTnb|9dK9GVhVy~$3&bHRwat*gyQDT}Dc$>g-3j<}C77ol z^G{c>-zb3(5YNDIdh4v=*x#hhXuale zswSgJQ@qUrHw_i39ihB(6moDmq;|)~$pPJ7mqY4?GzZ#l%=Pk#(I#BS^_J^&u@g@p zjR0`jy1gUc<#C}(zWfdOUZ1MwH~JJ2AHUTAM;hXl-YyY)8W5Oo4Fs#@S=T{U;NQqN zNQ+H32#R=>bI>y$dT*-vO|~vnYDCUKZEeqGV`Q3?^07K1ZmiSD_j|XF*H7 zO@u=|t(Z7I`GVA%<{mAZQ{|aZb58m_m+x`4UD%3n4h`+%!PH?=@;1Z&EuAkVhRlVR7~Jb=~E z4vRW#2IG1vvUfU5%uFv{-$y8tJn_O^7^)e7UhAui0rj*1O32+ZJ_7t zllOr-WBWi>^ELN@!sas!TelB%`K#IoI!;W3Q9%;52lUBxn?PFjO%+W|H3j3yAho!% ze{ie#I+f-S!{gh3pkx9{Yjn7GV zSvfC8Uy;RtJ#APXZ(RLtae=Z$7bv3%oW*rcw1t}2ZKe=k(jMogNt-Foi#{G>-Iz?N zBCfX5euYMUwR6jpx6)i+ZTg(b$PS&Q=5zLCZ$Y+%Tnh{gj1=@2QRf@kdWL(^LNF zsT)hLPk!6zsy*HOHT0DA_0@Xn*BE;De4R8ipzKXsWZw-dNeMJRZ=^uG;T{v{tzWf3 zZ%=;Bj$6QF9zD%>Sa$PLmuO{-%&3U(?7&9L(tlt|{>= z3IbVMi#b_`E%Gb3P{)>qyF6FT>DzKmPT%vyS0{LVfWbN0?Gq2dxI>-;li>GAjkS>0 z;S=nYBt$Dae%b=rl}yF5Guy828}%T2c0a?&BziHpK98_aM zpXY$u8VABI)gM@D>FL?0nVc{EaqWSneX#%1eqGFtfOyQ*S=GkHc?1d9w}+xB@MX!ue#A6LCJ7b1=>)Z{mEM zPu|EeIiI|N({et!mqT+txreiJK6yPy=zMZFC+U207YFKmawq50d~yfJ>wNM$PTBe7 zb`IP5Q!iS~mZLWK~!WNjq4A;gu$7Esw-W5*iP>4Ze zS;nGVRD^!|AP1?=F->|-0FlyS_XKV|>Dz`*7fh2c@Q_1oQG8d17a(N-1y(+?&iefZXkCi?zGX-#03Q{sQ z>+?Jo8qH_@OjGAJqt$(8xpAU*hQ(IVLa;)>x*E>iB8eq5j8Hl3ZiLFQb|bWYfR7_c zQvQI7Nn|mgiud4b%a;Od{o(Te@M?$4Ur7#^6TbZ_510SPj5FMjhC49+U#|OwHtp2) z%jN$ltdrQ48B~J&x<5Fik+NI3{BxCOi^IBSe3fifO9x!`v=(bbCMLT)ssxWWrCMxt zT`e0cTV_)nBUnCfXbn}ynOgYujI-2fhb<6AUgaSd!$xuxY2yCGip90Hp0#)r7rzpk z(tTI38X#8}sekS^O5I*s(`GG|>{P$@s3ffjy%uQ58a8Y_D8q2M-5?qdbx|}L_WjZ2 zYdAW(A(lW`s4pCqg>PrFIC$e1Pg&7QSwqoL6rIqwT_(ge4I z^SRsyhOFAoAu;ZCyXQtDa(;N}bb(u26Kq+U@D7h1E-BmA)fqsMJJDIeZYb1>oG@~6gRM-0H!mTjVNYKN35jyAN#)dNftqJaCte8j^AD+G^vx5-j zm6!<6bkO(DH&Dd!p}LkQ$vSE}`3;GR9p113M@+Dn$RVA$=Oc1 zP9_+(BPA#bi!Z%DQ9a|thMa3_Mcsb=t=OGtubUR_t-gL*xcBo7Xr=y!v|`ib>*mY! z8$!#>8`8?`8`8?$8`8@B8`8?c8`8?+8`8>-tF^-9mFl#7oy0OQyP9R-VAs<6R&1Wd z6vhLHrJ=ayMmJq!qs$z38!UIvjgiX?=gGA#Bqm5Bx3*erR?E1AHpO7bux^@k*l~+9 z9{X<7IfXRiXr}Qvih9Wba%o_dy6!NOZ%`NX(V+K>6AO9G9dEp5$65PuoUZ#ZT!N|_QDI0u6l7-ykt=JB?x z(oj94u4-S3@w-MU*xaO=CP&sjV}khVdb52!6?DEWm8@a zUahIGp~@TBl*2Bg;0d;*+h&&YHn}eg!>v`lD|xdm5p_9!)vXqbrr!50Z1QDwP;PPZ zrmx1b#j1c%^Bk`F)!a7*I=J0(s3#ZA>zn2(!L!3f4mlTBUCgNpIPvRcLhS|Rs=^RZtrPc6NNL&$!fN#F zZ9xE+!@aOXx!6#0&ONK5or`?nffGZ9UWZUqNTih<{yTPvAiPW~sWm%Ot2F0yRNsdh*u-JaET2;-k2fMuRj{Ytm*Q{; zFXU5M%acEojN7`n<#jL)hkL5fqUz6N-?uCh_xYO5yv3Zf6#QEI{@-tgKTnGL>7;^^8Y9Z@X9`@kJN$Rk(K+fgrNTqR@iBlnr0c!M74DL@ z74DL@74DL@74DL@74DL@74DL@74DL@74DL@74DL@74DL@74DL@74DL@74DL@74DL@ z74DL@74DL@74DL@74DL@74DL@74DL@74DL@74DL@74DL@74DL@74DL@74DL@74DL@ z74DL@74DL@74DL3h3Ci(^5eF`UDCF~U6Q$eT3g|@;vgTSu&r?W*33S>HKS_z^!Qe| zZn(+o?1oj(l>cEn(`|8Vi$8yd!oI`5IPB0dOH`vL!4gQDkUCMpl8Z_@1u~0}`?r`& z1g}3ujG$h8j~k|y#lX(I2ECh{(6BJYwW@-As2?~*3+E@>j~k|y#lX(I2E zCh{(6BJYwW@-As2?~*3+E@>j~k|y#lX(I2ECh{(6BJYwW@-As2?~*3+E@>j~k|y#l zX(I2ECh{(6BJYxR`okqn4K4_dMDvCZBhIsL&$nm8K5WWeiv z=UGJC`41vnKy(N`p9|CKRO1)i^yH;2M_=5@J%21D(;-(KZ!ifg4~96n%~D7v^N-tQ zFEXPopJEb18AGKOn|(}h-V1S1;s#Jx9vsnPoB~Ze8_sfY2s5A{m=I2l1ZuRo9~)!t zCgL!!yOWry3La^i@0R&}e}iy#g8jQtC0{&M%h?bMOMh;ri-px2Ci!p(B4e7Z<)>=z zzz%Rkge%Utl}75Fvs+7V?TAPjR6N39#JuAa zAx-R#hSvr&9zo4?phmXh3Vk3sAJM=N7S;;yd^mmJ-k{a*4d?Qj-Mqn!R%w3ss82}%hlRAjV* zTg`=EHl@rlXU?ZJ-k7w$Zit$;K*lRgAA1A*Lk7+rl_U`+OPzg9CQBYPS!R0(I?y}w z4|&MkWN9!rS-PZ6mM&?NrAyjm>5?{Cx};5(E@_jcOWI`Vk~Ueoq)nDCX_KW(+GOdH zHd(r)O_nZclch`AWa*MNS-PZ6mM&?NrAyjm>5?{Cx};5(E@_jcOWI`Vk~Ueoq)nDC zX_KW(+GOdHHd(r)O_nZclch`AWa*MNS-NEK4`=ZY=bV2y=O#-UwDHlIGU7!3sO0Q< zgmbPrZ~h^#s%Ga~^LD>URxIn4Xl&{OoD7){dLv1d+%IyhrA4kzQ1bQ|w#QA@);PzP zbxu|drdZngF7l%g;C2jj1*Lo~AAzu$%?KJBZK14ZDWSwTuZi#V==aJPR%tNa%5h zp(Ukk^JE$@qCyFUB4j=049wiIay86zZa@MrUKO{v0_~mwt%hTP=T%9;C0QWsn#%ez zdV)`7nGUD5bT-ZS)6&^b^LKh3c*dZ_m9Q?<8~ z=_D%n2=**bBrW;&jYC>vNZCCIZIf_hxoR+ShU}!juR5R;1p4a2R0lJM{jM?uWE*C_ zXs;o)*LfCUfT_ZVPz5j1#S~4||8%IFwx+L2=T(njO95Ai_c6Q_1aceEBqIi_Q9Y z3*egx#e$je%>=MCzg# zYiB7#hMK=b^Y-y-UOCsbgx1~LPgb_sY9J7V%E-f)HSuOOyf9DsL$zIzQ&rxTG)^s7 zw!tNvKVeU#DK-$>^Ts=13h)VC$6RSF==wL%^|9mQ8Ph!DJfm}-c>-ihl=!K;kgk`z%4JIgrkywLU$kh#EWgYaxvT$V;_&cDIO&E&?lTPh?2nud@?Sx!w&goX{8&Z+EA7g?JXB0IqmD zPtuTbGb25{`o$0A(fuZEEmwCrK5lQ)AH9C-zA7#0s`5|J zG7T8QROO!(Bw>@!5p3POUlzYst~3{>7shz8f*jjf)^Yqmon?>Y=L$GTw= zWYt-MYxTx>H=ff1j^Y;N2pd5>+YJ`=5W%Wx!5-zCrsI~!KdonTVS^&saml#dRKi7c zN^D@QJ^mIScHFjNxV=geB{vXP9=u3`x8zft5yP%9he`nL{5qKzT5LNrMd^_Eob*Sx z;9z!OWz>PHK0D8wcN*wiXSJ(Z7w7tgpK}FrLh*Re#Rvfln>X7Tu=11(-l@IIzzbDU zgE^_ew2rVF(X2wXf}ptzxP`MUYoMt$3w8WK9le1%d%JQSbr_{rrH&1~YoadWYK~G9 z2=VEJdb~-|<|wdpP6s*nqiFQZido_h>n2%8RNPLxQy9d_DLq=0DZrO=W|8(y(t=7! z1{q;=NG=7#=QcMvAwWCG7`)T3KT4)isDu;qnLoHy?seHt>s*)=er2kZDd}F_NgfTz zPSPgwJ8iceWvlma=}~U589|!pH)r`UYW}?>x#W>jIOO*8^qPV0yP(%{b1-RgTj9Wr zUcu$pUb5%ki_hd(*2VWW{-N0wmLo0;3hWvgxWT&=2$f@nqh!h`$;K!-uGpwL>~|K8 zyk#?{G7MFl<_*XqXx>C11#+}T;)`)eO5%1b0>nHxAR-Jcp#;Mvu(lm|%~f}AK`MR4 z2&k_NyKaK#*KUO8U;4^w?R42!pT(>k`l=4NIgpOaqPb|KJz&u0Ws2+pQ??KvP&#vD zEC*)!q4D_|FV^`YF&W{xg4dwz=u=kM-2`)DYHLn!Q7VAQ%?cKW(y#h`@tIX%3~C%H zO`XcsUMqbU8g-w3OM-Z5o93p~oWx2uSuwU&Lzq>B9^S(hRylH^nS$95jpukFH`qzG zoheXbO@`Xt0!G)OpEstJYFI6LoQpYmGm)$yy zMUYis)~uV*+xJD*vu)PVByH^JOfJMT{q$I18w;Ux9sici1=+y7DwJf=iGO5rP??2>$Eo@#D6TSCj#@5Qo?C)#j zf0@i0X1Ylq4#9CYwAl)8q6K86!uqoD8_w^o7MHoga%ttuUmAVt6F>U1 zFaKWUxt6VWszry4O)G!+#~=UQU;4TK^u?Q=YgtgPT09SYVdaMhU;dphed2dN@~Ml@ zwQP^CTC~YnOh01ZVnG`zN3M@rw>N%2ro?^5x%t<){Dc7k>U; z2YMOMFaFj~d}i?CAO7qw`eFliJv==xlJq3>NqVGcyfzL^GO52F4Jy7K4IE&8TaRg_ z`(6L}d%p6UU;fx1FkV9>Lxb~@e$$N00E#ZJ!c=IZ=;+HZqO>X_cN3Zv8j5Nt#FsXX1nUBXdgAmy-| z;F}H=`nJxci|3#4wD~qyE;hP;0vJqdIdFx05#6exTD)YCegYX9%Ec=(+l_zV zKt&Glb3Z7^FFVLzUdZOdI_8C1oT}~HSvFDCz$;}lH`mz#PYaS|DYFBPhzc`d&P$NH~q%$I)Q_{`yA1}+I_c(ue zch%y1uqt*G-_%GM%$qt^{%JC7J3eMG&uYRSQs%yL@~jqrm6G!|nO>IPgKd4fsGh&O zBDVpDn6v({y5dLHaUL*Rvkq)S8^N6acVM?_6^k^oZ$DLW9&2$|^axz@C(26#4Ba8# z$aNlr%Wu*k*F#nv1`&UUI4LL1x^i!1kn)a<sy z#2s*qxhMNE&$Q3zm+|w&^(!GlgzaOhaq?0>kLmImnB43MTMoDqH5G!x_<1` zY-P{nQ%~pFGg8HxmKHTy!Kspwei^aQ3<8ewnw4rXvZagz$ID!pP|-FGyh`s5lE4IP zxW8O_wZ-!W`EVj19fN#l0=aCEPm~bJ%eA%8}(7%lz@%HnJI`mL9>Gzlw&2g5@KuS1<=x2u2L}&i+d``7aR*yiF!n*{3EHz7N83@5OHzj=5b?L*|7}lD{N&rhil3Gqv8s@$5 z&83d47Ir$;o>r=-ppE^w@AI_PLgqe&&zU(+RxRGo;!XI0i6DjMh`PKnB-9)UUB?0i z%sqYUNbvZLlJz8f>Z7$<>*AqjZwzzcrGH!oKb@eI|GJ=|?iXV^^DB7W48(G^R>wa_ zx|p%-l91xVtfeiU$D+?oq5lk>vJh;gkSl0hReWAfy}plNLRl|tn;xm%+C)Q+R=8+N zKMlPcb+ocsOQWNeO^V(ftt>U?^>dTF>7$h!ai;mXf$e>M_OhkU4|n_N=X!3y=4X-X zXZcys?Q2IX^L*%upSdQlQE|0k^E&;^Gt{#vdi`A2+@qiE z&As~B*1UnyC6Tpm{Hc|%WFK9b{kR@0t()xeV|u8za+lZmxINceP4~RZJ=a?;_nf=u zsn*TzdD%TrxAxg{YyZmekAH0CEAD@_kFp{30ND4s!XUoE6+7^;e2;?(;q@*lT)SOT zXm+`x2Umn+r+Zko=CgK+;RRvX;p%~5|Hty{+=H6l?viSHn@g(ctuCpCw^-8CT^noo zvKn3%yAFOVZ@4OIbF)jT%}p+;HkVvdZ7#YboX8h`YUMNxSsZJ)r-tWUAxH6?dr<4M zE~(aMTvDx1yQEs5a!Iv*z#5+(YrIS2at8YP#mZjs&oBDlf&YDp-(vWy_=4=Y@x%K3 zSIw^3R$lu-Sn{$P#{2mWbjfhr=6bMoAjv(ra(jF2RPE)5=+?pUlA{M&2a}S^uH;Z9 zm&Z%K{6K3tDS6nHd`Tq_kCz-i&^o;GkN?DogSJ~-$$?59BE7Qh+5DEW286vxR?)tH zm4+%SKl<kN)z1{x=`*C#;mFwTspf{r2Cq*4nQ` z?~FcLO=5`XA5@}4V%ZV}-&F@NpzL8K`jkDS#7JtQM3=;^mMB`s^gE<1X9=i8*%L~% zN!+GHkFvL0qG;Wr-w|c+RANYxlS*_*oKm7s+0&LNT6gKU4d8AiMijY6i7ttIl^Bq9 zA9{*TO7WOsamJj2y7XFpcYfD5{?r;UXQbOk|73or14?lM@Kk=%0a4xnJDr~r?C$(DKMvoW4xf}D z;zL`fVbr*91txGu-o(71iLf8ogatqxWgxLcBSYaVjpT8 z&X2lQq+9`bC_n6gXjOpSk{@y~)G5Gj&2JIxcz!EC4xOyBhAKse0EZg;^CPYmsYw7H z$oD%S`Vn9U^8*fsVg%T7eo(N(`7%F3CqsT;V#t}1qGQoIaH=-Ktmmc+S02F1+v9!_ zcz0P2t>N6v!xT&=5moL8cDyXuI(Vw~ykK`Gu;o*=wqT}teIc=?Oxs@6qve_w4)kaZ z7)3AXQ8Y z?-&k`_ns2325fk*GvkAMyru8n=PiBbUT^6;(Zb*BrxMDVrSDMIEd79lS^74W%)rc2E*~DA<4GG7uI`FR~wC-t^*`mn?C1ICry!BQ|l%TO3pD zd18BBDn<}%(|!*cZQ37^u<5=Bu_w%3mTd}%Ne@e6Zx7>#!UV$H+@o@32ks5?B?=SD z9kDq$KV*Zmk=T1#mxx&T>okV8xQZgCB;c07Ei@-I965vL1eoUx?UV%gN%fFTqZ4P7 zlzH64dpXiGHhr8pRqK)y%=qPBA2Z{_JI!u7<2`0jdM8r@K4!H~rB*vNk^`56slFZa zG-k$52m5>{Ib()~9KljUGlHu1M!63?8;mme)*Iy^Fkw$|j65vG(f4>$W7Y$93780#WD1FQyg87 zH!;dZhwUUk(Z2Z5*z`FhBz}T9l@4K0UVdn70`A^z13Y|4UO;}^`bm7~vR``0+=0`| zX3*oz*JXB~&A~(F2;8e|_!hI<(4=vOt_bTIHRIzv0LD0tPuyS@Nh!JkFv(JiW5gG? z)orfrBxjizTe@@uoQ19&d`H<8eSwY_Cr_;Yjhe!K?nJINBa>x_<8g zlYFJJ+2f-@>PHG2QBF8gygko@6vqgd@TNFM$j!aLQaSA0Zo@S?*?NS(~AIl(jWjn<6$v4@lS)JviAqqq1$v+Em@8?0tfaNVw%B zWo@n4KiMiQ=gu|fNpvV;tGyu!Tgvq)yP`6^ldU)FcSzZ{DAA_KStSM}2q)1M%0B3A z`pMF!VL)XFRE8!_I#Z zQ6=n1exECc?F@B~I`8F}t<&5*d9Oo;0gK2maG}DT`TedD3}%4E1uF(Kz)pwtDh4ya zyz}M!Er-mnSFwz)5ENt8LWSe`n>@uOvbb8sN``XL-@-};*oMU_Rw;k5^sW%~^1;?7 zsfr9y5p$*9QWjDTGoPt$w(nTYkCkOwW;*X)udEchHz{;d77{HTvl=4`rHj8iy%`-d zUv21;c}Pv#z-S#;@ewdlk&@a4fsm$VWC%W`Z8Obde#T9U$C2V4 zcpPJRJ&qLC^EgskIvz)gw+9TjWejiM;~2y1aip-W$C2XgdK@XW`9RQQ7lgNo| zPUjA1x!RZ|Th|Qk@YZv5o420*+r8E7-r+-80L%{_Qr4MKAkK`EFf-b_!-ujcVrFzi z!pvxgB4$R1B#wG>cSor~$Yjuhdt)T4ghkuHJP^u7+koH)n6nLIMgb9Wxw0%}$>YI{ zAx@$8$rx2C%aul}Z5CgHu zY9Q=Hu*1k@fJFm>><3s}up#>a=9eGN;5p9RmJo}x{*ouQf2SM0F2vdlIv`;)=Kx}D z$h#1G3=MKikU${BBJ=@aT*D&Z0T$P=!;;wh!WtGO3g!Hm-j=L^PA9~&x*Uqw(~bZn z-c^(d4(YZ0_8>q=e`q)^!UiP)aSlMkLb+pZ4mfQL7q?`BkCr6Bkn*8*J9|c=$EJkD zT2hKF6mp7}S^V(RA72Cc0GBe809WT9T3KZ#&^{(XD*IN2sK)%q{xN6F$i4hlY_kk~ zbn?2#odYHhV0VZ>sVjg+IQgj1PO^T!IO<{^-M303x#WC=BnK~kULytGb(Fcb-(iBGr z9D=1dhTsrqQXGBS6W$a@m-f`(`x3l8VCrv*qYVzhQXB(t2ycp`2M*y)adc=;cvBoB zkM~%Dccd5Ia4v6a5#PmUJ>k`LaLk*X-f?esI%Jt;?wx2Mp9lv4XQ9z?XQ8R&99=58 z9gpL!x2o&_fH}H-Dw(6(rII>5mp436WI=R-)ugw zGm7_n3mjTOYZ2*C@@)Qy!-Dt*SoF6M-vD#|Hg!>v0DDvZpz7Xlo}oi_)*(YqT_GwU z$DzU<`CGjYSvDNqZuBCQ^KLiuT42pu?tJjvtq&ZsI~+2EGa^HHLnHU)4?AQiLx7c2 zYuT`OyRl^@q0R@--7>);^YKljJ|aV6L&GQYha56AAi&}biv|Q(oG&_MT_5u-!<<;9 z{LQ5`M%2p(GnRzI`sQv7UL(wWh-C?qYnWfx16 z)46puzauGX5rwz7qL<#{0(byre!h+<;n^~F>*YP6xQ`PQoKXz%0Ex>jwmM_se$i#9AkJrjuh7MI8wYLk0Zs~ z!B}EY$MAMNjxoF*M+$3u94X#5?WrFr-mb@y;_U&$@TPb*?xUm5L=A8C_OeI9Z6Y7> z_Og4_+sXE=&Wa5Hn7!;%*6ihwvSu%PWSO1p+}d)X0szilQr7I{h_cRJk`>I5T%SjQV_g!)u|Di@9D^MXq8jFmB8ibyBsGw5Bv^f< zGQgrG8KwQ?6s?;|dy6j7jV03YDWf@cVtAC4&KG1agk=9uiNsUGa zn(*LK15pg2Mg}`ILL*Nh*rSI!0JG4g)bv0{`(q@u!GXaYgAHg;cvBob+7sT?(Dglz z)O+lD94X!rFyTmHeQ?nJ7~U@J32%y{P2KeqRLA2;@eVzX6xQ=NQoJ2-(Eb?Sk;j`F z=Yhw|WE^;^f$rYoY-j&)h*6+{w(#x&F~@gs$UD4)!`?v!;G!3|1P>U9S@aIIO_AG& zohj~;<3hbO=R9DFm__eX+ecWDx~O4@XV8*6oF9mYhx|2fTo8K%Jd}&36!{CVG_>k1 z9wHR6AY!59-60B$I0e{|u+&C811wrW#5lmbzTXvBzc8fK(AM2-`QhA~dA`Llq#sx{ zqWg|jB#a?lSadcToj?p-MJ@xvlNO!^hMWgj=?|9W?zQtmltcDIIUf^pzN)i%X%yxT zb|C|?hn-aPAl8Io2#rn{NVqUR#2!JCoq&PHNa*ftljfq+nv9-}3pk<)=&Xj6cdoGD>3T88F?a^9ss86zt)(PNR~G4Gj! zIikmW!vx4Q175Kz3qeEOpi!7 zGkw5oW*c2K&1^4wlTHyc)BR;{ru&q2W|}OsJ%eRul{yqLGu@#TGt&dgnpGN5)|+X> z%4rAU+zDy9eYRW&R%%{ceIwvOqoSEcv;!JDO=kHo!_V zUDowRCtY^0Gt)17%QrgUm^XqU#;R^$RTqXBXL@9<1T&2+Mq-iGK!h_}unD;gu+mJI z#71L;?1yr%VW#in6rv|~xa>D~p~#u(APgN6E;a@EXM>eQs3WlmeL#3La25d%uxO@H zq5yNVoJ?6+*N^GRWFs@3Qy%0rBN3}W01_Vw=!W!KemXevNPj>UIfI4;m_P7?KTs0N zgsA{YIZt5Mu4<-Vie@^AKA4#v%1pO^%gppkGSl90m;baRU}8Dem=w;%m|-qd#Xd;2jY;VkPu7kzG1#Efs399yxENZ5+KM>7`N z=vVs ze$P0s4-tx35V27Eju5g$oC54EVe=4?4Y0T@M`Q!cM~KguMRHzW;&QccQLnr$cmDLv zjv<4L!XvL9gH_N7x;vhmfr zpY^#Xw!hy=#R$@z&kwO~nkC_!f3n_!G&z4d5D2jdeLxsv>Iis%#h5xu6ktU#=qOQu zJ>)`AM{RH%XH#Me0!bp)6M)3KiV%QCghq}9ZXx{v7CD241z4Qv(XasXk(r}*4o3vY zP>)5U(<2r~@$W^Cor*bAE~(%jXHdy02F_5wz)!Kg5&Y?1?v~*w#$cT-ZEB$${OQrS zB^{7y4)a5(G<9Eon_TD8Ft%2S&R~b%?6QY%lj9w;M`RbuKI5`qdRyy(Bzs6UW+G2v zUFgI-jhUGdFyUWG>h>W_NK{Yg^hp-M~b%(Ug1dbw!v{fu+*#$fC)#6w+~D>Qdr01NbwGV2}g>z2VUVw@s4iN z(2U{L_zrVtdONu{)4gWU%$7IC0}`g9{iau5%9^Tn$T2fLBw=Q{OO`vE*78<~=FCiw zC}L*1M-gY0$ns{o+w$5Wac)LUiDnwP3fdFRGy)!AMKIItvTkaoedHSvay6vOW$l%q z%ZO8G(d#Gq+{*>-W|38Y>Yso^M4KnZ$u zAvAF;%)Q8cfJLsLTLBiAXXsXdd82(ay7C(gbTVP!*GFp7xHYdU0WY5awF+_M;?h5= zq+WFQhUi5<|KOMxJtD_D&@VhV=0Nvvw19N?LHW({Vx!gVpxUVN`*Mkz#kYZ}n9wu!pOfaIHU@4Bi#|xf_w+#-N zI=syY8+g1aj;_a>_M_urDUPAXo8stsyeW>+UWYdgS@b>L6i3g)QXFlMH^njVcvBo* zk2l3J^my@_Lw_}XgBzShXx|WyOx@^Lvm+7~bnK&w?#RUr&S(rN>mtw;v2|{nB1f$` z5~jcX8+`<`@_v7HY@P1|k+gg2iR+eHm*ofVRYX!Z?xC5ssrRPjDvBgNbH zI8xXEm~fQ=LRoHsSNJ{Vt$xWfn(F%Pg!mU)2fz0POuQN(=a0Y%Jb z?oh-XY9rx&X2dG$84?(DCHlnbV6Pq8=)M{C)#7BgV@Nl!sux)Wi;N)y5;3%aEIK5zeY+#V7}`KC z0}-X|D`BPWD?8wAUpj>)&YwaXFL+`*d!1DDp~xna0pel8(1mIfh7pMv+CZoyu?T%2 zEQU4^@BoWGGD;L+F|>ga1=wqcHhLm9#8v`QxP?Z9Mq+3K=?}2T88j@w;!KZ*1=v>| z+USU$iJ^_l#qRcQoE-QMXOH$XU9xwcbEKDq7y#0 zapmk-Y-2=r8r$fd9gA)BF$QUDth?E9nN`9?OPuT*T*(GU|t{F7y?@# z+ZX^7j&!Zx1+N_Rbge%GFZOQCuJ*vYKDN>JIMR5+$n!RZ^(iMDDc%lvg(Jl~0Pp(P zMwj;1$2K}1$4WA141ozpinj+|;Yjhe!Mi@T(FgB@*hX)sU&-$9cDlVQs3r*)Xbw8s z+2yr&XK;xrVs^Sm5wp`HnsF=jUEVBF#O!pRB4(%C)OKcxgtya(l~WJNb4cqup-#$K?zIkbU4))T9z`GC1Y#@aSAQQ*ajjSV9`z^vH|v5v5g@|3~iyY z!}YlX7mQvAo-V{e0 z9HJ$~G4Oa(99@q$#WD1F)3`&=<4tk&JuJo1@pw}lLytGb(erpy93zi+U2LPf-C2ae zws34?yI;=suM6*&po$jc=xp~!gR&Ov7*f_^8$HS%mC0#S*7Uc%-NiO~lr=pbP}VtJ zlyy!QiEz4ZyVnDR7cmVw5n~&OVSq*5K>!1+^ms~G>KKODMrZ{rh+U|CUx;lWVgVN4 zmO#V;EXFnv;{clw+elsm;MF#7-+J3!pNFu+MS}vz1|*DQU08P)D;*0ncLOPqilhc~ zF|vVF23U-2Ao&4SzH3pEy5U_520V?32UFbl5;1~Qi)(bC(7oSC!UUlQsrMoMMk>PV z&_XK09Y{FhPRC)4O0pscQI=3H&Lk*HfO)U>WITJkj#M+n9zA*z(IexbiPPc8Bsvpd zkt^s-fO)PUb|rcr13GChs)v2RWRrItHD-#9nlz@tJDBTDakUZrgXeNz$bnKq0 zE^4Y*%gDiiu6qG+urnt!qfdJqUI3&$;bqc` znhYIm}474J^ z;`JD#5*FWXM*~7R|91Q7c$cGg^v15oc&MDC!qt7fyWM-Pqtjj!dYi&k2X}i-7~SPH zpm&#BKDGgvCUiD?1!&*n<-JcOllT5zZu!`utn+5bF)<%e$;7-vB@^?`-R?ct0cB0P z2b6WeLc|=)kC7$I-tijV-6FURfFiam?NG#)rCpkH;X}&$Whs{&MJ{(kTFcU}^Y3() z9F5CTZaxYeEux&=6=9Q>rJ-fUk_(SQ?X%&{TP`;Wu&8A15_5b3jSG}QxmSNDmYa=S zAqh@MujNO>N}F4bLL+yCt2((!DZrxsag$PjdHr)|@WW2D^G5;#ka68nsBkhKCMX-e zJKPS#RY{>-yuyGhl>*G`q*FtOEI2=*5XiXWC{#ERUcluZr2vcK&;3XN7B6?;ZlwU* zaJj>VP42|a&_$JT#^`QRl)bzhR5R2=a?-|pm)mJCsnp)A^;cO*Q&W1(X@i$Bq(b@v zEps_@eA&PTzhl5emcED(JP(#o(3UP=@psDJ^rW_4&D;z1_K6teNPw?8DzR6Ah!^Pl>V0i7anLY;6 zU6;HREbu1pAyC9!I6@J#zVYazTGd}o&06JZf zf`{~49`Bez-hwX02^ME6z~Tgpx&)ZhY+Pmz{Xv3T*o;EHtX4?twoHFnG6EIq$GH`u z4X`-3BD4YK=T&$#Nb{n(ohAZ5EO?LC9bpNVB0y)TFR3)L>A?C>(%Am{Y>qz=STPrUyFVNJ$uY z94V~hain%#@VY^1F7uqkWT;rA$F#;Q*xe+4~K=kx<{Mm&SAxL6A?#4f<% zUGoTdfcd-TSy|0Tm@@%mZW&?~u^@J#_6c_#FNzfM*Yc>%h*&6BYIBJ>XmiwKIFl-F zjPxzIKDVRU3mof^a2$g#rx;!{*+^$373mEm><>5kBdGxvuaHMl11w%4k2VC@ad(Bh zv+#~D$(`|hp~MFzyIvwj4A=o1e<(CTXp^vu;YN^p0!cDb5pst@rl=(Kw(ue^0v||- z97Ny)EZ*0JQU%y4cWLr|`-H#*QZ3Tw(Ifv6{V1f@xcWYP`=CS>xq>bPRGusN=_PtU z3GN@e9(nBI<1xlrq|c~H+-!_9k-mEIj@9Pd_%v6(+WdOSF+1b@XbYzCYwm+G;dIlB z+=1_41>Yy;Q(sw)#h}Zr+Skl{b$fWG^>)5}_Vy>v^DSjQMEP_v^T9^n8qA(*K;%NVbQ%No#>dY~i)D%y`i z=~c!+7qb27i~(kCCh5ar$4;%eBAb`LolB1+4)t z2Wib)znxo{shNDCh)=9g^B4Zb_x}FR{exflwX|lJNi4ZaoEtwGSKaNr^4Wj$$6xxn z|NIBL6EqzPD{DfhyEE<^M4$fKU-(!5;`285!u-I?aCaGfh06q8;0H8=SLECi4P~@parT=WG)n zs6ZP$)NOgrHQo1trkggsc4nIP@s#0A^RSF=Z?<_zzwNo^EqtNY%zN|Cu{hzQ2>Ids zV9wjq{Qodtx6r2ya9Q{q&HnsWK4-u@%?vH)40nmO>4E%q95fsaoH4u%=`Z24{8)Y@ zKdNgq^}(62j?+8I`sBl!>S`%^yPJV!|8thk`8~Y%eD_*@t9`mAd;(|9e|sUiPPa?d zL9DOxgeJzO%?`%cx;gE4C1(707zQNF&FId0KXXLlw%~7|PL7Lk6s>dVwcLLphtVrx z?sGYmL#0Ex_<>>8e3cnkUvZ@X2MYDkp~(ho?X6DE?Or(!}@&r>mhz>X(lBY`7wUd1tKdnzUnIPg?V z$m)73CJ@;6R7@a{PrDl#8wu=#ip#(!a1hgAb7Q;i_O80M@P)j3FkMsLbPY%xmN<6m zE>_p0tW7{8%HE=!Hbt0XIq6NpndrI;MfNFcA%PxcEw0z0h=l}3B-{eG=Hj^n%DRv* zWo-uRQp7?6Z49c->7$z8P@}9(;{(dt%-x}g+mNP`f8z&ja|TK38`5h`RQgK6|Ign0 zz}t0Q^_};ebML$Ny?ft#SAYHV$I`jSvi%gSM1e%|*qNg9K8fXEOUTAa45fpiX`4Rr z>Bmpj3f6bnK1+Qw*5$0MjbL42H=}MKObzx*gLoi~uv^ zVO%ob-&%X0bMDiVV}nxyBm1Lw_gQMW(zW@c9w7>R5e$4~R`d?&~2m}Nr|1awt|59XO4 zx#0{_Et2$B%iB&AZwub>hSNYrSTc56k)0=so$m9GE&_RYquXFt>#>D0SqfSqbSha_8l@e#w~~Vl8|GTdn1QP?vP{Fc_SyUa?An`rhV1U zIZy3O`O2;t{d%@`EQfZ+a;zQ8p`EcDYsYeEC*%k}$KMC`2_Ye!o_jCK#Cyy6vOW9< za()!)`=+xzU1;r1_3?MS1|fylA*AqHgcL@tr-q+4$4RUC*=ze2cDtYV$DAv8R$zU_ z&-NCJL!_7WZQur0EpND3prw0W1Fx1hw^+yxWA8OEYkB!%aeK^b;#RlBllM*J*|&&E z-=R;mH=QcQ2VyQQd~iIM{(LCrlD>01myvvP%q9ITG1tiTCO&Ww+=8b`yZC@0Dl*DNkbyktu@%S2I6FK%K+A;3$QL@HBZKgoZ7FU zOSC7%g>SG_&WV>m)wQhI6$; z;OP|Ypt;e%YFli12$}O%|NMypZ%$o5Bb%pwk&k~WrnyOc5}oDk&H8igE_%n_PDgoB zRLQ;-9czA>0robX4nWY`X9m;PThfyD^)Hsa#+WGAfCb@F*R<3B!>Pq??*RY*K*84g} z+1nfau@#IuKVWp{V+pGo{Z3+?aSddAX@sfnxQ>)3wL(#M+UT3XsJq=5gTWZrZH=)S z%+`VmC)RIUm+1F#PATZt3%29W7EC!?Q##mJMlhl2jV6*a^zB5d}8{={q zbvMUi<*2(k7K2fDV=SusBz2!F^H#YVQq&sSDq)XnJ(WXto`QDY<|$4iT)mK={A*T} zRsL#E;U7r$7!0Nst{1%cG9+nBm*q(g8+qB&^E?@n>`BCHD7B~aJW`5$c^K4JY;T59>8WxN*x5peUO$VxR;bY#_p3}pfG1`Exniu?45=I7R>FV1M zFV@v~nvSl*{jm!>{hROjck8ZJ7(7{bt1?hoo#VUjv@f^g9nq)cFVR&dFm@oiJm~XhyQDyV-j~`@LpTs^%90=wZ_79BZGBob z{3zuGcnN?8@l$&4Rxkg&9w(~D&+D<{j}brhFPOS-vCQ5-jUn{D>7@MLf3$qORSISH z(Xli3_@w?0KP&6Er7Y`ka%6N!_2kJ+CuwC_((1plw?#Mkq2cGvnD%zUpd3b6119r) zdT#%S#^%!(_G>e1K0UvG)Y0#Y`$x>eeEQP<5lEj;U*13J>G#6^(WHJ~**}`n@2mSq z17U7HeQiH65ZSKQ@tcd$;UZbulYWs47V|-_q}>WRWy$9RowTG~Y}vEqvx0UlX?Jr@ zSn?S`JC@XKjrdhm*;7jPEvefb=hMe-^+7y-s}JJLtv-m)-RgrleX9@Rkz0Kbr*8E@ zJbbGU;^eJy5D(qzgLv}RqVPeypvHU<=alq8yr`rP;=GbRh?kZ0LA<1-58@RieGnIv z)F6t9J?U$D&@hVbp7d27%ICRL2MrRcd-b3b{#ikoAl)VDkYz!bDkw8Ro)&~j+nJqr zh?3_>>LMSzJdGb+*TavlyBvPOiDEuIb6}JUe~%m(ZP)MV1EX#FefYrWO8uTXFxsl$ zhYpOk==bD-(PsS~KQP*)-_IQwU8Ua#4~%x?*6-)72iD=Umb9KOThhAtv?Yzzo+P|*S;Zh+Gu8d>w{QwQV$noqxYfS?|JpFE(bp853Y10y^)^XW4OMtEuF)8zxB zJM{bPff0V0`Sk38(FgVW+<_6EnECYi1EV|j`{Y5Vnx_srH9dWBbcNv092{-b@AARX z2K_#JaI{{(XAh3n>G!#VqqX{d{@`ehe!qBdG}Q08gHDYv930K+`TW7rjDBA{IGWb) zO9w@Du+~AR!V3ojYaJZ*%2x0t&gG-L0Jl31=Lhqv4wtWe=}X+w;wb^GyzB6$8BaNd8Uvmc#kx zCUDD<{EmF<;e1OIxb;Z>f&9wD`PL@z$|Ly)^KFOoE1SS=NAeHl+Yjg4n!xQx@;meV zaK60>%#W0GWBXE`1I@3}L$buMj=YavF1PMsK+kvYS;{vrQ_xqvilt}RJ<_Kw!^12-m+U*aCx{kSSACciA! z`=&-g3f-6-f8QYOBQqz6>GiGuIi9-wW2#1z{F~z6fPd5co8jLq|8C>okbi6Vx0ZkF z__v;a8~C@8e^>BNwRX@Il#J`@OebxnN&1FlJ+WzhJfopk5Sm9ISE64OR!g-Ym~Te% z0LO!9!Z|!X?2j*mM>c?!doDaa;*T$eM*;?vdp^#;sQxma`GU=F5K*bE_!HLhLCklAQ}Q|65_52L_6r2;B%mo&y$qHG)fU$6FtPP z5-81U} znmy^s@bt?5V(p&v;qY`}f3a>)dMZ4f+h2AU5&tw{iz$n$Qm^eV*6&FlQK6|l>1lqQ zoI#Sw+0*ZLBpHpPLV;gm$eTcrWMcSa6KGBbN*;HhUV0TInG|kdV))CpLL{!ypqd?W zRfkmHbs$o=dR|Zm&x_@$@MaRF5~CVW4TmOVS`i+t2u*=H>aQy^TL6T#PM-{3?J(Ls`yZ`x(nm@u)L}> zAur&=@~Uo)Vb3Jg*qUI;MAIJ&DnlCQSmU+#~umAyJ9 z?W>wxFVENI`EuQuo#;w9|Hl`bm+9~?7ahi(ci+uv=-9qqvudeC&;Y_dtL@}PA`37S z)rm%^u3q9G3j26*y$mfWPVtkdQ%kkryO_=$H^Szn^ ziz0Dp0?c(C?1_5H4Yp#+4Yp#+4YvA}E7&GZxr$XvrdrYIuomGpl3#^Ix%sdPV%wxl zihx1{ov+F|-$jjyhq@i|0JpwE;k1!Cub+%C>eaT3t#RKIws4K74jj%c{^N@WVmQY7 zIvhj0xVD%3B*j8l#xtvgWw85wB)4#orzv=-8643+l3RSpGi3Ce8MhtDEx=@%jN6(S zlSlHQc8#AUW3rhsIFeh4%2_f7&5Y?Ixy7tJN5*tBW9A4EPE_?g88gj{sTi^`1vFnD zLpFwlY#eHaZ1k7%+m`alrF^iIPcP*&OZn7NK3pwiW3-8wheLU1J|%J@pU}@_-qlYx z@976knn1G<9Yd51I|mJ){T4a49P5lpYk@RrJ`v*Mnldib=NQ^`Ka=g8lhN z^f1r^(E?|9h=gmh@i`B-VlEZDllKo7GxyL_dd%j3JT#ck-s2%0xUdx)m9 zMpVa_TKV8`(I-k~Desf>y!9pIOf_?!Q_f__nQZ3R7xH=`r`ODRR_}B}PPdt}telCE zGtta>Mme33(`n}DlW`EM1taCRHFKU)4oEnDpfm=_r<=Lj+lLBob|U!V%^s3z~L$Y4ESs__*R?KF#S!sk>iGV`PBQcE_ zXcpsWBo|{IiGeiUASTiz0Wp%(Do4zuaWXNK7U)Gx}A$@yCX z4oYHXA^179#MM=Dy%4MeNg9R}nqO=Saf}s^b2%Z(u>vhqZhMG=tbp&~cr-2u_5i5^>R?!^j(W;5b4TA*dp+ z?I*d$l6E!OT1&nn=sHW<-D>MC`LduJENPd+ZM5Wzf?i=st__Q^rY|TdnL$hx$?`cJ zVQBe4pCuhbpPy-@pK7EZZ={VB(36T7`fLDJ%&W!#ESEdR0IZb<13*7^1eC))Pu@y@ ztcvUC64N{U<&P6bOt5B*|1^5zRL}5Nf;56|KX*W4h_lNFJS^;SmR!*@63kE?9+7T( z{9JfM^6BwRctk4d@saR|#MI;I@c58FJ{%sAw8}jd9+AR&d?-93q4ju@$4aY!jfhdg zNob@aRRbh3E&^hkKoCWQDsf^>Ajl$ol{hg6DrslfRDW=%X>k|oq+s|OzbW4q%%jcu z_K@0==OMK6 z>o}nR{G`*z!GC0@k6rHx`EZiX9|v!eoj-2qLQftvT?p~&{eiEG4{5a}2G$|(;S90> z-x2}uS}eX*fWHv|h>zkw6Xe?>VJw6sl3|iJ> zgO>H!pk+NaXjzX9TGnHOmi5@6Wj!`%S&z{2ro0FwvpK&iq_*TcLTYP%FrR0^Yy5VlM|Nzm*li3ej)UIb$(Ro0MjyB5MmOJ-8$sQX8=-w5Hv+VvY=XKi#2gy1 zkaK9lLeQZR3sHw=a?u7f1d|v|75at7uF@|ww?n@Kb$_U$olW^>rkx;URKt9Wl8Z`8 zUm=+Ko29*PwqWY5%KN)kY_o?{2i-k{Nqb23mYnG6?JD{aud%5o6E2-A>+e|BSkN?~ z&?9C2ZOd8_5KWXfS%1s26ctSXw?}G^j^tM<>%*2cYGxHj@*T?ho0e5Hv#wGsHd)_c zSywf)c0^5n2hjYRqbC0$H2E#2$#3@HYr?KQ;Ci%_7ld6eED z_;@M*HYEdkZ?Dn&&PSE`wnwetmqYN^SmAjuyfPyF4psCwte%x9e!IPQt-rSt$sf>r z-(v5rMDlKX?;3w^C7M5|_wKa!R-$>Qy?3?0_d1BaJtF${H-zZhS3`8rCJ_S2m3!#Z zJ^40H0Bn;faL+0RL?|ykPii6>=PC(@nm9Co-*)W%m;qVrRny`pD2rA;l#c!dA)1x8n@ZU45l zeKNIro1@4t(6exmSZARz6I(#PND?DaNmipA6H!Tx0s~P=M6|-Um6ZC7ai}CxI>#PW z5@nefa-}$$J?kk{Hg>O491A?;so$nsNiZ2&1)M8ygf?2`c|96>$|hcPhPz#U z8v*Ppq+{G^ISNlYX`wTa@g^6}Pv~lx&q)8YeQ#4q>1SA%s?D)rh0xoOQ*Dxk9Qqt` z#y87s@!U^?5UaIt{8w9xJ818CtN+Pfn%uwszN_r1ypS9&GS89MDj&7=Gl#Ls&yYi7 z{PZva`Qd~|wvYC7hPti0}iU^#>8V?|GyGkRF&tZ`e3yugg+ z_y*4%u*;GDRRo3y!nANIh z^_PHp`E;nP7b;th<&Nd;d`6XZ@^)2O+bd(PtIC+;*tLngA8MNjwHX^8!(%W|P3^oJ zYJvmuE9zs@q6Bmr{g*v}H*Z4CY^XuU;J9}E2vc?%PaVkGU)I|bNE-YWsX|5|?7dme zPiJp7$IryxY{*Y{Z`R|dXR0VHA4S2hwv&nbaxO;R+q!~$cswssx}x5S;ft(p2Z~%+ zcTD}1M1UNt9^@I&V?`D-ht0v!ab}}>lWJRPj#Or;A*s|-JyMCKbWmTtzZ!_4XyHmyQ{=T5HjtXM)HEp}slCu4 z)wL9Fa+zPY@HQZ8fn*B>sWq0`OiH-T7S@uQwbT@;8B3+4rb#s>ksf59U;w*ME_5Gw z@I9>wD@YSu9GEU_=LO9{x^OKi&0V^11*wgenkBWtQe9H(Ni}AMxtRC_E$uo@Qk(jllH~rdunh5}~%Jq~>mngW#;5O*BO49RPtzqdSo)x6%#u2k)kd!m_0)6g=aZVe+$2kZu zgmJR1kd%GPrz_pil_>+LD+%ZSy@k*vb|z@PS2ET(#;%q2F-}-oW9(YNw$D~aVAYmc zzWUyYeeQ%as7q1LZust{RnIf^6ZqK7rRzSn9e~`2D1n8Bfs;UV*|(H9z`duUc0XS( zcGDKbo^(JewUn`}r6dYap~-Fa&rT*=5Nvt+?zCM1e0SO_+V|r+pC@-Ye9 zn?k*ttllkEu_+bPDCR{!(2|IzYa^Sq_PBEe$c(i&Y_zvt?X9);Hd=dctR*odn+a-3MB25H zOYj4Kd8(Mp78|`gWd+V*eH`bCZPBcPG18Yemo3!@&*4~V@H?;QFT6^mo?Wqw{ zC1xMUH>z1yD<{}?ASs`&PDL1!KW*kdHw|t31MmxV_-kL9eIUHmu}N;*Taq%8U+smB zC>IMepHL&e*1a#1DC$O4yVRCUD|Dc5)WW)ldT;Z|e2e$+*k4N}&$8;>cK;W;$y!M= zBnP^g3zQ7)Oo9hfP4cD#dPwXjFxDhry7!p^kMb!LX5`v?0~2vprdLdQ8Sxdf${Xma zz`SJJgrAjc6@3smSlHw!{ZjVky_4O9bzj#abHJE*4Xx)6Uo>jt}Tq5PVvr{e#0>S@pTpbckGBUPs$NKG9p zVjtHA1g)_?vSqJTM|0j;rCxEn^)&Sw>uN$D*IFNAUCarQ3Rah9roBpy;%e(@*N8@y zYjWT(h=O&{jRuyL?pQxNnr|WxtX9>XR&}Qp7EFN<76uG{;ZL&~_NKi*E}O!u8nVcB^&HI*kg zGe^7h+wT;Vouo|8>7wlmmK{rw;3619Ixq^NeBl`DMNjVPw*K%QdwcPX$;HBAQexJC zGZCROl8SDzFdDtZHsMUjnq4f0%2JSvveqvaYeLrA#bTYHYeE*Aa2D@EpR&bbgP`j} z*48>}<6?0|Gb_i<7%HR!UA}@I$e&a|-FCv|W0uNOZDjYX>@6r2ZHt;&vy^8``Fd2* zpk#&@Z>p5d5a`0|E|v*>5#I7S3k;b9DhjzGKsOq6BT&)gh5*eBngJE{&^`m(mOfrQMSpR%$nEI}OTk@ZF6Ap5Lz)0%SQB6jZ32wr?a*IYyxFC& z#sDkurfV<9@Fu_*-UJxKn*if@yZ5UQZ+K-Rr8LMyzS^_BwvN& z{c7UU%Y9j0+W*zV3peCOE-PV_2B(oT&S?USahd>QoF>3Hr=7jbX|ADQ^RA}UtfD^s z#jVYM^{D&uh%Qqd?x(KzKheyb{c=VGY=i<>%g`Dxxzht8)YvrOAr%;ZbAm7xgW>sFE08(=T$;A^u zYRBikuuIu-)r@&uR%xkjpsu&B?kic#DZ{|2)hb~GQU}``nb+yb;avcb;avfFXApHm&+qs&2f2ordRhlUdGF1yeJy*vaC}` z(Hmd(_zEpcjW1ZWwi}mka>Is6TIzeXEZ!VQ4NHxKSiA>Sdk$jpo~{-j2cawy38^OE*by2SnI=PB??qW>@_lV%_aa8=a+mVksx`v1gYz5L~Hn$<@vv zH7_Voh+|ql*^Z&rKXh%cbAS83?Ed7wDs_v!x}3$0A-R1qCZ!gqu_cEp{axjgezK^FbZVTFW!x44mup3L*^>X`>j813zP z$SO%Y(2)*_JZICl$7K`R`yEY%rdv!}(SIL3BE^jqI@$C}hZ8IQF=KKP4kHbSC9pH! z{nB=e^TqP_JK?O7vTjWNP;uIvvtf(dO7^|}`Y-lwpA$HvB=5h2()PuW_Ja1g?;g#l z7zL*D_D$2N9*7f3%6k{-l3_~m5&Yk|Wy|n69gr$!>9J6j&zARp!*rq(H)OwmI@J#! zbJ9o1l0_YG@iu3yrQtEIEa=D_p5cp;kJ6W!y#K_5k7^?FOh}mU4>8MKaEef5u&v!^ zH$IA?R#DI3Fpg!I5mKyChT6LRI~D$b8y>3-Y!W6%Jif-DkNr7}P(*_B4R$KRSe5cg zhnZ z=0jCGo3F7JLnDec(c1GW=La-M9pZ|1VQL4x;=-BcGkde^=@un-^TSC4*n$3Mc|P-K zdBsiB8Q4q-eGx+W%`2SFr$#zn;ilWiT*$n+dKGkAlYu^t?)d%)?p zP>Uip1~d-2dgJy%ywNoLkPpi!*7O zz#P-%cP)-OWy05cCPuT82;54e$1%|WrlDmQ3+;=<0ymP7XL5lEF>$%BIjVf2Zkegwu5!s530$Vsq5+ z0te@t#sJ9ixiLV_0md-^fhrrv0J}N%7y)A4d@tM!_RcvC4M>V=8bqWVhPW=|R8+(a zytj;kywVN2qK|hrv zdL{daGU|(e~F= zS3TJBb&9p(6es8;Bxg;dnBdD|P@NG|r@<+(mrkSkBIHY2Z9+wIgv_OgI4Ou+IWyDT6O8v}v5ugkwCg5s>6=prOUEl>9cjB4%1~WDrrLoUn%Y! z1{l{CMP%V|dgmN^QCA8mILg}gv?CNT% zysBCsM%7xly;=mXtk#Sz`PwFN`NH__e9xk^PxwHpdaZm(Wxf%%Ku)xEq(9;R?EOVY ze3;!b%?e_A=3E|y`_?>)@@>^+NqKceQc>M^vm;+c1e>yTg)~9V1i*h?^sB&%T_wbZ ztm3*W;d%W+g0Ja!7oW@Pa+c@qVPxy_cZAf2e0NA~%-bEaO`a=RAlwZyNNgLV6=(;F`bRz|d?wkpi z!fcJLCRGYMu)NL0Nr5fV%2{XVxa^)5x5P+*xB<4qB!}BvzPL;jd(Al7B9o+*Un!HM z#Z@&{&4>k_r>n4f__-RZho3a(4bUm;7d5siC9ni!I-7)$&SUs#Si58yRZ5|V0wP&W zKqRXPh@@OaKqTcV0wO6_5fF*>xM0mfESbTMVXO{8y;vT0A%%VvXs)GI0L`y!H?E^Z zYH+4^B9KQRF1p6`0o>RQ1-GC&FSx*FgJl@5IVu0?rUa2vL`y5I#j(h;eg6Av%2zI3F<0TuMe%r^M%LjsO%hil-`0hS4xicZrP%)(|PlZ zWDrE`3=)F{h?_%9l5oC7D-qI!l)P!&Jjv5=ark4lGGx3aPX$1P=7<6ER3#) zr{39kRZCt`hCco-iCYaZ4tu?pS_v`zX%By0&Gdh`XLkp1Xi00ebzHQ^u_u}mYkQ0H zoZMlUw7FHi!gag`L-TkG46Dq3-404VZj4w-x!zDWf%n5)qNAQWHaHS)cinJ2vdHj0 z>h;A@PqTept5xvHns1=pNnIv2nza7(@Gx2}Q+dZ6H@ZzS;R=A!6fZL$J$;*avOLeM zwCoM+9DidF-{|jZwe$v#Aj!P&#)XUDkYmWo;J=M8QTtRmI7$<1kK(Jo&{{fzV`73c z`uM$%AAh!m3y!nLd3HGOE~5NTC<=&y^B$uFjSQ}*!9n8;&Id&|VlNrsXhQ9BYrrA~ zM9+su3!|RU3o06e<9wqJj>KqEugRRi&pZ*vI1%5m;raU*`_y|xc&0PNV|W$1SSz0l z@8QJl=_ZG)G0aXJU}6sDyery5Jz`KytFADHE#O)P&H&4OHya_0K!ViYToN=C zXbS4NBr&ObbWn1F`Uy^vH{HUQK(G3_3@(l*H$gG6xF58>ERs3wKM8^&r6tVS1TuqsaIw_!V9go^21|Ht~tWE7Ljt!k46p*1iz zM~q2yBR96NNk9u2!akb#SJ^{RPvVkcl!^9mDd$|Vqho#CnvoZ+GDDV7S*P5G(FF0Z z2O%1e4D9IZ=m<6|h$sTVBS|{cGZ{o*e~a^0)gr>-K%k?nypQTMcuh%`CYiJZ3FpCL z`G7DgiJF!tJSnH>CfCK;qg7(^yaT}CXKpGEx|2w!d}K- zFUWQLJoFiZ$aSxFSla!OIEHw0}1rq$GF2rc>ph9+2PM^hQB^FH+HG-nA?$KF)0!0LObou7B{bKyZF zjMYfRr9y*Z#=9jMFa?k1{C{2(GyHEgvq-`YkPBlF&eea}ZldN0c~b#-Z=#!QvAAS| z`D^-SL#=^C^>zY@g|1RQX?^=e?=4a=1HH!a+ypSj@eoAdSd*b$l{C@G`XX*9m=w(T zEQn8M0~4Oc_?e6W1~msoI>|Mqo5o3jbf2cP%%xh1(%!&?{@F2QOV*`OG@T8kG%zsm zX`NCyv6g|?AA_wVS^#BW?EtICTX~BpY!k$rv-?%+KaoNnw#kokF<~0ZK^BJ977e1{ zaa_Emn-6D~&;fTVa^PR_+%BiyzeN{#wm|L(Uf?1m6;Z5nx)11aw5qK9xD+Zfk0<5R z;`HH9YdeCTCFR+``PKxbOX@m2d|LU`m#Tu;qyEV>P1)dgL0*n31HjaRym~auAhdR( zTDAAmxy-lcG0lK<93lrd@>Y-uhhUW1*=!(PLD1ywN7kAHD9`n7%2I`1k?$^+Xz9Tk zp>MrErbx9LT6x@u1Sh@4h0ihKQ@YEM)Fzfly=)Y9&i$jSa|q=z9#J zEgB8H7nh}Ez-koNz&BXe!q7f_ll^+;l66TI23_V2&f~L}tPAbqP1g0?rRtL0isoyc^vBH9UNBSt!$i_EcLHVG zk}+v{O!{FmFW!Iubdq9lTcnS3g%nG~dulpn#j?l``VF6AIpc+HyMupZFH7gZp~O}^ z_B|p2wNsn0L>e9=M2S^~g(uDSjWZps!d6lMxHn|(XgT+v7n5b{X8MO!f+EX;7y8pH zkAFY>WlGF_i!)g(N#%Y<($ie~8>eZ@D~cA*bcdI{z?2HGfaP}WoQD#jC!L|5nRe3n zuf^!5ydSbOIkaWA;~AuK+q!}YyBz_K4b{JePOegRIg|~r{#T8r8+_o}vrF+=?!+L!*wT z>QLh?7&kR1fRLmv^bE&tC+-KrZHEEJ%C*S~I3`ykz*0SoRWRMAzpVebc`~0?=G6Q@ z_MIRM;g5g!gZD167)v-ZYZK5RtF=uZ3b<7+BbfQ0F!fP$i=B=9)L72b`7@x<3=i`n z(c$ExE{Q<3{->t8_^QL=@$r<~hB4AS&sz27Y0uYXZeYg2bl5#ZEMU;L`J?R~X4`1d zisbIo%5_AI=*n@miJl_b)8)pp3H_Gif7ecX_h&K6?hNWf5*BN%q~*h(gtW_S_%qTx zH1GOft4^;-%Sn6%Fp@>lz$j*AwANUtnBTmh{h)H!BAl$gC#7G%U^l2-t#w-)2o449 zn1bAB8KGMHH|)*swe}zbxh0ZO3afIjqIsMseh!k;GLBK|4G5qWK6rt>glPq8x^mSr zH#;*fdbkr5$s0w~Sb6-uC8|ae$h8xz4i!sWc-5g|^;LlJ8tQVdFh!5vXRPi9J&hV$b7Mb(kJbc_Aer7i5ucoA?x|=* zJP?$<3N)y+Jp-Ax=n9W+Lm}5*WQu(A*!CarP&gQ*H^H=MrD-&R{{ZDUEuBuSW2ktC zkO^#75mRsndCOLU#)kh)gLG2e)!OF{R?BBJ@|a{0mfTh%uueI@(u1Nm|GfVzKJdME zSdwlrdYYw+>YODoM zNO=)@!8etAVmVhnICyfr-2FE@qcG||){Ip~)GV*?C+ z`DiqF+!9xYB(9@vA=&Gf+e5P3FY}O`z}^T+!ZeDIL{;r^Q!XTTE$+3fUtaAo9Xk}u zVe=!$Ez%pu_n&f8So;We1m5bP))+A(_w1@)zVbx`mrMJOjOmHtKMj&1cmqX!hx7sV zYO1aBXi*V?ji09+est7U<7iU&BIZZtv;OlE{`mVy^5IdMQb^sAf&m65Fi&7Hc*9IE z7-IsSV1kLr1SBF8a1^M?1U!fdCblp>#>r*^k5K4XN7&|DKgK~%RI6O2rg5U! z)Q}7vSE`_P@D$zc-oU(lWAe2;v8^qKAcC2{yBCK~ew?MlmX+l8z37_qAhF2qOj>)B zn`k!O)jH%0N~0kbp=4oi(n5=~b?ys9O((5A0Al02TDQT^u%oGv@?W41n32?tLuhzr zq<-#dm2t5as~#=a9f@P?({$wckN484`#Vu#Jf2pr3;K;NmJF9A8EhDHXsPFLdC-xx zd`6oi(iT#=B_0>(F=-ckTTAKh(Oc#{<>7i>d>Sapa|*oxi!7x4A=Y5{kGy^gN$9ZE zsGs4uhAOG96VlQh{_-G_(0u$t+uC^w^e6zE%>HR0k7j#|BXOKQj-mr8*cb zRfnkgv{nQ&5v}*_%^uU@KE=u;msz`%Z9qBtE|ln#q&9E^p!UVfCcH!(7#)nk3)D)L z1Pdc+O+ginNBUrI(Lgk@qbylraF$(IY0ONI@qfW3r#qK6LZzBJD`4ZX!ovhG- zZr{>3Ni_iF(ccOuI=D~_EbPbf8eO*=4vT3I39{}N9B%js@BUlV(rI_O{T|7IC;yn_ zl$2Gr_V%=XLzCUPp~Zl8D5CXSA_)&HVHCsP4pZ(UVruHZRv&dSMftOY#>LPZftg!b zRnOPp5dW%H_-Y}PDdksJVX%A5xi_CKecm_>#6TcmN+5QQ>9A7hc(VCSOeDq28DAD0=9OBMy@&8 z+u?}nz=m2_sOpU=9GDKXAED`Zy6A=d5r<}u$i$#c;~ z%5Wq}45j?`YT3CvpevWZ*G3#1yZ>-lTRNv2?)X$+TpF`30ZJgB&91Y`qZQxY) zieP5lG)x=8%(Q9PH6LdN(qL(~G+4%cmxgaOeHg&J3h?TQ%E;QZk@%oL$NX~6zP zOXmiBvCG{cV!2|SO1^`GvRasTweDJB8qr;J+^9qCOy2HBlGVK@*3l|+_35wG&#ZWf zSzJv6>f5nf&_7Hj;{QmpC-Y}j^cYsH@nx3G9fKZZg#Ib)F3yz*WIjAmQnDtqYI$` zuk^DQ>S|$M*0e18>RrREQ>Rz=wHGMmSU#d2?|JmL|Ab5xcd`F0$>44OC6ZnDwzv17 zB=ZvPcE)P{_9xUUTu)^w!grrQ%>SP7}74qFsYIXoyfNyIS{( z_Qem_FB||c*F5tidnOFSK#bn(Hueq}S#aRn{VHzCQJ1U{nLKy0^&B+zv0~2enY!5Lm2IMMc#^5$d9ef zv~$&tmWcMQT3#b;`^Uyo6XPtE?n7$GOu?OLjsfkP$tytU%6w~*4Xl=JV}f|>0DS-R zzH{YJsHX$8+M{wPK7k3K8=^}9wCrqwue+_WB<@@#=*V3h1Qz#a-+L8LwFBilfSHPP z;Q-JU8;Pi-_U!JxnLd~+hk*93aR{ilh+V1-6{@2GR1N|4QGm)JpnhhD=x5GF268eS z(f%FW#5n=u_lOFiD{L~7K_4SFL}zwB$lhr5)o#^uCbL%V7CG+bz5fS>$iy>vVSH;- zJ6Xn1E!)ZJiOpK2cCuh9B{5F!&e_k_7M6{GzZaruB1_VoW6WO|9lgb8TH7YFOWK-> zxAuQg(H+HrX8E))ZH8XCRg%78FEeI$W2=QHyv$6jZ?%w!US^$5YHYReATKkq*V-*e z^0Z{#+5&A=TP;bw)shUVt(Ih9US@k~P;Ip&^;SzVFfX$gsJ2>?LABMA463b`WKeCj zBm=z6bVS=NwN;V~s;!n}P;Ip&gKDcKaWAvCR&BK;gKDcK8B|*>$)MV5Ne0zcOERdo zT9QGv)shUVt(Ig^ZM7tWYO5uww_1{Vt0hsCu5Yy{GAeAfB*Ze5zSW}8h0?cLl7V@d zz3X_H3H&|E_*dO(VSYRiJbIZEv08_%kVup8Z>DcH!i9J_Y@?-J+D1zj-L9b5$XJAT zw}SIZ-&0F0j=1u-u+c)?xlt8zftMs8Cg6cIw)NKi=Ij@ReHLyJ2pr%h$;=z(fSEB4 z;0X?3Gu}CXMC1VCE}9&`gE)YgbdEX`{5=B)@X&S+Fqm_ICyfI~%So-_{dr0uhK((H0i8V7jNIKY#}0iLvd7Ec-nc+xn)lg0s_G!F2j zaeya{13YOQ;7Q{EPZ|e!(m24AeQh>+()L+AX&m55;{Z<@2YAvrz>~%So`eHt!~tD6 zV8ZuVbnJzF7RuZFK<&(6IBlNSSPSo#X31gq&0$B&3cS= za->LWwBzKKVTM7#iIWjk>hr27zRNgJZ{fx+@d0?xU1w z3}*UCz@lfEe|%^=smK(&`zwvI$z*C2W0YTxlIoHXTQ>Nxr!f}F_1jsd3;L?VwddFnj3bSxvxtp+h!*pX@ZwG~LttIf8{zpJ$gwS~^jsdH#g zdDk6HnDhJgwi48-Nns|OqHnbTtYL+cEVYMCZr1Za=PWj%apNA2IA4dD-E4eW7@Jnw zuQ&a>aV7blb=ee_bv42ASEXTH(+Rh+O@1ACJI?%q(6oFCdiR;qCjaLIdgxQj+Lt?{ zblBwQY!nZ>dGSf0Bw?pLDNzw5SwX8E{@oxza>OR8SDW&Jaz9-;$!f$>Zz{0rV{Tc3 ze2f1-u`PaTgSKq{h`sz^&08Z3!?ySvd--Zx%-xYw@v3$;?EiHXM6K01+32{}rrn9+;w#Rgt+cwJreiktNvr#|q^ z_P*Qm?R202k6kYkg(}opAHRpA2DVZTy^ffn(zwm9oJRLoZu6f>v@d=aZ~h2!*lc#} z4^eVjN-~FyfBDVA#=rb#iR86yJc=x|;r|4`8WDfNQ;^e8rznf?8_hERbm>s{D`e0^ zQx77zy&DYKaInDLmZ3{-+E2Yb@0-1r#0HVdF_NY&>a(jVH~p@uV3xo;1V8lV;d>(hM6Z2CIA$`6ctvE^sp-p!=yXNB+v}s`Xx8m1=M`_CAC}(r= zr#RE?`{5gAgW(t(@N^0LUe;m5!&Te&Hcq}F+qCZu=4{|eV*^hb8+g*#z>~%Xo-{V_ zq_Ke~jSW0$Y~V>_15X+oc+%Lwlg0*~G&b<0#Zh98ai@i`fkTZAJZWs;Nn-;~8XI`h z*uay<2A(uF@T9SUCyfm}X>8z0V*^hb8+g*#z>~%Xo-{V_q_Ke~jSV~rJrBhO9oV4n zY@q8juQF5gIk=@Bt0l9^*;qPP*TN z`t9AAe7AnPHzvmeJ-WCa{#$8e)Xj>)I?alq<%OLig!qUUp?Or1k=mvWZXk(mC!EAm zL%Uj^HE+U->@?~_807It17$y6#Y2e`n_-gCx>rZI)j(~m z$P*JX+NeN9_lbqUeML`eo7^pQtoLX!NzpbjvUF&&y3}V1WnI$knC>FbC4bVb)ZL+G zL3cB7OkSPuR!el3&{qQc?NZ8A+rKIIp3sSe7cm4=VzSE#uI*L38F&Jia|~_x8?JZf z{hb89X6W%;P^S>sw`+Q?Hzhzwz1g(8^j7*4tOkO{FxnDA_RKZ+dL%r`4kdMG2~lUQdmZOeohuMJlo!ek+p14515?C08OdC4D)E z)Z6-6WxX*KikD2gg&I>r)`WMQR|v2_INgdKAmKXK1Sg|upWwKjOw(m-D zv$$D}n!OmjVED%r0j)~ZI-4?zCJqidpnsn6(I*y68HHUCq~9<&XN_q2*#S4((X|6^ z5S=Jn++(JskTA(SMst;+x-~UHPmQOdLDc`v*>(y~P2Jy(G0f-d7-kL925Osx*-Vz; zPt^NTgWE?KIzirFY{ly%O@+P7WE~1*|&pm1$pAaOlH}PWB;g1NiWNcgTEt7cMR6=_ABx!UIlRA4VVLVj@G3Nm3q+ zm?xoNU5msVK)#cP5YlZwOrfo&k6XLe}jw;$7paSNd0{*l|4V7KA9F%(O}f`T`>@xI&hmz4WEev zeKzH?DM~D-BPM6w`Zk|FlMXGQG)Dxs@)-3GtyAK0T~<)tZ||@>1S0QHWMp9iYod#o z0UfgGwBd}zGZanmmhclKfbbVzoIpr$(G>3)^Y>J7&sYPGPb_3ah8fs%LR^dWOAT;#5&T?wvnN=p%C!5U2Dp%TDHMIy| zEh&0(^*umEw94yh9A~q2dJtMvd&KB_(PZeHCpVRc571Vi$x@sIh zmTEl}*O=Et?byO--cVmV{i6p|%xz>;qSya@jXB3srC3=$I|R$lWM1CKAR@cu7$gY7 zp^&>)9|3~kV&>Q6j17PQ0S|BIHq9z2$VaHPEq{fNg3b*8k4ue0#AYkME~nm^&3&vG z=CdEf4ng_Zne8st=x6vb&&`XqdTf1+E8*9EP;P{s*?h5HKfRBUH~GZJxc+zT2bZ{a zcKrtl8R2<7)uFw#_Ahal@EU+!fNS#M2U!XM9ySeyoATSoxC4bgr#Us`lUt~+ov*v2 zn0$f^gZRLxkF#d2YX+{5^_uJ7jAqj(PM565uXrCA21 zt)t@B7gC~9pktV7?%rq9Jh%`2@9BbXR%tZi!TafUijgccdDKO`n<~?ReY7N6L-?mj zk9tN=y1YV1>=IYC+mNkJ>H8;QSZlcRURQX-rOo+DkZB!fqdruQs$nB_@v)aDGu+!2#ZwjH8A9;9 z;UB64q)(f4g7UNS<5F_@ z^fdjMPtT|Bn$OB*n#6HBp#f>`c}pNXri$0{ASefEvIMdnF4ad}ihf!SBeZI~2F7ci zV!4BD^qT4L9&en~<#6@reKRB5)$(3x^kh1nNqba>UraghWLTl2VJ9Q2b~0Y1j40xK z=!(}6HZx*v>?LL8Kg{BWg@XfHzkdZdp!J7pFyl==rO$^_%dXZZbt@mgCo|zuAxxS& z;Smh^s09dEtO1}wqSOGw;CY)7@tcH1)Wy8}!dWDV##9J3)ElXyo)JSDU5I^Aj%_){ zxgy{(B1m=Hrc73T2HLdPw5hu7DMH*EYqC=St_O9wM#7H|v%vBho#-lLA zlbOq%7>B5{I#|r%wpC*{&>_Zms)S92xp=_N8Pbp}daa@dRXuep5OMs3qHKM9D(bhY zssbtP*s>|!v|c56P%So#g>8DAF)U> ze(k#I^=@w*(S0@wq&)0fWaSSscSfR`xAKR1vJW=d(-S=5d1+|_gQ?u(vmIw2ob2A) z`aYUzaIW1AAwF=byfk=u~?D+JX&Y}Pt14HdjF&QhyMK`LBD z25M%$j11IVN#HdYhyKd-p{^=t1+!ULXeAMw4ElP4G1TX?=~vH3;(o(|QJ2Tof{}Ht z5{(i-AfAp_Tjb`rsEjHTFO?kz^5bXebUJ$6(??b6WnS<6Ibckl4?-fAdDO%nRz zA$`aEqzH!6!~fHD8xhOz)ZWKxUlxrz`XR?lRJ}3Mv`JCpjp?d*BXp`E8OPS2##B}E z_se(jUk*F%peIy!+MQ?9INM=bgE-|)XbQHGYa8d4{lUUz1it%Xwc%;sUyYH}hSc4A zv!_MYC)rT6&vOiaFDMT(KTMiEjB_}$jDSIsJhB3e2o~KCxiMB6)j@pxcrvCsJjDL% zUE<-Bcm}np4+l^+(;yA7=md7L)?7`nuPk^e>y>v;i;{DYDC90F6Z@!((O6wUeejLu zP=oTQA-u&4CpCU>zah7BhG^%I?g4}B*hdt&)TpqQXrn8N+}R4P#dEm z&>O&#ytfhxsvVq4z^tQf}th@47I zFaUyH&Bbv=k{1r2*36{)a>8S4?#Gdb z&5Kk9p9ob@om_BQ0$-Z#i&chXb(KM1w4{8%My)dVR5w%xp8@ajiuL`Z&$8iCskc$!|gK=SJYx~85kuIzv7S-+7 z7mHFR)Y}F}(Z{GvD90KUuQ?Y65$7Z1W#uqA4b!UH#se&JgfXi@p_T zXj151K@d@-sY?7*y+Fl)(jKk(Y%%DA79NXRpJso z{Px(b|9a4jPrmTwRS3;W!^v>g=}KFJRW}9GTH(~>tCL`KQ7jzGg~jBo2>3J%nW1Pg$q988E~+n-n_Dz-TPJdvE$kTv4d_bypNM ze6bNKC=yhNYOE-N!jy<}AdG*SpxV*8I z2lMrZ1D3q!^~!U%B%%~7A*^0_9DR+2=crk=0waWD9Aw0MJ{hpUK5r8r*!_2VgWkaK z4+7%_PL0e_Y2ksZZLt{x+OmQ!H3mdq*QmIIDo&hO;SpAJ@%uc8iVAz^w{brMkaP(P ziE?aZ@}}v%G(V|&jsgp<}mlf(aB0SvAFQ@v~whjn!> zxV~Inq+Z9&NXZ@lU-`YFW05fS)gFC=ccf1)@s_*>x=Haf}#U%yA-Aey3|U)!;I3jX(WUs>+~cr1l3aBX3)Oq6^!(Fz~s z%3^(bMqi=osoNf`BvBAH1hp3{N3gaCJP<*6G1morSSEQIzCR^V!yquS*v47!8)rj( z>4}CE!ouCn94DV|nUgE=eMxL3A*0|nCU#+o2VpZrm?8Mu?lC_KHX#UtG{iJ=jx57g@U|$SinIs zqm3Aj0kR>Y=mVwThc35c3)4s06yvMe`u>DIgO~FUH1Y{%)uHxM;SeGGx;UI|;;_Qp zoa50D$f7Yl8A8g4-=ucizIQ5dwAA}!!cg4w4Rq8K9reQgm_^`ZVS6}6;=~SDTdj6( zprf6t8(Injv+K2qARyj4p9!%iykvXL)gH6jfqMD2kxdV>af;ce<6OjA(`DQ@;`OOq z_!sqy;GsVfRrEr0Aia^|&wJFSn1@Cv(aM38!{%OFLVZ)>VyIMt8$wn~%u8is>HB1& zm=>9Gw zmBy_u-6s%FJut+J1xFAUW$v4R>@=5CEUt7}dRL-$1zRf^@~{cpEEo%ZfUzPg^Fq4azNfz_0z z+L*a}kuh36ko?l!nBIH$w)ALbR;wJbrpe&aJ>k6X4Qd(;)_GZ95nWa$6u4nQme%AXcI(D56%1e(83{CWvlH zctsGma>y<18~?+9B9$f{5;)&!8pjRsBvRJ@<*1@zTRb9KaJSlZ>Wo^fV93IN>j0%M zO(^EY1W>vYpuq;am$&8vo`Y&0MU^I}d{^v$6jXNP>OJGoVCOswyJ(2&iBqE)I?tI` z#l$tUonB``YCg4F2i1gAYENo~ML!q>eAd_97zA{h1PS-oKsSeUlt~8Gyjvu`BJjY= zCL%0{_rfcbo~JYvW$)C-2*Z6la@LHn8l-qA04FUUZ2HU7YQy~)Qir31W4Lo?d0HNa zs;QxIG*Ip*ke`+}RMJ()M-7p`0Lp@37kj)-xACAA?PLw-$552zXr)fK&MOII#R)>R z>~LU^(}U3rY?YiIv`x`gE8XYuyHUfS2Nl6ze0q>vu^QB_m_?zIGr)mZ(6>Sg8mb6L zGhqGIidNC~3pcknPB2bCN ztt>2)kVQ|coPtJmLjhWM#gPOC>7$xcnj=1iiaJ%MDlqD2`@Et_ivgfjwDtQTM=9jg zA}@Xa{k%;2XfZ&&;vb6a6pAeWP-M}_dC4vsFh%xGhTZr3*$A0FR2c(@)Z=C7da6uF z!Fe~4gpPMzN`pAk`W;4L-RB-I*72ys+8ER; zAA{$U{%_%H_9;bzf$1ufsChz{_32`aKtX|KSW|6EIvj>hIuI9_P72PILMQb| z^#yF2;}^_{m&$8h>7b&DsDpM{dqVovcKso@Q*}^!SyUhJ)tQ5{A!5N?E=AiuIAqkO ztEI{jSIrnXWEJHps#T!)f6hBGuHCL-Qk~+P_L1Sw2Qy4}XOy{YPfjPYzt8-eDxGKp z@VGV>kZcdCJ2(+?+B#aKWx>o8w`^gC?4>|lR)h*PNto>O=_|G~F`r%l4We<@s!T?w zc(sK~phY7k>$`Oe4hxf!N@yi=s7qO9c2XUP=Hz<=fWS+1e#T3b1sB5TfR8B+u$p}o z2o}+#+6eguWx^Zow`q*Fx=23Ay!c#Q>FPk zRmW0l9Ff||DS8quO=R$EgXs{vMLPQ&N9$6 zI5c^z7@Ni6iy|x*i@MxqvSYEiV7D_0q18(@AIquv zSWI=QMpGr#TR)tk14Mo#gS>M{%YSWy@O#mFiwi-CVU=F^qc8m0FF*RwZ~WLR0j8VN z^TmbV`(Ho(NB_-pFZ|?-4KUYn|IUlw_ecNB%fIo=%K^-S8!FS!NAgrZIB(O1KmNk6 zJn*j`|IMHLBLGq)=v>|i`^U9tUYzF>Fi-{lKgY_G+LS?gICbKsb9k{PK^LB@DX&W5 z{u=jrf<=I8Pg8R`y*T2`Q+Wy~$(aDXDtZO<* z0;k<-aC82Q2$Y^r?+mwD(Z8}aS_f~g*D{rj))|RlB#E2onOi#a7uB`1na3&T(5oAh)%IaX{sQ9yp$QZBaW_uga0)`k3& z$BHZSxf2xIvM~M0eCvr~j-vV8!kSN7atq06CG*V-8$Ov|sY*8S+QOHT6BMM5SXQsA zl-i_i>Qm*Lj}>z#iY-)^Z{bC%*sM%%nanLG=!F_4lQ%7M&fc6m=56r`HOz(jXi;6V zMyTxs4boG~JV6wt)LXduG{3r&^%TEAAT{D1q&0s^*x!>r>+qBMq}j5kA-p~5!zu%V zzL41a62;YR?V2o}mR0VY;19PK%cs6?`M4GZ@$VVcjqi`c0?;!;!l~I7p~3{DJR$U{ zn6r!dokUa7lT+k2TP=(tw>2n|5HZxDc0TuLMUvZj2ZA2T5@;SP6cIL#6>1s6y9{mW zNa1=(=^li+O+MT8`F2TajwYZv1)nG<4j~$7h3i7D*JyWU`!w_UraOv^!2iuma7NfZ zjVteFCNd*;jI_Ov6lEg#DNNjFz#= zC&y;5nh8g=&!o0RdDeWyQ(DZd(C{?kO25lV(XIo?1z|?E*}We0d+lB)jy0h=Dxx}? z8vfsEoG-iNq5fJ)7*sM`3#ywwd;unwb91+)cOi<|SU?z*;vshtw&(dw%PJq5(rXYb z30bTLv#JDhE8bwXYzXGYzQL}H@A?)gRmati?;r%MR98!34V}(LIS6QdCL4`Bo7$kM z8Ghz*#Z#$ECJguWKxrOzA!G3yZ4WtgcSc<`IQW~fl(vgTMY=EFR))`#cu%XlM}3Hl zYkjoY!k8UDW<)uD#M7g)_tDW+$m}A|M?3P-XuJ5q>!@OLaqe3km3M&?G@;UBTWm#0 z2h-YtyNZk9^6h?U$@aV;?!xAop<6Hg`cVgkeu{5}k!715>uIsc4L<9u*am4bop08x z+PU3Lo}z*|PpNjhhy?a){aOOXcHGc0aHAQfIa?(c{-nID}tTb`Sj&XsGmd{YCx{w$;kIbagmcPRaJW&Yi*BXO?3YADl0a}iRRPi6V3j7`o%=lu&ed? zWOTKD&!W5L+o()}4k?y6L4d;KVJukMyShZXqHD!9TSlbIshq?$2AZDYMdYjKd7D;g z(-lo@oX?82#0qj&U)&aG-m^;_#$OOpuD*e8@OzCfl6lVf^gMFetnr!*u94+IG!?Q; z@_{51bdD$;o)QA9AR3FktuRu^CR-oy1L;!s8QU0($LVQ42r8laB0&`nlYSXNMTdiA zF|lOx90ZjF5ylGb!k6uIpZ`Cm{_0|o6(@nu`gfnS>XBse;OJGQmsa{FT23VaepiCb z2l%k>_lyntaT_$fcr0wgNvB#Tk(i`?al(spr@HU7wmKl&sO*aqzs*d2Kmn1uv7On<}BV(-ec$3|n?-90G6;X#5HFG4YjVi?oMLcOchy6?2 zsG`)^G28kgEkEBghY{tfLz|TsF@svCoE|6fSUr6~-o&Xot+=`84OwwBa&-<*3vyg> z=RJEayc!qex$yRGQ5uW$T3?c(A=6xl{9d*-Pjp|aN1C#W4pT~@(t%J@n8ImFaRP55 zJ)Gi6FIUP_&A1iypAXaz*K*p?NCRov(E=CU#cCT_$}K13FocYbzr}KfK@YRYLsiWq zmoJV{y*D*BSegmCAj7`&U>}wk2&Z3zrg_m|&!~(Kmb#)&!a1+;!Kxiw`SE$!tQ)0j zwIaHjx-%PxYG@pQU2Pm%zU&T)i?L?lixC%Ytf+8Do7W3>jl-BC{l<~iZx!<+AnuHG zt<6~3Xnt5q+9q;$ILb27)g^ercm<)P-DeIcn&lSucMG4NunRqmt>7cB4@azi6!Y(Q z(l+jd9RCDgV#{^>_<9jH-2m_&yTX_wFY;OO@lV0=XJ&_`MoT=te+yw0y1-;XSAKCc zO7b*$cZ(+pK{mUN*aw|+E+Jn0x)vb=Wp?z5PvqSPab$M5XTDeJ89gJi{gD{%7x&0=h1)!Q*bh9s5JFT+&1{mJ%qtz)-$X=^M8os zn0xw7)fuuixEOUpP@D}=p$NF{c#li3KJhPf zQbkIIqrHvI7RN!luN<-VyD!G%0ILRmEt~(aBD!q!(`Wmb4HJ13s&rjs(|d!A+E+`D zc;Ba8L9qjF(%5VRVk?x!lD-ML<7bWmLu;(%8h-+E7_GEkHtE=hK<7=Q^K$byX>?v) z0d64hlJW|FLXRaE!)Fa8%J+Hf9zgCpno3ZB07*;V;(QZVjA{^#9dtHqM0Cw7Mm0La z`K9g{rTNAkqjr-nC%1u8wKzr;siDHWa?HQZXxK^K3iw_?$)pb`Q)FzPlz(^e{BXo*cak*LsX@!ST4g0!&Sfp(*{15 z8miEQxZtFsb&A6cRB#P75I`T-1+}>M3NWcllVGS*1fRLNzyBC>&b9VF=UB(Yfrc;k zr?cmpYp(eibG+u5V~#oOjgg09EzIu*H%{(0-}g>4Rhbue+k$rNZm zidP2{*9%*I__==XvAF%URHy4^LI`n=NBBv++^(A$ktIloncc?^eDYp?IGXpr^A)i0 zu5^FbaDeS$iyy9OBm6eO(PHGk6tMrfqfCGIF-Mh>nnUDn!4aG{6-Bx1{5aO2u5{8e zng;%t$l`9P(NW?5@+OioLE8O_vxw@4nbLfRX4T`dJ>8eR!#d%Ay_p1VKeo% z(TwlWh%i{lW5#eGHNn(a6B2yaN;pvEzfnB}xHel{79{;_lJt_**ZYDwE^csS$z@*8 zogswieh4MnQgdSVxELbs-Sgh${RMLQKr@gGb*E0my|{)1zQ6Pb;OXJiTT;+-a9Kk6lRvY6s0ob_X@i2Q9*#>H~XNDRNhuJgW zFrOc&Rge?iYPOiDC_s5(XqYkL1`{x-Syc?)z-sjjL1H=X_$5QEm2$_IMIP1A?OY`z z{~C96#v5ih7r%Y4wtmx93x6B9<3rj=dQG_Fa_IP7TH_(KgRq`Z+IH_J-&6C`evbJj$cFOx$M4;hTL=sQ^&6%^8)D-rjB1j=DFz-rf?0J z=cY@TI(`kA=cY@TIv%9ibJHbE9lwUmbJHbE9lwUmbJHbE9lwUmb1g`-C(|WN9lwUm zbJHbE9lwUmbJHbE9lwUmbJHbE9lwUmb1g`-C(|WN7Rq=m25Da65+>$ni6G4*W=|W$ zL{<^X`uU9w%0l|)$PbUwZVjb{T9 z(G`KA2z0=by*B|Zj19K_T09vofUVu{lUVBKE2adzy&4zt@dPDw;&o&s;&o&btZ*9P z%6ZUrWF34l8I)WFHC_PEXJf{RtTDWpgULrf0Cyf$3+0%7oo-|7Eq)~z=EnK-L zjS@U*;mSQ}l;BAVSMEup1W#JHa!(p1c+$d^d(tSulNPSrlST=iv~cB~G)nNKg)8@@ zQGzFp5XINIZs>j)As28&q zE3hr(HP3b}0 zq?;!@e)p>D2*&C?`8B1-Z=Mv3jQ^ii-7#*6s)Of@X*wKSv^`1VfVGx0A}wbGEr;;k zuH^{k(sIVoa@fRst^Y4`G=9m0*Fwud()p#UB%+pM@ihKFJStvST~b{nVJIzUgcIl* zm}xmYjJTF#d9LMn(zF~;nwH~9({em%T8<}8%kiXXIi55v$CIYzc+#{SPnwqFNke^4 znwH~9Lw!#g>U+|(98a2-<4MzUJZV~vCr!)oq-i;xG%d%Irsa6jv>Z>Gmg7m&ay)5T zjwema@uX=vo-{4Tlcwc((zF~;nwI0qrj|42T8_3C&~m87=7-x?nY4zMLrfFXd{A6W z%i(rxX*r{nX*nntuI1nf$_Aw_*RvmOQu6MwO!64lk!#)KCIn<@&+zT_Y{Z&QFq|hP z2n&|qYDa-{~=tn1rk1>SHMB670h#e89lkA zZZ`UW(zr~F?DSNPOX@<988W}Vb^t9lWmoGQ0mv{>Y)6F(4xloTWBAiqN;h;W17#(~ zX7MwAC?wvAq^_7fkzhrbqd=7WkX)!VFQ&Jn6|1XWcc@vN^tyvRD^_URp?ae&xA;zG zN%j^v_b|bA*i@dg6=3_1>TLvw*l@7Vp7L({8{Z7@Gn~QL?tU3;6$ex3qZWwey;P;E zM8kb_3Xg-GUrL{1ofYJ)8o2I)JEey30nc!j_p{e?egBQTUun? zw;`FCUpVtpFwmH8_npPdQv$a9W9-uCM zVJkm68`vID((6T_jgyqPB1oIm;zg(QcspXp$9xyHFfF#yWWlHYwe(+-rBIDFMd`D} zrQ!`nYenfNwCI2ZJ|R~tcGYdC#8e4EB5aRC8wG^<(EhNPcJuVW)tI<68iGhnMZwZ#2dpJyG~ zZ^ZVHxrgDKmj!!!n+oo}wNNsGl>q{9i3!;uwh+_>If6RpN9!6F= z&)E@mh3F@Z-J7k6dif^zcqY1!8o*=y4GV=C zW6sw1)T`k8V0{by`P!2GYx@+F6|t+t=%>Ew_9?!$WY@;T*Ou>e7cw$^M5Xl>X+I z?4N9GlrP}op1DXubfOgxOG9*`K}in3$|;J@xKNPRzZTZDwriiS<=^TV*8*v6f!oe} zPrb9^okTV)8as)$eZguc*w{!!8=Jg`8as(R$i~K%->h!%^Jb;fxc}So+{Wffv$1*7 zY;2yy#wO5oIEHUFHqSL1ne@`0z zd(!aVlZOAEH2n9Z;lC#h|2=8=?@7adPa6Jv((vDthX0;4{P(2czb6gmBRT5e;;x+$9kH@a&l zT?yMsr{+w{{L?I;^!uECd5e|#l-5-6T>hS7HTBQpD#+GreX;)!aFv@MbGIT`68hNP zsvjK6)`=~$|7j!p&ssXflU2t&FUx2(+mwA5*YK#>%^70FP1ojJZmyfyQNtQg{^qo$ z3jUaD&zjj-GTG;@{!5*$djDVCR!^(PJ{%-ma}~#u(pR7obIF3H4z&pF(|QJBot!}BaQ9@=$yQJwk7dv z3K#Ys65wA9OMv=F*PX@6F2xgtyU*J~Kz_ur;029xSiF$7FmO|{#hn*@TEFqaw!fin zm_PF!7i|SH0VnKBymb04G2@?FJ_TZ3{RgZUKR4&Ws?J?f^RoK9W zm=?$ah2@|RIwaN66Tvw~9D;^u1TQ!H@ut>^4(Fy|xKHU|6u-wi9CGFN@lKECH^Ewa zQ~EvGA}AKW&$Nh$#qWt0;jr4hJWfkEL&o_iTqDKdvVK<>t@y)Y&k8_%Qoo=(j6Ew? zS%eZhEPH}3ilIEEUwF)M{lZcnm)9pr4qdeSt2xrI{4UWYI%-wJdWu1c6z zihGE!wOR+zdO17+$aAYRQME{~Y0)j)ZsB3ARp9(-9na?p8hP(LO2kbV;!3c6ypGfE zaUON7{M?dLu@(ufZ|kiUXF5;aOb5u|x^}?qxgfH9ylcxf??9ihfvGbBHBkz5R!u1oiZrpq zDYuvT=TLk1S6xyNHUr7R1!gV!V<*v4f0(H1nGWwx0b(KHOSGVkU_!Xy@-2V$Ku2LK z_+dGfmhgTqoR5Z^LMWO5xqhcFS3e7-C&perO?7iqZL3+t8TBDMI|L z+VSB11e96zZeTl8=3Jt^s+@T@XXQz)FQ?yK7Ki#>(&v{`?-dTRImVYdEIFw!FDNJ9 zO-QAQat&pO>cW?6No^>{-(9Xf)L%z>V>zZT*Fg|`35Y*qASUrlarzjs;yyITPmWVNgG!e#9-Y{E4M>-MXVgeND z^#bXMo~#`-ARQ1*`h(g=XK6|Kai2{uhgj1I)0h{|SJ43o)vHP&IhG(lHAShx0h1>- zuKdm`4EQ;f2w_b`_&hBd@Cz#A9EZAs{|WsV8nD_i`HUjq>^tpt9cPh3?LHdS@kg2% zrf`|jNOd$Zyaez(e=z_(zX3!<=;Iw0N39gx#DMLPRLjQ*r{#TkJPA3XnII{8d22gw z0>?M;*F-}@Q#3}RnXvt6xJY#$X;h+5BF|(bk3>)8$={tRrfPShLA4I$cv!R3vTfLh zmL(!pQn)76@*P4{L<57u=BiFA+f1*{#oY6HUZD=p* zHc}DHE}?>t>w0m1pK7^)JkA7H4}POv(!;s>7Fx}?Rq9%fP6pU&l8D<4Er(Fu90edE zO44#B=ttoc5)~X=M!1v0E=fVb85fLrsudg^Zuj`x6OkE?+p@?s8^zUO7&=3sMXK?~ z=(jZ6#uTPn3EyYfCJv*Sf#KHLFzqD9&dBp(+?d7X?fR*3|;~S8MHX)LEOU-Eze>P;h z=8HJoi|6!V&F|84s@ZgkK|-+P@kLF4O1cnh6jiLOldb*?n#>eh6&ldAX*bujT-DX8 zs6WMgla0FM1$ZX>nd6iqJBH88+zW6Wkrh~IGu1pup~__mA-sxE6{P!bwb*e)NOzUl z`$cf#n{9=`>3M`(jr-4v9D>v|(pUmcrzxXSLvRB05%&#FxiA(uNzU`mnK<0m`9qSR zPa#2R2?FqPO$oXfr?tpj1n;LhuLSQCeDI3!ekOkY%J6PaHpJ}^%%3ph5#xP4I*Bou zBpX*PsZ}nmGcKL`p~?K5WHB6TSWLQ~az#*HdcSRkl9A-f^8#m&GG4f{D1Pq$lNnz5 zDidrX2Wd6DgD7=pNJir)*UKq>!lWjRwhwdXbu=9UfENgu!TX1t9h&4FEP%{`OlFHG z+3L|ROYDxjP)!%9hfOig;VKj3G&yW_c|o`M&>9O&k|us%v_U^j*%NiQgy1i*B1f9q zYla`BJsmhXf;WI&R>#9LBmJ@7ILm$f^sGC&tb@2QNFKYkqtEF@t-SfcAJ7-+x{!&O zGKzYm+w9Cdg7diiS-H+`58H?tE15An_ke_y0@nN=YvzQX6GdB?o|U*XGpH>PdNX|N zx2=tviJ;5#YLlXbJtgc*aQp0xB_q*;sTLfKVmgK0U%|UjQ;vJ@KIv3t9J{3%j$Ld^F(b zcF7eK1nhBzVx)SkSzgOV;z;pVWzbMGJEJm)lv7-o041-BR!Ih$R$C}VHu>a@*XuOh z))FDpm}a}Q5R_s?JJJu=dia8^;qqx-o^hSqJtkWUt5mMrmXj+dUVttt2tPm*^wFUa zncXH#NuMakiBMB_q`6>JNBUp{BSIDkyTkM(Qi)V4IaM7;sWv4V{2$`K&v0eSam;vu zCs4BcSr;aOTNKe=s*0fN6%e80Nhsc4h7?Z?k|IC{mZyQGexH-BM+GXRN%wHzR)Ba& zDshTnfC5&3)B}QZm`6cPSVsq3Wa_ayNxoyp9fXfY5#b}t=~IG@8c$N`)G|<^@QJZK zmja-LY!Zt4*uq%Eq|eRd>m!doxl$f|#(=PxM++KNc)0>DJ!B*Qa=EnFq~pudE8b_Y z2RqLe-vDyYa8ZJOPmXZ5wSc1p+-dM}2D2<5KU4E@lE%ju*x|{lCHVLmuvmdq&MX~M*^_C$@QRn;K$J7 zCixLk>RNd84IZ=pD#?Nwf)!6UWWki`;-VqRf(b?gI7%+PfywEpkwpOO85=K0deh|2 zM2P_X&majR^!QBCxBKU)B_e_8CJ1A!E)S-xO5OjUM#?Gfe}E+hc|hmI{^;3MkOymQ z0R0KCN4@W@rE#xo!h}PzW=~+vhINLzux8Wkby$TbLS5?w6XhwIs-DsTuTaNXqC^ z*#SAFdO5p=gw_2hwsGNQxELueyXNRVMHDa`Qx|~jWbxjCxj2#hc>WGgWXNLf(BvSDbFotmy z&OW60Ex}w8FIqyJIe$Td4f2=3jA4xRcG(#MO;F0pvg9%LvM}18s->00j^6YQy3nHr zkhEoU#X}L&S`k_GqNa)BFAohi8AeRfgYm}rYGxWG89c|Nlar0fPLhEJVACu;k!mL- z>j8k5by-grkdf4^8U}@97~oJvC~iwu!~ni>lTF`FCfWOAoqQxp+v6*hwk|blX-kbE z>y>3}l&8KCy!@(%I2BZ>rBriSW zZfuR==aUZpE#Tggc`+oA+S8&{mezuQUnxJ_=gcH9L2EKte3kj(;)5&jtjG@+A6zSo zAEF>Sfgi@#{BRv4IP!4Qz?bER8#U4u`{T-i#MIMP^*@O}Zlr{-LVsL*aY5=4rvp!} z#2=SWpo0+O%|H8^Kkir5ANN`pP*?He-nazR_iZ5D0=r+3&47&KsHn&&i2#@~7Y%QU zzOZ@|+;RWB_Jy?%f;;Ya*|h}j+NaV4LzT7l1MPUzr_{XczhY89-jPQx0w#FmVgRzc z7&y|L`~=y9=JOcx)OKEJp03C3ditrZA|GRpw8-P^JxiG4>NsREo-MY@s9U{k8@ar1 zszKz-go{UFhd%V(XV9|bPDumqZ0e=tOQ0-s74+*z zs8jp()M@^u{*LNGO<^zJyiv_jEcgbHFVzBerHNT$L-0cqr4re^wxBWFiYKL!FrkeN zK@^N_#c^pUY!mWVVmCT6k(N>+2PXX)(v5g+J1i%O?(}V<6ZTaHBt#pz9=-&8HiCLeqaaCZn2h#u3Z7Z z7~|SAfMIf;mLf&ZD5}m3x+WY)Q$nShwlEi1Ml8&QMT>p}hW%9|)> z<~Y25%T*rSLiIdiU$kILAqoSNK!b|gCQdbSZ;R{i2o zc9`2=9m=-A$657TBTZV*|25EdTK{R{QHti7QfOYC5geh45s}*}cMevTX0`znWet&= zvH+8)zCmv6yg_daccir1f(JLz=f#lN6EVId=SwK8eN^)s;ZPdgGI5pk1nyMuDQ9nkne1W(sl7DsHA{J#Mt9v%YTTYEg zu9z8p8D|3_Xx?x(`1DBaY`}sI!eUE~G0wu>ntqaT6T?UOoQ*R2N!IFN+$wO7-b5Ir4Ys*gARpZ3UV+xjwpU>O%rM?D1<^q0 zxuu`tz|=Mg*gddW7cQiZ*Xuzx34{)dHwi>&e8XQr8_g-QM#VKDzAm3or&)Zz+Jht5 zxqdc$IvRu8NB5T$FaHGzrWg_WOkM|iXxvI;UO7f+@ZG)zTXdzPfRdcd;J}S6qc8Y+ z$db6=9FHPDf&Jz6*%oRf>eIvOoj_Ss-|xw*a1gRUEg^_n!C-wW_{49iz;b+2miY z$|s{i=#e^@6{Wb7CWjFO#m7d>t=~D|(4egI0D-IL34A(`g)fmJcEnQfLzSQMhB57u zFa;^tovlBrCjfOIn-(pbMlFUuPv3=>R8)Q`MW*2ZgYVFYHx*#%ZDed!0S4)JXo}1f zNN20~yUL?rd1RgzLR>!UI{8RkvgocK>GHMsm53Fdnz4n zYQ91fTb9PTAJu)Lf+RCZpObHzwxn9THu zWBqLL9cEGBn46|wLPM{p1DJ+(v>$q*}>@Yja=Li`-QZby+O;|AbJlKUCg zdm$WJ+)2wGBwoUjh4%BU{BS()TlndGUH;9EiTvg2m0)Yor7f%ni|UWExbP^d6PX?E ztp2o-hg8L8UQ~Zk=jo8*tqQMQq)0NJw8;paJRRr!SNy!&1@8 zoa@UCf3qQ6xl#`)i>C*vi1Yt!x^r$i!l9@*!kH8)dT>QlgUqH`otw_u{-k)g^9qW9nPfXAjeq^`;XcW4=0A*0t0t@bohnPGe_@Udr`LB6wY5$vZ z*z$zX*>`4EUU8%HiZcd-n2_$$8T5){osS&I)C_aim#;#jEsp={jzFCPPHoBMq%T(aO#joI%yskN>QC%x{kw| zOPO*)o8FSE^mlZ~5dfbh`~d}g`ZDA;z<1`HWS8= zSAp@C5CIoM+Nj+aWHXA?tC8ulTKO-CaRFza5?fyhbJO|?3lx}E9kuneT)-3n&b3FCD(mAYPOEh={TcUNl zaSn?QS#XA7oODn3hAq)R09WZKN`sCG^oOj8IFV17HBp^rWLS^X84WTmh5QXhk*Nd( z6~!(x>KS2HlxYh>2VN|!QQJABFmsT|P$!P!%@;etXlPkdB-o#o0aVp1HPC>n-Y^rw z0`E_3Q6RBN3vUJukEgLq1NB~$m#S-G0%m>kE~E}9pTW!Y>=>X78HENi82Dt&(1^8{ z?1*eeZocXMcEGK0;ztgnJ#k$<+fvC-+dNM^11+C_505SVo_73T6JF3ApUrJ0Eo90S znBp{k!RU7dGPgf&x1&^3B?(0a4hFtQM#IE-9kkoGb+jYoNWY6YGvc$Bt42xzhyChE zL(g*3UvOpX?}JX|#P!+l>6g1(HPVv6qdLo5PWgFVjmyCrE^f84s87}wgZ5P^dWmrJ z`Ml3?tIy?HG=>{ovmGA>W{t;~gZgZDkv4rXyWoj0R~W&LxklxjPj_s{iy+k^>2T+{j! zfYfzuid~{|wI|sbD$nsG(`?g5@bLf2v{etASIYm1p^vSCj7~5s*;Cxw_yG=xAw>=D z-JcT@ySCt57&;La&t^Y3VtmZW#r79I?sbVVTjv7X{3sS{HyC-g@r)m>GZ|L)Lqy6tmq}sjBtrY_GsE z-Z@RkZ*cs;XN)%)KG$gBb0bb8uQ#n;4}(-AhD`y5pmO6>U{k$?;uCMA;H~!S-IRb$ z9DW|=G{Re}3;wOG5%I&szlDectkdSwIC!WhGS?wE8Kcz42EuaE!*`5tb9@Q-Q+*Na znpQ=^8Eqbw6X}T^CUb-h_+-eReO}mBGlzfcY*CC(FfvJbdmQW?i^w?p8?L?;46@$If&;f8CmmmV9f+q zA7ITBXJgHx0vyvcQbPNn*E(l5jEQ2ZYlppHV0M%+=z^xRBZi_<=aXm@IH(TTuQ&FlJC^^_&{RsKZAwgsY0%w&?sy!+Ohj(t;_C%|0 zG9hE2-d<`ZFa&kiTZ|R1MB&kD$=MJSYZ%vHqCp>sb0gJ8T7fZcV{9&VOazfB^+qzt zr13AY;Sr?EuagWi=Rc4vob0*r_ft%VHbLQrcwAqT{alzHM#7-NCa7@lAE(_+jq*p* zlgj^idP=-bRQHpEJDuMPVAag#>;oo{HfKj|r&F~HYM_!i7C;&{JhBW&1Y9`rz|eVT zs1g7#1<%E>S7lSHcSw8b0}ZhZd=Se_FjK6C#(@jq#0T4@co5)}p|6GJMVp`)>J-=w zntRr0EBY@3G*&v=gVI~)9SVN^4Dxf0Oh>b2+bA+UJ2Av-c~4Tz~{xZ;-lvn`iee`x+8n==A7p)0UeX=<+2h9wpX zX5O$aFBV1ij&+8ZAd0E+!g3<44x$K}84^Kpb-<8)2=(f~33V0Of?!-7Fw$9;>xOH} zx24je1;R4x`RGmMsuMLYu|NCzC2kt!2evIL>=C2vA+oHN_H-ME?F7)CaD63cA(jf@Y28eR2Q zTq=Cu;8NjeTq=YH29^pKaoj@*x?-t-z8!jDz5RGm%V%k7Hn@*AVoE0U?MLfOiRm9A zs3cPWf&;lErhV|Kfk;7yRaUjP5y2m@ErBKG8&h&)l1WY&m<1W`iA_frddUo9S_bgc zlrtdXoN1C=o(4`N&Z#$u4pWyUYt^9i0z?AZrmq)-TAFW~L0L@oI|{&MlhMISQQJ(- z1_Pt2nk69$4p?;65VtAiQUthcs0 zu*I-FX?0+#vVF8!TPy!4OIe+gY^t)mm9O z-~N|;zA6fpSH-Q}JY|?0r^x#cWDKlB{5tYyW;OC>gCqRf1_hNEzlJGq&fwR~n(=F_ zACX_5Lj!@US@0CM+8EB-n!%QYnwx0R2^^ZkMb4;a0;9%B%gi`ztPHFbI1#2;6v9#; z%P^xpm+VJ;E@Z=rd|G1@W;>sbYXviQq>U@L!H2a%v0bAY)ObRkZFlkVWb`4T?qdy~ z8F{QXc6WHIb62!V)Qfgk_F(-HXO`)38ZPY6%AdEkqq3cK=vwRXlW< zjo-`D9@BUu6&-N~OL)H)uh-Ns)?^}$&yh?!4$Cg&R@R|T+7~Qh*P=fVD~@512_mJ? zl%x1YUHokVN0W(P3g$iaQ%^8$M>l)Il_h{#?_jV2!O#T07o-qpkg8Ln2}JcrK((+U ze9;8z2S#Fl%gK})Pon{-jS}oH;=tPIw&=itxn!3coutbF9YU8ub_Q2M6V_#D!nzDi zth~#gZMSkR@#;kPqLbY3Q(OwhETH zk+RIgsE=eClYy-Hf7$w2TuWqCKUuij)44r`-J-_rL2T#b_?t+_VN96uf=stLv$(2wDYnl!VXikEJ|Ts+IR=pB9V-%;CPWY68z zSq+{kjM`H1p_};dKXyRLj=pDM4;kEWOcZi2@_UahWk%(9->=OK(5FtKGm z)~ZZc?*Tj9Segl;m;gJ)U=NU)9bm8rrooJdJP;;Y>*#7M1lm%pFrl0w_*jqaY=z%u z)uYUbvd}$SZ{e#)!5n!~bbrzao{f3CG15KGjrC~%o>Gj-R07O_AtNbPa_ZxDMjK2y z31r#?RKp;EA&$N9KIpcdPv|3E*kD0m{8|p}K98Y>^3(3Ow&cWNVJEt$+YMUq2j6_p z4btWxA~c71DA|UTa5~4ru2Lh(HBj{R6Vy_{plbkBx2orEuc- zHl_{6V)1x1b%u_SBf)b5|CnKZ^c3C*bt@*N<}PBJ+JynylT}M>l;ZP!936o4*v+_= z>l=@VXHvts2zVl(7bVQZHfah2KL}*#*%CKRtn`?hd3iZoJVuZ8%T1<=E~{VfdmKLqoTT7M+-gZk5QtBhGTp=!(BxjRlWoPkqsc*8&I_T*LH#0M`3y8s_adsy z7T@IP@y!^P=*Nvhk{nEb@6>z9*qj|QwgA#JqC?f{F-QcjWvu3?bO8f0<7T{`RW+_x zjBU6dSpTZ-P3YF?No1|OiNeH$ThmU)E%MG8+tH-`iiBFys)`qWU|IX zSXjJbNtextv*vm$;?4TgWWavOG?!}_NRVVG2^^v^B=WXaQDzEc$CdB3{$DI6cw8$Q zP|+uyM`}hE|^MtqcQpir2$fc28cEMFpTaE0v@+i-d-IL~R?MXv+Pa3j&vNu@~ z_s2dnWcQ>YyC)6VJ!#19Nkeu|8nS!RklmAp?4C4a_oN}aCk@#>X~^zLLv~LZvU}2y z-IIpwo-}0lq#?T}4cR?u$nHr)c263zd(x2IlZNb`G-UUr-KXS9Lv~LZvU?I_$9a6d zw+dvRa%5NZKaiakZGHxkoui^TQL!vyJzB7C_t0(}{?-}jJuR7*e01_;iEvEgE+s;A znaeH|)<)~5h1EI$(Ngp%RHyzqAK%e?pntCJiwHik=YA|4QILABk3pwMFGxWn*86p* z21`EI!_TpLMa$&tVDiJb4WhS~v}xCzmH z9t$B{aI&mC&sIhJNzW*5Eh%mBJxZJWYs0fQ!y-)A0`W5y+^yo$hN%9wYFjms&%$ma z`TUFzvlh$60d#%PDH}}>`TV0jjFyd&Wc37L}I`QSCJ8@aGxjgMHHG+DWUM;mj$)Z+y_+Nk?I zJrbgwargTHR`$iJ(n?O1p#(3%U~u^SvMrrnN-(q5zG?b@Q+l46x`1XbKv}$?YM1=G zd4nVC$9fl(hOuw!ZLk__AqZq$dF1CHJ!qrSqDC&(A64rj{V|uM_-41*pg+nDoC@|M z70|^mMC&V=B((DKBAH-FLl!0YvO)6-u7%0byb!@obJZ(t{(3!{yQI9BZ~B*L58?vN zY)^B1fhMT*6jO+!TUM@TXI6Ako-c5mk24|zV1@9u>2IgOWMg3fBBvqzv^<;K#>D!P zo)01tOo|CaGF@WI4Rscwh;ahCq3A|EBDXPqw~w3EtigB&&9@z`I=|KFyX=@8wqU0y zSwRMC!7cxCZK=BkPXBCKq%uJlMbta5i}$tIyt9Oot`2|nu2cndWXRxsM9@WlpViS^ zOGN_<0iFk}Xk~C1D$j8nnqf6l8f>1ul9X{HCRQgYdwoDVD+6fSNiQ@nj^&zbLwkXr z85V6oD5a2}l&sX%3uez*g+^e`ixJSG2m!h=h)l+ub|oGC2V}+3swAi7FZ|*se~R5r z)yNJ_dk60pju8T08Ts`Y=1VQ0X3Js+uBsgT-0=_vPN**E#8&2%?EZ$TtZ?9{D~E~( zDzjR2>q3=n$re6vV!=-J*SVVQeqbHvuX%g>{tC{NJivqoJuy*{|tI)H&Rg z)+;9f^b&AnQB%WFmb5i{GM2WmTE~3Gmk9YQX-|G@`@@LA7)~k zsLk0!AFP|0%@*_&k;P_L^{QVw+`Fkb=nt1lMw~HowhX`tb>2@$PBy1A!o&b5Zo9I! zanATAS}^3dBhqF9GI`ehP1;b002wJ8_tO1ynTLvRUG#&-;&;iuefDmPb<3nVE5mjq zg3&m6gCLy%q-;ikA4ek)4fo$4pH|T2B|xe@NMT{ZqNPB(g0}yfLAq?Wmjvm?=H|pi zl_0Dbx3YjaTtA{H076c*$=U3~@hNI`;Dk-Bd!Wi3&FT)Wibj@K?2)nb*->{3c`3Ze z;k$*d2ZI-DgQJ>=v#YjYhp^@yI5)A=(-N8)BWTl*aT!gmP6^VXP1(bGYLaKgUM@Co zF;VeVg{BkZ)lB*hNMTJ`MeUJl8l6MBcFWF=KmNj}e(EQ_@H;>A+0Z#Sg$-{Q zbOXYs!phr#P2Ej)tH-@vNA zymk792}=`F&FPoGD}861ey)hn`gzO1E;t1>6bk^SeWJ4f&XtTGiS!5HX0soz8Err{ zcwPg?n!3g-0q*=kz_IH18wA{jvjDEvS^%7usb>M)kOpHIw@8Dj1_AdlEF>y2Lx8)s z$+$19YW!!;FQV&eZgci?4UF5ASwJ;Ma2L^>UG?R7l-16AS_d2TF}jPP53g@of^iJS zb4`(^#YP-?2W3D_KnZmb^Jq3f3@HA%zRgALv+&UPL5Z|r{2Tdky`Z>^LRaBI;$PIf zDeP=Y*#Z!KxYXx=>r?;Y&;Hv#`WVhM}Re`|4iEQ%2kEyO#_XatTOP~24|Iy zwM>&M(E!fYt+VS?EA4Fn;h<_YfKL6v>AxgRe?lk2-Ud1~8Caaf8UqG7(xuA~R`{-= z2Vh2f9TqYd`M)ewmdIyYU{m(bT$73>E0BOZgch@BL6g`vx_hWkgh3=jX}Rkq>J!6 z8`52#knZCHNcYjdPNZ8wC%)Q{?(#vT+w$5X-PW@pUA@`>>8>cJhgKVjwY?&i4Y9E( zq#{Pa;LK>~9Qu{T?-hgA`083f_Ya{3jH7K;NXG#cXz*^;#;+Vmdu_^n+0RMCorCA$Zjb8YDsFTN= z=7oql$@T_Pte^)g#QRt5<*QZ`m+kxt@c#P7>XAMBuPbp=0?1pk|0I->uEys6Y-U#n zI)XLvJ|0Vn=-R}40QQ!%Q&GVC;ffB{%Yi-w^z~RumNw&r3FFvH9o ztqRY2l;wXHv7G7Hlzl2bB{UsWKtBjNpAP68BAG@5>>%6whQ{1HS&!Jtu=q>z_!zXT4QPLVcg5OY z6FY1{X!BFAXBRQ8C9q@3W$o}%B`t)77tG0xzH9+wv{bpaTGK>^w=RbaU1Na16B%I3 z7FL_G-;DTR*zxb<(=yocA(nV)9#dNXdDVwc|D5-)0q~h+hnm}*#IcXRk0)eiwIr*dE zIr)P)3pOXe8=sb$lYb%sw1PRgsj;?ZPQH;j@wN5y4Su~Tv)e2N%tR}jlbgTXIl=2y zmh-q0*Gj%-y068Y)Vrt*U;A8xEA=oZj;DVrpeGsjg*ZdYOhL^GQuyb{GzZAy9Sxm~ zKD;xKMZ-31WYJjVo{cQ(MFeE=uI0`0qJov$m0ua^!8jLXl~x)-#<8Ol^flO0bJLok zDu(1MfcwkshYP&GO5oS5i;2|I4LKPdXb=njLMN>aZnD{C1$C z<}5Ww(CmfO!dLZi6V%O0rBcL-nqXP36B2hzm0xc9n)Nj6Z$hOxutxcG?v8s>W1A0m z^09b=a_ioH`%*;W0-KpA9loQ+#S&ZcAEEX=U&oJ~iSLgpr#Dt|RCr8h{-k$|qgth9 zCK5;*V=F7R;}nnQSFQ_030qNphN6Hdqp(f z$2hgFARAJ7NA$U$BjZUbMnAW%bn33ma>g58HXBcUweeo+bBv51IkmA!ZDZJ>5Au&p zIUIbG3mHCTUPj^kaFq%lXzkJ*4LiOX4O(lpmHy{+Ouse`&h~Gu#}Qs}U_D;nW8PIU zoSk}Aj)i9IXwO7?z`-g;8&F>i%HgHpj^ixn#)`&FjaSDy9Q_33IUcEid|a^UkLx%S zM?iJFhF`q2_|^CxJc0x3JQJOu9^XogQH`3>i&qT6MFPIEn4#W)Ut}Oef4$u zqs)dp2p*A1h&W3(?IEAfD61>WS)ft0mzNoFq!fj;jiZaB-Q;iQh0gR|Vn|qlk9ojH z;g(>P@rSR443>q7&hAYxWb-WG##XKc^k=fI6wuSzPe)1mOqeiYGKK@aWld6%Zly#Uxz8jXWCg_v@(v1@|M$QtG&=UJX;fT;aBY46 zLw9gc*0DGu>zGiK(>x-CY;rv7e%w<}RgLM!b?#f);P&j2&~%RUG=J`wQM7vY2Gc zqS_p^h;Qike}8>vjEO8B9C_e%k-eNAsrd`usfsPjPa6iJQw<9J<$%?x$}w{kRJOwP zf?gaD^{si{(3_sFWp7tUagKVV?S7VhhUG}-T%!7(bgq~;#=LT!qlY)CU^eOP)qg=} z?h*#ExsSxS$^`99n#NoC?pRLWyum{)_h%SFl@qaU z#$k*rIj?mPo1eG$@Df6J?dgf_5RaK7n$}YH{vHc24!H4*6T9-uv5!CWu^!zm?TBp( zR-?nU9Dv|wj8Fpnba59|b?_p90h1H|=$(VA?C}P0N_D=7|EI!0C;kU}>&m@d;j+47 zc4O335Q3lu<5V4FmaCk1!s;j8^Rrz}d6s5@Y%O-+zINd=IBY&A>=qwotu2=&ZEa6o zQ;)_QusHV6I!scBe;b!nr?)x61j+sCmGegwTI}ZeP@|f}NVa7o;^w%57 z=vX5%x<4Vx5IvqxFCO*e1tby3%9Yax0nP+o#iE`LIM@KQ-U4O`o(7ne3z+@1LIj=F z1ehnBTi_{)y z*{&YL2mZqJ^bwvmrl%)(vV#j&@=2a-VtHbi1|l5J2!q`r#0Kj*x)xfXk1mzCog(Hj zsEL#dvU^_uzW;b`Pts^j1bPlIym-P#2M=WGNkkgVZ;}waA4>8 z1d=!56HCe=1p?uoXc$H^YFlv%VMTO*+SR+l(HOQhDRhQyduJQ!U3djNjExEGrr)Kx zaweeM=DfzJWv20YS#ThRPZiRK-hwZNiB>O|WucvHERSQMW&ku?Pfoj1F5g^CE?M-Dlki{r2D=!XN=G-+M z?1PvsM@$A#f2LW8O0_`Yk#r59z`TYoppJ8tFgr6|Z0fKdN9#`tvBwOtPbjYa|BwT+EY3G>x;{l-x>C?LFAL;*24upz$1D>fVk7w@?um340U+Q-vL?+DR4eZG(roum{GQ3P`AUOnmJl+-2Y}XE4{O_t5TS z^#s`_gzV`_o=o`I)2Dg5B$a%cr`M&Y&+rsEfOHe^9fho%*<%eEK>F8~oxNm6QBCv< z!HI$o9_e4Vr@z+7cZO$4g9~f*Gz6+H*lLWjJOziVkTs1}Of!JR*h0i=~yD;RQ%EBc3M*B;<9 zQMDKq|1q9#Z{SQ(%@}0_Nz1slypE-Iu^mL0ZeOdlFaTd{PbQCE(UCV7P zBO)7tDHmxf$|JxsdIDpUusbrctwOb#V$*Vz?)Kd@;4^lzA3VtlEY+CV1>DpXqmyr zMUXheOF=}A$=>EB=h2Np23|1{FkzMoJg{@*HsvPz-4BZ-XEo&;m1T<7;Ul?;s&zhqp?@HvX%lAxk)j=O#)9SjF&izarQ}Hi%KlTGo8~~rZ|gdI#aex zF&NKu{%x7!GoG2$5e~1&fBrl+ljw#dMsMO#La{WmqLk(;cP?? zVt&)6F`TcCPMgMXfhT1Q-JoPtLnp;J;#fcv5z3@=9?wgxa8j(t^AbnIh!yh^W1JN8 z@^XnSN^Xd^Q8ku~$dAf(>c=|qKj6%n_yA|-LMB9_@>pOXF$3&2;sqeDSiu17h5dHJ$8ul5iAAq-4xrX zQ{BI(v?2=}yM6JeAAF$9?*Evs#N%eg>iKLxw~yuX)sOu!J+QcnnN9#bKnT$4u?P2+ zBYV8yaFG_(a=<*>@ugq*oh|Q%9@{;>6Zb@tv_D3(e~{@yHtz=Y^;=BFK)an+YQXIz zooeF7;Yy(I!R|^{g=Q2$O?t`JJ-DLFUh6XxyRoNwL)qHfeM)kL&dZMAuq<1Xzf;gg*`LyMv zZUqvcFvmamMj;|?&}9Ja!m}_0kaWQp;jCxKwD@%Ht5G zB1kx{(@{LZ>V9HzOtMQuFb32zsb<9MGPAQ=R%PmgKlr_1d?f!f)<~RX5nx-=sn_fG zL?(>K$Aa=9Xje;71~e_BivFiinfz?`>E%3r&fTrB7rUWhR76(1OYyhVU1n4Z0TC9) zu`x6ZEdrhlk^EEbpVAE>pm{uSlu^hiBVHaf9=xq9(Cn+K()g|3uO z>EikAyt|YkXx>}Wd@SH5VTbr#55Oj_QNIM6KNjK}#{@fa&W;A%IW~ey+Gxg3?#qPg zXZQyi^jqK!03cr|$!tl5_I_LzaMFC%>TYQIW@$xpW_|j3^{H%a&X^sA#jw2x0-4&p z5h~UD){J`JO4nk&RZ$(bfoQ79OU6q*EvuS{0Z3YMKeXY!vCg6o{@s-+Pe8rEK)N|Q zU&ymLTd#hxuUB%7orr{0@%C#VNyLxZ1kWVc^ols0ZrZSi^Y!*rd|SX-MbGKJm{xT< z-pjp8K_>^}TF`D4LrQSb=M!<_NC&Fj!4{Tw1c~%VJFF6wW=c;wJoTWQfqC|-*AXxhp*4D z@bWZuPjy;PIAHTMa!-0aUA20-Me%8TLu?A3&bg<0amjB|m9Y)nzp12H=+EaAMrC#)v~{4nOJ&C0&qGvVA0U$4>NtL>u1 z(LqQrClE`tbptB}-1GIOV?#)RSyW?jD``bapM?T(%SE9q5g>o0xSNvaTltba?LF0# zKXhV2b2Aoie20Rn$iK^c^6hz2KN>roG&zNxLV)Q0VvwkOC}j}DwmrGvvDW>+^qS4N zY;r2wapnh}dFg{sJo;~ECx3J#9|`z}P(K8r$~YvX0hil{kbejs*fc+I%+lhY7iE7j&K!@)^da|7lT%r)%2O%S^ZHDKHpa!3e-+1?%@uigZvDJF8{zUsHdibNhx zFyrcV(fyQq3J2k>_)QzEFzL-$SM!QdtTL2gzJNH)eUv@Yzd{WfWEkk!A(PSCHSN$G z`ZKL=&dMG_O+AxfEr&XY5lRCsxqNrLS5)+u4-h+JRqKWgRqN19y9Hgg1i4f!XezO= zZc>efi<~`g1^vqJQF*|qRIpQV&nvre0l2^&BPd381t&2e@yAjdXN&IYe`FwHJgj)& zNJACsiYa`rQY?ZSCC0_G+WSmoFMUkA%eNGY;+7=-^;C`G4rI_NNhIAQ^(ZN|}TbO2GZWji4ydQm5`7L(2-sT0C(mKu(H!~LKa z6O(@*S~naKlYBZOni{18)PYn)%-DVOASy4sUhfy8xGoprqj*v6$?wW*PQscZsAQB! z4x{LZfW-wj?y&$sq%PZ2+3Z^W4jgQ?^Zc1dPb^SU*7@-AQoe1$JX~#%pR>toae|T; z@S&pnF_%Q^4SE^VAoywm9epNy#oI{b5?e>Jn zsRuN%PLMFcMi(^7JK2#E=08Odl(o2>;~7Z3xb^25R1)`v?CUYEh2d*mTksh3CQN^n zU#7G8Na5_b`L_|nD)=F!7*@KYr4Y{Sc!>EvK?TnX5kQzyfxdp)00jRrlwwlvo=cMcEUME$#Vb+b6DTr8VG|5 z9cNcI#8z|VCrf5CwpJU*xPj1H^$`6GP(3-_a#a{%Cv=<17#o_LiN-|4A>ri`2KOp^ zUI)goH7h-DgzAzVT(gxTd0EfTfTKGe7GAO0@Uqa|8CqmRdct?S!Q24wc!McLX69dZ zUmRdb$d4NGK2H%AR1?P=XLqEY-N;cULKe6XVdCgAQPz-L0&CCUWnnC37;9Mu>!Nz# z@WmL>Y*bn)bNuJZ(6Iv+PRn3zm39BX1{nL5LfqLHG{0%?a7qia$jUIJ2H>$ow+D$0 z$F0bH!uLXQv7=;PmBdv>vPl~6c?#pI2@Al$E6O;VYjU^8DZ}K8*p4yBgRJiu4BjSo zRv$Y%aFEi&?!O9ie99OjQl=(TWf?I>MuS+fKJ=#&7qTuQ0Zs|q-V%%@nS}ghWW4-A zX2IFe`_&G9hm4vRw5(%!N24xA!Xv&BfvAJW zi)z3qB{G3vWMz*<^^Dl5fz30MJ0MsknP;oA$-%T^MkBLY@SDd%s94on7Ij*dBb8+t z&RF%KlqPD&F<`tvz(l4%e4V-2@rY+hF$kIo!25YJDZ^!Zh1NV`+Dx9K7%C-0!?Cn5 zj{P~iq+-$KfHvhQ#5E2I@4n#mR%aqsCo2dlgCQO*T^}tYo(BN4>KCzTGWSNTkYp*z#tAiP+2CueE22K$=wxtv#+svovYO z*>9XUs3eW!&PVg`OQX!NEvgd!CsQ#uf2B*ch^QJ2Q$ILUpIX4S(ei#&Y-+G>&?1AR z*1aRuZ1gK`s%u|vy37Hs7ARdExy$-vD-L=-Ry8C1^F+||c8u^(;^o#2)0b4Q??Lv> zpyxcCY2DCobA`1=#G*K1X1c^>rKlNR*clb0|zp#Xb~osh(9bR;B8Mfmr! z7WCYc7WCYc7WCYc7WCYc7WCYc7WCYc7WCYc7WCYc7WCYc7WCYc7WCYc7WCYc7WCYc z7WCYc7WCYc7WCYc7WCYc7WCYc7WCYc7WCYclZx=~Neg=JNeg=JNeg=JNeg=JNeg=J zNeg=JNmj*UF~a`{c7W=2wtZ7w$~~1nKelkL#^yDNhe{&+w@daQCYy*SFOkDcKH<;V zj!*z}Z31x9NB2jhtII4B3|v_F#`;`(Vo2@N4ZWGU3p9z_J)Mv5z>u)vW8eL$VPELmbiuX4MZB_2_oRC&%XfoFNGT`JjBLYtv5qJ_Jz;ZkfhP|OT;Y6SfNQi*CZGPBnWCkM< zaKmb+oal|oL9=t%&_37Y7AT;G54`n_W+PMEa6^$H^Dt_8+c!~#xY{GZ8jJ1ScjbJ? zl#7ABiM2s1?3ju@`;IBvv18!>3|fKh@5izO*=ISVX4H0X+o44wyGG2sJ6_Z z&Ui7MeLqTut)ath1%Am++-<3f6hRzgxr|=1)S4ERK7Q=S;6CxnY_rsS(#@O9p z{sV`&EFo5!c2yf<_t!dkx(ab2uXk4pX_pksso1>w|54Q2MQb*qT(URgl&$g-lRVaV$p@NF{LZ7;)#VdNg| zY%>GZ3@K?$yqN7{GVhRP%Y$6BFkv+*)@G#E--CsmFN%3~mt-R4lS|p2FG3AOTqK2J zN!fEqp?s=HNpo!;%|OiV)b-f}FGi|0+L@y0h^k}prm`EUPF=(1#T#`ED;TMD_f)IY zbX#RvORDVpKIUewq9t3sB|1DQ^;VEeOhJ zo$C+Tkc1T!)vtf)9|A=MM(nanpYJWRcTDG&lU0*@s(TNCmyt`~x zWgHdjv6i4IUAm?9C!1C!8-8Lz89o8wxUK5oB?QPdWQX{wuW6A%q%8J&t0el_UO7Yn z*_Ley(FX>=#uz$9RUGymHM|ROX|jCF!MT=Et5D{Js5g9P?^!N%|Gm1bE`b-?ez6b* zZGL#kvR$X<>=R(;EiF^o--FPM~ax4rX%i2RmV^gT%!*Y?wDWHrmp6!Y;unID7E3mvnAE_8I}Q$u@aB zt^MkNnv_D@FGWHZ-orkp7_4FL+c)Ti?(mR53pyW!qPdYrOxdyHs5o{MlEmyRR5FBK zd}to%WM#JZ@F9T#4rfn??p!pg)?};hG(6&6VieZpn-19tV+PdicW5f~Q=%UIRa>SE zrR3N%_m8O`=I5m=DYSjAS$X2eH7h`s>7$&$%iOWU0C$T%K6;pfjgM-BeUvCYUHy#| zvcVx>)7p_+A*IKt5sSkV{nYYL2+Ze_Ms#F^!Ho3KfXfU$lX`RudLMwHopd=dEwbPQ zFCzekT3ZD?mji`OI}L2CVdS07fv&}9K8YRH@*Vackk{~(?HanG(vK=EX z5*9mvl+gqDigr-B1%AlDpCTb3h(v$)EJ+K1MtT54h0^4Dgqa}{L({b_4Hc=v{2JQ% zzO|hq2lgU`((W`IF+>FmN6ImJX%G>rX>e?JFm}-b^b2*tSDd=2Qq-m6=S*Eq7ky3w z8Ml>RDl`Eqh%V~(S>ZM|eG2(qVD7 zII(QFF!_mn3O~d&)x7_&Iq*)P9ss$fXaYaf?TcA+!42W!U=1J$l=+Tnz$Vg){1Zk& z4pWrv9cC1utEN)iF`%vx&{0+7M6dS>GfMGEX3Kia)Eg)1+*C6XY1fgFFkbOI$d+a! zN6CBe3ir}5HlgOGm_`@`{%bXZFt5vz$RJuUznqyAOsN0CBjW9NR|A207{L=ZYlbs` zuTPaMVnH3B&3;D&&a-nBC`VicIE+BTh3MA+Y?G(@BH01V!PzNCeP-an9k78K^1X){ zT4x?E%#+}1XoMADs7r>>;$xvp#&dX9mqyjIMwjy8E*aHZZ?r2;4>cWh)7b&NK=(Fw zkmlZ54=8aDq+6r4A;Xhm+r3PntdUDjkRwLmBd&!&Ty6=mnM+8H%|h4!TC-#AWJdcM z1>hu8U}ZGc21&YQQlcC~5nx)x+^w`%A(qM1FTvdN0p<=z6mthB7BP1%-C7_8m9LDk zi*f2E7~SVcr~OezmP9Cv7<;Qhj}EjX`jGqj?syc1H&3^Os*vHoT0m(-D&4akPF6j5 zLm%f%P`5iTw^oc#`s~yCOc1kWb2*B)C>Xab=BvmFs~K{^(#6|~=TwMx za8!OKBx%h?PYEL}jwp#4@Msjct#~RthPRf>+b5L`GzSY?E^j~WZ=VToLt)G1?bH7D zWOy42TP|-u<8M!ex1q4*^7dJOdpf)gg)Nu2&-vRI!rM^Ta(PRCPx`Q{=e^*IphSo4ewpgQx0VYup7ggT1`As*Z$IsCp9yb6 zVaw(1)Bg5kcpC~^E^j~MZ%>7{p|Iuh_E~>>I=l^qEtj{?`P&!5+fdkYdHcM-eKEWZ zg)Nu2pYyk8!rM^Ta(Vlbzg^JcrY>x`JihF2kA}CQu;udhA!Re6;cX~vxx9VY-#!}N zhQgN1+YkBMW8rNmY`MIB%-=p9-iE@K3q?c5#?R`4AMt`H@$WUBXe?GTCx|^#95FIq zJ-FureEeC_hH-VN6k0;FTIWXxC=s0cL566RFPS#R8W_innv-S~ktkW&<*d|GZ^U=^ zs*E=ed$xl|Vsf67>kI(uF%nXoi?>VkNsBjL!fNTJeK*jsxF%fG0HB^G!Jae`SS9+8 zs%h{_0fU%K$OL1aJW{F?g@M?6Yr6@A5(S7sM=?;i@;v3N*89y%&Up$XR1=#eg(@r+ zZZCazn}@2^{|RoY+6I&i2sJHMyq?F5{XQUd@1CR%g4-2%l#sK=OArWE z%P|r>a|E)=R6J;7D(*7fi+eg1FG;x~DH_59gSC>wrK{^4MKeGhgPA(aD$3@`UuY6| zCk4RYVO>=qBrNt|q!#cLZdVVWYRfEJYp$U|n!#om7P7fL#f7XaI)yD{p~GO*fk51- z!&J(V&*BTwJ~5`xwvd&cs}<9Hzp;=7Eo>oMuw_?{20{~yfT(Rk8Gvwwu0y7_kS&;| z^QkE;WT`SPWHr6Xz!NYKGXlA`kYy*(4Ru;Qf%MQKs5T}i452};AGtvAgG;oaI>nC` zm6{dact0G>h75YIkEBdPxq}PYBGRfM6q+8xj|*9>c1tc~v1DqEY#p)wgdXUJ{;=(X z6_`b8&1qWOi|xi~P(2ksOz;Axa5X(bygZ@$Gg_>&pm5FYUoCqFK)SFPc9QI=kTz!8 z(F#5YNpEs>u*cR9FZBEwi3K~euk%dWZ(mYAU0?lTA)j!MWCP+ZO_)t#$Ef+BF1sC;V(~|vmVx22{XzM8VqyIvJ8gwW!PY- zWpO|Pf2{#S5lb5kp>{(-CdFsefn$9CRa*$ys0B^MITu?9umvP|uEatBI}0*NAh!O9 zdx26?h2nY>1meN5$Ob|QXms+qDLX)f*&}Sj2+z4LrT~&AOIdU85*fA-8{(B?MKN>lObmfP7WsP zTc*jFk(+FtJY(cCa&tt&kXcqUcnq2ho)9DO8@x=^6bK&e+%0idX)?jijX)qvP!S2C z(LjHELj6rm#!i*#97)s0oi%OTcBi#YE8zE&IL_|!3IqRI|E!j4he=Q zv#Qqd0%hMunQbC+9GPS(v@7^>!ercK||hS>Wu%Z zZPQLot1B9;Sro55=z4diLx5hv2MQCXcBQrz)d}RiXiEyFi2r=BBIvc$D!sPV+Ai8` z=(V=*2BbuF=(Xtk82JHTY*O-`N3GaQmIifFaY0?)gR-?A0M4_P6?t3WPyh}$GrEe( ztwg1yJqm8xq{$;myR@exWr6j+wqN_nL%Di1q!SRfKCvg{U1K`EC&Hr1$sbykk8(U! z>Luk^-3yq6hsDHC=nFL|@c34X_RVwY@037T^|E4n!ibXIu-+GOG9O$cokR@-bx~s{ ze&e!8jk&lcTz7bH(aB;z`5sVO|DJ?mo?HapW5KKK=j$l;V5W%z(!L$OwSoNk=C5>}f zS}sp8w6HY6@M2BS+lJM%lIa}gX3Qv4Y$)&2G9qK#?&g!YLWa-s6j#WccH~JbSv8B51Y_Md~l z7<~msMxhKQ$=J*SXL#pr457>VVE}9eSJ|s1{K?5}b}YU$<%|XZE>&;#1Ga&IFarus z#dQc+Lk*hQmlI?rO;`_SD+PPftIX#nmq3QZI~6dShUb-?%{NO@X^Ld3RnAKeZS8=dzO?GQwJeUw`~kv)l}9Nz^1%IleO#9Vefi8YJ$O6szlZCU zyqbrIDKa_v;}_?U?ZSy{^3jWT?L4@1*Y5fI$^-Yz9lm|vf%j!uc4^klHu8IZk!2lz z_wBy*@Xo{cZP~eR-+^6QjvU^#?}6>x0O5h zmve^?A2@7v@o7fY**X0CG_|egx1wL_-{OAVe%CyG+H&~rBlEkq+y_7Dch%L~cHOq?nk#p{`MRCAU2*kQ+pgKQ>#D1-+7j#8b>Q%v4UcNJ+;!kK zs*11bq5H5ml}GM8aQD93%3J5kx0L(l_LsA}kCgQ3-n?sly@ua)JpaU0*ZO}k&+7Z1 z0Gw%l56|6o;GUiP%H8{Ko4eOO-g?EAZ>ERWTzlQlTX)?ycl(_?kK9?_wsU@`s=s6Y z&U%KPrmhcA#|N35E&Oh|^T1tmTfTGm+`cWBYv^|$+%kXQz`k8~?%ciq$d>)P@3?b* z-+h~}+ zZ3#Rz40avZw{LEjX6?w9TjvkY&271B=Ru%FU+yfrhBFt>bTg(YjsM%eW$yM_p7meJ zzcK#lef&@9R(L4GujXCSlkByr=jl`0BsX{?_I6sPCHPe~#ype_8ncm%?)s zcDr^SzT?1_!*h4+J~9uw3jlZQp1r;I7SA%?aJ$}yY1HN=5}3s<(s$M zId|_ZV9MsLm%sV)tyUVa0fl$I>z!}=mbX=Jeb2Yt^sW57Rq0#eZ_K>K67iKkJxkw4 z>DS-mS2XmV@cX~=D?0oRel@0D{0e@1`JLeRZhpu4eSlxl-?zQ<=6Am9J@1^m?aHgK zzT&zg_Z^v^yX(l@u7g)zy>0Imyl=O=*}L`2Kf&qCfWfW%cJ7_K5)fQ>`4t8N&kz`( zPudavzkz?3@Nd`L!Ke3i*-MMe) z{#|oNZXx|Nd4d->Ja_oWE%OKFcka98$lV7I?z=C2|Mk4z#J?9QD;QGuky{S#y!*)9 zZK=%PC13qp)A9P|5A2=Wf8>^(==xs4+cR&%%C zvUAt219$JAH<;YA`!<91;kjMA5AKF@d#+$QQ0T~!IoR6a_;&7g_#$<_ow0wCf7=IP z@V*0w_Z~qC&26D02j>p&+j;Aekleig_W8|@HuiV(z5{pcb`j*XmOVqgBh-iNptHBl z9o%=|zPZCSPCX8SbBra6Z#15{BS#Vv7%JSo-+lsa-E!b|$AG(b@1MWruATeuyA{D? z3Cr1afUyJ8o%@g6K6e&A#kbgUO-Fe%b{sM}x9{A&Z|=71%emX`n7jPW|DV0{fUl~^9{;^}-hDMM z<>e(IG#?6zg@lBz2-sG|hCSFJB!JSB(3{u`D`LYIu)?~rizw=f9lI-t-L;@%Lq%P& z|G#JMotu{+TYkFx|NlRq-~Hs=H|NaEnRe#PnRZhniaxXZ?wPupF|`KmmZ`8hNAs<7 z;decXRQk}C3`UQb$}qOq9z*unYyTsLn()i~@c(sr-Ew>xH-1D7^1Efuf34^`uwNb7 zf7qi7(SCUwm}X=2ltQXTVfyXLc(Ip zWT*XK(PN(NrTd1AT>@frrhy{hQ}UPLHz(oQVA6-=kugqe1<%$R-%y_!Uz-_@RvS^b zYo>lwjkez~-!jAT65I<2rF-}86_`yuy7%nft9$S6eY*GU-mjv2MMXtrMURS}6}>8Y zSM;gqThR~Os-m*8vPWgl%3hVdEBjRTt?bvMdyk49l|6d&=-H!JkKR4{^yu58U(fD6 zD|%M;?9sC)c4zONeR}ro*{@gkUKPD6d-dqmvsbTPy?gcP)wfr_-rajw^semPqj%5V zy?XcV-KTfo-u?P??^DsIvQLjbJ^S?P)4NZfK7IT2>)X9=Mc>N4J^J?S+pBNyzJ2=k z?c1*(S?ovh{b1dXX#F5r)@JHNv`rLybX$JWUL$KVsA<2j8NXUQI<|TS+qb$#YRWf1 zEvqMS5e2J^PBRX7JKQyZ)PMJ>mUSF7vC~_oQCB}~62`u^b5YuQCegyu9@j9|lQ*OP z%T0J3ovQqTM=yAi)H!_Z$=-FhRn{j=YjCk#%r(=OWcom~l z<}m-I{vQa7ZaIHqmYw#$srPEej2S%v?b@xnVbbIpY}dYJy|h(|ja-2wjvmLvZ1jjs z{jiZ++H&`x6OX0rUjbc!Y6f@atS21;$MNHK-L+xdlu5%Tblvf!3{%=+nUfA4Kd$Da z3=A7;teK4WGH?A9h18K>(;MpQN9gn?3>!DP`V`MnvzFa%C(1_D3~v~D;^=X;<6oh| zy><(UI)l$1^22kC_hXHs8#?EK=$9IVl9on_e5NG8;#p%cz5siS?R*D|P+I~>2~2?1 z;(3pFQ7Bxwn*99Jug?PG?^`KYUddK|RBEw)+KYxIaN8Ddzy&4bRLXxSPXx z;c*noBXT^iivjx@JF+|BCjs`Yw&g4qUoko2LV3rI%;fhqaer-FkwP3&IQvLD@;BUa zN!6Z4v^-*{LrH*41!egwWr>fotZ*AAT0(%qKsd>F!yhEz(yV~(33P}Ae94aYqgEcr zU#1k{w{17^0gjI#$QTp;*pB6_&LY_F#*)8)ZzKRUX4yCHPp&rM3Sp0S*I>8q9$}xI4&xDCdPhcr3`%zqd@p` zJ9-;KvTa+@G}Ss72>$@)Y$6Tk@4TYl`zaQE39ms(%bEieodPn}PqOG9$BzC9 zWFt^?pKC{7r%cM{ZHdZ}3Ai!4G>UL=;d zJDX4zPo@3@K@9hz2i#bST?nhMAon`4)Q%u0frKmUHi^AJDoGkqvBJIWoH)nMHGwQx z;c<4cl^8;hy$P~ND1Gc?VtaxJL2?|PZ?}(^W)X59vpZVxfl!9vPgETwQ3v5@2-Jra zzR)gA)MOD#szPr3@NB{whsm3cR6``zQmpVbek4N(A_W8;DNhESxf0<7ZqE3YL0;F9b;kJq%bO$6}p~tdkp}Uh1;?HCe z+MM8|toWIDM*ut|j&y3Cf}W5*hn?0VZO~*BfY_>>2~_a$_^rS%_E0P_Bn!`*6pN*9 z!&9m}uXiXfuMy-nkhX)UnA8JcGCt+?4RuRB4f3{l&2e^$OSs8^WV~&UFxoivCJAho zz9y4gR2Be9__2wt;)NPBNGLC$cKR!TZ+6$#Tisg!io2~wqW(v)=4vjs67 zbcrCQgRT<9bkGeTK?iL|JGSVcLTK4RyFs~1GHx112rU}M5SkmN4?$Wq%m4@!rMY1Y zA*kbk(A+R$aud^Rb%2=`|e*57UdrT5?dO~vg%1axtd*Zqb zh`(V+ujlvg;@*hf;c_o)t^^%A6{nwId5Z# z4W=090Bj0N_$9QPm&+S*{Rk9xgKjzZO7w^2r3?Bvt^@H+)svSyk*di3yi!PhYKVll zoHt?Wydy6i;X_><(io}lv*9fF~T+TG1pUUelplxy3_HzG# zp$sI$Ut>t_MXR=*C4Bz`wjO9(8P+wms2oX?DznVo?n2xvsFPzfmEA6K=_~`$bGyPO zT=pMqJAE+HCB4$lL!_m9FlGe-P8QD-?fC0N6hCUzvPW>_r>H9~ zQVc?#J`JDIcH%=qiXW{fbH`M&f!rEGs*F}B+6S+*D1gbuT8TQrPJKnxC;{y0cCz?X zqE&&UdZ&ud>1J8Wa2H;iOvp$qi;R++^j&tUWX&OrO?Xn|)TIQ>r#aJi+v)I^c$`lt zS$0Z4W|xG2hOiWbWUTaRJ14w!h-JM6BIQVb>qq(6g!s;GpSTW&KSPk|clt?eSs9&$ zK!>r?1#HlV6ELZyU37+?vkTld5cY(Cz+35O?b7fOhc*+6?heN+SK{nX5SrLZKkvsm z6oO=}Xi+$=;{*hW<0W*uN$7PusS~=`kCcARZmT01LUTgz6J&cyXp^7NH?0#22+awl z5EEUZkNrs7LeM4J;Frh{bV6+gQlgWj=0C9u!UuwgxhUa_mPvu7PAZ`2s{hF6U$LbSUr6~8MBFBWr+ zCr{?J%Oo2ULj_hMO_t}7N)Jh;cPN>64W(Hn-g}3VagP63*W#-yVPFWd79N>F;I`5s z#}l4z(l>;l98Y)*p}9?a5=0A+>&NL2p@r}S1l^`u;*KLs7vXFBk;b=<6cBVIE3cX& zzarWHi=9lJMp0$q2Bb%750EHbu5EG1&6^C85#&QLxl5(v^#x5oU>7HD>tl09f=>Avh34YZ<$}-Oh|2?%DEq(PYEEBR5+)j&aJ`IAN979 z6Uf>31fVUg!nyLMY_$}|Iayxgd9|O+>kdG*N9mul2jm63BA4-c9*7m#5$g|@H3*3D zZ9h*-d!ydp_Vw1SQf=+XiduTaNYvU+c4YG?@x>}Z#`50AJp{M&R=A^8JQQrM_-u|9ABcMi z?#Sj?YImZq5_g`RDejBM+k&iUn@Hhq^Mm6JDD&)+cn-B35W30?avOpiPY_~Qk<;xC ziB2?8K-kAFO{B93iE`y87Qn=WNZjVc;`?V2;!iV*=_hrFlnTWV$+z=!PJ&A%>5!b| zexFPno`vUBF@KC?6V72_;(NH77&_h4vI&xI|13gtx+IXAA_XUDcW)=wZUw?Q2qf8- z`Ppgsj1r%toLKQA_{WfvgsUOr^>|-Ug8jrLHFZ z&4Q4byrV$!VV<3l(E19cO$yWK&r5^Pa@=d^tj5os>%`h#oJHUtC?hY8B}(tqWBb~R zUnAbr`x5tFJN(LEv09aGG4~TYFT5VYy%30Hxu4p3mLoy8*{f1m;)~;F zcKjlWaS;B}sojlsdw!ge$gDF?UiI>t#w&UzujhftcC4eU+lwMIHL ztqC<#dt5^=h~C8ObLkFo)-^lP6NUp3mXL|Gb`M_7{r7L6(tnescI3c6c>OoI7a^Uq zDMuzwKKl|)SHvGE#Kl1VIl^eUyjIHVL0-|vdHpEZVKG!O45ICL9WR_#W5!22&}R>m ze#=^-GXh6+0rg&Wk z!4iu!+ICNjEI=ctP-TAtH1emDJ;PNaea2eWSRlGytXP@BME8QlEFk^}6@DcwUIH}o zC@g*k1j(AiEI){B9E?HD9HxTbIpSsx6M6S&#>*Hq0qrvx$6`Umr^7xN(}4Cl1jkfC@L{sE2aGwYYDM#T z39p!tDeS zrU`VUB9IReiBS?seEJ#=_>hAc`gXvcf@XC$QSr(dxn?t$!|0O?!p z=p=q05%*m*(q}mOQBCQSKt7co+ z&yIHGw@%!z5alu)8wB|hBy|*h8c25~{&_go39<|EzsIpR(wDx|j*jH_9&x`-6vaI1 zARv7c$OIe@3DTbUpWx_oEJy}q1rBu_$N++M#W6>aRUo(G_)(C~B(v@DmNgMbudt(+ z^ZTy2pCwf21g7UedKgXmA&pRW63D}}&mlN25#(;_?*|-zpheP;*wL9Z$Z8<{6rpyk zX4L^m_arlmaC{_4e~^1epaW_^dXP*Rj;Vrt zJ(ZsSrFXVdZDnQ^5N=~kT0@9I3?1oicDuymAe98))q+s13gb=a>LVa1A>5~WS=#8H zZa9um#oFi&2*&6(guv)F1Y>j?+!)=Z%aM&L$;T+wRZsJ7F^P;(9o&cT-L;p}BY64@ z)xPamy4*krlCh%wIsf%6A@+w5m7Jc%|3JNmtRL!!NT01rb$h7e@d5KLwbZZfOqHWQ?pWo{F$B&Y5BctdgeI+b)~%GV77 zmb;a{9)e8!dO@HBdfKOFeL|3&7Txa8Y6F5d$4C?=IiXFUTcp4@C~t}_1k|IIepTfp zGKAP4!tN5{4VBcQCxmhdvB?*`;SdOrC3yMm^cZ-0ti}Q-c{*@4ex-^#Ju$#3T6np9CF;k5TqQ>X5m3O#=`d= z$=Lg(Ivr#ciRf&9pupM;r7d3&|7&PinZ5slzi!7yza0aDH^J;em{dPsDwiU+vg%<7 zMSqbMj2v0J=}s7#I;X$%mTopkBG^2I z)OuzRP5U-%XF<@-u!rAS1A=L5LkQa15KLPe+|-e7ue0Gx!d7}Ozq2lcpgZdyRDlk0 zw+S&=wb9-AsjLusnPQOS{0P4*t6lv%GRqX7?dB6qS3b0VtF9anOi>IWD2gGNq8Qv1 zMR(o1!M9sNca<7d785 z(q%26!{nK=>S3u96l%#z7u%&;40nd0Wx0e;m53}Gf|ljD6t~iJy8^q59?Awm(5>GF zCNh-m?Q;!;TL>+LJ0N5U_rV0ZQu0!2mulg@O^R)V`viPj2=_=okwCZuf)Q>*2!z`Z zjBp#=)S4FVdGKu^+}A;97Vgv&RKaS=+3|KPEQa2zXdQ4XJ;E+>E2y&d5NI_kJ=*Tl z_B;shLy$4KO<~$f9D-L@&SU9nA8&U|?2tuhD|_)p*#y07=O*BC2$2ee?WuM*-89ET z&|>u^V?^Fs^7Vz}YZ@z#?|^Iu(lh+k?%nqE+x0JOa7nuwf^JuiZ$UbWFgjOf*hQK{ z8;YGi-!4eVVTuL#>TzO)Q>+c#fbgilOudK@+K#x#@${e}czRIA!slCO!w|e|Bt}#8 z{v5#2+4!TqU7}|eL9b#Smrc;CrtuF5eGrkfXfLpP>%vTfpnKFs_V$VI$^XR=y3*;= zm)Y&L>g;`| zK<{^K!dKUbS$D4zU$gH1BfeU2%z(D@-hQ6VfVL2Vu5)9X1_U#p8G@GaRTRe%M8;*^ z-QY&XJ=;{W5v;raOe#I3P-flzZ1Fbh?w$7WGo{zvb%#Fd~3Iap=9tmy?>Az z;fh_n0+Q~<8=XQeB8K1@1&K1^KTepp9Qa&r7bQCRgq@{0-#bNGbG||dT|vFo&ZVOK zHV~>vw5Amn&AJJH7+C2aoD!}0M3tm-m8TZk?$=6n8iKF0L^<{(jIN(weB~GrP>xzb z4IqTJyDes2qOtaZpo?ZJPahp@LZnDo3V*%{5m6~!ctg;IZzKIh0sFg7f5g;^KWGZ_hf#+;8rp( zgcdTtFN78{9}tYp8$uxShG1mg;6XV==9fvvjLc6Vk!G3qwtLq?(~@zm-A1>&A$a4E zEGK+w@^%B`yU5DlO`IFqt``wE1h1pGGAq3fd!eH=%s#$xdou*B8I5rp5VU60O8R*} zOuE0_PBS(HPf3dkev=^DVj2ivQNbTVkeUnZKOyLZ%u+@`@KmrKkH7R|r3b-A%Jicj zE4{B@CPUC=(z$aPLUmOg=2w*=G*?vzGeRHfSJe&>bVDEQvo!>-s$zYah#W^RFk1nI z?0}vKq^CPNP4U-qF~jjr8yJF@=6rI#CqZ-P17vgPfl27o}nexs8$Z3>a5B974Vr&wrz5^g+sEhRNzUd$YEtSS}I1)k&)8Rx2 z(isD}6+#QS4G6yJpqt?qLTUNGp3?y$|Mx&>A^$>X!6zX2@-L=j@gaVpmO330(sW%R z=%)LV-*iG~(R5rlZEm_g__k=eTEoyZ-Lnu{n3Dm)G@T&?O=k$E=?vbY=`xaypy~Q? zn6^dJ^%ZZ^bjRV_+;qDB{tQXi-%Wn~Er-ye{)Et?{sMwme<@iC9U{rx$)<4x*Eg+at%n*W6%n-~d zX7HdKGK$?J88f3;4T)rpV$pp@TGj@kF*hf$Jx{G2|^^+zdfizy%>sI~zi? zcD|b+S_Btx07|s;1BP%>$kWbm7(!#n)6Ry_tet-*NGD17hLES7g&;WzW+sWlJ+TgE zCPffhh_w(}h;=~l)r(dGT?nPsz_lT7Rw;xQYTyNF3!}k%;@d(ERQss}J04F#&{Ah+ zl>xzswjl(fZ3srR4IYSuXz&e^jX(|bKBAQxkfAD214Hp`Rs;Gx;W9{i(EM}A)8O|) z$Ve4GMLWp=C5!L4fH_B)8N}fXwg(cXu&5S zczp6k?!fwvlyG?{ou~(CB*yiU`@1!@~~{TF6B} zFmhoCfm|4Zkqd*jkc+93jX*9&9^FbV7KpbQ9?r$LSuXVO@G2xdJUrqz&U+AAG>#Bj zG)_S98b^-^xmAAYo(*{$W5p2k+~%(#Z(~ddEk=cM2rWm2qoHUSH5+3A!BmkU1XW}R zriu(6RFRAda`rA56)qqV-413xe*=UTqrxf)Zbk)XXmfB&3(hOz{SrqtWs6_|-sn^- z{hWW0QV1=Eh|3{JeFiJ30l^Frh7b%9hG2#Wg9n9@A>s?kh8ZHBB$4JJB076C3#X&- zzl|OIM?eZs2H`Auv_FnB1<7Rx|M*j=8zB9*9r?=`&P8x^fEiPL zvcD%^I4S2E5}Si}HQt4jz0=Q^fa}&9z_9~^J6F@)y9=0$?! zNktvyw9|1mLeMRBu)ktx2wof+TM|8dfgXzGFQ=CaA#@QYC-`ScxA#K?rXo z>d>$e8ntj1ZKS0|_C%V`=9h4?^5Z_uXY>2Ad*~eq(+8=_@jemYBB9;sgA#8E$4J7n z6D{i}z_~N)%E(vky>n49u8i2Uf!qd(ab+a(a(BM9Q2~O-V1BO>ck8<(`*rYQ$KN5l z(Ooj^B>|2cheeembbX1@+*?%o-ePd{ zspBUE8$f2=Zg$7n)WC;;dzQWJdpFzGO;SU0E%uoPZdX!c?iD#3SiMpl1DJuIdu2iL zE<{6cQJd}|rO6ULZCqmF~%P0Cp zDPhT^NVy3dvCHBT zx;F$}Z4uiG{)z-wc5z(do``RpUpLR*nZg&)j**VMhDw9(MQ)wTk*dzu@p=VNSBLG+ z@8T$7;;+_%ys`~uMF!-vupM2sEhm)$b+~Kie~ZL-paG4DA7P7m>hblfc)ZwuvvLeM>!ktG)?k66>=F`Etnk76OyQ%mdK0(AS?>pIX)e*W%1l#o@+|)XP5V9iNN-r2B5xx%4}<0iLTKi0<$r&jZFQluo7TRs4&4Z-?cLNwddqFXt*e{U zt_EZ^NQ#~C#9}II&+EN@uPWT_5(~2kg)cc}iJR%kCPd*?PKlmz7(%gJpC3oI455hY z^TV_7n0I|1DUs>m(WLYgGA${k{tV%5@=-FLGu2Wbn*|wYd-ZX^4R&+!61$VDlZpHe ztV;&j$#x&ng!z;p1UCxDh#iMW!68DZVEwEL%lRM>Vft?0}Y=I4M5m+61 zf`sl-szcvRXsK``-T|(~yPkBK2q6-Z?2**5&z9JIJLuROTE!0VAog1(cHe>==~~}| zmkPH5oiv9WDj++z0UmHDB!o_XKvBE7Vr1>{wDN>qOX#&Z5F{ zq{5COvZ!DxEk`OXz;}!#B|Cyk@=|$%*MpY`?pM$0zQ3uS01vWv9wCS*)uTDw0FL4c zs_4E}90EMx@Gv2C0s9u{JZ%6M1B@z4N&|dv{QU}ep}7JQaz}OB8*Qr_;Z<)s(F<9G z!XbP?q{%02Pl)u-IXNp4^xnjfPF1)%FTQscUffphopWev7M*7ZfwZ=PZA#SS2GUh~ zyY00UNPMFr?;vD$8wR*8qNvE5`~*csYF-(ltNq=6T7iDt?5nGAlb^ETFL*Zp02ltA zijwQF@awF5*bqUCKAXQZtA|-BQBR}9{{Ua(e1m@rjUxmC_zKYKJY+ZT8y)IZ*Y5l( zNI`$14~$^Dq!%w=X9n0tNF`6oYmO4x{)tey>(&CBH6?od% zF#7}QnaH-e?Y$Kh6LIIso>8EV%eji2ig$*n>bR1Ge0(Fo2SsA>3$g-qDAV8cu%Z>+ z5p+Nu!ot%rI8GO21Xob!jIM~aWHy72pnR6vFVr@ETo%FW z#m*UsYV?o1o&-AVMBDlor1eGU*V<9KwV2VOyNsj_nqXNo0Qm5LXZ%!TF1vWqtSMR-B9$l`#BCC2%q;Fme6m-?qvjDTAU`IaHq?6fY zXO8~^1($OPu!7TTmAG%PBOmv&tix$5=+VVAQCUCSgP8f9fa6s`aG4k5{FfZ~Hdjwj9Q0P%6|#F4wh zm04vu0@b$?DE@0aPXyv^5-EN$F0$!3h;Jm!Yj>diP^paTsX*^D1G=!wKuf8$obGny zb?WobuDCDYb_c)OEngFHwjo4hXI^7~WE(qj6yBEr$*y*!a!1P=3nV-6X)1p26F2v& zyh46J0XuKcczGp-+zH17LDsS^^Bm#Y>;&?V9es-5Fr_a%1hIGY2M~1jc7*;okp78m zuwa9%M9=1R3y?3jknY9tt{`&P=$=m8C!Cb{mc2DS2Rq^$tN4yPWL*P zzO4TP;k@kH+hJ$}xgRhhSF810wn`z*T8n8S0NnJ{LbIa&(h`uN- zYjFdvWkBkakQUNqVcegFTq}26f=y{Jn7jCHf^3vvUwOe+NwBX8hDzN~M3281MD5dEwD z=-a^V`x7&`TGeqT=&gXgm+ed)j8Mh^DY*so{N)j#7$OVCdX%B7tw_ z^&VhuLT1(qUDh4O9jI0L4vX`S4ic<%ML#8< zm1IfHQ^NE~SUGFt^%}3pJG{0deOK;!^IWf_!R4b(A^V$YA}_tCbDxivJ(pj3-Yyab zAkO=|)Go&;3$1IJk$&G($$wH+L!OvLK3K>l>LtkZfgtozLf$#_5uEH^w(A_L^ta6n zv*X2kuQ2-Cis3boUwd!YihM!%K{G)1v!l=~x^}>FIC1U+oUk3fK|FcrxU_G~ii{xA zU0D$a;9(M5Po&-Fc@f`|SUkG}_PIoSl}J0zY)&ydVl9y#^drhTpgcO_ABlJ{ks7xW zaRZU|IL%AZ`_POZaUl^OAyRr4DIVdKaWq^_R!=6U{FBGNN{ z#EuRzcyz?;i1-tc4xaPtDgK>EL(cG0JUTn#QXJ2-wTnJR5(o5#VVAGX;Dl1$edmen-TaWO5>0s0sb$$??MLLah5{OeHuhH@v%S%n> z^^{?(2@N&cR_2 zNpCWe^vkgeX8IB*Yf16JZZCwX~WUhCzxfmi5LUONyWjG^mR z;1~O8_ZSIL&tzh%nMb zXyZjNco1QXiBJ@a?MuY5;0a+6AE5E6;4zJt=q#QJu8R;a(OEROW+-Jm+b~QN=?Le5 z`(@M-46Y*}$JQT%0A3|sWEkY_6yJ{`Tx{^-{Mbsu8$41=nI*+b2%xi=pVTQf8iv&J z68sGwqUP?!~}Oz-?LdS8%@xybHXaMemTWtZjiEfSmyI48*-Rus?8M7G3txx&pF2 zb`)Tqe(Vk%1-t}o&t6Vfpa)={lc28wu7I*(t$;vn!A@CEP#;9hBRL0ezXE-_Gjqiu}>%(FGR?C~56$ac*UEYO?B z&}CyMn=aud0F!`vz&zQs-Lv@oEA+Wpd@jX(4IukB4`$I<<6Z;E&dirt^p2#p9Z&}J z%1T!@P-+0#80nN%4=(OFPy`fb(a*xY8VIp!9tX@L^o773z$3rn|CUedMVwu;;_Z(6 zVW4Q4ZM6f;Bg^=g0n33EfO+1){T?8z_CEs-aU`yJHqke}1-6MZGXTu9HTn=nqho;4 zz=eQ$1eY%v)VHGl2>vtR!aI`1|M#Mw0nc-RHNcxdDTYToF+Tj~pZQ-xA6N|B3_J)t z1*`?ka|Hch0x$zO12E5G()bgw0(cTw3%muGXMg(6;lMDU4wwy`4VXv10k#|4??(c) zz*t}+U>@<8&vSJKx&jhTzO*$0_&vgB^Ok%V-X{Hj)xUzc@@cNE#owC0l*#x>`sUda z_YpvL8SBB%0?q-<^RI@JxO4ot3$x4*V66?`oLm@3?;kegQ&#o9S2Jz8&}rARn|a&lk8i z0Y3l*S^1HVQS=3N2jt@u=9z@M9+(X5w5zh@8x6~tZPG}{lmOcR+XH1lFJO0IZ{R@SaNt;A zIB+sB5ts(d1fg6FFf#tycz@xy^z#8B+;9cM&;7edLV95o3pe@h|Fi#A3 z3g`;#0~`n(37AJd7O(`k7FY`03A_rt4TyZ1M{dklaAErj;AOx(-$4I}d+M#}&p>+> zcnc7J^Q4I@H`liZgr9j%;PUfq;0i#lNt@?E+)n_jfoHSm)yVsF;4DDyC!0sE6u$=i z4R||?{ta%2rHKeo2^4h#dTfqGyvFb6mlI2Vv>y^DaW0Q1OQ-gUs=0J)WGp0!({ z@5KezYG4i^S7FVw6!)#bZNTy@`l0mUQ9uJAcTmmqAUg6+ZrA+?^yAi=c`gON4p;_= zzj@xmEw}N$0Dj1#cRz$rQw~wqSl}kWJQ3V!pcD{)^BjU(u7(W*#$?g;J+8wzs|V}^ z$o-~;fO+I5R}|d%8+s3}N*x7^2jo(fc`n1f7+3<_kVPK|kE4KUKyEXcr`zGk(Gm0` zU@2gp5bgq?7!ZH+9Ee-)wwwTr&Z3{eU5|@^O8~hUVjj5z@;tB>cqxniDemq^DXR~# z8(^Lja36LwA4&mU0nF12_nyGMfcTqd7H+vyaRG2e7QLnlI&d8z*9*+^H10LPTHw_z z`mCYo4&Y~C$77nqUkAPtcmj|k{^nuN%Nh;HE=xzIB^jVQPzlJFekTH}fQNx<%)c7o zm=J3pz-ho4z!QLZes6w~FTOGC{bx#kC0}C!$=6>1$=5JHUw2TfHGrHpl>D6vNd6uJ z%)@qwbvkekaK0h>?pyi28~82h8J6;YLFDV-@{w@)=C^s|3*RQ6a&poze^V$Hvmh4rYt^pl7|(* zL%`~+{0w4k=paD;f7(Dm{x6xFZkoiRPrqIvg?^g$R~R@0P=0#_W}7XY^)Of0_+LMCwE5z^8Wzjyd7-V-9Xl%ZQ>$? zd?m6sI#lk2UwjzjA%2y>rMP#d!uP@b4CRwgX(xzp9yxRL4j{*c9suM-&{XE{auU8A zki$Qd0J-O|LGlHB1IXd{dHG78_D;9s18cxUK#t6GVO}cdhPPo|K#sSKVIC_-T)qZm zhyPkYw(xE0NDk&D+hf}hXBi+j4d!#6UryPT1Llzp)!~5bpsodE%hW!WF%LKpkf+QK zEPGn=wEh*nAdmDFd0PK=_Q*lJ!9ISh|0_RIb;kq4fr)^5wnn#}h~)YU)x*4%YU#0F z2MSrg@Q6eqB>JKAZ}nFst_!~AKjDeQEd>{en@>cMIQchIB60Gshs=LC5s5p)W2@g^ z^Y)hMz4V3nkJA0U{LNR&&Bv+DSE$Vwkj=-K&Bvw9f4&e&r)XNzWmngH57m4wK_s1p z8ZGH^sdpdTXZey|f!jPk;&3e4jQD-aZ4ULB19#?3ow;jbj?bB!LguKOxn5%KQ%Daw zjy#$}XXfO+IUs5diJ3Dp<`9hZAkM|<9&{?d=B|!8)(S~KY3k0gWLw26zd52Hp8t*Z z-VOoTZEVNN?p`2R+amR|2zvbp5di`hlZ&ab$wTcc*nY1r`LlWHd0e1|T#&{etl zCGB$W+OxF4K2lDa^s^QFC#uXUuv6hdZN}xQ++7p9xdThjvP(&$jA%k{L3KOW75PH1 zN(^<6Mm2^zSS<;WGPY%OoJ0oyXn?wc#tc`J8eIYoh1o0d33z0Q$!z|X!8jz=iU|LdB-k9Su*}M;1Sv+kb)|6{)37l?Ij9)0(U~lfs?uEH z&;~yb(bZTQ_-VAQpnjd`xb1?1XtaG$s|gxQa?~N9cnv7DjsYz(PzTz^}wTL`N!^QL};ZLGEQZ7HzLWtI~EO2$(Rea-#NaF@Vj+DCPFaRbz^ zzHp0DKqS+FSZP^_2B;Q|SnD#zTjxI!q+x2>dg|KXKm3jvJ+4OnhgQgXoUw_2N&Q1^ zQhr490=D^2!Tht~@zwIbf?NOZV5?mI0ef|MZJ*vX)g!w1?%lVxdc^R`zWsXk>Rmme zx=-b>9{q-msNkQD_o=Ste~*_Nj?MpEdD^%wxR%#Vt1F)}tZr<1Sy_3*xVnZ36UI-f zuNm>1Q~S*f%4^5g|8^!5>L>knCfjjpfz?HLc@{Atv#4NRF5A!cKkRA zMfaRAX?%4}U7cWrn>1|7iIZy#hegrEK@C3&m z9XqUg(s<2_sgM+qbhTfMEKC|*KT5)(85%~9t3RajX5uCWc-`6U}9TQ|B|=UKdK z>PL+qp)m{_KXD4iWXO@pi~7W|-B^5E{dWy9T=(WsNUfPw?=Xe4`CrWJp;^(Co2%}eQx#S>%~=-;yPd_8^K^K=HmhEZ9GvAHR^MBhusUf1lYzb%oW>4M;++sSuf8s|QVmv~{CuT|7D%>8z!a_Xw+NW|r}tojmo9 zs;8lA)rWOuZeCbjnNvm;bY4J0IOc`-Bk$UAfOe$n-Q-~Pa2=U_EGJ_E?P~%Z*c>Rl zf3sUXP}fLSk*B$djN2x>z|BFdG6Yap&ieHxX#9^hK{T^v8+23WOB?)HzhH|tprUA$ zmCXhA%9fm`o}gesqqK8-s0&?bl%$#;LJYpIm$s(ZcRM0*B8!dxt}OnyDq`ioB8;Z2 z3t9=_y0BVRPo*M;NU@zIhO)e)9`VF*C^axq^a(v$0_I2SJ$Wsn1Izl4`aC9@D;8Hz zO?9@lbw#d-Gzv*QIdz?n>vV+BWCA#yk^1s(Vzy328E@Tet*alQjn@Cqj8tPI``ItA zA2q3F*l#y}%YPTMb8OAn){_7+*H83JmB4GluyLcSPaHNJyS>G{!Px!3-6|7Hymd{P zd4pA6J#5m*@#T|hMvlf_nI>5%ABk1dFuaV6cB`nVuI^pguiuE_{c5WFR`w_#F=nhb z!n$=Yt1PSVgyuJ~`0eHUT`XYcPy8WB!zNXaDzC=MtEnrOHaJleq*`R2)uZya=hri~ zn{8RKYXe&rgSFX~#jwq?WeKN+<&&W`Kx(y4IuK~x^6S@6mG*wrRkBZe+q&8ZO;-kLFD+{^m)bWEg^;~-aCSI<3B9RHX zm?~d2V19?IQ2Yhhs2I~ZPcm#|)L603+l1BTR7Qt?amGB&?UqozgjH9JEz|f1DZz8p zm174>JP8|CD{@KFb=9KDSe%U*q?)_W=^pJFRToUwDTh@IyM#baNDL||*m}0Q)Q=Pl zV=}H@n33`31>z-p1nM595_xVeWu6u7&ww?op49Txd8*1Ca2lnF4tClTf~cAJT9#*lcr^4aDSO12u**^Hg3cyy2+<8(%3=Rtj{=Np~)O7`C*!cSaczFrUB8smFI)_41VU?q1<~w^M(K6joQv z>JPoG`jF{I3Db}E;qBdaLnV%SASzLk>TyhP!T&;Kmtdk6*JDw7vHyw*CtkNFsvd9l z3oj&I0e1K5uv#)>rQ3zc3^S{OhB}P%8DgK3p^K84P+F~-vNBYpE@aM>W={C!lzORN z7cU*=R;B>Oq!_DePA=_kuTE87j&6xI>7xI&ez3`gPI;}Qd=V+>B8nAXNc}I6N#WUZ zGGbwVE%Uzf=QN5WY_@z!;1idQY$mBskc6E02C`YJ7R=VOv8B#nvQ|$raB5_}l6Lde zhxSUDudJQ5PI}MsNNrd>J+)Dc?Rz4F-L}^^oXXRsSCgJt zZ=PP&!0dj?0-5){9!1pJT*#EXiV5lgZkx%>+mOa0^*3@;5I%wV6DZL?0`D|ci`@^{ z#ZsU%BlEl-*I!Rq%cNDmrmB;AI)DC@jKupv%5VlekiO5OnFg}F$6&X!T4k+vOVuE$ zvW$9uN~8GyNE*crZo&Oza4u0;ikQbFuHdP~@R=;LNVSAUL2XC{o)#{P7V8W>RIkgZ zo=Tt!)VcNbe8#O-By{OiEyVXkMB?Vr?3L6JLQ|q%pgle5%xo#0Wc!;)rcU$zdYV*Q zOg$7{$GAZ0VwC5Q{%+}By81VVgil(XH)9^vB^B|r%;Ll9Ptp2Hl*mCVDa#pC7sz7G zT-{`@dU2{qb*Z`~;z{+3Q$-R4M+oO4d>tqp?b3~DY=;an50v%^AFUJoDkPO3B&d@k z`~t!k4Q-fGhpzdIwk5f_qQ!Krj1!S6RYeQjg41;6 zojgxh#G9@(Kz|BdLCdZ1n&SpKMO(x<)?d9Yec5jUb!9!}RPQIYsD4{m^vf8V0k(>()eEmR-4jc##;TR5MX&s()f zF3WcG!;tQcLqy+UJcRauWGSQs^6j=kJDNH zfqwG)Yez)x9w&na#EN5yjNzpin>Ado?wI8d&W~AxLv83F2Q{&D5>q>6z;aZTbTKMr zjHpeu(P{%$cVia)cWsB=qi?e3Od;O0N2dvQUy_W^af?O%&~=F8IvhRA}iGNjW{ zuKS%#`31Tro5VDvQ?2!7=99Q5>ks+ykQp@*z49glrp}63JT0`1E;0(_WCqh&Xh_(9 z=g|a3(E*zEWpg~U?qjQJq3%u3$8~QIwabt` zTa-}`#GlOp>FAAalXUd8x}!JICD>SEo}+u7geex^O>6|D-L6;_YQ5X`D-1U_0O+X< z>`Cd8X>~^f+c@22Vv@JGa$S0i+vX%sTQQw$Q|4|H?#cXsX^xCYFuEfm zjFM{YRK}^RJzGLXUZ}!IeaE<;QYGF{o^9h|{7E;CV+K@H7uw2olWg-Wo#Iahwr1#7 z{Tqhve^QmxfOj*c%uz|ktLEYUUaU4MhT&daFl{wc(=REU7{{+;9AiPe>@q#5aNEqM zv{AJ24bz$Hyya%P|53NXlS~%0KxAphuzGHimX58P)=NCoI;=i)z0vyAnTYlxHp+A} zorj&(-fP}0zW-}v|L2Tse^lLKD8mT8JM4{rcg)ZeiT3Iox{Fvz-_}VF?xLOxF}6L$ zq?hsc-Z1Vbrs;JG8L`1Gm_+Yl7ZO2As~4Gn#ni2Hw$yU{reY;MjKwG#>`}U=BypWB zTCiAM9?}aa>O&S-JiLm2?XO#08zCP|Bl@dXtTMH1&N}}$n!@fYQ#a08pkC#7=^U>d zH?u(~YVOuhmAZaTy?WgmJT zyg(&b0AS{~;CG$*d5ZtH&HPr%RP4Vo^SgS>nI9ucSp6O|KW#xbGI-^LSJNa7!RRA9 z>Y~P1+WzSCODq_D@Mxa+u`HMoYg?N3Uzp~NQxY{^VkBw?E1x%}Nrm!2S zE{jSRNvcn#=moENGjs)>!+C+C$+};@$;d3LNY}9loMh@)67KG%nH?2`%XMx26ltQn zsDy|zt0_}a?$1ou3p4lIRgAK=|2xVykFx(jHvMtZ8x>CzlTTeJ`^D z(u}-}+n1tl^QGJPc957ZC0Igf7G1*S{^)&Xbj#7(Z!sn~(qcZR0&M{lU;()4#crD& z#aKi=!?mX_7O+U86B)r_o0rh(Gx zJ9=g*V^x~P9M*KYokN*!AA-5QcWLP<>R`>DjHAs^B znH-__TP{HU7l$E4@S0h^p2=E<)O!whx$A?Pxr^Dlm=?cbMY3M@G467`<7p_=uCf8O zfeolaIpT5sY;ObVZF^p`&Xs#$>KsmiXr24kR8Qw#;14Qa*2|Hu7&@4FlR9T6Bak{R zY_itDi`i%Lb?_5>EI8Q=wMyemeRwv&`i4bvdRCekbiyJ z^RISJPa!XxDGK>*^-mOX6I%)`6ms%c6!K?kD+)PiF%+_J%2LQ}u5i;menlrU7))-G zRqWRZA7fFU`Rg&PZmaEC!n?%HKL)AUq#7sd4V1gRMPhZwj7>=5uiE&q>W`UU=9~F$ z>tZFgO`?5~V(((HZgT>HV9B0p>&W#=EZlk(XvENhWZd0pPHOLaisyO>OVYR1Z zOzVpQERU(Z*dta)(s_}|mIKIBNPkTIFy(&-kXBRke^o}eHh?UoVz(SXRN;aw#h@2w zf7c;|tw>o$|9^A{*O%L*HqVA?KA?Fy!nbL(b=V$jOPT+h?yQQ&kvv6>gHHmDf4u%ozygJPuhtof8pk zc!l}ssdTw|^*l3Ry+QMsC1XsBtuT7q9XY77C_}$mK3R`F_so>D5$Y*c*reC8`xRpa zkAvGY7cc`_1K0fiZaY#!rDdxHDtl5Fj^I?^Bm z?XCX6`&WMpmlGA_v_P$xyjs|W)om=lw&ceqUzoD8E5>T8?91t`JWhpD7p;>>yB#?r z&9Hpy0cR~ECW_`4^{ z=_}R5rWlwkWb1QS;*SNW9+^ZHe>Gcd=YOuHktOwu65CGiP_hV0vv1|x&(@^&Gb6R% za|oxUkZDPhUa%FGB1~F7KWr9>KxNS9?_+UZ4zOL2SRItzjL@~Jy_l=d)iY+ROF7{t zD|3%euF@<1pK}CBS5AF%<;ar4H}p82;6pR#wahEZ$~zf^MJ=C6kaJ`NEsU#Q*ul@a zPm)y^b2p$6jrD0=lg`&?xf~?8c!Dp^XZokiw&gYiPEiQAsHXzCg z;w^~T2XRfvEkk8pSKEREM|8K0AXkgFq-GyKHi?ycM^Cq4tM6_3x7vQ)Gq}{Xh4-*Y zlZH)ed1;A*s{VOUYS4GdQC2zWY!0u|K%Co^vy#R~+)#&&)8{JnY0B)IOb}XJ%@Wql zXFdfBE^2Yc&s?|SEa>E6V@8h{CKsyo9VoftA!Ie5esV=#>C7&%&?{aL?k)xFlFpMeIz2Be4@q!;_4R#zkQ5hnf zeAYm1Z{y3<@*;<$dm(oRwRsk2@gS+Qoplgg2#xywmyRQ!Ku`nyIN#fH<3Pfkhf0z- z-`HN9^JcT4?-80z04E~}%h^x)euBD`la^iL>eAWFIMgOawA|CYIjv+(zO100u{ilD zc^j#-maDotoo(+xs6!a}>Vmq11Acbgzs(haD&JsGpK=^C9KXfmCn?Go8Ptn}Es3kb z=z8WW_38@F{`tzai82(a#=7-x$7q@}t|>Kz$&x6ik8(2H{&D55(=~OJN&GN5d@mjC z+PYd!JaXo)AiNHy`modAZPrh&fs&ECWMMU4j?osWbd|nZHl|8As#Jfs=t;NZOPcA( z!9G(I{M{2J$#htq>Ua@G%DLDg)zQO-d(k`e*Ab7?Lj)Ps5$Ad7$!3ehXzRtOl^8{; z9SZHIS@UG*xRA4oa?9=LMtt^AJ7A6uaO0T?`+n*=%+7M$CbmLp^v5v!z(uQ*})&!s1pvMw$ zk^KVh4c1GV>YT}pSes$Wcyl%uD>e6Oy!Jtk*y;X|&&p8eL z7ddfI?L+cZpcc+)Vk0gGq|QpB1Opg`ZAV&a7^d z%AUu0oNy2C2)T%;d{#xhfrzH#tPor~xlttGZ)CG`I66;V!|Fqt{e8J+xp;D|8^@c+9jYzS9%`)!Qlef%2!&{4!(+8=!l9dK#o73<*B#}QHvh#tGElDCKJF@agsOr z#EZHiZpYPYEKcO8W$}8>ke8~fr>v)pIqE&{WY;SVESTU~MOH<+yNJZzLCIN*xjBvq ztZ68dUQT}L(TcNc&qP=2_I_p>*7aGOCQnGIH(P_{M070<4h4i&TaE{-S`Nahwz7V! zZ?wuq(lWYaQa#M|%IM9UkHd~qM@kna%0ip->g+piL@g%eTH`iNu3M*-#8WnkLk?af z-Dp_#$`G^Gi}a=??EhIL=7+n*_%SN^Og2s zh)M1obDGjS&;B$+XDOv*-#M&$5Of~JN$Dah1ZcxdB#rqOT%;efRmmzZ^EtX%(ib+0 zrd2p`H_mSIRrtz(SA~n3sNm=fr+>Hvaess8b{Px)RYszC>Ew5?isLaD?Cz=_MPZTC zxXGy=F8X*$E%bEn3i{W-se9)cVbL|xLic*=?Gg@aN@v?hMHQ&(CIrq?m&>&ddq#BF z@_($uo)aA=Jz49pjMic3^7Yb{u4<^2Qay*=qVLIz!jNx4sq3S*Tgqi@Mur@x(ssM6 z1m|jU*C6FFHHjdEwpN z{9Ro47Pp8i{amJ>vQ7rTXrp!^UyY8QPQA++t{gdg?8Z1m-GLQ@cC_Q)IL$?3>o_J} z`Z8NEQ()`IiAkNb3imQ*lbA^7PFqLjxFgS2x8SF7=3KrNFgGGcn5*1DVRaHK404`x zF3Y}h5<-#p2e|{jW0?CXdU^0+a$2B~9U0uK-0rdxrRuBP-rX52Wds48`fIg9F@+T! zW;v{yYiBoshxHu7A?O9ebzR1_URK_1)E)T|+4gUDD$RA%e%<{*VMgI6g z0B?Lr!9+e4raorVM;q_YPj#^4Qz*+jBEI$h99uXZq0#9ehPT9$4~wZyCe{;EoeD43 zN-hkGwf;C8z!GU?#83Nip9=w;?SzYns(hAAJ)LK}`_elH(3<;}xdW=)Bm7HI#RQRW z{;3y={Oo-+Mg~#&PQao-f(1tN`f>sA;o+rrn&Nzi@yP0_O0L}n+Qn92oe?yPyzEd2W@F>}yC;d10ks??Px+{jH9 zW=9+X;?oLH)SHYdxvFfQlV?gPA6er7k2Zk+PkV0yB}sPH_eM@nk7kt+h}8zShGv+7 znN-}^qtq(V)5;mOG)vPxi_n&ewX4)sm94DG?rF&b2nl##gv4UmU||rpvDsuc%kqHD zW`vCa8$aL~V?To*5Bz)%#sbVa1`Pgv_eMlURApvmb~OV$TRPK~nQ`Op_q*Tv|Ne-9 z{>5WoGP(5^wMcOaG3#cX1a7_#V1MkcNZ}%*A=z2qz&|%zU&p@(-#>aV;?bi}Z%B;u z^Bj8H2_t1@y9$7PL7&GgtB%-|qD{mmV!w3@Qt{2!&+zH!i$l2X<;|^PJQOK?59k#_ zqgCGxZcISEER%G;+E!B~2V>f=4-vh9zycn-Q;=BJZ#nk1JpoktIMFu3mWzJ(_#L;r z9O8@z?M=5_(iao&2!!9UPwE}N_4ZfrO#5@n#rEdci8JkIicPM6{9fFRUkAs?+sCfl ziX8?^!L2q0M3c?0w>=Hk$X#V!rJw;G`<$v97qk@8f6ehb-b?+@wVM{SK)m*(;ITaj z@Z@Wb-#MYXr|9VCnvULf%hlsA;b0H;gv$Oz9sVcU0oKnt_NA!#^a1`TS_U=Iy;V(b zxxgg!6~W+#dZp17%zE?GadqoUr?1{}D~i|;$a}o@nm+@tVWjyvh9_oNcny4U{4dZq zzYk9!u8b^zUY5HQH2&j{eR+>j_m2BuwTQ?p3v}1hdN?1NGYb;B3whL&U$ucq^+m5c z?jurJubDQcr{>t+FN#;Mf9tnQAJDP2<1hZd{?}^=<;m}{Hg`>qzv#WJ&~s+Hebt~;Zu)G3s%JDM0NSX!Z^$+ECrb%$ z99r6ncomC=^)i4KpwEr!nR!f&DwlaZcp-H$!nmOtWw0o)Cp7>=r303m3MwavrpLYt zP3jA8UuSQ<_}KShl@(SSO7Jn1hd1-nZxO9~9GIQw2rHNGA4T<7f4}K?|JYBwi7|S9h=sy&@1o7_ApW zDq-7?{r8?IBHd%3{5~kq3$d)8&{zSa61(a43Q8F>Mz)pgTs-l}BTqeg;$Dr6c;X5Q zZj|&VRNuGz_5(Yc7dQ5{uAR8IK}BTb9M z4!zKKf{s*3asH!uh_5{k4NL-MzWK` zJJle4Qk$=zhZSre)d>FI@ZuyH%WUR$Steni9M{inJC=S;pIZ-ajnZUmT8pVGFh48X z6y4muEF*Nv!Y^Vs4@)<4{IINRlE>CN-XVXUeO9Up+@Z|5e!1VT{+KFHP8|DWvaA2d zK4>1FmQJw`#;Mm155VQ; zxcON{#qQqbHk%uTA3S$bKh)ne-3Ufyxm)bfYOZ2Gj+B!}Dh+Zs8d&Dhse7Q%>(}3co8)p<-OP5K zB1-Hivc1IdIAM8S)om=%VkEWB%0KmN`TBt;50ooU8gl3E6lTK#M3vYyzY0>&;gz8$6h$6PYmAky#vE_myMA9v^!uIe z9V7*&P-Q9BuLwafuhpc%+bN!rl_=aeOu{tqGAB}T8q27j*{eEHS>~lac~4K6{!mYv zp02U`*dt*yz+YishRY5V@k?&jNz z`|C|^ud{>|yesERR!!MXYkuT?h+tKw-xq|_{-eodS;ey_&zyWnX8t;-sv1TS`q1m# z4t>~xIA#OrVN@N}hkf2)nqgGKDtGQRubt3;?mO|oy7|N~1&~$7=LdRty1-!_Hz=nSRFxnbvijCUy;HtB-ZKXaXt9e$g%w{nL4_=gm-$BrWs6v6ZLX zq*Oj#<@W|0*LrB@(aByzHeBk7YT#U7KjX68+8V-Mu?8x3A|Fzhg-PnehYhUy;iyZmdM=9>@!wF&IMMLrBuv@r{8OzKpP@YRj~sZQhA~ zHSc5lV)LZF?oZ3csCYr{PS{XcRp_4M;LP(=lc>JGt83h_Z2G_~(^zm7 z7{um|HZ8&@X1=f)p5tUr;t#C-h2}SVg>iPq>hg;U_^CU{S?xwj*>)DVMNz`F+OYV| zjOkjOrWTndx6>)vY^uy6AMryuzGn;N@06g=hzc65+PYx=G}Q;@_rUyquL(iSX(pw zm{Pq(>|szma~Zyk2K=Cm10O!bPn_5nrqet^NUE4WI#_TQEsywqj zKaH}O)8v#vPUTJiX1}ZaC5Zc4GY&~B%218%w%vfj|7?$JF_E7hVw!)Gd*$u-oNg^+MT3yJPGnJ$W&f>j&i+%j<*X; zx97s+qYxg7e0R7v8dh?v8;VXQE(+^1S&FiZeW-9x01^QFQJ%AYtz;Cqo0nO*BBnj-Tj$av*ikL!d8&6oo7v+~XF z=2~Tk`lCz3k*r3Nmu`YS%R?bj_%Y+qPfi&YtGa0xN&D;KJKVJA@+H_#o*AYh!rM`* za;LBpCJD_MBAj_t)ehTsk7?(G`KzT3qj{j7wYA5`xcIW~*DXGE+Hm;+?(!KLiG_i8 zeJ4v@FNht~E&Og;nBIxfuc|!RW_(*Ab=awwmId3qq34SajF(NuWAqq9V>qShC@S2* zkG$N4FHam{uNF;)h7&dPgZoNyaP-gXzcu%xH97~0jTR8NN&9^?FNR8^rX0z| zOC|J6m1&aZWkA{-m1a34r}cap?axx{zTC8h=vAtd&!%>@fLiz|ayL9z^=#oh?K?=G z(T}#cjM#NkRlp}Dk)U$30lGzMoA`7CL5RYNAh|}BG1Z8m9O99l^nI!!r%W>#P0!Aw zASg0cyHX7auhU6!rNT+%e4?CFmRCD-L^Lv(l| zmu#6!g7r^=z>eUF;=IT}D(BqID5o3H`DCheC`}Wd{2ErjMq9K0&dvZI|2?uU3%absV ziU2kQfkPhXw~laSE8E=4(nWoOJlpXi*N^ioDGEk9eLQ=t$}e`ZQBLRrb2UU&Pc5mN zk-I90VzkvN30T;DWoB13Z`zbEyNv5r876 zD4fE}%yce1k>(<1qx*VN=!xs2!$zHhEQTy0J<(6}7HduhJknI@8=#^bUQxVTx}p%V^i1&J3)XD=R=FkBa5?U z+Of__Y|+`Ba@35=*UnjS^S}{OqODtGU?9cQc#@$TrS>Q)9Xt0`#^epBK%0mcq-#Xy4fZm=>8*t$D9hBGQehV*nsASf&0y1NAhfzm5ga zsK6Ji{rzk-*%9U?^YhFOLxhCThL}L#^^MGg|cX45FM zYm%!82{qncj7P)E+BRN#s0J}xm#}WE16At%(=FHZ)`j>v?(S7|tX(c(INA|17(|Yo z4xe#nVH%2Zdv@7Va`Be;^6mLVN!hS@xgl9Q=a9Kci&!)aq2qbJibdX? zJ2%>d!kJ%N8}r{4B_>hMyl8h?tY2%sLO09pyv&gKeMHZy?uzwZrlR&dViFGHSa~5^ zIFHbDHuJbtzm}Qb96f4WByT@6&ipRbp0@5b`#fY@=g4quh$4a;%_5I`*-m}M zB394j*4k>BhY{9%{gZDDB~u2H4)psx?)T4e0ymQ_-ceEswxMju# z7AiZp6EA|4VNTZ}uFW>rCJSHxrtE#vfDz6PC128T-2wB87ST*7ZT~!OJ%xyLMo-5* zUYj`K-kb!LrR%w=n~0{^5Lz)Xu3P6ICFjiKHJ#P0iE2HWvS3kGmVOYp!uXeRxoQ?n zrdWHZTpZ&CqO-9ymCaKQgpkkO(YBo7I7QrX`~=qo+eT*&Ct#k{3{-vC7S#o1(kvN@ zwp1lv892Cmh?qlN@@#)yLey5`25RGaS%x;cT7+NGIJ8)S`9!@kp~njTGgmoO&T*9s zeG?OUTd-TnfNpz1kih(BK9Wiv$h2|Ack09GXzc9UZu}%{o-cGvcnP~G69|(E{TRtG zgE!Ytngv`?hjOGSE1z$Y_*1B{hjU5j1$LTcg<^k+&m7q{o`?1{*SY#b$7nTYsV#Gag!y^X^g z=-S~ID7z21EOk$O@l2BK4dqbw`vduWfsbbyQ|+?gA_mh<<&|mbl#o)-Q;u*0{9Z45 zWJsAI4=i+>WvXW7pdirghkTPJXZuTV!AEg|t*FE#=43EALQI;4mA%qsm3(;)pM=bM zc?5$m8!jnqFHCLrZOMMC>S&dzCw+@uRj;eegp5)z>Yo5-SX0ZQz|hD>!)q{0f|%*8 ziO<2Ysmab&l;-F-ha8`cxCj%*R;bAFa$N9W0H@CvR1;}F5enU5C(9K5PpP<&F*&8; znRKvNr_wp+Tm{0X$}vsheMz$>I#WM|!9haua+Srg82Qr61xL^#`;^e-YvflGL z30MDutQvc*ct&ocir92+&pDUZ6C-({xmtxrxfiv&REF;iDmOZc#a`Pw`MuM@Ib*Nh zcic1%;xy0v*mg5f#`1o($+$z|x8(9%Thn*w6Qk;;&^s;k7dcTZ8ae(>ZLg=+a9rF) zGneZwLI0j7u*=e&m9K$naOl?I0)L9ckb3*hyF24%ld>=Hfx^y>9|hZ+JBCKbkvLW6j)zbQ@kE?5kIYnx>%_7;_`17Vm#+2i+U3Br zWBgLez+5ZN+HwWUf!`f5*-eqYc+`mf*A zZd0eRU_L0zHjiQ+eC@1w|7jkqepNOxm%JP~H&0*^Gld2$L>Xx=e>n?lYkD7bD4qGe z%fnY5j!tnUZUMPHjF5%NpUQr2pVKZ$jeaV~W7V}h68t&0^S z_3*O9aY|T92L* z@(Gj4O)wdpNJ<5;SM3JPN$N&zRIp4;=CRC z9xhHeRXHk!x-Ch>R~yyyziKsoOFak0o{KpuL2D>{fmVhrLB3ZU;qy(nW8`gUtP|p1 zEOvRl@HdoXRQx7pJP4(O92mq2_r2jayMYT!5re8eSE6fT{13Tx^1S9>r+&D&eu(*b z>a?YIv}f4z=pb*Vm131+^ZCL!gk$7`!i6~^K5cfBA4#Z12!QITa37s+YWx3UO)#eo~1?8Jp=yRN9N?|o{68I@c zqO15_I#x@Wawhxz13J!!@ZReRiU$-cD~e@4`l~{md|W%1Pyrlj9Tj3kL@Jgi)siw* z5-2d8QHdC6rnJ#bv~ELFacE{|pU|wwrK?BLQcKHc8*!sn^zM@)o30iqcC!>;Xva_K zHK%a3u2xsi0qIv}w~>Dh#AJPe`1)&P1mdHO#uW#B)Y*?UK|#&H5g$1FLC~h#bh#q2JK`mtST2rSXRIWHuc$&hr z>vWycck!8VOP?sM2$I?@(h=Fa_K1#eCIOvzzs0tVFG&Vf4(j(^Dl(%CqK?cTQgwxV3)2V7|HC8y%G<7jgp_s7o=Y$lNQ6{c`t>;Z0 zov>OPZQ%B1HiSE+0>Y&7!Yxru6|tR46wvf>EsvkpFFYx_%-L0{RtXdid)Y=+yTY#E zMuD>NmCXtl^3pst4hN{nFyKn9sN?cj`x*$esZ#o*c^qLq#Svpy>;Zn^dIWccqB2c$ zapb8VHeH*i83~Xs#;D++RjSAfJV&CWAlfm7zM4lBWylH%Z9K!j&C%K05Kj;Sf{Ayr zwvxABvmW7}*A_TgaNX4X4@@y%7xSc;quS*f`di(V^dNULd`!a(&qBpcf?J;72@J@4 zo0lwFo!KCsPx4$j6xiPqE=dFqmT`gY*$E`z;*rPCoPK0@?(}14&kWBz{^Vm%)OF5T z1Qi~5BODItufDN@G9yaXvoqymi58)-dS*Q$Q#P;5R9Zc5Ivk0&zl2q=PI(a(>>bz> zKf-;CTI+}NCTSXB*AgmZYju`pMzdbsBq|*zEORzS9N-RwMU1|z+}xZ=Y3e_0EgLtQgThI}j8J=`_}!|Kn$px`ba|s?%qFxvO>F$Wxz96Hl2c=L)smc8OAc%^ zOOTtbE#=B@&DLtwh*8;vkT_hmFh6n^)J@NN(KTVdF3uJB3%dbEQx`W`CO{Ou#_&46 z%BjC(oqw7geW^Z6Q-A>TI53YrAtvl^eAtNS#nYKc5sbP>cbdw8Dgfcz-X3WsjO<=z zPk#$$R)sSOhPo_A*2Bq5JV5FJEwf)daU9~TAxvXY7{RfEFqWeVFcvCzZxT4utscXkkh_f85P83L(+w}3g1rw!y+m)V! zv+oXEWkUhg0rkPn6s@DE;bw2BO>=bWiVxc;p_hPK;iJ!v9Z_t~-zfVlZfyXhQw|6c zil3BrD1Z)n1I&1%MJ^Bz;~+wnh`k@DV~jHO!tQ%-7WHV=W2>|zI*E(e32a~7R_n3P zda)uq#M-imU_!(tAq(O{E@Wrgu_!;<<=wP7+ z7zHO*A{7*_leqj9f{IYj<$jmdh|z1{dYJ(`$_OODsFCAlEg?Ad!?~~H)V{l$T$F>w zBB(s&eCObS6cQs*J+s*Gmr%)PMN^HIAZjhst}vfsOowG>`EegBQMfxnDZ;&ZWTnML z>~Cg@YCIQ))LC8=*HGEZ_X%xP0N+K8-O}%yFx}Gv7ovr;S_EacH1H}HuI=s_or+<*vLuiDzyZOhQ3y!z67P+|RCE@JJ@ z6mcG*RTsth5SIik+4#HR!kH2zC{t=4o~o~**|vnPrSl9Bp^5n>e{SZ6jSJDSaD*17rM>t~S`u31a^jNKOL zGA;tb8vRtH`TF7Pc`!A2)rb+<@-W6s=jGTG#05+qEP6BC20!4kj*atRqmziB2XPAq z1cB{ko-KMmmJp-Oor#t>3Cj*~&-c?3Kd(3uj-h_Ks167jzTLwHBL=tbsAP*1u7F)O z6F z5!o&ge{2PU(XX#7EhR>C)S3^o&YUf0ErpFp#EwuVxsP*-hgBN4b%AS`K3=fpn--c6 zj<;2md%GK(u~x#_CDa)U zOIbgi9veB0`@CQ$ghb(-qo!f+M!y-;Cw%s?OoTYXh-51+emX9m0&_c*5VJv#zwX2&y`-5ZHXSq zHb`wmcL~`5-z0Lyi5QWZeJArbEi${xSz9SWYS`SlWJoCWbKg_H#P;Bhp9>ivVwCz1 z7F%g+#m#7Ho32}?0O6%U5jpT2j6SK z3^HvtH#`Cr5(S8_vY;lxuX_b|cBjNj<1{>t>k0E9{L2u;#v%I#%;@a&twoJS(q=gt z$tm(P&;q#b@zzYDKug`#!`U^=*pQI~5y-VJ3xo4`jE_9GtE-4&MZr-$Txm^aw4xl4 z#|r>D>q!Yv7L|C2Va_g60t7^tGA(fA=FkZ1+BBomH0t889uZB49w`c=Qv7)j6gzU$ zpbE5mJ9NMiHL{za$bhf&W#Wpt3Dw6sIjd4@_c#xs7mL ztn64miIZ80Gn@AGs0?BVhG7~I@ke+Y#0AD=1zuHmV`b*h9E65D#POp5&(BG6PhlAs zxmw7pdA?vbHaBqdVHO>YbY&gF0eQiYmk}ODKqA|NyP#^bQ|!o1yPAB|?Mtf~_!r9v z5#KN{qGJ*QQ+b&wHA4EzK)@ z)NUxxa9Z^eF>v?>?qYFgCn%Y4yP6rRiyXPhzzkL^Dr#*TBAlO~d;&Bf7srFnWuXfl zxmmk1B@A=nVZG4hU^u`S=N?W9P|oS&qc#4J6w zBX-rA1<>HGfjeq6vs%ksh44=coNgm{H(F-G%HeL`r-%+i zsUg9>fCxn5DAq35f{iKw>QF%;7&(}s1>~Sp&|piIq3aRG4!lVj1d-6y3&ll=`ksC2 z!|JKKHxiixq#Dl!Jy1Cbn_aFaexLp3jN==Np%2M*M`Y>P#&-Y~Cj-?);ZP-9NA+~U z5;s)6`7om$*c@syJqD{0ehSMcpd#SbAhOpFS8Ao6hZuHLF#E=09Ux2$48)=&BtFEa zl-X#WE(r4_SaR|JuyH)?Nl+jby(&^l zYsJ7$l~}3z^NIRX+tAv@EbHv2X}lDX8K5;|lnFhiK|p0`#^|!zfo2A=%tTBDS>gf_ zk9!d*2*mc#RDFF~M_45XFD~GgaG3zvQdijQk>vP zpqVY8{lTw-5ihaB1cDiM_|)U!Eqi)uTME)L1mGkmY7^m7&@tNuW>0n1k*q#9XwK<~ zljCItikZkG=27SE8B>LyEg{n4iJE{jl0&12H4H@YC=V9Q>c|4soHYGG+j;j5jJ) z`x3}$6tLnetDkj-*wB?3V^wN*V>H>y(OqncUDLxc15Z1F;~>UTz-C*|7Yw~=qxmqS zu}Ju_sv+!UI32@)#z9J;lANjP;Za+006~K!poE+VnQS(_@DJ$oy*Lf9o0Yk8Qd*r; zc9~Ah7$J@^_1d82^I=Bs zVX;L(2PxFJAQZrg;Hzhc1y*CO6v)l=`GUqY`?QQZB6UN@!Wd9MP-bN}G`veEOda3} zR9oos96~1mAnukke7ixo7u-89gMmqir;<>ic7-m~lI;%T5Fy%v?^HmHg^Dh{GLArL zZiuTD)-kF=dFqQov&6qAP$i4fF0f#V7A*q|T}8=U+(lub@c)476GQ;5{i-HdqkkGT%4@}%TF+owfennNg<|r7-kvZk{I;%K!C!Ca~1Q<{!$C3 z`rvL<2Ch@^--P@@*aZd+1a=q==DPw%()e(@b+Cw$Xe+rksxV|tFG!lCHv=daDEmY_ zNQvkY=HXy5@rJvobEC26Ol_gWu3RCt0b@7$jfS#`B-sR=Q%(^QuSZ%S{6Taa#DP*W zyZfqAC88Nv<`sB1meC9*TrkZYlJ{`VTF>i@0eUcNYX`DEh<{tab_eB<{*(yv1#qHl zQe0HTNyj|WoiH#X0wZ6eFBs8i+eC@c ztfebk;y|_w(l-e1DJfodwK=K8psWudh~s5}vpS48w~pi$>y(gsjZ{nMSd;iAFxaE9 z949aVH83ACK3a3cDttg(4HD2iJ=LVqxqpfa!b+bo{@N_;+S)@k946WH>NclA62@bb zZ3GDgFsyVvA5W85S{ zK9v4`z~Sk3tdLaoW@SI?zm=zf)Ih6bN&{%i<`fZIM%KVt9X8{vb96Z5hXHj0#CFh- zGq_OGO{$yr4hdbk`FMnFPB20ZG$NTx#EB57C4`YeAgeniP8moRJ-x0;wgmhRQF$Fy zP2gAi{nI-d0X*Ehb{WSkG5ZNhHJ+cLU8cnGh(KOFtK7wPAJ^9Ebber)%m9Ivba3aA zYmzl_y2$OB)&aK$ix%@XaMO{Cp9g4%B5p7Nf>S%41b%1*zBz47I(i)7Ljkox50~T0 zE%HXaQ>4YYFXA5pg&Cr5C^scWG!Bvs!Hzg|MNK!lm&K>_%^^GXxL z3(6yS3qa&KsLF6spUy<5*MaGX@wYzE?-VNMxdg{09`N)M_cXtF(~UaP&NW$J^c-la zLohxHfHZ?&#tvdbusbCVR1j5<1=w#|i$`osj#x^b4ZH^g*7jgAU6nb&CQZqK9nWq6 z5?P`qA-#oP+U=TOM&=u-61pAm9lr zx36I9NAuD6!~oeFA*AvQtUP2sty4PTkYGk{aK9Loyjh zJMsYs%gUqQ392XrIl~C}IEOUPXiGtzaSTDz4{Ru&w9JZ$Y?x8JbyL2yX>~e#U|k=K z0XQ^Nu*7R#T(N-bC4Z>I07D67Sq$@swzzWNZ?UB)%Ji~esf@@T;s!~A4JhQ@d4*+E z`Ia#sNdpTd72|!&>` z2BYV0UTr?isDm38p!5-{k6P6WgAT@c4lXkQ=_IycHrgfTc3RKOs>-BVaYj&K9>P@x zDJ+^H-@3j^&~MLsC0F5vcEqI5s|G$SOx<1Qi(WA-V_uzD0=F;2y#jDJ+1%R0l%)Zt zvGO7N%g#d}+FwHAMO`rjW`Ox zm%#fRI?}*f*r-DVBG)WhQ<6>vzyT1=iJvd#0Nv`sm-M2_MX)auaLwH|7mY;Atb{2% zMIZA#W!;~rdgs104OL>%mZVAW9Kr>9eP>2Y5^^nOqg=oEy94yf&E6P{}x|j1on%X5Al_jNTTpjiLR~@y|#W#*; z4~JV@SGFZQYth9sl#De1%i*_#{)9vwzMsMgE&K9QdczZbT0}df?(`nBY%efJ*^*{ql35wE}Yp+tPD@-{%HUJc8>HmL%vzFyOLSauuRQ zbD*Y`EWCL1MgaFXPM8QHz|qSok)oPibjaH`qz`&4kb91p27oU>Fe0tO@_ksi7nYs} z*$e;_;2wpOTLP>|Dgd*~&cnjpuyh|}JCNZKcQKMlk!gfWx^pBJuf@Xs(4q^Ah^*cY z*riY*qJSqCEzz}|9l7}BMZ00y9>``8EEFdJfh>k229u?|5DR;-a4#&|1KA2Tu<-<{ zB|sxMWO{<1nQn!JJy^ICmhFLT1d^kpv~yz@tt9E2IvZhO52F9y3uCa!*aj@3;Yd#= zkOR*?D?87xKmr5rp!SIJ{XQ??8M-l+sQ*f5uGLe!8)6}qEH?!3z^|hOCb~{sC&n{G zKlIF`V%)MG<-a+yA4Ob>xD=7URPHO{%@N@f;0T>06c%f;b!t;NCg&JdYdg=3*vZW~y``%Jj}!ri z0_$xe$C7oghI+&fBCUZt8Ivn6#mNntqai*QHPE0(R$!o~^ZfL#q`A^F&1OQ**WXz> zly|wK2nCK4Je&i@KYgsH!q`U+%yQF)-n9q)Z=CW41}jSvtaeBjx_ zfdA=7t)9=Xb%~y{ae?B*yFd3LfKAvTtF0X4q?ce2fmDSJBEsb<5{!{%pHZOIS6TXw z#(dd*X4(;GvQ!eO=lGa{1!H!|l9WLMb9E_$99}0UWlO*j(eWA)q38?zr8uZnETm|L!i! z+T^2L3TOwA&F-%ZRa#Q zS&0Lrfg4+lG`$}LPkfLyO42JS} zUxoaC8RMRX2_{O1Z{S&-4)&3{pGMKHjYyqL2pU<~gf30{xo-VK-ZLaXG4>1Ens0qO z6OGqVF}^~&r+E{-!3azSWb5DX@lelzx6oT0tF3KDX$p(!r&_)JZUi5s#>P%yy@F0k ztoGinbw9l{g{?Qy%VkqIe*rb@PPQwns-&w}TdVU<2pTQ|pVDJ>jE{=-cIL?#=T6;wU$r}#*0nWlUs|_*n-^>E6^VtH+wLLWKiuDB zo0`SD3~!p+7A@JKuoMn=CW2A+*l6c5KAd{PBzjYwOQTxN(_$mgJ*W@qqNL=_c2r1b%_?j*I&F!M{My#F`sIOwL<=iJ03b6rWKvGLWgK8Y#P z;N=E;`%9@8R}agk`5FE~=XhVIFup@pq4Hz>CaRFR5<+2pD_>gqWKZ2Q#o*q5{1y?2 zFQOq<(t0HWUpdSBRR&RYzBp#h`A$cF5XouwKY5K4Hx_i0EbVSIG zOkKT_)e_g_c8zKcBBAw7OtVf+D+Jp5bmpg~qKyNU_5IaSn7O{d%h#J^{$cumw#u<( z-NzR>)Kzkw->6B99?Ku|O-foHW>A7pggLR&6N)?8oPqf=?;2{+dJmftwy)0FzRYo` zW@*v3U$_1RO|+6gOCD=~KhunXk&%SM(+8(0?(WO0D z&5y%}ruAt7AOczVq5+HY4R!g?=nbT;wA*T%GeBQJw> z>tSj&I=9{}L_~XlS%1u2>9W?h(FDL|oA^m!qpQ!T_0!WG zC(Ok;`lQKkLO9?a4#*3Lz>ib6AqdtPT9mO1=$`ed^rwCM2;KQ-bw7rhuHQ#9#&P-( zc7xZf=RQu@L16_y@G{H#n%k@v{NE4r+?dL1s{8{mk1GH)y+GFF5Ht&+cFSNSy!?ey zPPXto+x2U1ksV;*wXN@9-xT>01@+Q$#`)dcla>V^9W~1gFp-Or9+q&N16Z8 ztu$^Rx8?rRt|Ft+w)KP5WsJGj8`)a;ZR3qwhrz8HYWLq{v}BC{Gs9jvIchNmoy$0O0?xv5zYW^)+Si(jA=b4;CBQ)Pn8_PPF{5EB$fa_nt zHz7{dy&(X}9fa40|FLVX@~au)l>2>GHU1e%qiZUA@w1ttX^70cnfw|~J^?J&Z!$m2 z!w3Bqy=j=#|C3kiz;}(EGOw*31+N!b;hhX;#gLaiCl2yb$BxbG)o-#Er(3Z4FJ){s zq^x27m&OYIYC5?n)aqwgw!_Ge#*f#kPd!Z!`eszs-|w-pZU ze_`(~6Gi(N1Jyv?zr!A=DddmPMPZDWL6W;u%4#70dHZNeiw|Tnu>KNjD5TdwXwTbOa>KMkxA#-f zb?ZfPV#Xt~C+}Kk>8lV~>pY7+^>(zLV~P(4b$AmsOS{|^(T;nl8lOY!m_7|$_ts0O=X$`^e?>?;`(iPR z@O9K)0VjWy7sMs3i#0lL&yML}h0^~sd^A+}99*JEfy=`(-3|R}xkT2kd4J5$W)}(= zXpvh#DF^B>WQ|XhHPvVom40u9HNA<0Pzi|rdd4fF{5~GZ3e38(SG;9DPUaX1?&RI< zpkLc$8e~k-KhDZkIKSG9Dwz>S?T)0S1^L=7M!I-t?SlRh9x|; z^>B9;=1teFl$XpqR!C(n+4e`K3!^V<&1=Yw{nuEL8m`9rUP@`P_lH;*h!~O+s*XD5 za9*1qq-$NgqIo4ZW%=949Y4$6(9+UbuWxQt-MIA#9a=r<&9?{@O2t#1830KIYWy4g zRA16x$kd43{t0?VXg+D-YJZqc>|Wc+th2m0>vmp|nEXDoVCJimFy~Fz1-4SnXjW3! zhVDy~Amwi`ENH*vN_lEd=c@MpR)!$@2 z^9sxQ-4|QdzvVxZ81C2jqr>F2v~%uRAwP%$X4m>f zx}}8=>-}`HRzrO4ix?8Bq+RO`JQqvUx5;6XkQ+<@qSV%8B<`riK!56!F%|t4FT12Ijx#1 zS}&oc89D1d#?SRBk-1v8-X=@AD>Kxz@?V(LsVx6dUa2fu-$`>xekCEyQ`vYF@v*sinuD1)&616^sP_V;q2rlzI; zht+E5z_i}N$~5Ms|4$aD5UuOFB|;C8iO}1VchuSwqGL5 zhz{VJ6*p)7I*$*=aqTeG`tqmea-oVwRz~q7b9Szo@_GB_=jvUoh44@3+%s-+)!N($8v z(f_$@quyViPK~W(nU=*C6%qOpf9p*~67W5itLfy>wq8l6WiqNgCi7bFGBJ!)zjr5M zd~u@B&tjAJy7gD6yBlQKV>(0t{(L$m3C(|E`5n?6-(_2WH*l7_%nD zOYGRzkPq9dk5m6S$#`^jryN;#OXF~3Z=kVCko#`g3UVTZZ2T%;^o2LIl37pl&K2}+ zxz1~}YjK&+i3WEVs0eQViZ@to>&q!A#A(iA{d>A*E+1O{An!^y5NO8M@9<(}LHk(> z8FA(h_(TYu@R=E=7P7bME`MS5qV*9z>@+IpdAG`2+1bLkXsm%&jO0|W0XuM_)#K)l zhkq9XI5tt-f~-4et+@!b3q_ZfOfTcxR#@1TiNW_XDYG~fIiVP|%)TT%t+GANTMCgX zpx3o=?o+re8IB&PC|hJYtY2eW^J5*k{44z4mL}dM6GE(DVf`{sp1g4O^@HJ~r_aB3 zaNc^ZIvyCFD?Z~BxirL|ZkSw6fZ7!O1@XDL^#?Spf0u+c)_-*3=9+=}&SjL+~FVg}bEZO{a)yA6+{Cq(?JTJ%fO2x}9jd3gp?_*%Wgm%3|L zpj-^tdL{qeWNkfeK79t?%#0Y@fY0~JK4n-Y!_(i(&!zw$thX`WH(B3F6(8gD{$>6X zbI{v)Qe`xHCqFe@qfD~_ar{F*Rj_oQ$;U=)|Em<&=V6;)+j*6~nFqBf@nd{$TzA-K z);2$I_ZYBI>$iB7Ez#iWS#RL+g$lX#Lp&6hKi!QM;bf@%R<~B3d*k zw7=YZ*K63uWV9ZVme6%upH$VXGox6KN>!50;)7LBB(Z{ZLHdlQo?KVf&rw3=z<}uX z`PL}ctuN!7(IC3E-P*T_@(HZOgCBo5L_)+j^UHI zS78_4t)EsoRIIPB+K^GTrcSb6h~3IWUt1ofv?fd6P%_su%A4uex(e$Ts%mu|+UcTd z{TFH7Km=Q#$44!NP}chJ&9dn}@cEYY_c&PpnO~++1`ETt9P3MYq1lel@}`aq`%G$I zvI@_7k94Z{VW@M+Qj0J6lIA3z$z^ojES+c8GU+8OCU;IxVHl#{w_ zR~+lyGF_3#yZ1BHT3E^;3(GbUS)a2)Y0r8G?Z{dDJIjn0-bb!B+3}OAJS@~NbQ+W` zIxoy~=xBeo=~xyPR@MvY+>(Vo%Uu5Z9JQ^7m#-qSzQU}|!u_Nfxi_29(|t=k7MYMm zBQcxnpEFH|7L@SPucXEnEqeJf4ak=H4Aa0Ny_ZA8(@WJaJ^5m~ zJe9)Ux6HuVTHi~rrmMZ^vw z&^IjOzoZy^jyd>ESj-x~N(9a?@%K@D;l%4zeBwkGC%3?>X}EKF%K6Za;r!+NR_^uI zsdhQ3;4M7w`qz)-4g8BYtpCBMCZ? zEF)=F_dv!Q@1nNr-CjK$7kf9oxcV$ot;iF__}C{mk5LwFh@_HENQ5%J`Gu{rmx^o0 z>+e_*hkU=KuFI(GlC4Scf;+2MwA^^>w1D1-ymQ-&ssbV=O+c8s{Zm_w$at70VE*J{ zyW=IZ9^LuU>Q`~d!s$@NVm(@*S;vCfH@SS*J#&hH5qOC#wSZmV4Y|AV!n>++Fb#Ma zzv#}2DbsAg$KBB~UB38*)uYNh@bPzX>Em1V zSHFGor*#T;{5C)3R-S46!%qz*#z;40{#8qYDt_9_dGUHtZ~j8mv>H|}?F5M}1H1Sa z@2}%?rZ7J9(d<6mIoQr&n2eusZ}W}-LoI+@{7Y*G`?4%p-idqaccqc}*kUi0_0fod zH44*`*j;x&DZ{u9NXErTke~VVbyj;A(&Nb^_Lo^CnCSqJ<7b_f{_6dGR3yiH(t0Us zz_1&SX8755-Ntl#n@{uL4DXe57^GXtCCL$^|Bz7Zsbu`1`K+_T5)7adQ~->s1ewB4 zNyGs7`F+3NYo>OgfNo9X((}}VmUJLYeJd&{ni@r4m(W?M=LsfjpzCV4X)f{lO6&KhmH~4`_4`lm2#fLf_`JTd zOilIVRp4$|JMgWOZXb$^#?+E-+9AeRa3+DPd*GcYC0MRPlW>#ImNkHHL2O=WUF%AYVdt!-dc2UA|zdQCUHi%kT zCNk3iHR3w-5mavbf1$%vrcUgEgq(qglmLo7P!G$L5(TYSMocriVYW4t55bv7p5TuP z;i-(jUoJYgi+dZ)B2)-u9H;HnV~E;Gsix zs&J#aj=%v0CJ0HF8Y$O{{ek~7>M%gS2+0SrXFZM*NWy6X3Uiv$Xs|6q^bHy4i~wTP z@4vRVc9by!-3T;F>_?onJXHB0)MH%kpt*&l*rAk>uvB{^x?aUk8=L}d@w{v44}hd_GZ?3LgX zdU+ZSUjESX6QR>|vm=-U*Z~KO5%P`&iIaxz;M7X%;dx|g0y6+8aPrj@YVe9xx=~4W zbc6Jp89A|leF;nQb9saHYYZnchqX;E;1ITk*w`jqac3TRNB$94T$K)4 zgaSv>5rl(Re&bEFUCB8I*&R<<7qBy54fMcPA=lxd9LV*sIgef+lha{uR$z_>`9+QJ zE|a5O&q|$VJ4zFH48dgbLA6)j;PZsD?^5s}8(+H&W8x*d*S3i`A8%$NtH32G)%qw9@zpCigaad;h>x3pAe3fSM z?25_jPiO{ zLxJc5^4`O5I9ko^O=6P(!Iw-mQ^++DH%mE#@5~>fvz5m(;m#esY*zL4Zt(0$>X#HNPX~{^9yQ1(ZI9} zmHmtZ0$R6PeyXr@Y#;1UUUCBdgY1ewHfl7f*>)75(vAny#@*@+9zC<5=FW5mn_2*(5>V*^L4hwLm+=Dx z_SmCT(xpCv)Ty;`yGjlCbnTq@2JVuC1-&FYjkG)3TafC2AS}Er^yv*Oa|wKj+iT>QB}nzXtx%131>@U2L@_~UN-zc6DEkeKl>f)J)wkyd|xjhm|4sm1g*Pj|ue;Cf-m_=2L@GI(x_Q*SQS5wEua)IqZ zSP+1eii9=}o)#88GSYvSvEhbflMTn47dQ4m>N0!oy#Chd!J@hMNN$9R)Q|Ge&LS{d zUnlbynC1=_dKOg;NM;a&fs_`cY|Bb_&{seVeZkvg{tR%_;q}j(yhS$;X%K<=N=PQ* zyClJL2d~eiNdtJ56_>pbPEc2TW^m36FBpNmGhyQCoKkV(z5c6nq!!~1aNd*nMdTZfLyVjK~7VEX-U?B zH(xj9BQv6M9Fk=M=S*hRY%sizWy@0_=|F!?xPS`>HN{(YZsZPA&faJ**&6OnE??df znah*(%Bmp4iXW$BuN)+Ay^-xns@}^9wkg??PL#SH*wN%HA{B5P57N(~Eiy%LBv7?z zs~W|CceLTA$@E9c#1ySurZqK-#qxUlN3~^*iqK5DWZd<=(iV8(Y(RE`8+clc2){Ri z#gu!PgNi;V_R&g{Yc2{0#VK0bccV8%TB%%aU!z^(Z5O;TGDmx8Tgoy?qd|Ft`zrI> z^fls+jzN%v%H(e3d4r27eGSajQ;|-fh5CJfJ~})@hm>gw4bs$($iMPOxC&qYAoCHT zvrbCJ6O!YB+>jgBeX@Wec2heK@=~Lkhl9l>AJ~Glxl@&GiH@185vwkK+?&Vi%Mu)YcM)W z#;8^rgq6-9(87(j1;r%7h)Hb~a!P!1IPa{og~%QN)H|04nDU{Ym4nfrBOMZ`vLR`? z$P!Lkq!5h$%h!466WfV_%e6_ilKZ6V7`$zzC16i@Q7*f-2;$VW2ji7qC+RS_l@4-V znTBL{8tmR!a*F%m-f){h7d9It5`a)Nm$3)9qKXE46E7$p{3>~>$=>MD*qK&WsCU)(ze5B|=c_%JN0qTO~`d+mxC|u9oQssE;dG=D=Ps~HO&WK*1NOKBYt`B^kI$e=P9EA&Z1ON zY=fW5=m-Bt?>5bP;PSNj6-S$tfO7+CF=su88}PEhSN8O#UT|XKrfu0ZDD)%l))a#; zOsE?Cm4j2_!GFRXVBhgl4CX1?&Xo=ho6*fZEaHCTku)_Jyr*}IVZFY(cj(@1c(mA$ zS&otvcO?lj!gBE5gFP+LX^<(J{7@v01v+~0zTRyO$Ne>j&rDO6nSsB`Am=`?#VX2* zVDPmE+k?*JuB##^!az+P$idgGHZx%Wf<3uS$ZSBKO4Ko5-#f0wgTLB)!DL5&dVlX$ zO(NHrGPGz$p*gl32He)5}TvkdcQWQY72S;=$kV*;LvXP3k<-`l%Rv8f<84jJsYUhOaqQR;nP?}&b}I6^TeXlTffj3ZGF0Svrg z@cq3T;KioUS zkLo}U?|;}EuosS=ulplC5iOfNH8sSkLlbBJqn>!u9RBK|sk5K!y{fLLRMRm5Yff%>Vlc z{f)_f{1aLVTa@^BnmqVGdg7024ybv#`7k4W@U)f#DTsfv_gY5Ryxe@4QOgoZi2s?E z(VI$|4>M|;n^X9o_ii!qo0judFdY1J?`8>S{h1y?I7Dob{K$IpHb5-% zNk)v-O}9$2;R&9{y_?U2gl64Y;ae8@1L?KiaoJ(nXQ{q#_w5IE#D=_e?ZmyLO~SVd RLHh(rO6>=f^MLa2`=2_^hI0S_ From 6f0dd32df1fec06f1dda1472d93aa53a9db6e98d Mon Sep 17 00:00:00 2001 From: Maciej Zielinski Date: Wed, 7 Jul 2021 09:56:50 +0200 Subject: [PATCH 39/98] Replace URI with Meta --- cep47-logic/Cargo.toml | 3 +- cep47-logic/src/lib.rs | 38 ++-- cep47-logic/src/tests.rs | 223 ++++++++++++------------ cep47/Cargo.toml | 2 +- cep47/src/lib.rs | 87 ++++----- dragons-nft-tests/Cargo.toml | 1 + dragons-nft-tests/src/cep47.rs | 48 +++-- dragons-nft-tests/src/contract_tests.rs | 95 ++++++---- dragons-nft-tests/src/lib.rs | 2 +- dragons-nft-tests/src/market.rs | 52 ------ dragons-nft/src/main.rs | 6 +- 11 files changed, 276 insertions(+), 281 deletions(-) delete mode 100644 dragons-nft-tests/src/market.rs diff --git a/cep47-logic/Cargo.toml b/cep47-logic/Cargo.toml index eb1f628..ae619e8 100644 --- a/cep47-logic/Cargo.toml +++ b/cep47-logic/Cargo.toml @@ -8,4 +8,5 @@ edition = "2018" casper-types = "1.2.0" [dev-dependencies] -rand = "0.7.3" \ No newline at end of file +rand = "0.7.3" +maplit = "1.0.2" \ No newline at end of file diff --git a/cep47-logic/src/lib.rs b/cep47-logic/src/lib.rs index 4aad53c..13fb923 100644 --- a/cep47-logic/src/lib.rs +++ b/cep47-logic/src/lib.rs @@ -1,13 +1,19 @@ #![allow(dead_code)] #![allow(unused_imports)] +use std::collections::BTreeMap; + use casper_types::{ApiError, AsymmetricType, PublicKey, URef, U256}; +#[cfg(test)] +#[macro_use] +extern crate maplit; + #[cfg(test)] pub mod tests; pub type TokenId = String; -pub type URI = String; +pub type Meta = BTreeMap; #[repr(u16)] pub enum Error { @@ -35,8 +41,8 @@ pub trait CEP47Contract: WithStorage { self.storage().symbol() } - fn uri(&self) -> URI { - self.storage().uri() + fn meta(&self) -> Meta { + self.storage().meta() } // Getters @@ -52,8 +58,8 @@ pub trait CEP47Contract: WithStorage { self.storage().total_supply() } - fn token_uri(&self, token_id: TokenId) -> Option { - self.storage().token_uri(token_id) + fn token_meta(&self, token_id: TokenId) -> Option { + self.storage().token_meta(token_id) } fn tokens(&self, owner: PublicKey) -> Vec { @@ -74,17 +80,17 @@ pub trait CEP47Contract: WithStorage { // Minter function. // Guarded by the entrypoint group. - fn mint_one(&mut self, recipient: PublicKey, token_uri: URI) { + fn mint_one(&mut self, recipient: PublicKey, token_meta: Meta) { self.storage_mut() - .mint_copies(recipient, token_uri, U256::one()); + .mint_copies(recipient, token_meta, U256::one()); } - fn mint_many(&mut self, recipient: PublicKey, token_uris: Vec) { - self.storage_mut().mint_many(recipient, token_uris); + fn mint_many(&mut self, recipient: PublicKey, token_metas: Vec) { + self.storage_mut().mint_many(recipient, token_metas); } - fn mint_copies(&mut self, recipient: PublicKey, token_uri: URI, count: U256) { - self.storage_mut().mint_copies(recipient, token_uri, count); + fn mint_copies(&mut self, recipient: PublicKey, token_meta: Meta, count: U256) { + self.storage_mut().mint_copies(recipient, token_meta, count); } fn burn_one(&mut self, owner: PublicKey, token_id: TokenId) { @@ -134,6 +140,8 @@ pub trait CEP47Contract: WithStorage { return Err(Error::PermissionDenied); } let mut sender_tokens = self.storage().get_tokens(sender.clone()); + println!("Sender tokens: {:?}", sender_tokens); + for token_id in token_ids.iter() { if !sender_tokens.contains(token_id) { return Err(Error::PermissionDenied); @@ -193,13 +201,13 @@ pub trait CEP47Storage { // Metadata. fn name(&self) -> String; fn symbol(&self) -> String; - fn uri(&self) -> URI; + fn meta(&self) -> Meta; // Getters fn balance_of(&self, owner: PublicKey) -> U256; fn onwer_of(&self, token_id: TokenId) -> Option; fn total_supply(&self) -> U256; - fn token_uri(&self, token_id: TokenId) -> Option; + fn token_meta(&self, token_id: TokenId) -> Option; // Controls fn is_paused(&self) -> bool; @@ -209,8 +217,8 @@ pub trait CEP47Storage { // Setters fn get_tokens(&self, owner: PublicKey) -> Vec; fn set_tokens(&mut self, owner: PublicKey, token_ids: Vec); - fn mint_many(&mut self, recipient: PublicKey, token_uris: Vec); - fn mint_copies(&mut self, recipient: PublicKey, token_uri: URI, count: U256); + fn mint_many(&mut self, recipient: PublicKey, token_metas: Vec); + fn mint_copies(&mut self, recipient: PublicKey, token_metas: Meta, count: U256); fn burn_one(&mut self, owner: PublicKey, token_id: TokenId); fn burn_many(&mut self, owner: PublicKey, token_ids: Vec); diff --git a/cep47-logic/src/tests.rs b/cep47-logic/src/tests.rs index 6017d7d..622ff05 100644 --- a/cep47-logic/src/tests.rs +++ b/cep47-logic/src/tests.rs @@ -2,7 +2,7 @@ use casper_types::AccessRights; use rand::Rng; use crate::{ - AsymmetricType, CEP47Contract, CEP47Storage, PublicKey, TokenId, URef, WithStorage, U256, URI, + AsymmetricType, CEP47Contract, CEP47Storage, Meta, PublicKey, TokenId, URef, WithStorage, U256, }; use std::{ collections::{hash_map::DefaultHasher, BTreeMap}, @@ -13,11 +13,11 @@ use std::{ struct TestStorage { name: String, symbol: String, - uri: URI, + meta: Meta, paused: bool, total_supply: U256, tokens: BTreeMap>, - token_uris: BTreeMap, + token_metas: BTreeMap, balances: BTreeMap, belongs_to: BTreeMap, urefs: BTreeMap, @@ -28,13 +28,13 @@ impl TestStorage { TestStorage { name: String::from("Casper Enhancement Proposal 47"), symbol: String::from("CEP47"), - uri: URI::from("https://github.com/casper-ecosystem/casper-nft-cep47"), + meta: meta::contract_info(), paused: false, total_supply: U256::from(0), tokens: BTreeMap::new(), balances: BTreeMap::new(), belongs_to: BTreeMap::new(), - token_uris: BTreeMap::new(), + token_metas: BTreeMap::new(), urefs: BTreeMap::new(), } } @@ -49,8 +49,8 @@ impl CEP47Storage for TestStorage { self.symbol.clone() } - fn uri(&self) -> URI { - self.uri.clone() + fn meta(&self) -> Meta { + self.meta.clone() } fn balance_of(&self, owner: PublicKey) -> U256 { @@ -75,10 +75,10 @@ impl CEP47Storage for TestStorage { self.total_supply } - fn token_uri(&self, token_id: TokenId) -> Option { - let uri = self.token_uris.get(&token_id); - if uri.is_some() { - Some(uri.unwrap().clone()) + fn token_meta(&self, token_id: TokenId) -> Option { + let meta = self.token_metas.get(&token_id); + if meta.is_some() { + Some(meta.unwrap().clone()) } else { None } @@ -120,7 +120,7 @@ impl CEP47Storage for TestStorage { self.balances.insert(owner, owner_new_balance); } - fn mint_many(&mut self, recipient: PublicKey, token_uris: Vec) { + fn mint_many(&mut self, recipient: PublicKey, token_metas: Vec) { let recipient_balance = self.balances.get(&recipient); let recipient_tokens = self.tokens.get(&recipient); let mut recipient_new_balance = if recipient_balance.is_none() { @@ -136,11 +136,11 @@ impl CEP47Storage for TestStorage { let mut hasher = DefaultHasher::new(); - for token_uri in token_uris.clone() { - let token_info = (self.uri.clone(), token_uri.clone()); + for token_meta in token_metas.clone() { + let token_info = (self.meta.clone(), token_meta.clone(), self.total_supply()); Hash::hash(&token_info, &mut hasher); let token_id: TokenId = TokenId::from(hasher.finish().to_string()); - self.token_uris.insert(token_id.clone(), token_uri); + self.token_metas.insert(token_id.clone(), token_meta); recipient_new_tokens.push(token_id.clone()); self.belongs_to.insert(token_id, recipient.clone()); recipient_new_balance = recipient_new_balance + 1; @@ -151,9 +151,9 @@ impl CEP47Storage for TestStorage { self.tokens.insert(recipient, recipient_new_tokens); } - fn mint_copies(&mut self, recipient: PublicKey, token_uri: URI, count: U256) { - let token_uris: Vec = vec![token_uri; count.as_usize()]; - self.mint_many(recipient, token_uris); + fn mint_copies(&mut self, recipient: PublicKey, token_meta: Meta, count: U256) { + let token_metas: Vec = vec![token_meta; count.as_usize()]; + self.mint_many(recipient, token_metas); } fn burn_many(&mut self, owner: PublicKey, token_ids: Vec) { @@ -176,7 +176,7 @@ impl CEP47Storage for TestStorage { .position(|x| *x == token_id.clone()) .unwrap(); owner_new_tokens.remove(index); - self.token_uris.remove(&token_id.clone()); + self.token_metas.remove(&token_id.clone()); self.belongs_to.remove(&token_id.clone()); owner_new_balance = owner_new_balance - 1; self.total_supply = self.total_supply - 1; @@ -203,7 +203,7 @@ impl CEP47Storage for TestStorage { .position(|x| *x == token_id.clone()) .unwrap(); owner_new_tokens.remove(index); - self.token_uris.remove(&token_id.clone()); + self.token_metas.remove(&token_id.clone()); self.belongs_to.remove(&token_id.clone()); self.total_supply = self.total_supply - 1; self.balances.insert(owner.clone(), owner_new_balance - 1); @@ -262,6 +262,37 @@ impl WithStorage for TestContract { impl CEP47Contract for TestContract {} +mod meta { + use super::BTreeMap; + + pub fn contract_info() -> BTreeMap { + btreemap! { + "github".to_string() => "https://github.com/casper-ecosystem/casper-nft-cep47".to_string() + } + } + + pub fn apple() -> BTreeMap { + btreemap! { + "fruit".to_string() => "Apple".to_string(), + "size".to_string() => "A".to_string() + } + } + + pub fn orange() -> BTreeMap { + btreemap! { + "fruit".to_string() => "Orange".to_string(), + "size".to_string() => "B".to_string() + } + } + + pub fn banana() -> BTreeMap { + btreemap! { + "fruit".to_string() => "Banana".to_string(), + "size".to_string() => "B".to_string() + } + } +} + #[test] fn test_metadata() { let contract = TestContract::new(); @@ -270,11 +301,9 @@ fn test_metadata() { String::from("Casper Enhancement Proposal 47") ); assert_eq!(contract.symbol(), String::from("CEP47")); - assert_eq!( - contract.uri(), - String::from("https://github.com/casper-ecosystem/casper-nft-cep47") - ); + assert_eq!(contract.meta(), meta::contract_info()); } + #[test] fn test_mint_many() { let mut contract = TestContract::new(); @@ -282,11 +311,8 @@ fn test_mint_many() { let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); assert_eq!(contract.total_supply(), U256::from(0)); - contract.mint_many(ali.clone(), vec![URI::from("Apple URI")]); - contract.mint_many( - bob.clone(), - vec![URI::from("Banana URI"), URI::from("Orange URI")], - ); + contract.mint_many(ali.clone(), vec![meta::apple()]); + contract.mint_many(bob.clone(), vec![meta::banana(), meta::orange()]); assert_eq!(contract.total_supply(), U256::from(3)); let ali_balance = contract.balance_of(ali.clone()); @@ -295,16 +321,16 @@ fn test_mint_many() { assert_eq!(bob_balance, U256::from(2)); let ali_tokens: Vec = contract.tokens(ali); - let ali_first_token_uri: URI = contract - .token_uri(ali_tokens.get(0).unwrap().clone()) + let ali_first_token_meta: Meta = contract + .token_meta(ali_tokens.get(0).unwrap().clone()) .unwrap(); - assert_eq!(ali_first_token_uri, URI::from("Apple URI")); + assert_eq!(ali_first_token_meta, meta::apple()); let bob_tokens: Vec = contract.tokens(bob); - let bob_first_token_uri: URI = contract - .token_uri(bob_tokens.get(1).unwrap().clone()) + let bob_first_token_meta: Meta = contract + .token_meta(bob_tokens.get(1).unwrap().clone()) .unwrap(); - assert_eq!(bob_first_token_uri, URI::from("Orange URI")); + assert_eq!(bob_first_token_meta, meta::orange()); } #[test] fn test_mint_copies() { @@ -312,65 +338,52 @@ fn test_mint_copies() { let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); assert_eq!(contract.total_supply(), U256::from(0)); - contract.mint_copies(ali.clone(), URI::from("Casper Fan URI"), U256::from(7)); + contract.mint_copies(ali.clone(), meta::apple(), U256::from(7)); assert_eq!(contract.total_supply(), U256::from(7)); let ali_balance = contract.balance_of(ali.clone()); assert_eq!(ali_balance, U256::from(7)); let ali_tokens: Vec = contract.tokens(ali); - let ali_first_token_uri: URI = contract - .token_uri(ali_tokens.get(0).unwrap().clone()) + let ali_first_token_meta: Meta = contract + .token_meta(ali_tokens.get(0).unwrap().clone()) .unwrap(); - let ali_third_token_uri: URI = contract - .token_uri(ali_tokens.get(2).unwrap().clone()) + let ali_third_token_meta: Meta = contract + .token_meta(ali_tokens.get(2).unwrap().clone()) .unwrap(); - assert_eq!(ali_first_token_uri, URI::from("Casper Fan URI")); - assert_eq!(ali_third_token_uri, URI::from("Casper Fan URI")); + assert_eq!(ali_first_token_meta, meta::apple()); + assert_eq!(ali_third_token_meta, meta::apple()); } #[test] fn test_burn_many() { let mut contract = TestContract::new(); let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); - assert_eq!(contract.total_supply(), U256::from(0)); + contract.mint_many( ali.clone(), - vec![ - URI::from("Banana URI"), - URI::from("Orange URI"), - URI::from("Apple URI"), - URI::from("Grape URI"), - ], + vec![meta::banana(), meta::orange(), meta::apple()], ); - assert_eq!(contract.total_supply(), U256::from(4)); + assert_eq!(contract.total_supply(), U256::from(3)); - let mut ali_balance = contract.balance_of(ali.clone()); - assert_eq!(ali_balance, U256::from(4)); + let ali_balance = contract.balance_of(ali.clone()); + assert_eq!(ali_balance, U256::from(3)); - let mut ali_tokens: Vec = contract.tokens(ali.clone()); - contract.burn_many( - ali.clone(), - vec![ - ali_tokens.get(0).unwrap().clone(), - ali_tokens.get(3).unwrap().clone(), - ], - ); - let mut ali_first_token_uri = contract.token_uri(ali_tokens.first().unwrap().clone()); - assert_eq!(ali_first_token_uri, None); - let mut ali_last_token_uri = contract.token_uri(ali_tokens.last().unwrap().clone()); - assert_eq!(ali_first_token_uri, None); - assert_eq!(ali_last_token_uri, None); + let ali_tokens: Vec = contract.tokens(ali.clone()); + let banana = ali_tokens.get(0).unwrap().clone(); + let orange = ali_tokens.get(1).unwrap().clone(); + let apple = ali_tokens.get(2).unwrap().clone(); - ali_tokens = contract.tokens(ali.clone()); - ali_first_token_uri = contract.token_uri(ali_tokens.first().unwrap().clone()); - ali_last_token_uri = contract.token_uri(ali_tokens.last().unwrap().clone()); - assert_eq!(ali_first_token_uri, Some(URI::from("Orange URI"))); - assert_eq!(ali_last_token_uri, Some(URI::from("Apple URI"))); + contract.burn_many(ali.clone(), vec![banana.clone(), apple.clone()]); + let ali_tokens_after_burn = contract.tokens(ali.clone()); + assert_eq!(ali_tokens_after_burn, vec![orange.clone()]); - assert_eq!(contract.total_supply(), U256::from(2)); - ali_balance = contract.balance_of(ali); - assert_eq!(ali_balance, U256::from(2)); + assert!(contract.token_meta(banana.clone()).is_none()); + assert!(contract.token_meta(orange.clone()).is_some()); + assert!(contract.token_meta(apple.clone()).is_none()); + + assert_eq!(contract.total_supply(), U256::from(1)); + assert_eq!(contract.balance_of(ali), U256::from(1)); } #[test] fn test_burn_one() { @@ -378,10 +391,7 @@ fn test_burn_one() { let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); assert_eq!(contract.total_supply(), U256::from(0)); - contract.mint_many( - ali.clone(), - vec![URI::from("Banana URI"), URI::from("Orange URI")], - ); + contract.mint_many(ali.clone(), vec![meta::banana(), meta::orange()]); assert_eq!(contract.total_supply(), U256::from(2)); let mut ali_balance = contract.balance_of(ali.clone()); @@ -389,12 +399,12 @@ fn test_burn_one() { let mut ali_tokens: Vec = contract.tokens(ali.clone()); contract.burn_one(ali.clone(), ali_tokens.get(0).unwrap().clone()); - let mut ali_first_token_uri = contract.token_uri(ali_tokens.get(0).unwrap().clone()); - assert_eq!(ali_first_token_uri, None); + let mut ali_first_token_meta = contract.token_meta(ali_tokens.get(0).unwrap().clone()); + assert_eq!(ali_first_token_meta, None); ali_tokens = contract.tokens(ali.clone()); - ali_first_token_uri = contract.token_uri(ali_tokens.get(0).unwrap().clone()); - assert_eq!(ali_first_token_uri, Some(URI::from("Orange URI"))); + ali_first_token_meta = contract.token_meta(ali_tokens.get(0).unwrap().clone()); + assert_eq!(ali_first_token_meta, Some(meta::orange())); assert_eq!(contract.total_supply(), U256::from(1)); ali_balance = contract.balance_of(ali); @@ -407,7 +417,7 @@ fn test_transfer_token() { let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); assert_eq!(contract.total_supply(), U256::from(0)); - contract.mint_one(ali.clone(), URI::from("Casper Fan URI")); + contract.mint_one(ali.clone(), meta::apple()); assert_eq!(contract.total_supply(), U256::from(1)); let mut ali_balance = contract.balance_of(ali.clone()); @@ -417,8 +427,8 @@ fn test_transfer_token() { let ali_tokens: Vec = contract.tokens(ali.clone()); let ali_first_token_id: TokenId = ali_tokens.get(0).unwrap().clone(); - let ali_first_token_uri: URI = contract.token_uri(ali_first_token_id.clone()).unwrap(); - assert_eq!(ali_first_token_uri, URI::from("Casper Fan URI")); + let ali_first_token_meta: Meta = contract.token_meta(ali_first_token_id.clone()).unwrap(); + assert_eq!(ali_first_token_meta, meta::apple()); let transfer_res = contract.transfer_token(ali.clone(), bob.clone(), ali_first_token_id.clone()); @@ -438,11 +448,8 @@ fn test_transfer_all_tokens() { let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); assert_eq!(contract.total_supply(), U256::from(0)); - contract.mint_many( - ali.clone(), - vec![URI::from("Apple URI"), URI::from("Banana URI")], - ); - contract.mint_one(ali.clone(), URI::from("Casper Fan URI")); + contract.mint_many(ali.clone(), vec![meta::apple(), meta::banana()]); + contract.mint_one(ali.clone(), meta::apple()); assert_eq!(contract.total_supply(), U256::from(3)); let mut ali_balance = contract.balance_of(ali.clone()); @@ -452,8 +459,8 @@ fn test_transfer_all_tokens() { let ali_tokens: Vec = contract.tokens(ali.clone()); let ali_second_token_id: TokenId = ali_tokens.get(1).unwrap().clone(); - let ali_second_token_uri: URI = contract.token_uri(ali_second_token_id.clone()).unwrap(); - assert_eq!(ali_second_token_uri, URI::from("Banana URI")); + let ali_second_token_meta: Meta = contract.token_meta(ali_second_token_id.clone()).unwrap(); + assert_eq!(ali_second_token_meta, meta::banana()); let transfer_res = contract.transfer_all_tokens(ali.clone(), bob.clone()); assert!(transfer_res.is_ok()); @@ -474,25 +481,20 @@ fn test_transfer_many_tokens() { let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); assert_eq!(contract.total_supply(), U256::from(0)); - contract.mint_many( - ali.clone(), - vec![URI::from("Apple URI"), URI::from("Banana URI")], - ); - contract.mint_copies(ali.clone(), URI::from("Casper Fan URI"), U256::from(3)); + contract.mint_many(ali.clone(), vec![meta::apple(), meta::banana()]); + contract.mint_copies(ali.clone(), meta::apple(), U256::from(3)); assert_eq!(contract.total_supply(), U256::from(5)); - let mut ali_balance = contract.balance_of(ali.clone()); - let mut bob_balance = contract.balance_of(bob.clone()); - assert_eq!(ali_balance, U256::from(5)); - assert_eq!(bob_balance, U256::from(0)); + assert_eq!(contract.balance_of(ali.clone()), U256::from(5)); + assert_eq!(contract.balance_of(bob.clone()), U256::from(0)); let ali_tokens: Vec = contract.tokens(ali.clone()); let ali_second_token_id: TokenId = ali_tokens.get(1).unwrap().clone(); - let ali_second_token_uri: URI = contract.token_uri(ali_second_token_id.clone()).unwrap(); + let ali_second_token_meta: Meta = contract.token_meta(ali_second_token_id.clone()).unwrap(); let ali_third_token_id: TokenId = ali_tokens.get(2).unwrap().clone(); - let ali_third_token_uri: URI = contract.token_uri(ali_third_token_id.clone()).unwrap(); - assert_eq!(ali_second_token_uri, URI::from("Banana URI")); - assert_eq!(ali_third_token_uri, URI::from("Casper Fan URI")); + let ali_third_token_meta: Meta = contract.token_meta(ali_third_token_id.clone()).unwrap(); + assert_eq!(ali_second_token_meta, meta::banana()); + assert_eq!(ali_third_token_meta, meta::apple()); let transfer_res = contract.transfer_many_tokens( ali.clone(), @@ -500,11 +502,8 @@ fn test_transfer_many_tokens() { vec![ali_second_token_id.clone(), ali_third_token_id.clone()], ); assert!(transfer_res.is_ok()); - - ali_balance = contract.balance_of(ali); - bob_balance = contract.balance_of(bob.clone()); - assert_eq!(ali_balance, U256::from(3)); - assert_eq!(bob_balance, U256::from(2)); + assert_eq!(contract.balance_of(ali), U256::from(3)); + assert_eq!(contract.balance_of(bob.clone()), U256::from(2)); let owner_of_second_token_id = contract.owner_of(ali_second_token_id); let owner_of_third_token_id = contract.owner_of(ali_third_token_id); @@ -518,7 +517,7 @@ fn test_attach_and_detach() { let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); - contract.mint_one(ali.clone(), URI::from("0x12af")); + contract.mint_one(ali.clone(), meta::banana()); let token_id: TokenId = contract.tokens(ali.clone())[0].clone(); let token_uref: URef = contract.detach(ali.clone(), token_id.clone()).unwrap(); @@ -528,8 +527,8 @@ fn test_attach_and_detach() { assert_eq!(contract.token_id(token_uref.clone()), token_id.clone()); assert_eq!( - contract.token_uri(token_id.clone()).unwrap(), - URI::from("0x12af") + contract.token_meta(token_id.clone()).unwrap(), + meta::banana() ); contract.attach(token_uref, bob.clone()); diff --git a/cep47/Cargo.toml b/cep47/Cargo.toml index 7eacf6e..99eddd1 100644 --- a/cep47/Cargo.toml +++ b/cep47/Cargo.toml @@ -16,7 +16,7 @@ name = "cep47" default = ["casper-contract/std", "casper-types/std"] no_name = [] no_symbol = [] -no_uri = [] +no_meta = [] no_balance_of = [] no_owner_of = [] no_total_supply = [] diff --git a/cep47/src/lib.rs b/cep47/src/lib.rs index 19b9c40..f750f4d 100644 --- a/cep47/src/lib.rs +++ b/cep47/src/lib.rs @@ -20,7 +20,9 @@ use casper_types::{ EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Key, Parameter, PublicKey, URef, U256, }; -use cep47_logic::{CEP47Contract, CEP47Storage, TokenId, WithStorage, URI}; +pub use cep47_logic::Meta; +use cep47_logic::{CEP47Contract, CEP47Storage, TokenId, WithStorage}; + use core::convert::TryInto; use std::{ collections::hash_map::DefaultHasher, @@ -41,8 +43,8 @@ impl CEP47Storage for CasperCEP47Storage { fn symbol(&self) -> String { get_key::("symbol").unwrap() } - fn uri(&self) -> URI { - get_key::("uri").unwrap() + fn meta(&self) -> Meta { + get_key::("meta").unwrap() } // Getters @@ -60,8 +62,8 @@ impl CEP47Storage for CasperCEP47Storage { fn total_supply(&self) -> U256 { get_key::("total_supply").unwrap() } - fn token_uri(&self, token_id: TokenId) -> Option { - get_key::(&uri_key(&token_id)) + fn token_meta(&self, token_id: TokenId) -> Option { + get_key::(&meta_key(&token_id)) } fn is_paused(&self) -> bool { get_key::("paused").unwrap() @@ -101,24 +103,24 @@ impl CEP47Storage for CasperCEP47Storage { prev_total_supply - owner_prev_balance + owner_new_balance, ); } - fn mint_many(&mut self, recipient: PublicKey, token_uris: Vec) { + fn mint_many(&mut self, recipient: PublicKey, token_metas: Vec) { let mut recipient_tokens = self.get_tokens(recipient.clone()); let mut recipient_balance = self.balance_of(recipient.clone()); let mut total_supply = self.total_supply(); - let uri = self.uri(); + let meta = self.meta(); let mut hasher = DefaultHasher::new(); - for token_uri in token_uris.clone() { - let token_info = (uri.clone(), token_uri.clone()); + for token_meta in token_metas.clone() { + let token_info = (meta.clone(), token_meta.clone()); Hash::hash(&token_info, &mut hasher); let token_id = TokenId::from(hasher.finish().to_string()); recipient_tokens.push(token_id.clone()); total_supply = total_supply + 1; - set_key(&uri_key(&token_id), token_uri); + set_key(&meta_key(&token_id), token_meta); set_key(&owner_key(&token_id), recipient.clone()); } - recipient_balance = recipient_balance + U256::from(token_uris.len() as u64); + recipient_balance = recipient_balance + U256::from(token_metas.len() as u64); set_key( &balance_key(&recipient.to_account_hash()), recipient_balance, @@ -126,9 +128,9 @@ impl CEP47Storage for CasperCEP47Storage { set_key(&token_key(&recipient.to_account_hash()), recipient_tokens); set_key("total_supply", total_supply); } - fn mint_copies(&mut self, recipient: PublicKey, token_uri: URI, count: U256) { - let token_uris: Vec = vec![token_uri; count.as_usize()]; - self.mint_many(recipient, token_uris); + fn mint_copies(&mut self, recipient: PublicKey, token_meta: Meta, count: U256) { + let token_metas: Vec = vec![token_meta; count.as_usize()]; + self.mint_many(recipient, token_metas); } fn burn_many(&mut self, owner: PublicKey, token_ids: Vec) { let mut owner_tokens = self.get_tokens(owner.clone()); @@ -141,7 +143,7 @@ impl CEP47Storage for CasperCEP47Storage { .position(|x| *x == token_id.clone()) .unwrap_or_revert(); owner_tokens.remove(index); - remove_key(&uri_key(&token_id)); + remove_key(&meta_key(&token_id)); remove_key(&owner_key(&token_id)); owner_balance = owner_balance - 1; total_supply = total_supply - 1; @@ -159,7 +161,7 @@ impl CEP47Storage for CasperCEP47Storage { .position(|x| *x == token_id.clone()) .unwrap_or_revert(); owner_tokens.remove(index); - remove_key(&uri_key(&token_id)); + remove_key(&meta_key(&token_id)); remove_key(&owner_key(&token_id)); set_key(&balance_key(&owner.to_account_hash()), owner_balance - 1); set_key(&token_key(&owner.to_account_hash()), owner_tokens); @@ -236,11 +238,11 @@ pub extern "C" fn symbol() { ret(contract.symbol()) } -#[cfg(not(feature = "no_uri"))] +#[cfg(not(feature = "no_meta"))] #[no_mangle] -pub extern "C" fn uri() { +pub extern "C" fn meta() { let contract = CasperCEP47Contract::new(); - ret(contract.uri()) + ret(contract.meta()) } #[cfg(not(feature = "no_balance_of"))] @@ -266,12 +268,12 @@ pub extern "C" fn total_supply() { ret(contract.total_supply()) } -#[cfg(not(feature = "no_token_uri"))] +#[cfg(not(feature = "no_token_meta"))] #[no_mangle] -pub extern "C" fn token_uri() { +pub extern "C" fn token_meta() { let token_id: TokenId = runtime::get_named_arg("token_id"); let contract = CasperCEP47Contract::new(); - ret(contract.token_uri(token_id)) + ret(contract.token_meta(token_id)) } #[cfg(not(feature = "no_tokens"))] @@ -307,28 +309,28 @@ pub extern "C" fn unpause() { #[no_mangle] pub extern "C" fn mint_one() { let recipient: PublicKey = runtime::get_named_arg("recipient"); - let token_uri: URI = runtime::get_named_arg("token_uri"); + let token_meta: Meta = runtime::get_named_arg("token_meta"); let mut contract = CasperCEP47Contract::new(); - contract.mint_one(recipient, token_uri); + contract.mint_one(recipient, token_meta); } #[cfg(not(feature = "no_mint_many"))] #[no_mangle] pub extern "C" fn mint_many() { let recipient: PublicKey = runtime::get_named_arg("recipient"); - let token_uris: Vec = runtime::get_named_arg("token_uris"); + let token_metas: Vec = runtime::get_named_arg("token_metas"); let mut contract = CasperCEP47Contract::new(); - contract.mint_many(recipient, token_uris); + contract.mint_many(recipient, token_metas); } #[cfg(not(feature = "no_mint_copies"))] #[no_mangle] pub extern "C" fn mint_copies() { let recipient: PublicKey = runtime::get_named_arg("recipient"); - let token_uri: URI = runtime::get_named_arg("token_uri"); + let token_meta: Meta = runtime::get_named_arg("token_meta"); let count: U256 = runtime::get_named_arg("count"); let mut contract = CasperCEP47Contract::new(); - contract.mint_copies(recipient, token_uri, count); + contract.mint_copies(recipient, token_meta, count); } #[cfg(not(feature = "no_burn_many"))] @@ -430,7 +432,7 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints let mut entry_points = EntryPoints::new(); entry_points.add_entry_point(endpoint("name", vec![], CLType::String, None)); entry_points.add_entry_point(endpoint("symbol", vec![], CLType::String, None)); - entry_points.add_entry_point(endpoint("uri", vec![], CLType::String, None)); + entry_points.add_entry_point(endpoint("meta", vec![], CLType::String, None)); entry_points.add_entry_point(endpoint("total_supply", vec![], CLType::U256, None)); entry_points.add_entry_point(endpoint("is_paused", vec![], CLType::Bool, None)); entry_points.add_entry_point(endpoint( @@ -466,7 +468,7 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints None, )); entry_points.add_entry_point(endpoint( - "token_uri", + "token_meta", vec![Parameter::new("token_id", CLType::String)], CLType::Option(Box::new(CLType::String)), None, @@ -487,7 +489,7 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints "mint_one", vec![ Parameter::new("recipient", CLType::PublicKey), - Parameter::new("token_uri", CLType::String), + Parameter::new("token_meta", CLType::String), ], CLType::Unit, if secure { @@ -500,7 +502,7 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints "mint_many", vec![ Parameter::new("recipient", CLType::PublicKey), - Parameter::new("token_uris", CLType::List(Box::new(CLType::String))), + Parameter::new("token_metas", CLType::List(Box::new(CLType::String))), ], CLType::Unit, if secure { @@ -539,7 +541,7 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints "mint_copies", vec![ Parameter::new("recipient", CLType::PublicKey), - Parameter::new("token_uri", CLType::String), + Parameter::new("token_meta", CLType::String), Parameter::new("count", CLType::U256), ], CLType::Unit, @@ -600,17 +602,20 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints } pub fn deploy( - token_name: &str, - token_symbol: &str, - token_uri: &str, + token_name: String, + token_symbol: String, + token_meta: Meta, entry_points: EntryPoints, contract_package_hash: ContractPackageHash, paused: bool, ) { let mut named_keys = NamedKeys::new(); - named_keys.insert("name".to_string(), storage::new_uref(token_name).into()); + named_keys.insert( + "name".to_string(), + storage::new_uref(token_name.clone()).into(), + ); named_keys.insert("symbol".to_string(), storage::new_uref(token_symbol).into()); - named_keys.insert("uri".to_string(), storage::new_uref(token_uri).into()); + named_keys.insert("meta".to_string(), storage::new_uref(token_meta).into()); named_keys.insert( "total_supply".to_string(), storage::new_uref(U256::zero()).into(), @@ -620,7 +625,7 @@ pub fn deploy( let (contract_hash, _) = storage::add_contract_version(contract_package_hash, entry_points, named_keys); runtime::put_key( - format!("{}_contract", token_name).as_str(), + format!("{}_contract", &token_name).as_str(), contract_hash.into(), ); let contract_hash_pack = storage::new_uref(contract_hash); @@ -671,8 +676,8 @@ fn owner_key(token_id: &TokenId) -> String { format!("owners_{}", token_id) } -fn uri_key(token_id: &TokenId) -> String { - format!("uris_{}", token_id) +fn meta_key(token_id: &TokenId) -> String { + format!("metas_{}", token_id) } fn uref_key(uref: &URef) -> String { diff --git a/dragons-nft-tests/Cargo.toml b/dragons-nft-tests/Cargo.toml index b3ee76a..d331919 100644 --- a/dragons-nft-tests/Cargo.toml +++ b/dragons-nft-tests/Cargo.toml @@ -10,6 +10,7 @@ edition = "2018" casper-contract = "1.2.0" casper-types = "1.2.0" casper-engine-test-support = "1.2.0" +maplit = "1.0.2" [features] default = ["casper-contract/std", "casper-types/std", "casper-contract/test-support"] diff --git a/dragons-nft-tests/src/cep47.rs b/dragons-nft-tests/src/cep47.rs index b0990ab..042b0b3 100644 --- a/dragons-nft-tests/src/cep47.rs +++ b/dragons-nft-tests/src/cep47.rs @@ -1,3 +1,5 @@ +use std::collections::BTreeMap; + use casper_engine_test_support::{Code, Hash, SessionBuilder, TestContext, TestContextBuilder}; use casper_types::{ account::AccountHash, bytesrepr::FromBytes, runtime_args, CLTyped, PublicKey, RuntimeArgs, @@ -5,13 +7,21 @@ use casper_types::{ }; pub mod token_cfg { - pub const NAME: &str = "CasperNFT"; - pub const SYMBOL: &str = "CNFT"; - pub const URI: &str = "https://casper.network/network"; + use super::Meta; + use maplit::btreemap; + + pub const NAME: &str = "DragonsNFT"; + pub const SYMBOL: &str = "DRAG"; + + pub fn contract_meta() -> Meta { + btreemap! { + "origin".to_string() => "fire".to_string() + } + } } -pub const CONTRACT_KEY: &str = "CasperNFT_contract"; -pub const CONTRACT_HASH_KEY: &str = "CasperNFT_contract_hash"; +pub const CONTRACT_KEY: &str = "DragonsNFT_contract"; +pub const CONTRACT_HASH_KEY: &str = "DragonsNFT_contract_hash"; pub struct Sender(pub AccountHash); pub struct CasperCEP47Contract { @@ -23,7 +33,7 @@ pub struct CasperCEP47Contract { } pub type TokenId = String; -pub type URI = String; +pub type Meta = BTreeMap; impl CasperCEP47Contract { pub fn deploy() -> Self { @@ -39,7 +49,7 @@ impl CasperCEP47Contract { let session_args = runtime_args! { "token_name" => token_cfg::NAME, "token_symbol" => token_cfg::SYMBOL, - "token_uri" => token_cfg::URI + "token_meta" => token_cfg::contract_meta() }; let session = SessionBuilder::new(session_code, session_args) .with_address(admin.to_account_hash()) @@ -94,8 +104,8 @@ impl CasperCEP47Contract { self.query_contract("symbol").unwrap() } - pub fn uri(&self) -> URI { - self.query_contract("uri").unwrap() + pub fn meta(&self) -> Meta { + self.query_contract("meta").unwrap() } pub fn total_supply(&self) -> U256 { @@ -116,21 +126,21 @@ impl CasperCEP47Contract { .unwrap_or_default() } - pub fn token_uri(&self, token_id: TokenId) -> Option { - self.query_contract(uri_key(&token_id).as_str()) + pub fn token_meta(&self, token_id: TokenId) -> Option { + self.query_contract(meta_key(&token_id).as_str()) } pub fn token_uref(&self, token_id: &TokenId) -> Option { self.query_contract(test_uref_key(&token_id).as_str()) } - pub fn mint_one(&mut self, recipient: PublicKey, token_uri: URI, sender: Sender) { + pub fn mint_one(&mut self, recipient: PublicKey, token_meta: Meta, sender: Sender) { self.call( sender, "mint_one", runtime_args! { "recipient" => recipient, - "token_uri" => token_uri + "token_meta" => token_meta }, ); } @@ -138,7 +148,7 @@ impl CasperCEP47Contract { pub fn mint_copies( &mut self, recipient: PublicKey, - token_uri: URI, + token_meta: Meta, count: U256, sender: Sender, ) { @@ -147,19 +157,19 @@ impl CasperCEP47Contract { "mint_copies", runtime_args! { "recipient" => recipient, - "token_uri" => token_uri, + "token_meta" => token_meta, "count" => count }, ); } - pub fn mint_many(&mut self, recipient: PublicKey, token_uris: Vec, sender: Sender) { + pub fn mint_many(&mut self, recipient: PublicKey, token_metas: Vec, sender: Sender) { self.call( sender, "mint_many", runtime_args! { "recipient" => recipient, - "token_uris" => token_uris + "token_metas" => token_metas }, ); } @@ -242,8 +252,8 @@ fn owner_key(token_id: &TokenId) -> String { format!("owners_{}", token_id) } -fn uri_key(token_id: &TokenId) -> String { - format!("uris_{}", token_id) +fn meta_key(token_id: &TokenId) -> String { + format!("metas_{}", token_id) } fn token_key(account: &AccountHash) -> String { diff --git a/dragons-nft-tests/src/contract_tests.rs b/dragons-nft-tests/src/contract_tests.rs index e9cf007..a904585 100644 --- a/dragons-nft-tests/src/contract_tests.rs +++ b/dragons-nft-tests/src/contract_tests.rs @@ -1,39 +1,68 @@ -use crate::cep47::{token_cfg, CasperCEP47Contract, Sender, TokenId, URI}; +use crate::cep47::{token_cfg, CasperCEP47Contract, Meta, Sender, TokenId}; use casper_types::U256; +mod meta { + use super::Meta; + use maplit::btreemap; + + pub fn red_dragon() -> Meta { + btreemap! { + "color".to_string() => "red".to_string() + } + } + + pub fn blue_dragon() -> Meta { + btreemap! { + "color".to_string() => "blue".to_string() + } + } + + pub fn black_dragon() -> Meta { + btreemap! { + "color".to_string() => "black".to_string() + } + } + + pub fn gold_dragon() -> Meta { + btreemap! { + "color".to_string() => "gold".to_string() + } + } +} + #[test] fn test_deploy() { let contract = CasperCEP47Contract::deploy(); assert_eq!(contract.name(), token_cfg::NAME); assert_eq!(contract.symbol(), token_cfg::SYMBOL); - assert_eq!(contract.uri(), token_cfg::URI); + assert_eq!(contract.meta(), token_cfg::contract_meta()); assert_eq!(contract.total_supply(), U256::zero()); } #[test] -fn test_token_uri() { +fn test_token_meta() { let mut contract = CasperCEP47Contract::deploy(); - let token_uri = URI::from("MonaLisa"); + let token_meta = meta::red_dragon(); contract.mint_one( contract.ali.clone(), - token_uri.clone(), + token_meta.clone(), Sender(contract.admin.clone().to_account_hash()), ); let ali_tokens: Vec = contract.tokens(contract.ali.clone()); - let ali_token_uri = contract.token_uri(ali_tokens[0].clone()); + let ali_token_meta = contract.token_meta(ali_tokens[0].clone()); - assert_eq!(ali_token_uri, Some(token_uri)); + assert_eq!(ali_token_meta, Some(token_meta)); } #[test] fn test_mint_one() { let mut contract = CasperCEP47Contract::deploy(); - let token_uri = URI::from("MonaLisa"); + let token_meta = meta::red_dragon(); contract.mint_one( contract.ali.clone(), - token_uri, + token_meta, Sender(contract.admin.clone().to_account_hash()), ); @@ -48,10 +77,10 @@ fn test_mint_one() { #[test] fn test_mint_copies() { let mut contract = CasperCEP47Contract::deploy(); - let token_uri = URI::from("Casper Golden Card"); + let token_meta = meta::gold_dragon(); contract.mint_copies( contract.ali.clone(), - token_uri, + token_meta, U256::from(3), Sender(contract.admin.clone().to_account_hash()), ); @@ -75,10 +104,10 @@ fn test_mint_copies() { #[test] fn test_mint_many() { let mut contract = CasperCEP47Contract::deploy(); - let token_uris: Vec = vec![URI::from("Casper Golden Card"), URI::from("Mona Lisa")]; + let token_metas: Vec = vec![meta::gold_dragon(), meta::red_dragon()]; contract.mint_many( contract.ali.clone(), - token_uris, + token_metas, Sender(contract.admin.clone().to_account_hash()), ); @@ -97,15 +126,15 @@ fn test_mint_many() { #[test] fn test_burn_many() { let mut contract = CasperCEP47Contract::deploy(); - let token_uris: Vec = vec![ - URI::from("Casper Golden Card"), - URI::from("Casper Siver Card"), - URI::from("Casper Bronze Card"), - URI::from("Mona Lisa"), + let token_metas: Vec = vec![ + meta::gold_dragon(), + meta::blue_dragon(), + meta::black_dragon(), + meta::red_dragon(), ]; contract.mint_many( contract.ali.clone(), - token_uris, + token_metas, Sender(contract.admin.clone().to_account_hash()), ); @@ -133,10 +162,10 @@ fn test_burn_many() { #[test] fn test_burn_one() { let mut contract = CasperCEP47Contract::deploy(); - let token_uris: Vec = vec![URI::from("Casper Golden Card"), URI::from("Mona Lisa")]; + let token_metas: Vec = vec![meta::gold_dragon(), meta::red_dragon()]; contract.mint_many( contract.ali.clone(), - token_uris, + token_metas, Sender(contract.admin.clone().to_account_hash()), ); @@ -161,13 +190,10 @@ fn test_burn_one() { #[test] fn test_transfer_token() { let mut contract = CasperCEP47Contract::deploy(); - let token_uris: Vec = vec![ - URI::from("Casper Golden Card"), - URI::from("Casper Silver Card"), - ]; + let token_metas: Vec = vec![meta::gold_dragon(), meta::blue_dragon()]; contract.mint_many( contract.ali.clone(), - token_uris, + token_metas, Sender(contract.admin.clone().to_account_hash()), ); let ali_tokens: Vec = contract.tokens(contract.ali.clone()); @@ -194,14 +220,14 @@ fn test_transfer_token() { #[test] fn test_transfer_many_tokens() { let mut contract = CasperCEP47Contract::deploy(); - let token_uris: Vec = vec![ - URI::from("Casper Golden Card"), - URI::from("Casper Silver Card"), - URI::from("Casper Bronze Card"), + let token_metas: Vec = vec![ + meta::gold_dragon(), + meta::black_dragon(), + meta::black_dragon(), ]; contract.mint_many( contract.ali.clone(), - token_uris, + token_metas, Sender(contract.admin.clone().to_account_hash()), ); let ali_tokens: Vec = contract.tokens(contract.ali.clone()); @@ -232,13 +258,10 @@ fn test_transfer_many_tokens() { #[test] fn test_transfer_all_tokens() { let mut contract = CasperCEP47Contract::deploy(); - let token_uris: Vec = vec![ - URI::from("Casper Golden Card"), - URI::from("Casper Silver Card"), - ]; + let token_metas: Vec = vec![meta::gold_dragon(), meta::blue_dragon()]; contract.mint_many( contract.ali.clone(), - token_uris, + token_metas, Sender(contract.admin.clone().to_account_hash()), ); let ali_tokens: Vec = contract.tokens(contract.ali.clone()); diff --git a/dragons-nft-tests/src/lib.rs b/dragons-nft-tests/src/lib.rs index 6bfe26c..f86f3b0 100644 --- a/dragons-nft-tests/src/lib.rs +++ b/dragons-nft-tests/src/lib.rs @@ -1,5 +1,5 @@ +#[cfg(test)] pub mod cep47; -pub mod market; #[cfg(test)] pub mod contract_tests; diff --git a/dragons-nft-tests/src/market.rs b/dragons-nft-tests/src/market.rs deleted file mode 100644 index fb8d420..0000000 --- a/dragons-nft-tests/src/market.rs +++ /dev/null @@ -1,52 +0,0 @@ -use casper_engine_test_support::{Code, Hash, SessionBuilder, TestContext}; -use casper_types::{account::AccountHash, runtime_args, PublicKey, RuntimeArgs}; - -pub struct MarketTest { - pub market_hash: Hash, -} - -impl MarketTest { - pub fn deploy(context: &mut TestContext, deployer: AccountHash) -> Self { - let session_code = Code::from("marketplace.wasm"); - let session_args = runtime_args! {}; - let session = SessionBuilder::new(session_code, session_args) - .with_address(deployer) - .with_authorization_keys(&[deployer]) - .build(); - context.run(session); - let market_hash = context - .query(deployer, &["marketplace_contract_package_hash".to_string()]) - .unwrap() - .into_t() - .unwrap(); - Self { market_hash } - } - - // fn call( - // &self, - // context: &mut TestContext, - // account: &AccountHash, - // method: &str, - // args: RuntimeArgs, - // ) { - // let code = Code::Hash(self.market_hash, method.to_string()); - // let session = SessionBuilder::new(code, args) - // .with_address(*account) - // .with_authorization_keys(&[*account]) - // .build(); - // context.run(session); - // } - - pub fn call_test(&self, context: &mut TestContext, account: &PublicKey, seller: &PublicKey) { - let session_code = Code::from("send_tokens.wasm"); - let session_args = runtime_args! { - "marketplace_contract" => self.market_hash, - "seller" => seller.clone(), - }; - let session = SessionBuilder::new(session_code, session_args) - .with_address(account.to_account_hash()) - .with_authorization_keys(&[account.to_account_hash()]) - .build(); - context.run(session); - } -} diff --git a/dragons-nft/src/main.rs b/dragons-nft/src/main.rs index 8628114..5c48dc8 100644 --- a/dragons-nft/src/main.rs +++ b/dragons-nft/src/main.rs @@ -11,9 +11,9 @@ pub extern "C" fn call() { let (contract_package_hash, _) = create_contract_package_at_hash(); let entry_points = cep47::get_entrypoints(None); cep47::deploy( - &get_named_arg::("token_name"), - &get_named_arg::("token_symbol"), - &get_named_arg::("token_uri"), + get_named_arg::("token_name"), + get_named_arg::("token_symbol"), + get_named_arg::("token_meta"), entry_points, contract_package_hash, false, From 80cf6a2eb66a245bdcb97db507b23c692a654b00 Mon Sep 17 00:00:00 2001 From: astro019 Date: Fri, 9 Jul 2021 02:05:14 +1000 Subject: [PATCH 40/98] wip add cep47-test --- Cargo.toml | 3 +- Makefile | 1 + cep47-test/Cargo.toml | 16 ++ cep47-test/src/cep47.rs | 256 ++++++++++++++++++++ cep47-test/src/contract_tests.rs | 389 +++++++++++++++++++++++++++++++ cep47-test/src/lib.rs | 5 + cep47-test/wasm/dragons-nft.wasm | Bin 0 -> 492201 bytes dragons-nft-tests/Cargo.toml | 1 + 8 files changed, 670 insertions(+), 1 deletion(-) create mode 100644 cep47-test/Cargo.toml create mode 100644 cep47-test/src/cep47.rs create mode 100644 cep47-test/src/contract_tests.rs create mode 100644 cep47-test/src/lib.rs create mode 100755 cep47-test/wasm/dragons-nft.wasm diff --git a/Cargo.toml b/Cargo.toml index 284c799..2e926cf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,9 @@ [workspace] members = [ - "cep47-logic", "cep47", + "cep47-logic", + "cep47-test", "dragons-nft", "dragons-nft-tests" ] diff --git a/Makefile b/Makefile index b008ec7..3478233 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,7 @@ build-contract: cargo build --release -p dragons-nft --target wasm32-unknown-unknown test-only: + cargo test -p cep47-test cargo test -p cep47-logic cargo test -p dragons-nft-tests diff --git a/cep47-test/Cargo.toml b/cep47-test/Cargo.toml new file mode 100644 index 0000000..0d2c06e --- /dev/null +++ b/cep47-test/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "cep47-test" +version = "0.1.0" +authors = ["astro019 "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +casper-contract = "1.2.0" +casper-types = "1.2.0" +casper-engine-test-support = "1.2.0" +maplit = "1.0.2" + +[features] +default = ["casper-contract/std", "casper-types/std", "casper-contract/test-support"] diff --git a/cep47-test/src/cep47.rs b/cep47-test/src/cep47.rs new file mode 100644 index 0000000..bb9d749 --- /dev/null +++ b/cep47-test/src/cep47.rs @@ -0,0 +1,256 @@ +use std::collections::BTreeMap; + +use casper_engine_test_support::{Code, Hash, SessionBuilder, TestContext, TestContextBuilder}; +use casper_types::{ + account::AccountHash, bytesrepr::FromBytes, runtime_args, CLTyped, PublicKey, RuntimeArgs, + SecretKey, URef, U256, U512, +}; + +pub type TokenId = String; +pub type Meta = BTreeMap; + +pub const CONTRACT_KEY_SUFFIX: &str = "_contract"; +pub const CONTRACT_HASH_KEY_SUFFIX: &str = "_contract_hash"; +pub const CONTRACT_NAME_KEY: &str = "name"; +pub const CONTRACT_SYMBOL_KEY: &str = "symbol"; +pub const CONTRACT_META_KEY: &str = "meta"; +pub const CONTRACT_TOTAL_SUPPLY_KEY: &str = "total_supply"; + +pub struct Sender(pub AccountHash); + +pub struct TestConfig { + pub context: TestContext, + pub contract_hash: Hash, + pub contract_key: String, + pub accounts: Vec, +} + +pub trait CEP47TestContract { + fn config(&self) -> &TestConfig; + fn config_mut(&mut self) -> &mut TestConfig; + + fn deploy(token_name: &str, token_symbol: &str, token_meta: Meta, wasm: &str) -> TestConfig { + let admin: PublicKey = SecretKey::ed25519_from_bytes([1u8; 32]).unwrap().into(); + let ali: PublicKey = SecretKey::ed25519_from_bytes([3u8; 32]).unwrap().into(); + let bob: PublicKey = SecretKey::ed25519_from_bytes([5u8; 32]).unwrap().into(); + let mut context = TestContextBuilder::new() + .with_public_key(admin.clone(), U512::from(500_000_000_000_000_000u64)) + .with_public_key(ali.clone(), U512::from(500_000_000_000_000_000u64)) + .with_public_key(bob.clone(), U512::from(500_000_000_000_000_000u64)) + .build(); + let session_code = Code::from(wasm); + let session_args = runtime_args! { + "token_name" => token_name, + "token_symbol" => token_symbol, + "token_meta" => token_meta + }; + let session = SessionBuilder::new(session_code, session_args) + .with_address(admin.to_account_hash()) + .with_authorization_keys(&[admin.to_account_hash()]) + .build(); + context.run(session); + let contract_hash = context + .query( + admin.to_account_hash(), + &[format!("{}{}", token_name, CONTRACT_HASH_KEY_SUFFIX)], + ) + .unwrap() + .into_t() + .unwrap(); + let contract_key = format!("{}{}", token_name, CONTRACT_KEY_SUFFIX); + + TestConfig { + context, + contract_hash, + contract_key, + accounts: vec![admin, ali, bob], + } + } + + fn call(&mut self, sender: Sender, method: &str, args: RuntimeArgs) { + let Sender(address) = sender; + let code = Code::Hash(self.config().contract_hash, method.to_string()); + let session = SessionBuilder::new(code, args) + .with_address(address) + .with_authorization_keys(&[address]) + .build(); + self.config_mut().context.run(session); + } + + fn query_contract(&self, name: &str) -> Option { + match self.config().context.query( + self.config().accounts.first().unwrap().to_account_hash(), + &[self.config().contract_key.clone(), name.to_string()], + ) { + Err(_) => None, + Ok(maybe_value) => { + let value = maybe_value + .into_t() + .unwrap_or_else(|_| panic!("{} is not expected type.", name)); + Some(value) + } + } + } + + fn name(&self) -> String { + self.query_contract(CONTRACT_NAME_KEY).unwrap() + } + + fn symbol(&self) -> String { + self.query_contract(CONTRACT_SYMBOL_KEY).unwrap() + } + + fn meta(&self) -> Meta { + self.query_contract(CONTRACT_META_KEY).unwrap() + } + + fn total_supply(&self) -> U256 { + self.query_contract(CONTRACT_TOTAL_SUPPLY_KEY) + .unwrap_or_default() + } + + fn owner_of(&self, token_id: &TokenId) -> Option { + self.query_contract(owner_key(&token_id).as_str()) + } + + fn balance_of(&self, owner: PublicKey) -> U256 { + self.query_contract(balance_key(&owner.to_account_hash()).as_str()) + .unwrap_or_default() + } + + fn tokens(&self, owner: PublicKey) -> Vec { + self.query_contract::>(token_key(&owner.to_account_hash()).as_str()) + .unwrap_or_default() + } + + fn token_meta(&self, token_id: TokenId) -> Option { + self.query_contract(meta_key(&token_id).as_str()) + } + + fn token_uref(&self, token_id: &TokenId) -> Option { + self.query_contract(test_uref_key(&token_id).as_str()) + } + + fn mint_one(&mut self, recipient: PublicKey, token_meta: Meta, sender: Sender) { + self.call( + sender, + "mint_one", + runtime_args! { + "recipient" => recipient, + "token_meta" => token_meta + }, + ); + } + + fn mint_copies(&mut self, recipient: PublicKey, token_meta: Meta, count: U256, sender: Sender) { + self.call( + sender, + "mint_copies", + runtime_args! { + "recipient" => recipient, + "token_meta" => token_meta, + "count" => count + }, + ); + } + + fn mint_many(&mut self, recipient: PublicKey, token_metas: Vec, sender: Sender) { + self.call( + sender, + "mint_many", + runtime_args! { + "recipient" => recipient, + "token_metas" => token_metas + }, + ); + } + + fn burn_many(&mut self, owner: PublicKey, token_ids: Vec, sender: Sender) { + self.call( + sender, + "burn_many", + runtime_args! { + "owner" => owner, + "token_ids" => token_ids + }, + ); + } + + fn burn_one(&mut self, owner: PublicKey, token_id: TokenId, sender: Sender) { + self.call( + sender, + "burn_one", + runtime_args! { + "owner" => owner, + "token_id" => token_id + }, + ); + } + + fn transfer_token( + &mut self, + owner: PublicKey, + recipient: PublicKey, + token_id: TokenId, + sender: Sender, + ) { + self.call( + sender, + "transfer_token", + runtime_args! { + "sender" => owner, + "recipient" => recipient, + "token_id" => token_id + }, + ); + } + + fn transfer_many_tokens( + &mut self, + owner: PublicKey, + recipient: PublicKey, + token_ids: Vec, + sender: Sender, + ) { + self.call( + sender, + "transfer_many_tokens", + runtime_args! { + "sender" => owner, + "recipient" => recipient, + "token_ids" => token_ids + }, + ); + } + + fn transfer_all_tokens(&mut self, owner: PublicKey, recipient: PublicKey, sender: Sender) { + self.call( + sender, + "transfer_all_tokens", + runtime_args! { + "sender" => owner, + "recipient" => recipient + }, + ); + } +} + +fn balance_key(account: &AccountHash) -> String { + format!("balances_{}", account) +} + +fn owner_key(token_id: &TokenId) -> String { + format!("owners_{}", token_id) +} + +fn meta_key(token_id: &TokenId) -> String { + format!("metas_{}", token_id) +} + +fn token_key(account: &AccountHash) -> String { + format!("tokens_{}", account) +} + +fn test_uref_key(token_id: &TokenId) -> String { + format!("turef_{}", token_id) +} diff --git a/cep47-test/src/contract_tests.rs b/cep47-test/src/contract_tests.rs new file mode 100644 index 0000000..ba15923 --- /dev/null +++ b/cep47-test/src/contract_tests.rs @@ -0,0 +1,389 @@ +use crate::cep47::{CEP47TestContract, Meta, Sender, TestConfig, TokenId}; +use casper_types::U256; +use maplit::btreemap; + +pub struct CasperCEP47Contract { + config: TestConfig, +} + +impl CEP47TestContract for CasperCEP47Contract { + fn config(&self) -> &TestConfig { + &self.config + } + + fn config_mut(&mut self) -> &mut TestConfig { + &mut self.config + } +} + +impl CasperCEP47Contract { + fn new() -> Self { + let config = Self::deploy( + "CasperNFT", + "CNFT", + btreemap! {"origin".to_string() => "fire".to_string()}, + "dragons-nft.wasm", + ); + Self { config } + } +} + +mod meta { + use super::Meta; + use maplit::btreemap; + + pub fn red_dragon() -> Meta { + btreemap! { + "color".to_string() => "red".to_string() + } + } + + pub fn blue_dragon() -> Meta { + btreemap! { + "color".to_string() => "blue".to_string() + } + } + + pub fn black_dragon() -> Meta { + btreemap! { + "color".to_string() => "black".to_string() + } + } + + pub fn gold_dragon() -> Meta { + btreemap! { + "color".to_string() => "gold".to_string() + } + } +} + +#[test] +fn test_deploy() { + let contract = CasperCEP47Contract::new(); + + assert_eq!(contract.name(), "CasperNFT"); + assert_eq!(contract.symbol(), "CNFT"); + assert_eq!( + contract.meta(), + btreemap! {"origin".to_string() => "fire".to_string()} + ); + assert_eq!(contract.total_supply(), U256::zero()); +} + +#[test] +fn test_token_meta() { + let mut contract = CasperCEP47Contract::new(); + let ali = contract.config().accounts.get(1).unwrap().clone(); + let token_meta = meta::red_dragon(); + contract.mint_one( + ali.clone(), + token_meta.clone(), + Sender( + contract + .config() + .accounts + .first() + .unwrap() + .clone() + .to_account_hash(), + ), + ); + + let ali_tokens: Vec = contract.tokens(ali.clone()); + let ali_token_meta = contract.token_meta(ali_tokens[0].clone()); + + assert_eq!(ali_token_meta, Some(token_meta)); +} + +#[test] +fn test_mint_one() { + let mut contract = CasperCEP47Contract::new(); + let ali = contract.config().accounts.get(1).unwrap().clone(); + let token_meta = meta::red_dragon(); + contract.mint_one( + ali.clone(), + token_meta, + Sender( + contract + .config() + .accounts + .first() + .unwrap() + .clone() + .to_account_hash(), + ), + ); + + let ali_tokens: Vec = contract.tokens(ali.clone()); + + assert_eq!(contract.total_supply(), U256::one()); + assert_eq!(contract.balance_of(ali.clone()), U256::one()); + assert_eq!(U256::from(ali_tokens.len() as u64), U256::one()); + assert_eq!(contract.owner_of(&ali_tokens[0]), Some(ali.clone())); +} + +#[test] +fn test_mint_copies() { + let mut contract = CasperCEP47Contract::new(); + let ali = contract.config().accounts.get(1).unwrap().clone(); + let token_meta = meta::gold_dragon(); + contract.mint_copies( + ali.clone(), + token_meta, + U256::from(3), + Sender( + contract + .config() + .accounts + .first() + .unwrap() + .clone() + .to_account_hash(), + ), + ); + + let ali_tokens: Vec = contract.tokens(ali.clone()); + + assert_eq!(contract.total_supply(), U256::from(3)); + assert_eq!(contract.balance_of(ali.clone()), U256::from(3)); + assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(3)); + assert_eq!(contract.owner_of(&ali_tokens[0]), Some(ali.clone())); + assert_eq!(contract.owner_of(&ali_tokens[1]), Some(ali.clone())); + assert_eq!(contract.owner_of(&ali_tokens[2]), Some(ali.clone())); +} + +#[test] +fn test_mint_many() { + let mut contract = CasperCEP47Contract::new(); + let ali = contract.config().accounts.get(1).unwrap().clone(); + let token_metas: Vec = vec![meta::gold_dragon(), meta::red_dragon()]; + contract.mint_many( + ali.clone(), + token_metas, + Sender( + contract + .config() + .accounts + .first() + .unwrap() + .clone() + .to_account_hash(), + ), + ); + + let ali_tokens: Vec = contract.tokens(ali.clone()); + + assert_eq!(contract.total_supply(), U256::from(2)); + assert_eq!(contract.balance_of(ali.clone()), U256::from(2)); + assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(2)); + assert_eq!(contract.owner_of(&ali_tokens[0]), Some(ali.clone())); + assert_eq!(contract.owner_of(&ali_tokens[1]), Some(ali.clone())); +} + +#[test] +fn test_burn_many() { + let mut contract = CasperCEP47Contract::new(); + let ali = contract.config().accounts.get(1).unwrap().clone(); + let token_metas: Vec = vec![ + meta::gold_dragon(), + meta::blue_dragon(), + meta::black_dragon(), + meta::red_dragon(), + ]; + contract.mint_many( + ali.clone(), + token_metas, + Sender( + contract + .config() + .accounts + .first() + .unwrap() + .clone() + .to_account_hash(), + ), + ); + + let mut ali_tokens: Vec = contract.tokens(ali.clone()); + + assert_eq!(contract.total_supply(), U256::from(4)); + assert_eq!(contract.balance_of(ali.clone()), U256::from(4)); + assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(4)); + + contract.burn_many( + ali.clone(), + vec![ + ali_tokens.first().unwrap().clone(), + ali_tokens.last().unwrap().clone(), + ], + Sender( + contract + .config() + .accounts + .first() + .unwrap() + .clone() + .to_account_hash(), + ), + ); + assert_eq!(contract.total_supply(), U256::from(2)); + assert_eq!(contract.balance_of(ali.clone()), U256::from(2)); + + ali_tokens = contract.tokens(ali.clone()); + assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(2)); +} + +#[test] +fn test_burn_one() { + let mut contract = CasperCEP47Contract::new(); + let ali = contract.config().accounts.get(1).unwrap().clone(); + let token_metas: Vec = vec![meta::gold_dragon(), meta::red_dragon()]; + contract.mint_many( + ali.clone(), + token_metas, + Sender( + contract + .config() + .accounts + .first() + .unwrap() + .clone() + .to_account_hash(), + ), + ); + + let mut ali_tokens: Vec = contract.tokens(ali.clone()); + + assert_eq!(contract.total_supply(), U256::from(2)); + assert_eq!(contract.balance_of(ali.clone()), U256::from(2)); + assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(2)); + + contract.burn_one( + ali.clone(), + ali_tokens.first().unwrap().clone(), + Sender( + contract + .config() + .accounts + .first() + .unwrap() + .clone() + .to_account_hash(), + ), + ); + assert_eq!(contract.total_supply(), U256::from(1)); + assert_eq!(contract.balance_of(ali.clone()), U256::from(1)); + + ali_tokens = contract.tokens(ali.clone()); + assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(1)); +} + +#[test] +fn test_transfer_token() { + let mut contract = CasperCEP47Contract::new(); + let ali = contract.config().accounts.get(1).unwrap().clone(); + let bob = contract.config().accounts.get(2).unwrap().clone(); + let token_metas: Vec = vec![meta::gold_dragon(), meta::blue_dragon()]; + contract.mint_many( + ali.clone(), + token_metas, + Sender( + contract + .config() + .accounts + .first() + .unwrap() + .clone() + .to_account_hash(), + ), + ); + let ali_tokens: Vec = contract.tokens(ali.clone()); + contract.transfer_token( + ali.clone(), + bob.clone(), + ali_tokens[1].clone(), + Sender(ali.clone().to_account_hash()), + ); + + assert_eq!(contract.balance_of(ali.clone()), U256::from(1)); + assert_eq!(contract.balance_of(bob.clone()), U256::from(1)); + assert_eq!(contract.total_supply(), U256::from(2)); + assert_eq!(contract.owner_of(&ali_tokens[0]), Some(ali.clone())); + assert_eq!(contract.owner_of(&ali_tokens[1]), Some(bob.clone())); +} + +#[test] +fn test_transfer_many_tokens() { + let mut contract = CasperCEP47Contract::new(); + let ali = contract.config().accounts.get(1).unwrap().clone(); + let bob = contract.config().accounts.get(2).unwrap().clone(); + let token_metas: Vec = vec![ + meta::gold_dragon(), + meta::black_dragon(), + meta::black_dragon(), + ]; + contract.mint_many( + ali.clone(), + token_metas, + Sender( + contract + .config() + .accounts + .first() + .unwrap() + .clone() + .to_account_hash(), + ), + ); + let ali_tokens: Vec = contract.tokens(ali.clone()); + contract.transfer_many_tokens( + ali.clone(), + bob.clone(), + ali_tokens[..2].to_vec(), + Sender(ali.clone().to_account_hash()), + ); + + assert_eq!(contract.balance_of(ali.clone()), U256::from(1)); + assert_eq!(contract.balance_of(bob.clone()), U256::from(2)); + assert_eq!(contract.total_supply(), U256::from(3)); + assert_eq!(contract.owner_of(&ali_tokens[0]), Some(bob.clone())); + assert_eq!(contract.owner_of(&ali_tokens[1]), Some(bob.clone())); + assert_eq!(contract.owner_of(&ali_tokens[2]), Some(ali.clone())); +} + +#[test] +fn test_transfer_all_tokens() { + let mut contract = CasperCEP47Contract::new(); + let ali = contract.config().accounts.get(1).unwrap().clone(); + let bob = contract.config().accounts.get(2).unwrap().clone(); + let token_metas: Vec = vec![meta::gold_dragon(), meta::blue_dragon()]; + contract.mint_many( + ali.clone(), + token_metas, + Sender( + contract + .config() + .accounts + .first() + .unwrap() + .clone() + .to_account_hash(), + ), + ); + let ali_tokens: Vec = contract.tokens(ali.clone()); + assert_eq!(contract.balance_of(ali.clone()), U256::from(2)); + assert_eq!(contract.balance_of(bob.clone()), U256::from(0)); + assert_eq!(contract.owner_of(&ali_tokens[0]), Some(ali.clone())); + assert_eq!(contract.owner_of(&ali_tokens[1]), Some(ali.clone())); + + contract.transfer_all_tokens( + ali.clone(), + bob.clone(), + Sender(ali.clone().to_account_hash()), + ); + assert_eq!(contract.balance_of(ali.clone()), U256::from(0)); + assert_eq!(contract.balance_of(bob.clone()), U256::from(2)); + assert_eq!(contract.total_supply(), U256::from(2)); + assert_eq!(contract.owner_of(&ali_tokens[0]), Some(bob.clone())); + assert_eq!(contract.owner_of(&ali_tokens[1]), Some(bob.clone())); +} diff --git a/cep47-test/src/lib.rs b/cep47-test/src/lib.rs new file mode 100644 index 0000000..f86f3b0 --- /dev/null +++ b/cep47-test/src/lib.rs @@ -0,0 +1,5 @@ +#[cfg(test)] +pub mod cep47; + +#[cfg(test)] +pub mod contract_tests; diff --git a/cep47-test/wasm/dragons-nft.wasm b/cep47-test/wasm/dragons-nft.wasm new file mode 100755 index 0000000000000000000000000000000000000000..d014f8991192441c709ade9bf51c33d704ae5fcc GIT binary patch literal 492201 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

$wm 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 TA;jhhZbM+5?C5ky+sFPFt3KgL diff --git a/cep47/Cargo.toml b/cep47/Cargo.toml index 692596f..dc27420 100644 --- a/cep47/Cargo.toml +++ b/cep47/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "cep47" -version = "0.1.0" +version = "0.2.0" authors = ["astro019 "] edition = "2018" [dependencies] -casper-contract = "1.2.0" -casper-types = "1.2.0" +casper-contract = "1.2.1" +casper-types = "1.2.1" cep47-logic = { path = "../cep47-logic" } [lib] diff --git a/cep47/src/lib.rs b/cep47/src/lib.rs index ddb70d4..a3a3acb 100644 --- a/cep47/src/lib.rs +++ b/cep47/src/lib.rs @@ -412,7 +412,7 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints BTreeSet::default(), ) .unwrap_or_revert(); - runtime::put_key("deployer_access", Key::URef(deployer_group[0])); + runtime::put_key("deployer_group_access", Key::URef(deployer_group[0])); true } else { false @@ -429,7 +429,7 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints vec![], CLType::Unit, if secure { - Some("deployer_access") + Some("deployer") } else { None }, @@ -439,7 +439,7 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints vec![], CLType::Unit, if secure { - Some("deployer_access") + Some("deployer") } else { None }, @@ -478,11 +478,11 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints "mint_one", vec![ Parameter::new("recipient", CLType::PublicKey), - Parameter::new("token_meta", CLType::String), + Parameter::new("token_meta", CLType::String), // TODO: ], CLType::Unit, if secure { - Some("deployer_access") + Some("deployer") } else { None }, @@ -495,7 +495,7 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints ], CLType::Unit, if secure { - Some("deployer_access") + Some("deployer") } else { None }, @@ -509,7 +509,7 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints ], CLType::Unit, if secure { - Some("deployer_access") + Some("deployer") } else { None }, @@ -522,7 +522,7 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints ], CLType::Unit, if secure { - Some("deployer_access") + Some("deployer") } else { None }, @@ -535,7 +535,7 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints ], CLType::Unit, if secure { - Some("deployer_access") + Some("deployer") } else { None }, diff --git a/dragons-nft-scripts/package-lock.json b/dragons-nft-scripts/package-lock.json index 768a988..5ba13d1 100644 --- a/dragons-nft-scripts/package-lock.json +++ b/dragons-nft-scripts/package-lock.json @@ -4,7097 +4,426 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@ethersproject/bignumber": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.4.0.tgz", + "integrity": "sha512-OXUu9f9hO3vGRIPxU40cignXZVaYyfx6j9NNMjebKdnaCL3anCLSSy8/b8d03vY6dh7duCC0kW72GEC4tZer2w==", + "requires": { + "@ethersproject/bytes": "^5.4.0", + "@ethersproject/logger": "^5.4.0", + "bn.js": "^4.11.9" + } + }, + "@ethersproject/bytes": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.4.0.tgz", + "integrity": "sha512-H60ceqgTHbhzOj4uRc/83SCN9d+BSUnOkrr2intevqdtEMO1JFVZ1XL84OEZV+QjV36OaZYxtnt4lGmxcGsPfA==", + "requires": { + "@ethersproject/logger": "^5.4.0" + } + }, + "@ethersproject/constants": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.4.0.tgz", + "integrity": "sha512-tzjn6S7sj9+DIIeKTJLjK9WGN2Tj0P++Z8ONEIlZjyoTkBuODN+0VfhAyYksKi43l1Sx9tX2VlFfzjfmr5Wl3Q==", + "requires": { + "@ethersproject/bignumber": "^5.4.0" + } + }, + "@ethersproject/logger": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.4.0.tgz", + "integrity": "sha512-xYdWGGQ9P2cxBayt64d8LC8aPFJk6yWCawQi/4eJ4+oJdMMjEBMrIcIMZ9AxhwpPVmnBPrsB10PcXGmGAqgUEQ==" + }, + "@open-rpc/client-js": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@open-rpc/client-js/-/client-js-1.7.0.tgz", + "integrity": "sha512-cRGJbXTgdhJNU49vWzJIATRmKBLP2x6tuHJzX9Jg3N8f1VEkge0riUEek2LFIrZiM4TdUp8XV4Ns1W0SZzdfSw==", + "requires": { + "isomorphic-fetch": "^3.0.0", + "isomorphic-ws": "^4.0.1", + "strict-event-emitter-types": "^2.0.0", + "ws": "^7.0.0" + } + }, + "@types/bn.js": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", + "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", + "requires": { + "@types/node": "*" + } + }, + "@types/eccrypto": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@types/eccrypto/-/eccrypto-1.1.3.tgz", + "integrity": "sha512-3O0qER6JMYReqVbcQTGmXeMHdw3O+rVps63tlo5g5zoB3altJS8yzSvboSivwVWeYO9o5jSATu7P0UIqYZPgow==", + "requires": { + "@types/expect": "^1.20.4", + "@types/node": "*" + } + }, + "@types/elliptic": { + "version": "6.4.13", + "resolved": "https://registry.npmjs.org/@types/elliptic/-/elliptic-6.4.13.tgz", + "integrity": "sha512-e8iyLJ8vMLpWxXpVWrIt0ujqsfHWgVe5XAz9IMhBYoDirK6th7J+mHjzp797OLc62ZX419nrlwwzsNAA0a0mKg==", + "requires": { + "@types/bn.js": "*" + } + }, + "@types/eslint": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.28.0.tgz", + "integrity": "sha512-07XlgzX0YJUn4iG1ocY4IX9DzKSmMGUs6ESKlxWhZRaa0fatIWaHWUVapcuGa8r5HFnTqzj+4OCjd5f7EZ/i/A==", + "requires": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "@types/eslint-scope": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.1.tgz", + "integrity": "sha512-SCFeogqiptms4Fg29WpOTk5nHIzfpKCemSN63ksBQYKTcXoJEmJagV+DhVmbapZzY4/5YaOV1nZwrsU79fFm1g==", + "requires": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "@types/estree": { + "version": "0.0.50", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz", + "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==" + }, + "@types/expect": { + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/@types/expect/-/expect-1.20.4.tgz", + "integrity": "sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg==" + }, + "@types/json-schema": { + "version": "7.0.8", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.8.tgz", + "integrity": "sha512-YSBPTLTVm2e2OoQIDYx8HaeWJ5tTToLH67kXR7zYNGupXMEHa2++G8k+DczX2cFVgalypqtyZIcU19AFcmOpmg==" + }, + "@types/node": { + "version": "16.4.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.4.0.tgz", + "integrity": "sha512-HrJuE7Mlqcjj+00JqMWpZ3tY8w7EUd+S0U3L1+PQSWiXZbOgyQDvi+ogoUxaHApPJq5diKxYBQwA3iIlNcPqOg==" + }, + "@types/pbkdf2": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", + "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", + "requires": { + "@types/node": "*" + } + }, + "@types/secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==", + "requires": { + "@types/node": "*" + } + }, + "@webassemblyjs/ast": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", + "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", + "requires": { + "@webassemblyjs/helper-numbers": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", + "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==" + }, + "@webassemblyjs/helper-api-error": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", + "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==" + }, + "@webassemblyjs/helper-buffer": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", + "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==" + }, + "@webassemblyjs/helper-numbers": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", + "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", + "requires": { + "@webassemblyjs/floating-point-hex-parser": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", + "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==" + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", + "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", + "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", + "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", + "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==" + }, + "@webassemblyjs/wasm-edit": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", + "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/helper-wasm-section": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-opt": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "@webassemblyjs/wast-printer": "1.11.1" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", + "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", + "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", + "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", + "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@xtuc/long": "4.2.2" + } + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" + }, + "acorn": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", + "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==" + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==" + }, + "asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "base-x": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz", + "integrity": "sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "optional": true, + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "bip66": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", + "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", + "optional": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "blakejs": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.1.tgz", + "integrity": "sha512-bLG6PHOCZJKNshTjGRBvET0vTciwQE6zFKOKKXPDJfwFBd4Ac0yBfPZqcGvGJap50l7ktvlpFqc2jGVaUgbJgg==" + }, + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserslist": { + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", + "requires": { + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", + "escalade": "^3.1.1", + "node-releases": "^1.1.71" + } + }, + "bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", + "requires": { + "base-x": "^3.0.2" + } + }, + "bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "requires": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" + }, + "caniuse-lite": { + "version": "1.0.30001246", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001246.tgz", + "integrity": "sha512-Tc+ff0Co/nFNbLOrziBXmMVtpt9S2c2Y+Z9Nk9Khj09J+0zR9ejvIW5qkZAErCbOrVODCx/MN+GpB5FNBs5GFA==" + }, "casper-cep47-js-client": { - "version": "file:../../casper-cep47-js-client", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/casper-cep47-js-client/-/casper-cep47-js-client-0.2.0.tgz", + "integrity": "sha512-zc+3LeDsIEzc9wp7f3Tw5+nxNJgz/WwcnZ3nmpM2LM7BCzka9y46M7ZNNVn/IVhlDme5kHhEcDTpgnWkHTdECw==", "requires": { "@ethersproject/bignumber": "^5.0.8", - "casper-js-sdk": "file:../../casper-js-sdk" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", - "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", - "requires": { - "@babel/highlight": "^7.14.5" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", - "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==" - }, - "@babel/highlight": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", - "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", - "requires": { - "@babel/helper-validator-identifier": "^7.14.5", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@ethersproject/bignumber": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.4.0.tgz", - "integrity": "sha512-OXUu9f9hO3vGRIPxU40cignXZVaYyfx6j9NNMjebKdnaCL3anCLSSy8/b8d03vY6dh7duCC0kW72GEC4tZer2w==", - "requires": { - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "bn.js": "^4.11.9" - } - }, - "@ethersproject/bytes": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.4.0.tgz", - "integrity": "sha512-H60ceqgTHbhzOj4uRc/83SCN9d+BSUnOkrr2intevqdtEMO1JFVZ1XL84OEZV+QjV36OaZYxtnt4lGmxcGsPfA==", - "requires": { - "@ethersproject/logger": "^5.4.0" - } - }, - "@ethersproject/logger": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.4.0.tgz", - "integrity": "sha512-xYdWGGQ9P2cxBayt64d8LC8aPFJk6yWCawQi/4eJ4+oJdMMjEBMrIcIMZ9AxhwpPVmnBPrsB10PcXGmGAqgUEQ==" - }, - "@tsconfig/node10": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", - "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==" - }, - "@tsconfig/node12": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", - "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==" - }, - "@tsconfig/node14": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", - "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==" - }, - "@tsconfig/node16": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.1.tgz", - "integrity": "sha512-FTgBI767POY/lKNDNbIzgAX6miIDBs6NTCbdlDb8TrWovHsSvaVIZDlTqym29C6UqhzwcJx4CYr+AlrMywA0cA==" - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" - }, - "casper-js-sdk": { - "version": "file:../../casper-js-sdk", - "requires": { - "@ethersproject/bignumber": "^5.0.8", - "@ethersproject/bytes": "^5.0.5", - "@ethersproject/constants": "^5.0.5", - "@open-rpc/client-js": "^1.6.2", - "@types/eccrypto": "^1.1.2", - "blakejs": "^1.1.0", - "eccrypto": "^1.1.6", - "eslint-plugin-prettier": "^3.4.0", - "ethereum-cryptography": "^0.1.3", - "glob": "^7.1.6", - "humanize-duration": "^3.24.0", - "key-encoder": "^2.0.3", - "reflect-metadata": "^0.1.13", - "ts-results": "^3.2.1", - "tweetnacl-ts": "^1.0.3", - "tweetnacl-util": "^0.15.0", - "typedjson": "^1.6.0-rc2", - "webpack": "^5.24.3" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", - "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", - "requires": { - "@babel/highlight": "^7.12.13" - } - }, - "@babel/compat-data": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.13.15.tgz", - "integrity": "sha512-ltnibHKR1VnrU4ymHyQ/CXtNXI6yZC0oJThyW78Hft8XndANwi+9H+UIklBDraIjFEJzw8wmcM427oDd9KS5wA==" - }, - "@babel/core": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.16.tgz", - "integrity": "sha512-sXHpixBiWWFti0AV2Zq7avpTasr6sIAu7Y396c608541qAU2ui4a193m0KSQmfPSKFZLnQ3cvlKDOm3XkuXm3Q==", - "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.13.16", - "@babel/helper-compilation-targets": "^7.13.16", - "@babel/helper-module-transforms": "^7.13.14", - "@babel/helpers": "^7.13.16", - "@babel/parser": "^7.13.16", - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.15", - "@babel/types": "^7.13.16", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", - "semver": "^6.3.0", - "source-map": "^0.5.0" - }, - "dependencies": { - "@babel/generator": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.1.tgz", - "integrity": "sha512-TMGhsXMXCP/O1WtQmZjpEYDhCYC9vFhayWZPJSZCGkPJgUqX0rF0wwtrYvnzVxIjcF80tkUertXVk5cwqi5cAQ==", - "requires": { - "@babel/types": "^7.14.1", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - }, - "dependencies": { - "@babel/types": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.1.tgz", - "integrity": "sha512-S13Qe85fzLs3gYRUnrpyeIrBJIMYv33qSTg1qoBwiG6nPKwUWAD9odSzWhEedpwOIzSEI6gbdQIWEMiCI42iBA==", - "requires": { - "@babel/helper-validator-identifier": "^7.14.0", - "to-fast-properties": "^2.0.0" - } - } - } - }, - "@babel/helper-validator-identifier": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", - "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==" - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - } - } - }, - "@babel/helper-compilation-targets": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz", - "integrity": "sha512-3gmkYIrpqsLlieFwjkGgLaSHmhnvlAYzZLlYVjlW+QwI+1zE17kGxuJGmIqDQdYp56XdmGeD+Bswx0UTyG18xA==", - "requires": { - "@babel/compat-data": "^7.13.15", - "@babel/helper-validator-option": "^7.12.17", - "browserslist": "^4.14.5", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } - } - }, - "@babel/helper-function-name": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", - "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", - "requires": { - "@babel/helper-get-function-arity": "^7.12.13", - "@babel/template": "^7.12.13", - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", - "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", - "requires": { - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz", - "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==", - "requires": { - "@babel/types": "^7.13.12" - } - }, - "@babel/helper-module-imports": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz", - "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==", - "requires": { - "@babel/types": "^7.13.12" - } - }, - "@babel/helper-module-transforms": { - "version": "7.13.14", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.13.14.tgz", - "integrity": "sha512-QuU/OJ0iAOSIatyVZmfqB0lbkVP0kDRiKj34xy+QNsnVZi/PA6BoSoreeqnxxa9EHFAIL0R9XOaAR/G9WlIy5g==", - "requires": { - "@babel/helper-module-imports": "^7.13.12", - "@babel/helper-replace-supers": "^7.13.12", - "@babel/helper-simple-access": "^7.13.12", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/helper-validator-identifier": "^7.12.11", - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.13", - "@babel/types": "^7.13.14" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", - "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", - "requires": { - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-replace-supers": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz", - "integrity": "sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw==", - "requires": { - "@babel/helper-member-expression-to-functions": "^7.13.12", - "@babel/helper-optimise-call-expression": "^7.12.13", - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.12" - } - }, - "@babel/helper-simple-access": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz", - "integrity": "sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==", - "requires": { - "@babel/types": "^7.13.12" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", - "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", - "requires": { - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==" - }, - "@babel/helper-validator-option": { - "version": "7.12.17", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz", - "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==" - }, - "@babel/helpers": { - "version": "7.13.17", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.13.17.tgz", - "integrity": "sha512-Eal4Gce4kGijo1/TGJdqp3WuhllaMLSrW6XcL0ulyUAQOuxHcCafZE8KHg9857gcTehsm/v7RcOx2+jp0Ryjsg==", - "requires": { - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.17", - "@babel/types": "^7.13.17" - } - }, - "@babel/highlight": { - "version": "7.13.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.10.tgz", - "integrity": "sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg==", - "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "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==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/parser": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.16.tgz", - "integrity": "sha512-6bAg36mCwuqLO0hbR+z7PHuqWiCeP7Dzg73OpQwsAB1Eb8HnGEz5xYBzCfbu+YjoaJsJs+qheDxVAuqbt3ILEw==" - }, - "@babel/template": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", - "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", - "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/parser": "^7.12.13", - "@babel/types": "^7.12.13" - } - }, - "@babel/traverse": { - "version": "7.13.17", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.17.tgz", - "integrity": "sha512-BMnZn0R+X6ayqm3C3To7o1j7Q020gWdqdyP50KEoVqaCO2c/Im7sYZSmVgvefp8TTMQ+9CtwuBp0Z1CZ8V3Pvg==", - "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.13.16", - "@babel/helper-function-name": "^7.12.13", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/parser": "^7.13.16", - "@babel/types": "^7.13.17", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "dependencies": { - "@babel/generator": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.1.tgz", - "integrity": "sha512-TMGhsXMXCP/O1WtQmZjpEYDhCYC9vFhayWZPJSZCGkPJgUqX0rF0wwtrYvnzVxIjcF80tkUertXVk5cwqi5cAQ==", - "requires": { - "@babel/types": "^7.14.1", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - }, - "dependencies": { - "@babel/types": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.1.tgz", - "integrity": "sha512-S13Qe85fzLs3gYRUnrpyeIrBJIMYv33qSTg1qoBwiG6nPKwUWAD9odSzWhEedpwOIzSEI6gbdQIWEMiCI42iBA==", - "requires": { - "@babel/helper-validator-identifier": "^7.14.0", - "to-fast-properties": "^2.0.0" - } - } - } - }, - "@babel/helper-validator-identifier": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", - "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==" - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - } - } - }, - "@babel/types": { - "version": "7.13.17", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.17.tgz", - "integrity": "sha512-RawydLgxbOPDlTLJNtoIypwdmAy//uQIzlKt2+iBiJaRlVuI6QLUxVAyWGNfOzp8Yu4L4lLIacoCyTNtpb4wiA==", - "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "to-fast-properties": "^2.0.0" - } - }, - "@discoveryjs/json-ext": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz", - "integrity": "sha512-HyYEUDeIj5rRQU2Hk5HTB2uHsbRQpF70nvMhVzi+VJR0X+xNEhjPui4/kBf3VeH/wqD28PT4sVOm8qqLjBrSZg==" - }, - "@eslint/eslintrc": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.0.tgz", - "integrity": "sha512-2ZPCc+uNbjV5ERJr+aKSPRwZgKd2z11x0EgLvb1PURmUrn9QNRXFqje0Ldq454PfAVyaJYyrDvvIKSFP4NnBog==", - "requires": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - }, - "dependencies": { - "globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", - "requires": { - "type-fest": "^0.8.1" - } - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" - }, - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" - } - } - }, - "@ethersproject/bignumber": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.1.1.tgz", - "integrity": "sha512-AVz5iqz7+70RIqoQTznsdJ6DOVBYciNlvO+AlQmPTB6ofCvoihI9bQdr6wljsX+d5W7Yc4nyvQvP4JMzg0Agig==", - "requires": { - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/logger": "^5.1.0", - "bn.js": "^4.4.0" - } - }, - "@ethersproject/bytes": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.1.0.tgz", - "integrity": "sha512-sGTxb+LVjFxJcJeUswAIK6ncgOrh3D8c192iEJd7mLr95V6du119rRfYT/b87WPkZ5I3gRBUYIYXtdgCWACe8g==", - "requires": { - "@ethersproject/logger": "^5.1.0" - } - }, - "@ethersproject/constants": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.1.0.tgz", - "integrity": "sha512-0/SuHrxc8R8k+JiLmJymxHJbojUDWBQqO+b+XFdwaP0jGzqC09YDy/CAlSZB6qHsBifY8X3I89HcK/oMqxRdBw==", - "requires": { - "@ethersproject/bignumber": "^5.1.0" - } - }, - "@ethersproject/logger": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.1.0.tgz", - "integrity": "sha512-wtUaD1lBX10HBXjjKV9VHCBnTdUaKQnQ2XSET1ezglqLdPdllNOIlLfhyCRqXm5xwcjExVI5ETokOYfjPtaAlw==" - }, - "@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "requires": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" - } - } - }, - "@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==" - }, - "@nodelib/fs.scandir": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", - "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==", - "requires": { - "@nodelib/fs.stat": "2.0.4", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz", - "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==" - }, - "@nodelib/fs.walk": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz", - "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==", - "requires": { - "@nodelib/fs.scandir": "2.1.4", - "fastq": "^1.6.0" - } - }, - "@open-rpc/client-js": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/@open-rpc/client-js/-/client-js-1.6.3.tgz", - "integrity": "sha512-KNlYB258FgMUopHUXqPAU4JZMAO/8HnGN7LcL/mXnwH/Qcd0GAMVwLLIXc5d9BBqtmDox8wxxAXGBCajRhyczA==", - "requires": { - "isomorphic-fetch": "^3.0.0", - "isomorphic-ws": "^4.0.1", - "strict-event-emitter-types": "^2.0.0", - "ws": "^7.0.0" - } - }, - "@sindresorhus/is": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.0.1.tgz", - "integrity": "sha512-Qm9hBEBu18wt1PO2flE7LPb30BHMQt1eQgbV76YntdNk73XZGpn3izvGTYxbGgzXKgbCjiia0uxTd3aTNQrY/g==" - }, - "@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==", - "requires": { - "defer-to-connect": "^2.0.0" - } - }, - "@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", - "requires": { - "@types/node": "*" - } - }, - "@types/body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==", - "requires": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "@types/cacheable-request": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", - "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", - "requires": { - "@types/http-cache-semantics": "*", - "@types/keyv": "*", - "@types/node": "*", - "@types/responselike": "*" - } - }, - "@types/chai": { - "version": "4.2.16", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.16.tgz", - "integrity": "sha512-vI5iOAsez9+roLS3M3+Xx7w+WRuDtSmF8bQkrbcIJ2sC1PcDgVoA0WGpa+bIrJ+y8zqY2oi//fUctkxtIcXJCw==" - }, - "@types/connect": { - "version": "3.4.34", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz", - "integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==", - "requires": { - "@types/node": "*" - } - }, - "@types/eccrypto": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/eccrypto/-/eccrypto-1.1.2.tgz", - "integrity": "sha512-qmB/iGIoqDdCMHAcJiOKI4ZBI1Z3kBQGYQCkgNP/Z9ge5w/EVx5uxQYkGOFpllm6l2N/B3qXcn9vjqXGaV1vRQ==", - "requires": { - "@types/expect": "^1.20.4", - "@types/node": "*" - } - }, - "@types/elliptic": { - "version": "6.4.12", - "resolved": "https://registry.npmjs.org/@types/elliptic/-/elliptic-6.4.12.tgz", - "integrity": "sha512-gP1KsqoouLJGH6IJa28x7PXb3cRqh83X8HCLezd2dF+XcAIMKYv53KV+9Zn6QA561E120uOqZBQ+Jy/cl+fviw==", - "requires": { - "@types/bn.js": "*" - } - }, - "@types/eslint": { - "version": "7.2.10", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.10.tgz", - "integrity": "sha512-kUEPnMKrqbtpCq/KTaGFFKAcz6Ethm2EjCoKIDaCmfRBWLbFuTcOJfTlorwbnboXBzahqWLgUp1BQeKHiJzPUQ==", - "requires": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "@types/eslint-scope": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.0.tgz", - "integrity": "sha512-O/ql2+rrCUe2W2rs7wMR+GqPRcgB6UiqN5RhrR5xruFlY7l9YLMn0ZkDzjoHLeiFkR8MCQZVudUuuvQ2BLC9Qw==", - "requires": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "@types/estree": { - "version": "0.0.47", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.47.tgz", - "integrity": "sha512-c5ciR06jK8u9BstrmJyO97m+klJrrhCf9u3rLu3DEAJBirxRqSCvDQoYKmxuYwQI5SZChAWu+tq9oVlGRuzPAg==" - }, - "@types/expect": { - "version": "1.20.4", - "resolved": "https://registry.npmjs.org/@types/expect/-/expect-1.20.4.tgz", - "integrity": "sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg==" - }, - "@types/express": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.11.tgz", - "integrity": "sha512-no+R6rW60JEc59977wIxreQVsIEOAYwgCqldrA/vkpCnbD7MqTefO97lmoBe4WE0F156bC4uLSP1XHDOySnChg==", - "requires": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.18", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "@types/express-serve-static-core": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.19.tgz", - "integrity": "sha512-DJOSHzX7pCiSElWaGR8kCprwibCB/3yW6vcT8VG3P0SJjnv19gnWG/AZMfM60Xj/YJIp/YCaDHyvzsFVeniARA==", - "requires": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*" - } - }, - "@types/http-cache-semantics": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", - "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" - }, - "@types/humanize-duration": { - "version": "3.18.1", - "resolved": "https://registry.npmjs.org/@types/humanize-duration/-/humanize-duration-3.18.1.tgz", - "integrity": "sha512-MUgbY3CF7hg/a/jogixmAufLjJBQT7WEf8Q+kYJkOc47ytngg1IuZobCngdTjAgY83JWEogippge5O5fplaQlw==" - }, - "@types/json-schema": { - "version": "7.0.7", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", - "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==" - }, - "@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=" - }, - "@types/keyv": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.2.tgz", - "integrity": "sha512-/FvAK2p4jQOaJ6CGDHJTqZcUtbZe820qIeTg7o0Shg7drB4JHeL+V/dhSaly7NXx6u8eSee+r7coT+yuJEvDLg==", - "requires": { - "@types/node": "*" - } - }, - "@types/mime": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", - "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" - }, - "@types/mocha": { - "version": "5.2.7", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", - "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==" - }, - "@types/node": { - "version": "14.14.41", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.41.tgz", - "integrity": "sha512-dueRKfaJL4RTtSa7bWeTK1M+VH+Gns73oCgzvYfHZywRCoPSd8EkXBL0mZ9unPTveBn+D9phZBaxuzpwjWkW0g==" - }, - "@types/normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==" - }, - "@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" - }, - "@types/pbkdf2": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", - "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", - "requires": { - "@types/node": "*" - } - }, - "@types/qs": { - "version": "6.9.6", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.6.tgz", - "integrity": "sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA==" - }, - "@types/range-parser": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", - "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==" - }, - "@types/responselike": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", - "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", - "requires": { - "@types/node": "*" - } - }, - "@types/secp256k1": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.2.tgz", - "integrity": "sha512-QMg+9v0bbNJ2peLuHRWxzmy0HRJIG6gFZNhaRSp7S3ggSbCCxiqQB2/ybvhXyhHOCequpNkrx7OavNhrWOsW0A==", - "requires": { - "@types/node": "*" - } - }, - "@types/serve-static": { - "version": "1.13.9", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.9.tgz", - "integrity": "sha512-ZFqF6qa48XsPdjXV5Gsz0Zqmux2PerNd3a/ktL45mHpa19cuMi/cL8tcxdAx497yRh+QtYPuofjT9oWw9P7nkA==", - "requires": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "@typescript-eslint/eslint-plugin": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.22.0.tgz", - "integrity": "sha512-U8SP9VOs275iDXaL08Ln1Fa/wLXfj5aTr/1c0t0j6CdbOnxh+TruXu1p4I0NAvdPBQgoPjHsgKn28mOi0FzfoA==", - "requires": { - "@typescript-eslint/experimental-utils": "4.22.0", - "@typescript-eslint/scope-manager": "4.22.0", - "debug": "^4.1.1", - "functional-red-black-tree": "^1.0.1", - "lodash": "^4.17.15", - "regexpp": "^3.0.0", - "semver": "^7.3.2", - "tsutils": "^3.17.1" - } - }, - "@typescript-eslint/experimental-utils": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.22.0.tgz", - "integrity": "sha512-xJXHHl6TuAxB5AWiVrGhvbGL8/hbiCQ8FiWwObO3r0fnvBdrbWEDy1hlvGQOAWc6qsCWuWMKdVWlLAEMpxnddg==", - "requires": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/scope-manager": "4.22.0", - "@typescript-eslint/types": "4.22.0", - "@typescript-eslint/typescript-estree": "4.22.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^2.0.0" - } - }, - "@typescript-eslint/parser": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.22.0.tgz", - "integrity": "sha512-z/bGdBJJZJN76nvAY9DkJANYgK3nlRstRRi74WHm3jjgf2I8AglrSY+6l7ogxOmn55YJ6oKZCLLy+6PW70z15Q==", - "requires": { - "@typescript-eslint/scope-manager": "4.22.0", - "@typescript-eslint/types": "4.22.0", - "@typescript-eslint/typescript-estree": "4.22.0", - "debug": "^4.1.1" - } - }, - "@typescript-eslint/scope-manager": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.22.0.tgz", - "integrity": "sha512-OcCO7LTdk6ukawUM40wo61WdeoA7NM/zaoq1/2cs13M7GyiF+T4rxuA4xM+6LeHWjWbss7hkGXjFDRcKD4O04Q==", - "requires": { - "@typescript-eslint/types": "4.22.0", - "@typescript-eslint/visitor-keys": "4.22.0" - } - }, - "@typescript-eslint/types": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.22.0.tgz", - "integrity": "sha512-sW/BiXmmyMqDPO2kpOhSy2Py5w6KvRRsKZnV0c4+0nr4GIcedJwXAq+RHNK4lLVEZAJYFltnnk1tJSlbeS9lYA==" - }, - "@typescript-eslint/typescript-estree": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.22.0.tgz", - "integrity": "sha512-TkIFeu5JEeSs5ze/4NID+PIcVjgoU3cUQUIZnH3Sb1cEn1lBo7StSV5bwPuJQuoxKXlzAObjYTilOEKRuhR5yg==", - "requires": { - "@typescript-eslint/types": "4.22.0", - "@typescript-eslint/visitor-keys": "4.22.0", - "debug": "^4.1.1", - "globby": "^11.0.1", - "is-glob": "^4.0.1", - "semver": "^7.3.2", - "tsutils": "^3.17.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.22.0.tgz", - "integrity": "sha512-nnMu4F+s4o0sll6cBSsTeVsT4cwxB7zECK3dFxzEjPBii9xLpq4yqqsy/FU5zMfan6G60DKZSCXAa3sHJZrcYw==", - "requires": { - "@typescript-eslint/types": "4.22.0", - "eslint-visitor-keys": "^2.0.0" - } - }, - "@webassemblyjs/ast": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.0.tgz", - "integrity": "sha512-kX2W49LWsbthrmIRMbQZuQDhGtjyqXfEmmHyEi4XWnSZtPmxY0+3anPIzsnRb45VH/J55zlOfWvZuY47aJZTJg==", - "requires": { - "@webassemblyjs/helper-numbers": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.0.tgz", - "integrity": "sha512-Q/aVYs/VnPDVYvsCBL/gSgwmfjeCb4LW8+TMrO3cSzJImgv8lxxEPM2JA5jMrivE7LSz3V+PFqtMbls3m1exDA==" - }, - "@webassemblyjs/helper-api-error": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.0.tgz", - "integrity": "sha512-baT/va95eXiXb2QflSx95QGT5ClzWpGaa8L7JnJbgzoYeaA27FCvuBXU758l+KXWRndEmUXjP0Q5fibhavIn8w==" - }, - "@webassemblyjs/helper-buffer": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.0.tgz", - "integrity": "sha512-u9HPBEl4DS+vA8qLQdEQ6N/eJQ7gT7aNvMIo8AAWvAl/xMrcOSiI2M0MAnMCy3jIFke7bEee/JwdX1nUpCtdyA==" - }, - "@webassemblyjs/helper-numbers": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.0.tgz", - "integrity": "sha512-DhRQKelIj01s5IgdsOJMKLppI+4zpmcMQ3XboFPLwCpSNH6Hqo1ritgHgD0nqHeSYqofA6aBN/NmXuGjM1jEfQ==", - "requires": { - "@webassemblyjs/floating-point-hex-parser": "1.11.0", - "@webassemblyjs/helper-api-error": "1.11.0", - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.0.tgz", - "integrity": "sha512-MbmhvxXExm542tWREgSFnOVo07fDpsBJg3sIl6fSp9xuu75eGz5lz31q7wTLffwL3Za7XNRCMZy210+tnsUSEA==" - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.0.tgz", - "integrity": "sha512-3Eb88hcbfY/FCukrg6i3EH8H2UsD7x8Vy47iVJrP967A9JGqgBVL9aH71SETPx1JrGsOUVLo0c7vMCN22ytJew==", - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-buffer": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/wasm-gen": "1.11.0" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.0.tgz", - "integrity": "sha512-KXzOqpcYQwAfeQ6WbF6HXo+0udBNmw0iXDmEK5sFlmQdmND+tr773Ti8/5T/M6Tl/413ArSJErATd8In3B+WBA==", - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.0.tgz", - "integrity": "sha512-aqbsHa1mSQAbeeNcl38un6qVY++hh8OpCOzxhixSYgbRfNWcxJNJQwe2rezK9XEcssJbbWIkblaJRwGMS9zp+g==", - "requires": { - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/utf8": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.0.tgz", - "integrity": "sha512-A/lclGxH6SpSLSyFowMzO/+aDEPU4hvEiooCMXQPcQFPPJaYcPQNKGOCLUySJsYJ4trbpr+Fs08n4jelkVTGVw==" - }, - "@webassemblyjs/wasm-edit": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.0.tgz", - "integrity": "sha512-JHQ0damXy0G6J9ucyKVXO2j08JVJ2ntkdJlq1UTiUrIgfGMmA7Ik5VdC/L8hBK46kVJgujkBIoMtT8yVr+yVOQ==", - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-buffer": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/helper-wasm-section": "1.11.0", - "@webassemblyjs/wasm-gen": "1.11.0", - "@webassemblyjs/wasm-opt": "1.11.0", - "@webassemblyjs/wasm-parser": "1.11.0", - "@webassemblyjs/wast-printer": "1.11.0" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.0.tgz", - "integrity": "sha512-BEUv1aj0WptCZ9kIS30th5ILASUnAPEvE3tVMTrItnZRT9tXCLW2LEXT8ezLw59rqPP9klh9LPmpU+WmRQmCPQ==", - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/ieee754": "1.11.0", - "@webassemblyjs/leb128": "1.11.0", - "@webassemblyjs/utf8": "1.11.0" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.0.tgz", - "integrity": "sha512-tHUSP5F4ywyh3hZ0+fDQuWxKx3mJiPeFufg+9gwTpYp324mPCQgnuVKwzLTZVqj0duRDovnPaZqDwoyhIO8kYg==", - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-buffer": "1.11.0", - "@webassemblyjs/wasm-gen": "1.11.0", - "@webassemblyjs/wasm-parser": "1.11.0" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.0.tgz", - "integrity": "sha512-6L285Sgu9gphrcpDXINvm0M9BskznnzJTE7gYkjDbxET28shDqp27wpruyx3C2S/dvEwiigBwLA1cz7lNUi0kw==", - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-api-error": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/ieee754": "1.11.0", - "@webassemblyjs/leb128": "1.11.0", - "@webassemblyjs/utf8": "1.11.0" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.0.tgz", - "integrity": "sha512-Fg5OX46pRdTgB7rKIUojkh9vXaVN6sGYCnEiJN1GYkb0RPwShZXp6KTDqmoMdQPKhcroOXh3fEzmkWmCYaKYhQ==", - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@xtuc/long": "4.2.2" - } - }, - "@webpack-cli/configtest": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.0.2.tgz", - "integrity": "sha512-3OBzV2fBGZ5TBfdW50cha1lHDVf9vlvRXnjpVbJBa20pSZQaSkMJZiwA8V2vD9ogyeXn8nU5s5A6mHyf5jhMzA==" - }, - "@webpack-cli/info": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.2.3.tgz", - "integrity": "sha512-lLek3/T7u40lTqzCGpC6CAbY6+vXhdhmwFRxZLMnRm6/sIF/7qMpT8MocXCRQfz0JAh63wpbXLMnsQ5162WS7Q==", - "requires": { - "envinfo": "^7.7.3" - } - }, - "@webpack-cli/serve": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.3.1.tgz", - "integrity": "sha512-0qXvpeYO6vaNoRBI52/UsbcaBydJCggoBBnIo/ovQQdn6fug0BgwsjorV1hVS7fMqGVTZGcVxv8334gjmbj5hw==" - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" - }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" - }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" - }, - "acorn": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.1.1.tgz", - "integrity": "sha512-xYiIVjNuqtKXMxlRMDc6mZUhXehod4a3gbZ1qRlM7icK4EbxUFNLhWoPblCvFtB2Y9CIqHP3CF/rdxLItaQv8g==" - }, - "acorn-jsx": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", - "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==" - }, - "aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==" - }, - "ansi-align": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", - "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", - "requires": { - "string-width": "^3.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==" - }, - "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==", - "requires": { - "type-fest": "^0.21.3" - }, - "dependencies": { - "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==" - } - } - }, - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "append-transform": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", - "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", - "requires": { - "default-require-extensions": "^3.0.0" - } - }, - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=" - }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "array-differ": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-2.1.0.tgz", - "integrity": "sha512-KbUpJgx909ZscOc/7CLATBFam7P1Z1QRQInvgT0UztM9Q72aGKCunKASAl7WNW0tnPmPyEMeMhdsfWhfmW037w==" - }, - "array-filter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz", - "integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=" - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==" - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" - }, - "asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - } - }, - "assert": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-2.0.0.tgz", - "integrity": "sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A==", - "requires": { - "es6-object-assign": "^1.1.0", - "is-nan": "^1.2.1", - "object-is": "^1.0.1", - "util": "^0.12.0" - } - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==" - }, - "astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==" - }, - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "requires": { - "lodash": "^4.17.14" - } - }, - "available-typed-arrays": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz", - "integrity": "sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ==", - "requires": { - "array-filter": "^1.0.0" - } - }, - "axios": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", - "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", - "requires": { - "follow-redirects": "^1.10.0" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "base-x": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz", - "integrity": "sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bip66": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", - "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", - "optional": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "blakejs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", - "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" - }, - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "boxen": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", - "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", - "requires": { - "ansi-align": "^3.0.0", - "camelcase": "^5.3.1", - "chalk": "^3.0.0", - "cli-boxes": "^2.2.0", - "string-width": "^4.1.0", - "term-size": "^2.1.0", - "type-fest": "^0.8.1", - "widest-line": "^3.1.0" - }, - "dependencies": { - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" - } - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "requires": { - "fill-range": "^7.0.1" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", - "requires": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - } - } - }, - "browserify-sign": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", - "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - } - } - }, - "browserslist": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.4.tgz", - "integrity": "sha512-d7rCxYV8I9kj41RH8UKYnvDYCRENUlHRgyXy/Rhr/1BaeLGfiCptEdFE8MIrvGfWbBFNjVYx76SQWvNX1j+/cQ==", - "requires": { - "caniuse-lite": "^1.0.30001208", - "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.712", - "escalade": "^3.1.1", - "node-releases": "^1.1.71" - } - }, - "bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", - "requires": { - "base-x": "^3.0.2" - } - }, - "bs58check": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", - "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", - "requires": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" - } - }, - "buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=" - }, - "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==" - }, - "cacheable-request": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", - "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", - "requires": { - "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" - }, - "dependencies": { - "normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==" - } - } - }, - "caching-transform": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", - "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", - "requires": { - "hasha": "^5.0.0", - "make-dir": "^3.0.0", - "package-hash": "^4.0.0", - "write-file-atomic": "^3.0.0" - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" - }, - "caniuse-lite": { - "version": "1.0.30001214", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001214.tgz", - "integrity": "sha512-O2/SCpuaU3eASWVaesQirZv1MSjUNOvmugaD8zNSJqw6Vv5SGwoOpA9LJs3pNPfM745nxqPvfZY3MQKY4AKHYg==" - }, - "chai": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", - "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=" - }, - "chokidar": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", - "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.3.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" - } - }, - "chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==" - }, - "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==" - }, - "cli-boxes": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", - "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==" - }, - "cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "requires": { - "restore-cursor": "^3.1.0" - } - }, - "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==", - "requires": { - "slice-ansi": "^3.0.0", - "string-width": "^4.2.0" - }, - "dependencies": { - "slice-ansi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", - "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - } - } - } - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "requires": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - } - }, - "clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "requires": { - "mimic-response": "^1.0.0" - } - }, - "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==", - "requires": { - "color-name": "~1.1.4" - } - }, - "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==" - }, - "colorette": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", - "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==" - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "comment-parser": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.1.2.tgz", - "integrity": "sha512-AOdq0i8ghZudnYv8RUnHrhTgafUGs61Rdz9jemU5x2lnZwAWyOq7vySo626K59e1fVKH1xSRorJwPVRLSWOoAQ==" - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" - }, - "compare-versions": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz", - "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "concurrently": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-6.0.2.tgz", - "integrity": "sha512-u+1Q0dJG5BidgUTpz9CU16yoHTt/oApFDQ3mbvHwSDgMjU7aGqy0q8ZQyaZyaNxdwRKTD872Ux3Twc6//sWA+Q==", - "requires": { - "chalk": "^4.1.0", - "date-fns": "^2.16.1", - "lodash": "^4.17.21", - "read-pkg": "^5.2.0", - "rxjs": "^6.6.3", - "spawn-command": "^0.0.2-1", - "supports-color": "^8.1.0", - "tree-kill": "^1.2.2", - "yargs": "^16.2.0" - }, - "dependencies": { - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "configstore": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", - "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", - "requires": { - "dot-prop": "^5.2.0", - "graceful-fs": "^4.1.2", - "make-dir": "^3.0.0", - "unique-string": "^2.0.0", - "write-file-atomic": "^3.0.0", - "xdg-basedir": "^4.0.0" - } - }, - "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "requires": { - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "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==" - } - } - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cosmiconfig": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", - "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==", - "requires": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - } - }, - "create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==" - }, - "date-fns": { - "version": "2.21.1", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.21.1.tgz", - "integrity": "sha512-m1WR0xGiC6j6jNFAyW4Nvh4WxAi4JF4w9jRJwSI8nBmNcyZXPcP9VUQG+6gHQXAmqaGEKDKhOqAtENDC941UkA==" - }, - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "requires": { - "ms": "2.1.2" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" - }, - "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==", - "requires": { - "mimic-response": "^3.1.0" - }, - "dependencies": { - "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==" - } - } - }, - "dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=" - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "requires": { - "type-detect": "^4.0.0" - } - }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" - }, - "default-require-extensions": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", - "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==", - "requires": { - "strip-bom": "^4.0.0" - } - }, - "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==" - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "requires": { - "object-keys": "^1.0.12" - } - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "requires": { - "path-type": "^4.0.0" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "requires": { - "esutils": "^2.0.2" - } - }, - "dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "requires": { - "is-obj": "^2.0.0" - }, - "dependencies": { - "is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==" - } - } - }, - "drbg.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", - "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", - "optional": true, - "requires": { - "browserify-aes": "^1.0.6", - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4" - } - }, - "duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" - }, - "eccrypto": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/eccrypto/-/eccrypto-1.1.6.tgz", - "integrity": "sha512-d78ivVEzu7Tn0ZphUUaL43+jVPKTMPFGtmgtz1D0LrFn7cY3K8CdrvibuLz2AAkHBLKZtR8DMbB2ukRYFk987A==", - "requires": { - "acorn": "7.1.1", - "elliptic": "6.5.4", - "es6-promise": "4.2.8", - "nan": "2.14.0", - "secp256k1": "3.7.1" - }, - "dependencies": { - "acorn": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", - "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==" - }, - "secp256k1": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.7.1.tgz", - "integrity": "sha512-1cf8sbnRreXrQFdH6qsg2H71Xw91fCCS9Yp021GnUNJzWJS/py96fS4lHbnTnouLp08Xj6jBoBB6V78Tdbdu5g==", - "optional": true, - "requires": { - "bindings": "^1.5.0", - "bip66": "^1.1.5", - "bn.js": "^4.11.8", - "create-hash": "^1.2.0", - "drbg.js": "^1.0.1", - "elliptic": "^6.4.1", - "nan": "^2.14.0", - "safe-buffer": "^5.1.2" - } - } - } - }, - "electron-to-chromium": { - "version": "1.3.719", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.719.tgz", - "integrity": "sha512-heM78GKSqrIzO9Oz0/y22nTBN7bqSP1Pla2SyU9DiSnQD+Ea9SyyN5RWWlgqsqeBLNDkSlE9J9EHFmdMPzxB/g==" - }, - "elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "requires": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "email-addresses": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-3.1.0.tgz", - "integrity": "sha512-k0/r7GrWVL32kZlGwfPNgB2Y/mMXVTq/decgLczm/j34whdaspNrZO8CnXPf1laaHxI6ptUlsnAxN+UAPw+fzg==" - }, - "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==" - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" - }, - "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==", - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.0.tgz", - "integrity": "sha512-Sl3KRpJA8OpprrtaIswVki3cWPiPKxXuFxJXBp+zNb6s6VwNWwFRUdtmzd2ReUut8n+sCPx7QCtQ7w5wfJhSgQ==", - "requires": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - } - }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "requires": { - "ansi-colors": "^4.1.1" - } - }, - "envinfo": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", - "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==" - }, - "errno": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", - "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", - "requires": { - "prr": "~1.0.1" - } - }, - "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==", - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0.tgz", - "integrity": "sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw==", - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "is-callable": "^1.2.3", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.2", - "is-string": "^1.0.5", - "object-inspect": "^1.9.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.0" - } - }, - "es-module-lexer": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.4.1.tgz", - "integrity": "sha512-ooYciCUtfw6/d2w56UVeqHPcoCFAiJdz5XOkYpv/Txl1HMUozpXjz/2RIQgqwKdXNDPSF1W7mJCFse3G+HDyAA==" - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==" - }, - "es6-object-assign": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", - "integrity": "sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw=" - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" - }, - "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==" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "eslint": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.24.0.tgz", - "integrity": "sha512-k9gaHeHiFmGCDQ2rEfvULlSLruz6tgfA8DEn+rY9/oYPFFTlz55mM/Q/Rij1b2Y42jwZiK3lXvNTw6w6TXzcKQ==", - "requires": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash": "^4.17.21", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.4", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "requires": { - "@babel/highlight": "^7.10.4" - } - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" - } - } - }, - "eslint-config-prettier": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.2.0.tgz", - "integrity": "sha512-dWV9EVeSo2qodOPi1iBYU/x6F6diHv8uujxbxr77xExs3zTAlNXvVZKiyLsQGNz7yPV2K49JY5WjPzNIuDc2Bw==" - }, - "eslint-plugin-jsdoc": { - "version": "32.3.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-32.3.0.tgz", - "integrity": "sha512-zyx7kajDK+tqS1bHuY5sapkad8P8KT0vdd/lE55j47VPG2MeenSYuIY/M/Pvmzq5g0+3JB+P3BJGUXmHxtuKPQ==", - "requires": { - "comment-parser": "1.1.2", - "debug": "^4.3.1", - "jsdoctypeparser": "^9.0.0", - "lodash": "^4.17.20", - "regextras": "^0.7.1", - "semver": "^7.3.4", - "spdx-expression-parse": "^3.0.1" - } - }, - "eslint-plugin-prefer-arrow": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-prefer-arrow/-/eslint-plugin-prefer-arrow-1.2.3.tgz", - "integrity": "sha512-J9I5PKCOJretVuiZRGvPQxCbllxGAV/viI20JO3LYblAodofBxyMnZAJ+WGeClHgANnSJberTNoFWWjrWKBuXQ==" - }, - "eslint-plugin-prettier": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.0.tgz", - "integrity": "sha512-UDK6rJT6INSfcOo545jiaOwB701uAIt2/dR7WnFQoGCVl1/EMqdANBmwUaqqQ45aXprsTGzSa39LI1PyuRBxxw==", - "requires": { - "prettier-linter-helpers": "^1.0.0" - } - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "requires": { - "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" - } - } - }, - "eslint-visitor-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", - "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==" - }, - "espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "requires": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "dependencies": { - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" - }, - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" - } - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "requires": { - "estraverse": "^5.1.0" - }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==" - } - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "requires": { - "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==" - } - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" - }, - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", - "requires": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==" - }, - "fast-glob": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", - "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", - "merge2": "^1.3.0", - "micromatch": "^4.0.2", - "picomatch": "^2.2.1" - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" - }, - "fastest-levenshtein": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", - "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==" - }, - "fastq": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", - "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==", - "requires": { - "reusify": "^1.0.4" - } - }, - "figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "requires": { - "flat-cache": "^3.0.4" - } - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "optional": true - }, - "filename-reserved-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-1.0.0.tgz", - "integrity": "sha1-5hz4BfDeHJhFZ9A4bcXfUO5a9+Q=" - }, - "filenamify": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-1.2.1.tgz", - "integrity": "sha1-qfL/0RxQO+0wABUCknI3jx8TZaU=", - "requires": { - "filename-reserved-regex": "^1.0.0", - "strip-outer": "^1.0.0", - "trim-repeated": "^1.0.0" - } - }, - "filenamify-url": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/filenamify-url/-/filenamify-url-1.0.0.tgz", - "integrity": "sha1-syvYExnvWGO3MHi+1Q9GpPeXX1A=", - "requires": { - "filenamify": "^1.0.0", - "humanize-url": "^1.0.0" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-cache-dir": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", - "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", - "requires": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "find-versions": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-4.0.0.tgz", - "integrity": "sha512-wgpWy002tA+wgmO27buH/9KzyEOQnKsG/R0yrcjPT9BOFm0zRBVQbZ95nRGXWMywS8YR5knRbpohio0bcJABxQ==", - "requires": { - "semver-regex": "^3.1.2" - } - }, - "flat": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", - "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", - "requires": { - "is-buffer": "~2.0.3" - } - }, - "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", - "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==" - }, - "follow-redirects": { - "version": "1.13.3", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.3.tgz", - "integrity": "sha512-DUgl6+HDzB0iEptNQEXLx/KhTmDb8tZUHSeLqpnjpknR70H0nC2t9N73BK6fN4hOvJ84pKlIQVQ4k5FFlBedKA==" - }, - "foreach": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" - }, - "foreground-child": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", - "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", - "requires": { - "cross-spawn": "^7.0.0", - "signal-exit": "^3.0.2" - } - }, - "fromentries": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", - "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==" - }, - "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==", - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" - }, - "gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" - }, - "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==" - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=" - }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "get-own-enumerable-property-symbols": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", - "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" - }, - "get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==" - }, - "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==", - "requires": { - "pump": "^3.0.0" - } - }, - "gh-pages": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-3.1.0.tgz", - "integrity": "sha512-3b1rly9kuf3/dXsT8+ZxP0UhNLOo1CItj+3e31yUVcaph/yDsJ9RzD7JOw5o5zpBTJVQLlJAASNkUfepi9fe2w==", - "requires": { - "async": "^2.6.1", - "commander": "^2.18.0", - "email-addresses": "^3.0.1", - "filenamify-url": "^1.0.0", - "find-cache-dir": "^3.3.1", - "fs-extra": "^8.1.0", - "globby": "^6.1.0" - }, - "dependencies": { - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "requires": { - "array-uniq": "^1.0.1" - } - }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - } - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "requires": { - "is-glob": "^4.0.1" - } - }, - "glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" - }, - "global-dirs": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.1.0.tgz", - "integrity": "sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==", - "requires": { - "ini": "1.3.7" - } - }, - "globals": { - "version": "13.8.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.8.0.tgz", - "integrity": "sha512-rHtdA6+PDBIjeEvA91rpqzEvk/k3/i7EeNQiryiWuJH0Hw9cpyJMAt2jtbAwUaRdhD+573X4vWw6IcjKPasi9Q==", - "requires": { - "type-fest": "^0.20.2" - }, - "dependencies": { - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==" - } - } - }, - "globby": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz", - "integrity": "sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==", - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - } - }, - "google-protobuf": { - "version": "3.15.8", - "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.15.8.tgz", - "integrity": "sha512-2jtfdqTaSxk0cuBJBtTTWsot4WtR9RVr2rXg7x7OoqiuOKopPrwXpM1G4dXIkLcUNRh3RKzz76C8IOkksZSeOw==" - }, - "got": { - "version": "11.8.2", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.2.tgz", - "integrity": "sha512-D0QywKgIe30ODs+fm8wMZiAcZjypcCodPNuMz5H9Mny7RJ+IjJ10BdmGW7OM7fHXP+O7r6ZwapQ/YQmMSvB0UQ==", - "requires": { - "@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.1", - "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" - } - }, - "graceful-fs": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==" - }, - "handlebars": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", - "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", - "requires": { - "minimist": "^1.2.5", - "neo-async": "^2.6.0", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4", - "wordwrap": "^1.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" - }, - "has-yarn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", - "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==" - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "hasha": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", - "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", - "requires": { - "is-stream": "^2.0.0", - "type-fest": "^0.8.0" - }, - "dependencies": { - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" - } - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "highlight.js": { - "version": "10.7.2", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.2.tgz", - "integrity": "sha512-oFLl873u4usRM9K63j4ME9u3etNF0PLiJhSQ8rdfuL51Wn3zkD6drf9ZW0dOzjnZI22YYG24z30JcmfCZjMgYg==" - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "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==" - }, - "html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" - }, - "http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" - }, - "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==", - "requires": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.0.0" - } - }, - "human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==" - }, - "humanize-duration": { - "version": "3.25.2", - "resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.25.2.tgz", - "integrity": "sha512-zSerjahuzBazDaE8skjMI7Xmrt/EirvW5cDsXgysx8tYIjcgCMnI5Y5985y3LxYeLah9L5cQY3WEw1k7GRWbfg==" - }, - "humanize-url": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/humanize-url/-/humanize-url-1.0.1.tgz", - "integrity": "sha1-9KuZ4NKIF0yk4eUEB8VfuuRk7/8=", - "requires": { - "normalize-url": "^1.0.0", - "strip-url-auth": "^1.0.0" - } - }, - "husky": { - "version": "4.3.8", - "resolved": "https://registry.npmjs.org/husky/-/husky-4.3.8.tgz", - "integrity": "sha512-LCqqsB0PzJQ/AlCgfrfzRe3e3+NvmefAdKQhRYpxS4u6clblBoDdzzvHi8fmxKRzvMxPY/1WZWzomPZww0Anow==", - "requires": { - "chalk": "^4.0.0", - "ci-info": "^2.0.0", - "compare-versions": "^3.6.0", - "cosmiconfig": "^7.0.0", - "find-versions": "^4.0.0", - "opencollective-postinstall": "^2.0.2", - "pkg-dir": "^5.0.0", - "please-upgrade-node": "^3.2.0", - "slash": "^3.0.0", - "which-pm-runs": "^1.0.0" - }, - "dependencies": { - "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==", - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "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==", - "requires": { - "p-locate": "^5.0.0" - } - }, - "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==", - "requires": { - "p-limit": "^3.0.2" - } - }, - "pkg-dir": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", - "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", - "requires": { - "find-up": "^5.0.0" - } - } - } - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" - }, - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==" - }, - "ignore-by-default": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=" - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "import-lazy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", - "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=" - }, - "import-local": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", - "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", - "requires": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" - }, - "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==" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ini": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", - "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==" - }, - "interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==" - }, - "is-arguments": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", - "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==", - "requires": { - "call-bind": "^1.0.0" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" - }, - "is-bigint": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.1.tgz", - "integrity": "sha512-J0ELF4yHFxHy0cmSxZuheDOz2luOdVvqjwmEcj8H/L1JHeuEDSDbeRP+Dk9kFVk5RTFzbucJ2Kb9F7ixY2QaCg==" - }, - "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==", - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-boolean-object": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.0.tgz", - "integrity": "sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA==", - "requires": { - "call-bind": "^1.0.0" - } - }, - "is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==" - }, - "is-callable": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", - "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==" - }, - "is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "requires": { - "ci-info": "^2.0.0" - } - }, - "is-core-module": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", - "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", - "requires": { - "has": "^1.0.3" - } - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==" - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" - }, - "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==" - }, - "is-generator-function": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.8.tgz", - "integrity": "sha512-2Omr/twNtufVZFr1GhxjOMFPAj2sjc/dKaIqBhvo4qciXfJmITGH6ZGd8eZYNHza8t1y0e01AuqRhJwfWp26WQ==" - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-installed-globally": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", - "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", - "requires": { - "global-dirs": "^2.0.1", - "is-path-inside": "^3.0.1" - } - }, - "is-nan": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", - "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - } - }, - "is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==" - }, - "is-npm": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", - "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==" - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" - }, - "is-number-object": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz", - "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==" - }, - "is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" - }, - "is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==" - }, - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "requires": { - "isobject": "^3.0.1" - } - }, - "is-regex": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", - "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", - "requires": { - "call-bind": "^1.0.2", - "has-symbols": "^1.0.1" - } - }, - "is-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=" - }, - "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" - }, - "is-string": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", - "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==" - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typed-array": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.5.tgz", - "integrity": "sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug==", - "requires": { - "available-typed-arrays": "^1.0.2", - "call-bind": "^1.0.2", - "es-abstract": "^1.18.0-next.2", - "foreach": "^2.0.5", - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" - }, - "is-yarn-global": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", - "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - }, - "isomorphic-fetch": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", - "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", - "requires": { - "node-fetch": "^2.6.1", - "whatwg-fetch": "^3.4.1" - } - }, - "isomorphic-ws": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", - "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==" - }, - "istanbul-lib-coverage": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", - "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==" - }, - "istanbul-lib-hook": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", - "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", - "requires": { - "append-transform": "^2.0.0" - } - }, - "istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", - "requires": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } - } - }, - "istanbul-lib-processinfo": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz", - "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==", - "requires": { - "archy": "^1.0.0", - "cross-spawn": "^7.0.0", - "istanbul-lib-coverage": "^3.0.0-alpha.1", - "make-dir": "^3.0.0", - "p-map": "^3.0.0", - "rimraf": "^3.0.0", - "uuid": "^3.3.3" - }, - "dependencies": { - "p-map": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" - }, - "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==", - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "requires": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - } - }, - "istanbul-lib-source-maps": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", - "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - } - }, - "istanbul-reports": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", - "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", - "requires": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - } - }, - "jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - } - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbi": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/jsbi/-/jsbi-3.1.4.tgz", - "integrity": "sha512-52QRRFSsi9impURE8ZUbzAMCLjPm4THO7H2fcuIvaaeFTbSysvkodbQQXIVsNgq/ypDbq6dJiuGKL0vZ/i9hUg==" - }, - "jsdoctypeparser": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/jsdoctypeparser/-/jsdoctypeparser-9.0.0.tgz", - "integrity": "sha512-jrTA2jJIL6/DAEILBEh2/w9QxCuwmvNXIry39Ay/HVfhE3o2yVV0U44blYkqdHA/OKloJEqvJy0xU+GSdE2SIw==" - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" - }, - "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==" - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" - }, - "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==" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=" - }, - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "requires": { - "minimist": "^1.2.5" - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "keccak": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.1.tgz", - "integrity": "sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA==", - "requires": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - } - }, - "key-encoder": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/key-encoder/-/key-encoder-2.0.3.tgz", - "integrity": "sha512-fgBtpAGIr/Fy5/+ZLQZIPPhsZEcbSlYu/Wu96tNDFNSjSACw5lEIOFeaVdQ/iwrb8oxjlWi6wmWdH76hV6GZjg==", - "requires": { - "@types/elliptic": "^6.4.9", - "asn1.js": "^5.0.1", - "bn.js": "^4.11.8", - "elliptic": "^6.4.1" - } - }, - "keyv": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.3.tgz", - "integrity": "sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA==", - "requires": { - "json-buffer": "3.0.1" - } - }, - "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==" - }, - "latest-version": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", - "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", - "requires": { - "package-json": "^6.3.0" - } - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=" - }, - "lint-staged": { - "version": "10.5.4", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-10.5.4.tgz", - "integrity": "sha512-EechC3DdFic/TdOPgj/RB3FicqE6932LTHCUm0Y2fsD9KGlLB+RwJl2q1IYBIvEsKzDOgn0D4gll+YxG5RsrKg==", - "requires": { - "chalk": "^4.1.0", - "cli-truncate": "^2.1.0", - "commander": "^6.2.0", - "cosmiconfig": "^7.0.0", - "debug": "^4.2.0", - "dedent": "^0.7.0", - "enquirer": "^2.3.6", - "execa": "^4.1.0", - "listr2": "^3.2.2", - "log-symbols": "^4.0.0", - "micromatch": "^4.0.2", - "normalize-path": "^3.0.0", - "please-upgrade-node": "^3.2.0", - "string-argv": "0.3.1", - "stringify-object": "^3.3.0" - }, - "dependencies": { - "commander": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", - "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==" - } - } - }, - "listr2": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.7.1.tgz", - "integrity": "sha512-cNd368GTrk8351/ov/IV+BSwyf9sJRgI0UIvfORonCZA1u9UHAtAlqSEv9dgafoQIA1CgB3nu4No79pJtK2LHw==", - "requires": { - "chalk": "^4.1.0", - "cli-truncate": "^2.1.0", - "figures": "^3.2.0", - "indent-string": "^4.0.0", - "log-update": "^4.0.0", - "p-map": "^4.0.0", - "rxjs": "^6.6.7", - "through": "^2.3.8", - "wrap-ansi": "^7.0.0" - } - }, - "loader-runner": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", - "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==" - }, - "loader-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", - "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "requires": { - "p-locate": "^4.1.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=" - }, - "lodash.flattendeep": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=" - }, - "lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=" - }, - "log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "requires": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - } - }, - "log-update": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", - "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", - "requires": { - "ansi-escapes": "^4.3.0", - "cli-cursor": "^3.1.0", - "slice-ansi": "^4.0.0", - "wrap-ansi": "^6.2.0" - }, - "dependencies": { - "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - } - } - }, - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" - }, - "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==", - "requires": { - "yallist": "^4.0.0" - } - }, - "lunr": { - "version": "2.3.9", - "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", - "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==" - }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "requires": { - "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } - } - }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" - }, - "marked": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-1.0.0.tgz", - "integrity": "sha512-Wo+L1pWTVibfrSr+TTtMuiMfNzmZWiOPeO7rZsQUY5bgsxpHesBEcIWJloWVTFnrMXnf/TL30eTFSGJddmQAng==" - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "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" - } - }, - "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==" - }, - "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==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" - }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - } - }, - "mime-db": { - "version": "1.47.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", - "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==" - }, - "mime-types": { - "version": "2.1.30", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", - "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", - "requires": { - "mime-db": "1.47.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" - }, - "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, - "mkdirp": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz", - "integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==", - "requires": { - "minimist": "^1.2.5" - } - }, - "mocha": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.3.tgz", - "integrity": "sha512-0R/3FvjIGH3eEuG17ccFPk117XL2rWxatr81a57D+r/x2uTYZRbdZ4oVidEUMh2W2TJDa7MdAb12Lm2/qrKajg==", - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "2.2.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.4", - "ms": "2.1.1", - "node-environment-flags": "1.0.5", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "dependencies": { - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==" - }, - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "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==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.0.0" - } - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", - "requires": { - "chalk": "^2.0.1" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "requires": { - "has-flag": "^3.0.0" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - }, - "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } - }, - "mri": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.1.6.tgz", - "integrity": "sha512-oi1b3MfbyGa7FJMP9GmLTttni5JoICpYBRlq+x5V16fZbLsnL9N3wFqqIm/nIG43FjUFkFh9Epzp/kzUGUnJxQ==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "multimatch": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-3.0.0.tgz", - "integrity": "sha512-22foS/gqQfANZ3o+W7ST2x25ueHDVNWl/b9OlGcLpy/iKxjCpvcNCM51YCenUi7Mt/jAjjqv8JwZRs8YP5sRjA==", - "requires": { - "array-differ": "^2.0.3", - "array-union": "^1.0.2", - "arrify": "^1.0.1", - "minimatch": "^3.0.4" - }, - "dependencies": { - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "requires": { - "array-uniq": "^1.0.1" - } - } - } - }, - "nan": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" - }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" - }, - "node-addon-api": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" - }, - "node-environment-flags": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", - "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==", - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" - }, - "node-gyp-build": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", - "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==" - }, - "node-preload": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", - "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", - "requires": { - "process-on-spawn": "^1.0.0" - } - }, - "node-releases": { - "version": "1.1.71", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz", - "integrity": "sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==" - }, - "nodemon": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.7.tgz", - "integrity": "sha512-XHzK69Awgnec9UzHr1kc8EomQh4sjTQ8oRf8TsGrSmHDx9/UmiGG9E/mM3BuTfNeFwdNBvrqQq/RHL0xIeyFOA==", - "requires": { - "chokidar": "^3.2.2", - "debug": "^3.2.6", - "ignore-by-default": "^1.0.1", - "minimatch": "^3.0.4", - "pstree.remy": "^1.1.7", - "semver": "^5.7.1", - "supports-color": "^5.5.0", - "touch": "^3.1.0", - "undefsafe": "^2.0.3", - "update-notifier": "^4.1.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "nopt": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", - "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", - "requires": { - "abbrev": "1" - } - }, - "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==", - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" - }, - "normalize-url": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", - "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", - "requires": { - "object-assign": "^4.0.1", - "prepend-http": "^1.0.0", - "query-string": "^4.1.0", - "sort-keys": "^1.0.0" - } - }, - "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==", - "requires": { - "path-key": "^3.0.0" - } - }, - "nyc": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", - "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", - "requires": { - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "caching-transform": "^4.0.0", - "convert-source-map": "^1.7.0", - "decamelize": "^1.2.0", - "find-cache-dir": "^3.2.0", - "find-up": "^4.1.0", - "foreground-child": "^2.0.0", - "get-package-type": "^0.1.0", - "glob": "^7.1.6", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-hook": "^3.0.0", - "istanbul-lib-instrument": "^4.0.0", - "istanbul-lib-processinfo": "^2.0.2", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "make-dir": "^3.0.0", - "node-preload": "^0.2.1", - "p-map": "^3.0.0", - "process-on-spawn": "^1.0.0", - "resolve-from": "^5.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "spawn-wrap": "^2.0.0", - "test-exclude": "^6.0.0", - "yargs": "^15.0.2" - }, - "dependencies": { - "cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "p-map": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" - }, - "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "requires": { - "ansi-regex": "^5.0.0" - } - }, - "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" - }, - "yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "requires": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - } - }, - "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "object-inspect": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.2.tgz", - "integrity": "sha512-gz58rdPpadwztRrPjZE9DZLOABUpTGdcANUgOwBFO1C+HZZhePoP83M65WGDmbpwFYJSWqavbl4SgDn4k8RYTA==" - }, - "object-is": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", - "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" - }, - "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz", - "integrity": "sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "opencollective-postinstall": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz", - "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==" - }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - } - }, - "p-cancelable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==" - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "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==", - "requires": { - "p-limit": "^2.2.0" - }, - "dependencies": { - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - } - } - }, - "p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "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==" - }, - "package-hash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", - "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", - "requires": { - "graceful-fs": "^4.1.15", - "hasha": "^5.0.0", - "lodash.flattendeep": "^4.4.0", - "release-zalgo": "^1.0.0" - } - }, - "package-json": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", - "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", - "requires": { - "got": "^9.6.0", - "registry-auth-token": "^4.0.0", - "registry-url": "^5.0.0", - "semver": "^6.2.0" - }, - "dependencies": { - "@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==" - }, - "@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", - "requires": { - "defer-to-connect": "^1.0.1" - } - }, - "cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", - "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" - }, - "dependencies": { - "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==", - "requires": { - "pump": "^3.0.0" - } - }, - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" - } - } - }, - "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "requires": { - "mimic-response": "^1.0.0" - } - }, - "defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==" - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - }, - "got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", - "requires": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" - } - }, - "json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" - }, - "keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", - "requires": { - "json-buffer": "3.0.0" - } - }, - "lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" - }, - "normalize-url": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", - "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==" - }, - "p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==" - }, - "responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", - "requires": { - "lowercase-keys": "^1.0.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } - } - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", - "requires": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "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==", - "requires": { - "@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" - } - }, - "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==" - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" - }, - "pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==" - }, - "pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "picomatch": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", - "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==" - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "requires": { - "find-up": "^4.0.0" - } - }, - "please-upgrade-node": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", - "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", - "requires": { - "semver-compare": "^1.0.0" - } - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" - }, - "prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" - }, - "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==" - }, - "prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "requires": { - "fast-diff": "^1.1.2" - } - }, - "pretty-quick": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-1.11.1.tgz", - "integrity": "sha512-kSXCkcETfak7EQXz6WOkCeCqpbC4GIzrN/vaneTGMP/fAtD8NerA9bPhCUqHAks1geo7biZNl5uEMPceeneLuA==", - "requires": { - "chalk": "^2.3.0", - "execa": "^0.8.0", - "find-up": "^2.1.0", - "ignore": "^3.3.7", - "mri": "^1.1.0", - "multimatch": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "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==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "execa": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.8.0.tgz", - "integrity": "sha1-2NdrvBtVIX7RkP1t1J08d07PyNo=", - "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "requires": { - "locate-path": "^2.0.0" - } - }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "ignore": { - "version": "3.3.10", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", - "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==" - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "requires": { - "path-key": "^2.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" - } - } - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" - }, - "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==" - }, - "process-on-spawn": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", - "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", - "requires": { - "fromentries": "^1.2.0" - } - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" - }, - "pstree.remy": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", - "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "pupa": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", - "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", - "requires": { - "escape-goat": "^2.0.0" - } - }, - "query-string": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", - "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", - "requires": { - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - } - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" - }, - "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==" - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" - } - } - }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - } - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", - "requires": { - "picomatch": "^2.2.1" - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "requires": { - "resolve": "^1.1.6" - } - }, - "reflect-metadata": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", - "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" - }, - "regexpp": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", - "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==" - }, - "regextras": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/regextras/-/regextras-0.7.1.tgz", - "integrity": "sha512-9YXf6xtW+qzQ+hcMQXx95MOvfqXFgsKDZodX3qZB0x2n5Z94ioetIITsBtvJbiOyxa/6s9AtyweBLCdPmPko/w==" - }, - "registry-auth-token": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", - "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", - "requires": { - "rc": "^1.2.8" - } - }, - "registry-url": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", - "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", - "requires": { - "rc": "^1.2.8" - } - }, - "release-zalgo": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", - "requires": { - "es6-error": "^4.0.1" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" - }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" - }, - "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", - "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - } - }, - "resolve-alpn": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.1.2.tgz", - "integrity": "sha512-8OyfzhAtA32LVUsJSke3auIyINcwdh5l3cvYKdKO0nvsYSKuiLfTM5i78PJswFPT8y6cPW+L1v6/hE95chcpDA==" - }, - "resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "requires": { - "resolve-from": "^5.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" - } - } - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" - }, - "responselike": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", - "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", - "requires": { - "lowercase-keys": "^2.0.0" - } - }, - "restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "requires": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - } - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "requires": { - "glob": "^7.1.3" - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "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==", - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "requires": { - "tslib": "^1.9.0" - } - }, - "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==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "schema-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", - "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", - "requires": { - "@types/json-schema": "^7.0.6", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - }, - "scrypt-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" - }, - "secp256k1": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz", - "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==", - "requires": { - "elliptic": "^6.5.2", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - } - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "requires": { - "lru-cache": "^6.0.0" - } - }, - "semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=" - }, - "semver-diff": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", - "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", - "requires": { - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } - } - }, - "semver-regex": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-3.1.2.tgz", - "integrity": "sha512-bXWyL6EAKOJa81XG1OZ/Yyuq+oT0b2YLlxx7c+mrdYPaPbnj6WgVULXhinMIeZGufuUBu/eVRqXEhiv4imfwxA==" - }, - "serialize-javascript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", - "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", - "requires": { - "randombytes": "^2.1.0" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "requires": { - "kind-of": "^6.0.2" - } - }, - "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==", - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" - }, - "shelljs": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz", - "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==", - "requires": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - } - }, - "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" - }, - "slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - } - }, - "sort-keys": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", - "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", - "requires": { - "is-plain-obj": "^1.0.0" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "spawn-command": { - "version": "0.0.2-1", - "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", - "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=" - }, - "spawn-wrap": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", - "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", - "requires": { - "foreground-child": "^2.0.0", - "is-windows": "^1.0.2", - "make-dir": "^3.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "which": "^2.0.1" - }, - "dependencies": { - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==" - }, - "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==", - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz", - "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==" - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "stream-browserify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", - "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", - "requires": { - "inherits": "~2.0.4", - "readable-stream": "^3.5.0" - } - }, - "stream-http": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz", - "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==", - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "xtend": "^4.0.2" - } - }, - "strict-event-emitter-types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strict-event-emitter-types/-/strict-event-emitter-types-2.0.0.tgz", - "integrity": "sha512-Nk/brWYpD85WlOgzw5h173aci0Teyv8YdIAEtV+N88nDB0dLlazZyJMIsN6eo1/AR61l+p6CJTG1JIyFaoNEEA==" - }, - "strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" - }, - "string-argv": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", - "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==" - }, - "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "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==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "stringify-object": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", - "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", - "requires": { - "get-own-enumerable-property-symbols": "^3.0.0", - "is-obj": "^1.0.1", - "is-regexp": "^1.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "requires": { - "ansi-regex": "^5.0.0" - } - }, - "strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" - }, - "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" - }, - "strip-outer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", - "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", - "requires": { - "escape-string-regexp": "^1.0.2" - } - }, - "strip-url-auth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-url-auth/-/strip-url-auth-1.0.1.tgz", - "integrity": "sha1-IrD6OkE4WzO+PzMVUbu4N/oM164=" - }, - "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==", - "requires": { - "has-flag": "^4.0.0" - } - }, - "table": { - "version": "6.3.2", - "resolved": "https://registry.npmjs.org/table/-/table-6.3.2.tgz", - "integrity": "sha512-I9/Ca6Huf2oxFag7crD0DhA+arIdfLtWunSn0NIXSzjtUlDgIBGVZY7SsMkNPNT3Psd/z4gza0nuEpmra9eRbg==", - "requires": { - "ajv": "^8.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "lodash.clonedeep": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.0" - }, - "dependencies": { - "ajv": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.1.0.tgz", - "integrity": "sha512-B/Sk2Ix7A36fs/ZkuGLIR86EdjbgR6fsAcbx9lOP/QBSXujDNbVmIS/U4Itz5k8fPFDeVZl/zQ/gJW4Jrq6XjQ==", - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - } - } - }, - "tapable": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", - "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==" - }, - "term-size": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", - "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==" - }, - "terser": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.6.1.tgz", - "integrity": "sha512-yv9YLFQQ+3ZqgWCUk+pvNJwgUTdlIxUk1WTN+RnaFJe2L7ipG2csPT0ra2XRm7Cs8cxN7QXmK1rFzEwYEQkzXw==", - "requires": { - "commander": "^2.20.0", - "source-map": "~0.7.2", - "source-map-support": "~0.5.19" - }, - "dependencies": { - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" - } - } - }, - "terser-webpack-plugin": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.1.tgz", - "integrity": "sha512-5XNNXZiR8YO6X6KhSGXfY0QrGrCRlSwAEjIIrlRQR4W8nP69TaJUlh3bkuac6zzgspiGPfKEHcY295MMVExl5Q==", - "requires": { - "jest-worker": "^26.6.2", - "p-limit": "^3.1.0", - "schema-utils": "^3.0.0", - "serialize-javascript": "^5.0.1", - "source-map": "^0.6.1", - "terser": "^5.5.1" - } - }, - "test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "requires": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" - }, - "to-readable-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==" - }, - "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==", - "requires": { - "is-number": "^7.0.0" - } - }, - "touch": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", - "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", - "requires": { - "nopt": "~1.0.10" - } - }, - "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==" - }, - "trim-repeated": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", - "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=", - "requires": { - "escape-string-regexp": "^1.0.2" - } - }, - "ts-loader": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-8.1.0.tgz", - "integrity": "sha512-YiQipGGAFj2zBfqLhp28yUvPP9jUGqHxRzrGYuc82Z2wM27YIHbElXiaZDc93c3x0mz4zvBmS6q/DgExpdj37A==", - "requires": { - "chalk": "^4.1.0", - "enhanced-resolve": "^4.0.0", - "loader-utils": "^2.0.0", - "micromatch": "^4.0.0", - "semver": "^7.3.4" - }, - "dependencies": { - "enhanced-resolve": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz", - "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==", - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==" - } - } - }, - "ts-node": { - "version": "8.10.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz", - "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==", - "requires": { - "arg": "^4.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "source-map-support": "^0.5.17", - "yn": "3.1.1" - }, - "dependencies": { - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" - } - } - }, - "ts-protoc-gen": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/ts-protoc-gen/-/ts-protoc-gen-0.10.0.tgz", - "integrity": "sha512-EEbgDWNHK3CvcNhmib94I4HMO23qLddjLRdXW8EUE11VJxbi3n5J0l2DiX/L1pijOaPTkbEoRK+zQinKgKGqsw==", - "requires": { - "google-protobuf": "^3.6.1" - } - }, - "ts-results": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ts-results/-/ts-results-3.2.1.tgz", - "integrity": "sha512-cMvWPLvxM39fSQgSHRT2d+dwQfpK+ttfj5FpPuXum9m/pm6iDmgsirpWXp/3/ErmZqx1x+rAhJi/33NQqCCM3Q==" - }, - "tsconfig-paths": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", - "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", - "requires": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.0", - "strip-bom": "^3.0.0" - }, - "dependencies": { - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "requires": { - "minimist": "^1.2.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" - } - } - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "tslint": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz", - "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==", - "requires": { - "@babel/code-frame": "^7.0.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.3.0", - "commander": "^2.12.1", - "diff": "^4.0.1", - "glob": "^7.1.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.3", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.13.0", - "tsutils": "^2.29.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "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==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "requires": { - "tslib": "^1.8.1" - } - } - } - }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "requires": { - "tslib": "^1.8.1" - } - }, - "tweetnacl-ts": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl-ts/-/tweetnacl-ts-1.0.3.tgz", - "integrity": "sha512-C5I/dWf6xjAXaCDlf84T4HvozU/8ycAlq5WRllF1hAeeq5390tfXD+bNas5bhEV0HMSOx8bsQYpLjPl8wfnEeQ==", - "requires": { - "tslib": "^1" - } - }, - "tweetnacl-util": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", - "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==" - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" - }, - "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==" - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "typedjson": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/typedjson/-/typedjson-1.7.0.tgz", - "integrity": "sha512-MnRgQLwtEcdHqQG0FkT8ebpBG53Wgr/axYRbiD2WL5NcYx8Z2AoCpXvtTfLnuPqOBKG/9JpXq0O/nl2m4wqJYw==", - "requires": { - "tslib": "^2.0.1" - }, - "dependencies": { - "tslib": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", - "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" - } - } - }, - "typedoc": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.17.8.tgz", - "integrity": "sha512-/OyrHCJ8jtzu+QZ+771YaxQ9s4g5Z3XsQE3Ma7q+BL392xxBn4UMvvCdVnqKC2T/dz03/VXSLVKOP3lHmDdc/w==", - "requires": { - "fs-extra": "^8.1.0", - "handlebars": "^4.7.6", - "highlight.js": "^10.0.0", - "lodash": "^4.17.15", - "lunr": "^2.3.8", - "marked": "1.0.0", - "minimatch": "^3.0.0", - "progress": "^2.0.3", - "shelljs": "^0.8.4", - "typedoc-default-themes": "^0.10.2" - } - }, - "typedoc-default-themes": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/typedoc-default-themes/-/typedoc-default-themes-0.10.2.tgz", - "integrity": "sha512-zo09yRj+xwLFE3hyhJeVHWRSPuKEIAsFK5r2u47KL/HBKqpwdUSanoaz5L34IKiSATFrjG5ywmIu98hPVMfxZg==", - "requires": { - "lunr": "^2.3.8" - } - }, - "typescript": { - "version": "3.9.9", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.9.tgz", - "integrity": "sha512-kdMjTiekY+z/ubJCATUPlRDl39vXYiMV9iyeMuEuXZh2we6zz80uovNN2WlAxmmdE/Z/YQe+EbOEXB5RHEED3w==" - }, - "uglify-js": { - "version": "3.13.4", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.4.tgz", - "integrity": "sha512-kv7fCkIXyQIilD5/yQy8O+uagsYIOt5cZvs890W40/e/rvjMSzJw81o9Bg0tkURxzZBROtDQhW2LFjOGoK3RZw==", - "optional": true - }, - "unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - } - }, - "undefsafe": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz", - "integrity": "sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==", - "requires": { - "debug": "^2.2.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "unique-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "requires": { - "crypto-random-string": "^2.0.0" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "update-notifier": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", - "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==", - "requires": { - "boxen": "^4.2.0", - "chalk": "^3.0.0", - "configstore": "^5.0.1", - "has-yarn": "^2.1.0", - "import-lazy": "^2.1.0", - "is-ci": "^2.0.0", - "is-installed-globally": "^0.3.1", - "is-npm": "^4.0.0", - "is-yarn-global": "^0.3.0", - "latest-version": "^5.0.0", - "pupa": "^2.0.1", - "semver-diff": "^3.1.1", - "xdg-basedir": "^4.0.0" - }, - "dependencies": { - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "requires": { - "punycode": "^2.1.0" - } - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" - } - } - }, - "url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", - "requires": { - "prepend-http": "^2.0.0" - }, - "dependencies": { - "prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" - } - } - }, - "util": { - "version": "0.12.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.3.tgz", - "integrity": "sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog==", - "requires": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "safe-buffer": "^5.1.2", - "which-typed-array": "^1.1.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" - }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==" - }, - "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==", - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "watchpack": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.1.1.tgz", - "integrity": "sha512-Oo7LXCmc1eE1AjyuSBmtC3+Wy4HcV8PxWh2kP6fOl8yTlNS7r0K9l1ao2lrrUza7V39Y3D/BbJgY8VeSlc5JKw==", - "requires": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - } - }, - "webpack": { - "version": "5.35.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.35.0.tgz", - "integrity": "sha512-au3gu55yYF/h6NXFr0KZPZAYxS6Nlc595BzYPke8n0CSff5WXcoixtjh5LC/8mXunkRKxhymhXmBY0+kEbR6jg==", - "requires": { - "@types/eslint-scope": "^3.7.0", - "@types/estree": "^0.0.47", - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/wasm-edit": "1.11.0", - "@webassemblyjs/wasm-parser": "1.11.0", - "acorn": "^8.0.4", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.8.0", - "es-module-lexer": "^0.4.0", - "eslint-scope": "^5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.4", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.0.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.1", - "watchpack": "^2.0.0", - "webpack-sources": "^2.1.1" - } - }, - "webpack-cli": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.6.0.tgz", - "integrity": "sha512-9YV+qTcGMjQFiY7Nb1kmnupvb1x40lfpj8pwdO/bom+sQiP4OBMKjHq29YQrlDWDPZO9r/qWaRRywKaRDKqBTA==", - "requires": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^1.0.2", - "@webpack-cli/info": "^1.2.3", - "@webpack-cli/serve": "^1.3.1", - "colorette": "^1.2.1", - "commander": "^7.0.0", - "enquirer": "^2.3.6", - "execa": "^5.0.0", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^2.2.0", - "rechoir": "^0.7.0", - "v8-compile-cache": "^2.2.0", - "webpack-merge": "^5.7.3" - }, - "dependencies": { - "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==" - }, - "execa": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.0.0.tgz", - "integrity": "sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==", - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - } - }, - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==" - }, - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==" - }, - "interpret": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", - "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==" - }, - "rechoir": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.0.tgz", - "integrity": "sha512-ADsDEH2bvbjltXEP+hTIAmeFekTFK0V2BTxMkok6qILyAJEXV0AFfoWcAq4yfll5VdIMd/RVXq0lR+wQi5ZU3Q==", - "requires": { - "resolve": "^1.9.0" - } - } - } - }, - "webpack-merge": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.7.3.tgz", - "integrity": "sha512-6/JUQv0ELQ1igjGDzHkXbVDRxkfA57Zw7PfiupdLFJYrgFqY5ZP8xxbpp2lU3EPwYx89ht5Z/aDkD40hFCm5AA==", - "requires": { - "clone-deep": "^4.0.1", - "wildcard": "^2.0.0" - } - }, - "webpack-node-externals": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/webpack-node-externals/-/webpack-node-externals-2.5.2.tgz", - "integrity": "sha512-aHdl/y2N7PW2Sx7K+r3AxpJO+aDMcYzMQd60Qxefq3+EwhewSbTBqNumOsCE1JsCUNoyfGj5465N0sSf6hc/5w==" - }, - "webpack-sources": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.2.0.tgz", - "integrity": "sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w==", - "requires": { - "source-list-map": "^2.0.1", - "source-map": "^0.6.1" - } - }, - "whatwg-fetch": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", - "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==" - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "requires": { - "isexe": "^2.0.0" - } - }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" - }, - "which-pm-runs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", - "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=" - }, - "which-typed-array": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.4.tgz", - "integrity": "sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA==", - "requires": { - "available-typed-arrays": "^1.0.2", - "call-bind": "^1.0.0", - "es-abstract": "^1.18.0-next.1", - "foreach": "^2.0.5", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.1", - "is-typed-array": "^1.1.3" - } - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "widest-line": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", - "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", - "requires": { - "string-width": "^4.0.0" - } - }, - "wildcard": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", - "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==" - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" - }, - "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==", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "ws": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz", - "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==" - }, - "xdg-basedir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", - "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "requires": { - "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" - } - }, - "yargs-parser": { - "version": "20.2.7", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz", - "integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==" - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "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==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - }, - "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } - }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" - }, - "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==" - } - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "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==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" - }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" - }, - "dotenv": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", - "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-core-module": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", - "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", - "requires": { - "has": "^1.0.3" - } - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "requires": { - "minimist": "^1.2.5" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "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==" - }, - "prettier": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz", - "integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==" - }, - "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", - "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - }, - "ts-node": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.0.0.tgz", - "integrity": "sha512-ROWeOIUvfFbPZkoDis0L/55Fk+6gFQNZwwKPLinacRl6tsxstTF1DbAcLKkovwnpKMVvOMHP1TIbnwXwtLg1gg==", - "requires": { - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "source-map-support": "^0.5.17", - "yn": "3.1.1" - } - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "tslint": { - "version": "5.20.1", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.20.1.tgz", - "integrity": "sha512-EcMxhzCFt8k+/UP5r8waCf/lzmeSyVlqxqMEDQE7rWYiQky8KpIBz1JAoYXfROHrPZ1XXd43q8yQnULOLiBRQg==", - "requires": { - "@babel/code-frame": "^7.0.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.3.0", - "commander": "^2.12.1", - "diff": "^4.0.1", - "glob": "^7.1.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.8.0", - "tsutils": "^2.29.0" - } - }, - "tslint-config-prettier": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz", - "integrity": "sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==" - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "requires": { - "tslib": "^1.8.1" - } - }, - "typescript": { - "version": "3.9.10", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", - "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==" - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" - } + "casper-js-sdk": "2.2.0" } }, "casper-js-sdk": { - "version": "file:../../casper-js-sdk", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/casper-js-sdk/-/casper-js-sdk-2.2.0.tgz", + "integrity": "sha512-VU2GxGHt++68IR+n2h+UiZnrwBnNVkQKAJ1RWSv3A+zqHZwTZahMF+NO5pz43xwrDBG+sET2vu8JqJ4JJ7AsnQ==", "requires": { "@ethersproject/bignumber": "^5.0.8", "@ethersproject/bytes": "^5.0.5", @@ -7114,5077 +443,791 @@ "tweetnacl-util": "^0.15.0", "typedjson": "^1.6.0-rc2", "webpack": "^5.24.3" + } + }, + "chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==" + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "colorette": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==" + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "drbg.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", + "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", + "optional": true, + "requires": { + "browserify-aes": "^1.0.6", + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4" + } + }, + "eccrypto": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/eccrypto/-/eccrypto-1.1.6.tgz", + "integrity": "sha512-d78ivVEzu7Tn0ZphUUaL43+jVPKTMPFGtmgtz1D0LrFn7cY3K8CdrvibuLz2AAkHBLKZtR8DMbB2ukRYFk987A==", + "requires": { + "acorn": "7.1.1", + "elliptic": "6.5.4", + "es6-promise": "4.2.8", + "nan": "2.14.0", + "secp256k1": "3.7.1" + } + }, + "electron-to-chromium": { + "version": "1.3.784", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.784.tgz", + "integrity": "sha512-JTPxdUibkefeomWNaYs8lI/x/Zb4cOhZWX+d7kpzsNKzUd07pNuo/AcHeNJ/qgEchxM1IAxda9aaGUhKN/poOg==" + }, + "elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "requires": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "enhanced-resolve": { + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz", + "integrity": "sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==", + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + } + }, + "es-module-lexer": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.7.1.tgz", + "integrity": "sha512-MgtWFl5No+4S3TmhDmCz2ObFGm6lEpTnzbQi+Dd+pw4mlTIZTmM2iAs5gRlmx5zS9luzobCSBSI90JM/1/JgOw==" + }, + "es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, + "eslint-plugin-prettier": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.0.tgz", + "integrity": "sha512-UDK6rJT6INSfcOo545jiaOwB701uAIt2/dR7WnFQoGCVl1/EMqdANBmwUaqqQ45aXprsTGzSa39LI1PyuRBxxw==", + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "requires": { + "estraverse": "^5.2.0" }, "dependencies": { - "@babel/code-frame": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", - "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", - "requires": { - "@babel/highlight": "^7.12.13" - } - }, - "@babel/compat-data": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.13.15.tgz", - "integrity": "sha512-ltnibHKR1VnrU4ymHyQ/CXtNXI6yZC0oJThyW78Hft8XndANwi+9H+UIklBDraIjFEJzw8wmcM427oDd9KS5wA==" - }, - "@babel/core": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.16.tgz", - "integrity": "sha512-sXHpixBiWWFti0AV2Zq7avpTasr6sIAu7Y396c608541qAU2ui4a193m0KSQmfPSKFZLnQ3cvlKDOm3XkuXm3Q==", - "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.13.16", - "@babel/helper-compilation-targets": "^7.13.16", - "@babel/helper-module-transforms": "^7.13.14", - "@babel/helpers": "^7.13.16", - "@babel/parser": "^7.13.16", - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.15", - "@babel/types": "^7.13.16", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", - "semver": "^6.3.0", - "source-map": "^0.5.0" - }, - "dependencies": {} - }, - "@babel/helper-compilation-targets": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz", - "integrity": "sha512-3gmkYIrpqsLlieFwjkGgLaSHmhnvlAYzZLlYVjlW+QwI+1zE17kGxuJGmIqDQdYp56XdmGeD+Bswx0UTyG18xA==", - "requires": { - "@babel/compat-data": "^7.13.15", - "@babel/helper-validator-option": "^7.12.17", - "browserslist": "^4.14.5", - "semver": "^6.3.0" - }, - "dependencies": {} - }, - "@babel/helper-function-name": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", - "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", - "requires": { - "@babel/helper-get-function-arity": "^7.12.13", - "@babel/template": "^7.12.13", - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", - "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", - "requires": { - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz", - "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==", - "requires": { - "@babel/types": "^7.13.12" - } - }, - "@babel/helper-module-imports": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz", - "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==", - "requires": { - "@babel/types": "^7.13.12" - } - }, - "@babel/helper-module-transforms": { - "version": "7.13.14", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.13.14.tgz", - "integrity": "sha512-QuU/OJ0iAOSIatyVZmfqB0lbkVP0kDRiKj34xy+QNsnVZi/PA6BoSoreeqnxxa9EHFAIL0R9XOaAR/G9WlIy5g==", - "requires": { - "@babel/helper-module-imports": "^7.13.12", - "@babel/helper-replace-supers": "^7.13.12", - "@babel/helper-simple-access": "^7.13.12", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/helper-validator-identifier": "^7.12.11", - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.13", - "@babel/types": "^7.13.14" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", - "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", - "requires": { - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-replace-supers": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz", - "integrity": "sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw==", - "requires": { - "@babel/helper-member-expression-to-functions": "^7.13.12", - "@babel/helper-optimise-call-expression": "^7.12.13", - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.12" - } - }, - "@babel/helper-simple-access": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz", - "integrity": "sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==", - "requires": { - "@babel/types": "^7.13.12" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", - "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", - "requires": { - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==" - }, - "@babel/helper-validator-option": { - "version": "7.12.17", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz", - "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==" - }, - "@babel/helpers": { - "version": "7.13.17", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.13.17.tgz", - "integrity": "sha512-Eal4Gce4kGijo1/TGJdqp3WuhllaMLSrW6XcL0ulyUAQOuxHcCafZE8KHg9857gcTehsm/v7RcOx2+jp0Ryjsg==", - "requires": { - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.17", - "@babel/types": "^7.13.17" - } - }, - "@babel/highlight": { - "version": "7.13.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.10.tgz", - "integrity": "sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg==", - "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": {} - }, - "@babel/parser": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.16.tgz", - "integrity": "sha512-6bAg36mCwuqLO0hbR+z7PHuqWiCeP7Dzg73OpQwsAB1Eb8HnGEz5xYBzCfbu+YjoaJsJs+qheDxVAuqbt3ILEw==" - }, - "@babel/template": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", - "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", - "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/parser": "^7.12.13", - "@babel/types": "^7.12.13" - } - }, - "@babel/traverse": { - "version": "7.13.17", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.17.tgz", - "integrity": "sha512-BMnZn0R+X6ayqm3C3To7o1j7Q020gWdqdyP50KEoVqaCO2c/Im7sYZSmVgvefp8TTMQ+9CtwuBp0Z1CZ8V3Pvg==", - "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.13.16", - "@babel/helper-function-name": "^7.12.13", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/parser": "^7.13.16", - "@babel/types": "^7.13.17", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "dependencies": {} - }, - "@babel/types": { - "version": "7.13.17", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.17.tgz", - "integrity": "sha512-RawydLgxbOPDlTLJNtoIypwdmAy//uQIzlKt2+iBiJaRlVuI6QLUxVAyWGNfOzp8Yu4L4lLIacoCyTNtpb4wiA==", - "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "to-fast-properties": "^2.0.0" - } - }, - "@discoveryjs/json-ext": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz", - "integrity": "sha512-HyYEUDeIj5rRQU2Hk5HTB2uHsbRQpF70nvMhVzi+VJR0X+xNEhjPui4/kBf3VeH/wqD28PT4sVOm8qqLjBrSZg==" - }, - "@eslint/eslintrc": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.0.tgz", - "integrity": "sha512-2ZPCc+uNbjV5ERJr+aKSPRwZgKd2z11x0EgLvb1PURmUrn9QNRXFqje0Ldq454PfAVyaJYyrDvvIKSFP4NnBog==", - "requires": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - }, - "dependencies": {} - }, - "@ethersproject/bignumber": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.1.1.tgz", - "integrity": "sha512-AVz5iqz7+70RIqoQTznsdJ6DOVBYciNlvO+AlQmPTB6ofCvoihI9bQdr6wljsX+d5W7Yc4nyvQvP4JMzg0Agig==", - "requires": { - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/logger": "^5.1.0", - "bn.js": "^4.4.0" - } - }, - "@ethersproject/bytes": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.1.0.tgz", - "integrity": "sha512-sGTxb+LVjFxJcJeUswAIK6ncgOrh3D8c192iEJd7mLr95V6du119rRfYT/b87WPkZ5I3gRBUYIYXtdgCWACe8g==", + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==" + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" + }, + "ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "requires": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + }, + "dependencies": { + "secp256k1": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz", + "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==", "requires": { - "@ethersproject/logger": "^5.1.0" + "elliptic": "^6.5.2", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" } - }, - "@ethersproject/constants": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.1.0.tgz", - "integrity": "sha512-0/SuHrxc8R8k+JiLmJymxHJbojUDWBQqO+b+XFdwaP0jGzqC09YDy/CAlSZB6qHsBifY8X3I89HcK/oMqxRdBw==", - "requires": { - "@ethersproject/bignumber": "^5.1.0" - } - }, - "@ethersproject/logger": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.1.0.tgz", - "integrity": "sha512-wtUaD1lBX10HBXjjKV9VHCBnTdUaKQnQ2XSET1ezglqLdPdllNOIlLfhyCRqXm5xwcjExVI5ETokOYfjPtaAlw==" - }, - "@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "requires": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "dependencies": {} - }, - "@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==" - }, - "@nodelib/fs.scandir": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", - "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==", - "requires": { - "@nodelib/fs.stat": "2.0.4", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz", - "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==" - }, - "@nodelib/fs.walk": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz", - "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==", - "requires": { - "@nodelib/fs.scandir": "2.1.4", - "fastq": "^1.6.0" - } - }, - "@open-rpc/client-js": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/@open-rpc/client-js/-/client-js-1.6.3.tgz", - "integrity": "sha512-KNlYB258FgMUopHUXqPAU4JZMAO/8HnGN7LcL/mXnwH/Qcd0GAMVwLLIXc5d9BBqtmDox8wxxAXGBCajRhyczA==", - "requires": { - "isomorphic-fetch": "^3.0.0", - "isomorphic-ws": "^4.0.1", - "strict-event-emitter-types": "^2.0.0", - "ws": "^7.0.0" - } - }, - "@sindresorhus/is": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.0.1.tgz", - "integrity": "sha512-Qm9hBEBu18wt1PO2flE7LPb30BHMQt1eQgbV76YntdNk73XZGpn3izvGTYxbGgzXKgbCjiia0uxTd3aTNQrY/g==" - }, - "@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==", - "requires": { - "defer-to-connect": "^2.0.0" - } - }, - "@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", - "requires": { - "@types/node": "*" - } - }, - "@types/body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==", - "requires": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "@types/cacheable-request": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", - "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", - "requires": { - "@types/http-cache-semantics": "*", - "@types/keyv": "*", - "@types/node": "*", - "@types/responselike": "*" - } - }, - "@types/chai": { - "version": "4.2.16", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.16.tgz", - "integrity": "sha512-vI5iOAsez9+roLS3M3+Xx7w+WRuDtSmF8bQkrbcIJ2sC1PcDgVoA0WGpa+bIrJ+y8zqY2oi//fUctkxtIcXJCw==" - }, - "@types/connect": { - "version": "3.4.34", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz", - "integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==", - "requires": { - "@types/node": "*" - } - }, - "@types/eccrypto": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/eccrypto/-/eccrypto-1.1.2.tgz", - "integrity": "sha512-qmB/iGIoqDdCMHAcJiOKI4ZBI1Z3kBQGYQCkgNP/Z9ge5w/EVx5uxQYkGOFpllm6l2N/B3qXcn9vjqXGaV1vRQ==", - "requires": { - "@types/expect": "^1.20.4", - "@types/node": "*" - } - }, - "@types/elliptic": { - "version": "6.4.12", - "resolved": "https://registry.npmjs.org/@types/elliptic/-/elliptic-6.4.12.tgz", - "integrity": "sha512-gP1KsqoouLJGH6IJa28x7PXb3cRqh83X8HCLezd2dF+XcAIMKYv53KV+9Zn6QA561E120uOqZBQ+Jy/cl+fviw==", - "requires": { - "@types/bn.js": "*" - } - }, - "@types/eslint": { - "version": "7.2.10", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.10.tgz", - "integrity": "sha512-kUEPnMKrqbtpCq/KTaGFFKAcz6Ethm2EjCoKIDaCmfRBWLbFuTcOJfTlorwbnboXBzahqWLgUp1BQeKHiJzPUQ==", - "requires": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "@types/eslint-scope": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.0.tgz", - "integrity": "sha512-O/ql2+rrCUe2W2rs7wMR+GqPRcgB6UiqN5RhrR5xruFlY7l9YLMn0ZkDzjoHLeiFkR8MCQZVudUuuvQ2BLC9Qw==", - "requires": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "@types/estree": { - "version": "0.0.47", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.47.tgz", - "integrity": "sha512-c5ciR06jK8u9BstrmJyO97m+klJrrhCf9u3rLu3DEAJBirxRqSCvDQoYKmxuYwQI5SZChAWu+tq9oVlGRuzPAg==" - }, - "@types/expect": { - "version": "1.20.4", - "resolved": "https://registry.npmjs.org/@types/expect/-/expect-1.20.4.tgz", - "integrity": "sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg==" - }, - "@types/express": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.11.tgz", - "integrity": "sha512-no+R6rW60JEc59977wIxreQVsIEOAYwgCqldrA/vkpCnbD7MqTefO97lmoBe4WE0F156bC4uLSP1XHDOySnChg==", - "requires": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.18", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "@types/express-serve-static-core": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.19.tgz", - "integrity": "sha512-DJOSHzX7pCiSElWaGR8kCprwibCB/3yW6vcT8VG3P0SJjnv19gnWG/AZMfM60Xj/YJIp/YCaDHyvzsFVeniARA==", - "requires": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*" - } - }, - "@types/http-cache-semantics": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", - "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" - }, - "@types/humanize-duration": { - "version": "3.18.1", - "resolved": "https://registry.npmjs.org/@types/humanize-duration/-/humanize-duration-3.18.1.tgz", - "integrity": "sha512-MUgbY3CF7hg/a/jogixmAufLjJBQT7WEf8Q+kYJkOc47ytngg1IuZobCngdTjAgY83JWEogippge5O5fplaQlw==" - }, - "@types/json-schema": { - "version": "7.0.7", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", - "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==" - }, - "@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=" - }, - "@types/keyv": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.2.tgz", - "integrity": "sha512-/FvAK2p4jQOaJ6CGDHJTqZcUtbZe820qIeTg7o0Shg7drB4JHeL+V/dhSaly7NXx6u8eSee+r7coT+yuJEvDLg==", - "requires": { - "@types/node": "*" - } - }, - "@types/mime": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", - "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" - }, - "@types/mocha": { - "version": "5.2.7", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", - "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==" - }, - "@types/node": { - "version": "14.14.41", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.41.tgz", - "integrity": "sha512-dueRKfaJL4RTtSa7bWeTK1M+VH+Gns73oCgzvYfHZywRCoPSd8EkXBL0mZ9unPTveBn+D9phZBaxuzpwjWkW0g==" - }, - "@types/normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==" - }, - "@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" - }, - "@types/pbkdf2": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", - "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", - "requires": { - "@types/node": "*" - } - }, - "@types/qs": { - "version": "6.9.6", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.6.tgz", - "integrity": "sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA==" - }, - "@types/range-parser": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", - "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==" - }, - "@types/responselike": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", - "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", - "requires": { - "@types/node": "*" - } - }, - "@types/secp256k1": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.2.tgz", - "integrity": "sha512-QMg+9v0bbNJ2peLuHRWxzmy0HRJIG6gFZNhaRSp7S3ggSbCCxiqQB2/ybvhXyhHOCequpNkrx7OavNhrWOsW0A==", - "requires": { - "@types/node": "*" - } - }, - "@types/serve-static": { - "version": "1.13.9", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.9.tgz", - "integrity": "sha512-ZFqF6qa48XsPdjXV5Gsz0Zqmux2PerNd3a/ktL45mHpa19cuMi/cL8tcxdAx497yRh+QtYPuofjT9oWw9P7nkA==", - "requires": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "@typescript-eslint/eslint-plugin": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.22.0.tgz", - "integrity": "sha512-U8SP9VOs275iDXaL08Ln1Fa/wLXfj5aTr/1c0t0j6CdbOnxh+TruXu1p4I0NAvdPBQgoPjHsgKn28mOi0FzfoA==", - "requires": { - "@typescript-eslint/experimental-utils": "4.22.0", - "@typescript-eslint/scope-manager": "4.22.0", - "debug": "^4.1.1", - "functional-red-black-tree": "^1.0.1", - "lodash": "^4.17.15", - "regexpp": "^3.0.0", - "semver": "^7.3.2", - "tsutils": "^3.17.1" - } - }, - "@typescript-eslint/experimental-utils": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.22.0.tgz", - "integrity": "sha512-xJXHHl6TuAxB5AWiVrGhvbGL8/hbiCQ8FiWwObO3r0fnvBdrbWEDy1hlvGQOAWc6qsCWuWMKdVWlLAEMpxnddg==", - "requires": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/scope-manager": "4.22.0", - "@typescript-eslint/types": "4.22.0", - "@typescript-eslint/typescript-estree": "4.22.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^2.0.0" - } - }, - "@typescript-eslint/parser": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.22.0.tgz", - "integrity": "sha512-z/bGdBJJZJN76nvAY9DkJANYgK3nlRstRRi74WHm3jjgf2I8AglrSY+6l7ogxOmn55YJ6oKZCLLy+6PW70z15Q==", - "requires": { - "@typescript-eslint/scope-manager": "4.22.0", - "@typescript-eslint/types": "4.22.0", - "@typescript-eslint/typescript-estree": "4.22.0", - "debug": "^4.1.1" - } - }, - "@typescript-eslint/scope-manager": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.22.0.tgz", - "integrity": "sha512-OcCO7LTdk6ukawUM40wo61WdeoA7NM/zaoq1/2cs13M7GyiF+T4rxuA4xM+6LeHWjWbss7hkGXjFDRcKD4O04Q==", - "requires": { - "@typescript-eslint/types": "4.22.0", - "@typescript-eslint/visitor-keys": "4.22.0" - } - }, - "@typescript-eslint/types": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.22.0.tgz", - "integrity": "sha512-sW/BiXmmyMqDPO2kpOhSy2Py5w6KvRRsKZnV0c4+0nr4GIcedJwXAq+RHNK4lLVEZAJYFltnnk1tJSlbeS9lYA==" - }, - "@typescript-eslint/typescript-estree": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.22.0.tgz", - "integrity": "sha512-TkIFeu5JEeSs5ze/4NID+PIcVjgoU3cUQUIZnH3Sb1cEn1lBo7StSV5bwPuJQuoxKXlzAObjYTilOEKRuhR5yg==", - "requires": { - "@typescript-eslint/types": "4.22.0", - "@typescript-eslint/visitor-keys": "4.22.0", - "debug": "^4.1.1", - "globby": "^11.0.1", - "is-glob": "^4.0.1", - "semver": "^7.3.2", - "tsutils": "^3.17.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.22.0.tgz", - "integrity": "sha512-nnMu4F+s4o0sll6cBSsTeVsT4cwxB7zECK3dFxzEjPBii9xLpq4yqqsy/FU5zMfan6G60DKZSCXAa3sHJZrcYw==", - "requires": { - "@typescript-eslint/types": "4.22.0", - "eslint-visitor-keys": "^2.0.0" - } - }, - "@webassemblyjs/ast": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.0.tgz", - "integrity": "sha512-kX2W49LWsbthrmIRMbQZuQDhGtjyqXfEmmHyEi4XWnSZtPmxY0+3anPIzsnRb45VH/J55zlOfWvZuY47aJZTJg==", - "requires": { - "@webassemblyjs/helper-numbers": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.0.tgz", - "integrity": "sha512-Q/aVYs/VnPDVYvsCBL/gSgwmfjeCb4LW8+TMrO3cSzJImgv8lxxEPM2JA5jMrivE7LSz3V+PFqtMbls3m1exDA==" - }, - "@webassemblyjs/helper-api-error": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.0.tgz", - "integrity": "sha512-baT/va95eXiXb2QflSx95QGT5ClzWpGaa8L7JnJbgzoYeaA27FCvuBXU758l+KXWRndEmUXjP0Q5fibhavIn8w==" - }, - "@webassemblyjs/helper-buffer": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.0.tgz", - "integrity": "sha512-u9HPBEl4DS+vA8qLQdEQ6N/eJQ7gT7aNvMIo8AAWvAl/xMrcOSiI2M0MAnMCy3jIFke7bEee/JwdX1nUpCtdyA==" - }, - "@webassemblyjs/helper-numbers": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.0.tgz", - "integrity": "sha512-DhRQKelIj01s5IgdsOJMKLppI+4zpmcMQ3XboFPLwCpSNH6Hqo1ritgHgD0nqHeSYqofA6aBN/NmXuGjM1jEfQ==", - "requires": { - "@webassemblyjs/floating-point-hex-parser": "1.11.0", - "@webassemblyjs/helper-api-error": "1.11.0", - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.0.tgz", - "integrity": "sha512-MbmhvxXExm542tWREgSFnOVo07fDpsBJg3sIl6fSp9xuu75eGz5lz31q7wTLffwL3Za7XNRCMZy210+tnsUSEA==" - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.0.tgz", - "integrity": "sha512-3Eb88hcbfY/FCukrg6i3EH8H2UsD7x8Vy47iVJrP967A9JGqgBVL9aH71SETPx1JrGsOUVLo0c7vMCN22ytJew==", - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-buffer": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/wasm-gen": "1.11.0" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.0.tgz", - "integrity": "sha512-KXzOqpcYQwAfeQ6WbF6HXo+0udBNmw0iXDmEK5sFlmQdmND+tr773Ti8/5T/M6Tl/413ArSJErATd8In3B+WBA==", - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.0.tgz", - "integrity": "sha512-aqbsHa1mSQAbeeNcl38un6qVY++hh8OpCOzxhixSYgbRfNWcxJNJQwe2rezK9XEcssJbbWIkblaJRwGMS9zp+g==", - "requires": { - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/utf8": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.0.tgz", - "integrity": "sha512-A/lclGxH6SpSLSyFowMzO/+aDEPU4hvEiooCMXQPcQFPPJaYcPQNKGOCLUySJsYJ4trbpr+Fs08n4jelkVTGVw==" - }, - "@webassemblyjs/wasm-edit": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.0.tgz", - "integrity": "sha512-JHQ0damXy0G6J9ucyKVXO2j08JVJ2ntkdJlq1UTiUrIgfGMmA7Ik5VdC/L8hBK46kVJgujkBIoMtT8yVr+yVOQ==", - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-buffer": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/helper-wasm-section": "1.11.0", - "@webassemblyjs/wasm-gen": "1.11.0", - "@webassemblyjs/wasm-opt": "1.11.0", - "@webassemblyjs/wasm-parser": "1.11.0", - "@webassemblyjs/wast-printer": "1.11.0" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.0.tgz", - "integrity": "sha512-BEUv1aj0WptCZ9kIS30th5ILASUnAPEvE3tVMTrItnZRT9tXCLW2LEXT8ezLw59rqPP9klh9LPmpU+WmRQmCPQ==", - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/ieee754": "1.11.0", - "@webassemblyjs/leb128": "1.11.0", - "@webassemblyjs/utf8": "1.11.0" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.0.tgz", - "integrity": "sha512-tHUSP5F4ywyh3hZ0+fDQuWxKx3mJiPeFufg+9gwTpYp324mPCQgnuVKwzLTZVqj0duRDovnPaZqDwoyhIO8kYg==", - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-buffer": "1.11.0", - "@webassemblyjs/wasm-gen": "1.11.0", - "@webassemblyjs/wasm-parser": "1.11.0" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.0.tgz", - "integrity": "sha512-6L285Sgu9gphrcpDXINvm0M9BskznnzJTE7gYkjDbxET28shDqp27wpruyx3C2S/dvEwiigBwLA1cz7lNUi0kw==", - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-api-error": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/ieee754": "1.11.0", - "@webassemblyjs/leb128": "1.11.0", - "@webassemblyjs/utf8": "1.11.0" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.0.tgz", - "integrity": "sha512-Fg5OX46pRdTgB7rKIUojkh9vXaVN6sGYCnEiJN1GYkb0RPwShZXp6KTDqmoMdQPKhcroOXh3fEzmkWmCYaKYhQ==", - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@xtuc/long": "4.2.2" - } - }, - "@webpack-cli/configtest": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.0.2.tgz", - "integrity": "sha512-3OBzV2fBGZ5TBfdW50cha1lHDVf9vlvRXnjpVbJBa20pSZQaSkMJZiwA8V2vD9ogyeXn8nU5s5A6mHyf5jhMzA==" - }, - "@webpack-cli/info": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.2.3.tgz", - "integrity": "sha512-lLek3/T7u40lTqzCGpC6CAbY6+vXhdhmwFRxZLMnRm6/sIF/7qMpT8MocXCRQfz0JAh63wpbXLMnsQ5162WS7Q==", - "requires": { - "envinfo": "^7.7.3" - } - }, - "@webpack-cli/serve": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.3.1.tgz", - "integrity": "sha512-0qXvpeYO6vaNoRBI52/UsbcaBydJCggoBBnIo/ovQQdn6fug0BgwsjorV1hVS7fMqGVTZGcVxv8334gjmbj5hw==" - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" - }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" - }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" - }, - "acorn": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.1.1.tgz", - "integrity": "sha512-xYiIVjNuqtKXMxlRMDc6mZUhXehod4a3gbZ1qRlM7icK4EbxUFNLhWoPblCvFtB2Y9CIqHP3CF/rdxLItaQv8g==" - }, - "acorn-jsx": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", - "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==" - }, - "aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==" - }, - "ansi-align": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", - "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", - "requires": { - "string-width": "^3.0.0" - }, - "dependencies": {} - }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==" - }, - "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==", - "requires": { - "type-fest": "^0.21.3" - }, - "dependencies": {} - }, - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "append-transform": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", - "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", - "requires": { - "default-require-extensions": "^3.0.0" - } - }, - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=" - }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "array-differ": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-2.1.0.tgz", - "integrity": "sha512-KbUpJgx909ZscOc/7CLATBFam7P1Z1QRQInvgT0UztM9Q72aGKCunKASAl7WNW0tnPmPyEMeMhdsfWhfmW037w==" - }, - "array-filter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz", - "integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=" - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==" - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" - }, - "asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - } - }, - "assert": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-2.0.0.tgz", - "integrity": "sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A==", - "requires": { - "es6-object-assign": "^1.1.0", - "is-nan": "^1.2.1", - "object-is": "^1.0.1", - "util": "^0.12.0" - } - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==" - }, - "astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==" - }, - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "requires": { - "lodash": "^4.17.14" - } - }, - "available-typed-arrays": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz", - "integrity": "sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ==", - "requires": { - "array-filter": "^1.0.0" - } - }, - "axios": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", - "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", - "requires": { - "follow-redirects": "^1.10.0" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "base-x": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz", - "integrity": "sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bip66": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", - "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", - "optional": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "blakejs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", - "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" - }, - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "boxen": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", - "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", - "requires": { - "ansi-align": "^3.0.0", - "camelcase": "^5.3.1", - "chalk": "^3.0.0", - "cli-boxes": "^2.2.0", - "string-width": "^4.1.0", - "term-size": "^2.1.0", - "type-fest": "^0.8.1", - "widest-line": "^3.1.0" - }, - "dependencies": {} - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "requires": { - "fill-range": "^7.0.1" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", - "requires": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - }, - "dependencies": {} - }, - "browserify-sign": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", - "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": {} - }, - "browserslist": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.4.tgz", - "integrity": "sha512-d7rCxYV8I9kj41RH8UKYnvDYCRENUlHRgyXy/Rhr/1BaeLGfiCptEdFE8MIrvGfWbBFNjVYx76SQWvNX1j+/cQ==", - "requires": { - "caniuse-lite": "^1.0.30001208", - "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.712", - "escalade": "^3.1.1", - "node-releases": "^1.1.71" - } - }, - "bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", - "requires": { - "base-x": "^3.0.2" - } - }, - "bs58check": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", - "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", - "requires": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" - } - }, - "buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=" - }, - "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==" - }, - "cacheable-request": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", - "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", - "requires": { - "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" - }, - "dependencies": {} - }, - "caching-transform": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", - "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", - "requires": { - "hasha": "^5.0.0", - "make-dir": "^3.0.0", - "package-hash": "^4.0.0", - "write-file-atomic": "^3.0.0" - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" - }, - "caniuse-lite": { - "version": "1.0.30001214", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001214.tgz", - "integrity": "sha512-O2/SCpuaU3eASWVaesQirZv1MSjUNOvmugaD8zNSJqw6Vv5SGwoOpA9LJs3pNPfM745nxqPvfZY3MQKY4AKHYg==" - }, - "chai": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", - "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=" - }, - "chokidar": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", - "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.3.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" - } - }, - "chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==" - }, - "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==" - }, - "cli-boxes": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", - "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==" - }, - "cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "requires": { - "restore-cursor": "^3.1.0" - } - }, - "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==", - "requires": { - "slice-ansi": "^3.0.0", - "string-width": "^4.2.0" - }, - "dependencies": {} - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "requires": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - } - }, - "clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "requires": { - "mimic-response": "^1.0.0" - } - }, - "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==", - "requires": { - "color-name": "~1.1.4" - } - }, - "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==" - }, - "colorette": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", - "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==" - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "comment-parser": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.1.2.tgz", - "integrity": "sha512-AOdq0i8ghZudnYv8RUnHrhTgafUGs61Rdz9jemU5x2lnZwAWyOq7vySo626K59e1fVKH1xSRorJwPVRLSWOoAQ==" - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" - }, - "compare-versions": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz", - "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "concurrently": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-6.0.2.tgz", - "integrity": "sha512-u+1Q0dJG5BidgUTpz9CU16yoHTt/oApFDQ3mbvHwSDgMjU7aGqy0q8ZQyaZyaNxdwRKTD872Ux3Twc6//sWA+Q==", - "requires": { - "chalk": "^4.1.0", - "date-fns": "^2.16.1", - "lodash": "^4.17.21", - "read-pkg": "^5.2.0", - "rxjs": "^6.6.3", - "spawn-command": "^0.0.2-1", - "supports-color": "^8.1.0", - "tree-kill": "^1.2.2", - "yargs": "^16.2.0" - }, - "dependencies": {} - }, - "configstore": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", - "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", - "requires": { - "dot-prop": "^5.2.0", - "graceful-fs": "^4.1.2", - "make-dir": "^3.0.0", - "unique-string": "^2.0.0", - "write-file-atomic": "^3.0.0", - "xdg-basedir": "^4.0.0" - } - }, - "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "requires": { - "safe-buffer": "~5.1.1" - }, - "dependencies": {} - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cosmiconfig": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", - "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==", - "requires": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - } - }, - "create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==" - }, - "date-fns": { - "version": "2.21.1", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.21.1.tgz", - "integrity": "sha512-m1WR0xGiC6j6jNFAyW4Nvh4WxAi4JF4w9jRJwSI8nBmNcyZXPcP9VUQG+6gHQXAmqaGEKDKhOqAtENDC941UkA==" - }, - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "requires": { - "ms": "2.1.2" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" - }, - "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==", - "requires": { - "mimic-response": "^3.1.0" - }, - "dependencies": {} - }, - "dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=" - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "requires": { - "type-detect": "^4.0.0" - } - }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" - }, - "default-require-extensions": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", - "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==", - "requires": { - "strip-bom": "^4.0.0" - } - }, - "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==" - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "requires": { - "object-keys": "^1.0.12" - } - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "requires": { - "path-type": "^4.0.0" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "requires": { - "esutils": "^2.0.2" - } - }, - "dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "requires": { - "is-obj": "^2.0.0" - }, - "dependencies": {} - }, - "drbg.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", - "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", - "optional": true, - "requires": { - "browserify-aes": "^1.0.6", - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4" - } - }, - "duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" - }, - "eccrypto": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/eccrypto/-/eccrypto-1.1.6.tgz", - "integrity": "sha512-d78ivVEzu7Tn0ZphUUaL43+jVPKTMPFGtmgtz1D0LrFn7cY3K8CdrvibuLz2AAkHBLKZtR8DMbB2ukRYFk987A==", - "requires": { - "acorn": "7.1.1", - "elliptic": "6.5.4", - "es6-promise": "4.2.8", - "nan": "2.14.0", - "secp256k1": "3.7.1" - }, - "dependencies": {} - }, - "electron-to-chromium": { - "version": "1.3.719", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.719.tgz", - "integrity": "sha512-heM78GKSqrIzO9Oz0/y22nTBN7bqSP1Pla2SyU9DiSnQD+Ea9SyyN5RWWlgqsqeBLNDkSlE9J9EHFmdMPzxB/g==" - }, - "elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "requires": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "email-addresses": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-3.1.0.tgz", - "integrity": "sha512-k0/r7GrWVL32kZlGwfPNgB2Y/mMXVTq/decgLczm/j34whdaspNrZO8CnXPf1laaHxI6ptUlsnAxN+UAPw+fzg==" - }, - "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==" - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" - }, - "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==", - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.0.tgz", - "integrity": "sha512-Sl3KRpJA8OpprrtaIswVki3cWPiPKxXuFxJXBp+zNb6s6VwNWwFRUdtmzd2ReUut8n+sCPx7QCtQ7w5wfJhSgQ==", - "requires": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - } - }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "requires": { - "ansi-colors": "^4.1.1" - } - }, - "envinfo": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", - "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==" - }, - "errno": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", - "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", - "requires": { - "prr": "~1.0.1" - } - }, - "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==", - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0.tgz", - "integrity": "sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw==", - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "is-callable": "^1.2.3", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.2", - "is-string": "^1.0.5", - "object-inspect": "^1.9.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.0" - } - }, - "es-module-lexer": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.4.1.tgz", - "integrity": "sha512-ooYciCUtfw6/d2w56UVeqHPcoCFAiJdz5XOkYpv/Txl1HMUozpXjz/2RIQgqwKdXNDPSF1W7mJCFse3G+HDyAA==" - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==" - }, - "es6-object-assign": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", - "integrity": "sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw=" - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" - }, - "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==" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "eslint": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.24.0.tgz", - "integrity": "sha512-k9gaHeHiFmGCDQ2rEfvULlSLruz6tgfA8DEn+rY9/oYPFFTlz55mM/Q/Rij1b2Y42jwZiK3lXvNTw6w6TXzcKQ==", - "requires": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash": "^4.17.21", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.4", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": {} - }, - "eslint-config-prettier": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.2.0.tgz", - "integrity": "sha512-dWV9EVeSo2qodOPi1iBYU/x6F6diHv8uujxbxr77xExs3zTAlNXvVZKiyLsQGNz7yPV2K49JY5WjPzNIuDc2Bw==" - }, - "eslint-plugin-jsdoc": { - "version": "32.3.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-32.3.0.tgz", - "integrity": "sha512-zyx7kajDK+tqS1bHuY5sapkad8P8KT0vdd/lE55j47VPG2MeenSYuIY/M/Pvmzq5g0+3JB+P3BJGUXmHxtuKPQ==", - "requires": { - "comment-parser": "1.1.2", - "debug": "^4.3.1", - "jsdoctypeparser": "^9.0.0", - "lodash": "^4.17.20", - "regextras": "^0.7.1", - "semver": "^7.3.4", - "spdx-expression-parse": "^3.0.1" - } - }, - "eslint-plugin-prefer-arrow": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-prefer-arrow/-/eslint-plugin-prefer-arrow-1.2.3.tgz", - "integrity": "sha512-J9I5PKCOJretVuiZRGvPQxCbllxGAV/viI20JO3LYblAodofBxyMnZAJ+WGeClHgANnSJberTNoFWWjrWKBuXQ==" - }, - "eslint-plugin-prettier": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.0.tgz", - "integrity": "sha512-UDK6rJT6INSfcOo545jiaOwB701uAIt2/dR7WnFQoGCVl1/EMqdANBmwUaqqQ45aXprsTGzSa39LI1PyuRBxxw==", - "requires": { - "prettier-linter-helpers": "^1.0.0" - } - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "requires": { - "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": {} - }, - "eslint-visitor-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", - "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==" - }, - "espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "requires": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "dependencies": {} - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "requires": { - "estraverse": "^5.1.0" - }, - "dependencies": {} - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "requires": { - "estraverse": "^5.2.0" - }, - "dependencies": {} - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" - }, - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", - "requires": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==" - }, - "fast-glob": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", - "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", - "merge2": "^1.3.0", - "micromatch": "^4.0.2", - "picomatch": "^2.2.1" - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" - }, - "fastest-levenshtein": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", - "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==" - }, - "fastq": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", - "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==", - "requires": { - "reusify": "^1.0.4" - } - }, - "figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "requires": { - "flat-cache": "^3.0.4" - } - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "optional": true - }, - "filename-reserved-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-1.0.0.tgz", - "integrity": "sha1-5hz4BfDeHJhFZ9A4bcXfUO5a9+Q=" - }, - "filenamify": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-1.2.1.tgz", - "integrity": "sha1-qfL/0RxQO+0wABUCknI3jx8TZaU=", - "requires": { - "filename-reserved-regex": "^1.0.0", - "strip-outer": "^1.0.0", - "trim-repeated": "^1.0.0" - } - }, - "filenamify-url": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/filenamify-url/-/filenamify-url-1.0.0.tgz", - "integrity": "sha1-syvYExnvWGO3MHi+1Q9GpPeXX1A=", - "requires": { - "filenamify": "^1.0.0", - "humanize-url": "^1.0.0" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-cache-dir": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", - "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", - "requires": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "find-versions": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-4.0.0.tgz", - "integrity": "sha512-wgpWy002tA+wgmO27buH/9KzyEOQnKsG/R0yrcjPT9BOFm0zRBVQbZ95nRGXWMywS8YR5knRbpohio0bcJABxQ==", - "requires": { - "semver-regex": "^3.1.2" - } - }, - "flat": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", - "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", - "requires": { - "is-buffer": "~2.0.3" - } - }, - "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", - "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==" - }, - "follow-redirects": { - "version": "1.13.3", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.3.tgz", - "integrity": "sha512-DUgl6+HDzB0iEptNQEXLx/KhTmDb8tZUHSeLqpnjpknR70H0nC2t9N73BK6fN4hOvJ84pKlIQVQ4k5FFlBedKA==" - }, - "foreach": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" - }, - "foreground-child": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", - "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", - "requires": { - "cross-spawn": "^7.0.0", - "signal-exit": "^3.0.2" - } - }, - "fromentries": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", - "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==" - }, - "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==", - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" - }, - "gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" - }, - "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==" - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=" - }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "get-own-enumerable-property-symbols": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", - "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" - }, - "get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==" - }, - "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==", - "requires": { - "pump": "^3.0.0" - } - }, - "gh-pages": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-3.1.0.tgz", - "integrity": "sha512-3b1rly9kuf3/dXsT8+ZxP0UhNLOo1CItj+3e31yUVcaph/yDsJ9RzD7JOw5o5zpBTJVQLlJAASNkUfepi9fe2w==", - "requires": { - "async": "^2.6.1", - "commander": "^2.18.0", - "email-addresses": "^3.0.1", - "filenamify-url": "^1.0.0", - "find-cache-dir": "^3.3.1", - "fs-extra": "^8.1.0", - "globby": "^6.1.0" - }, - "dependencies": {} - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "requires": { - "is-glob": "^4.0.1" - } - }, - "glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" - }, - "global-dirs": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.1.0.tgz", - "integrity": "sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==", - "requires": { - "ini": "1.3.7" - } - }, - "globals": { - "version": "13.8.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.8.0.tgz", - "integrity": "sha512-rHtdA6+PDBIjeEvA91rpqzEvk/k3/i7EeNQiryiWuJH0Hw9cpyJMAt2jtbAwUaRdhD+573X4vWw6IcjKPasi9Q==", - "requires": { - "type-fest": "^0.20.2" - }, - "dependencies": {} - }, - "globby": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz", - "integrity": "sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==", - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - } - }, - "google-protobuf": { - "version": "3.15.8", - "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.15.8.tgz", - "integrity": "sha512-2jtfdqTaSxk0cuBJBtTTWsot4WtR9RVr2rXg7x7OoqiuOKopPrwXpM1G4dXIkLcUNRh3RKzz76C8IOkksZSeOw==" - }, - "got": { - "version": "11.8.2", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.2.tgz", - "integrity": "sha512-D0QywKgIe30ODs+fm8wMZiAcZjypcCodPNuMz5H9Mny7RJ+IjJ10BdmGW7OM7fHXP+O7r6ZwapQ/YQmMSvB0UQ==", - "requires": { - "@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.1", - "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" - } - }, - "graceful-fs": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==" - }, - "handlebars": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", - "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", - "requires": { - "minimist": "^1.2.5", - "neo-async": "^2.6.0", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4", - "wordwrap": "^1.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" - }, - "has-yarn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", - "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==" - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "hasha": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", - "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", - "requires": { - "is-stream": "^2.0.0", - "type-fest": "^0.8.0" - }, - "dependencies": {} - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "highlight.js": { - "version": "10.7.2", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.2.tgz", - "integrity": "sha512-oFLl873u4usRM9K63j4ME9u3etNF0PLiJhSQ8rdfuL51Wn3zkD6drf9ZW0dOzjnZI22YYG24z30JcmfCZjMgYg==" - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "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==" - }, - "html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" - }, - "http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" - }, - "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==", - "requires": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.0.0" - } - }, - "human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==" - }, - "humanize-duration": { - "version": "3.25.2", - "resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.25.2.tgz", - "integrity": "sha512-zSerjahuzBazDaE8skjMI7Xmrt/EirvW5cDsXgysx8tYIjcgCMnI5Y5985y3LxYeLah9L5cQY3WEw1k7GRWbfg==" - }, - "humanize-url": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/humanize-url/-/humanize-url-1.0.1.tgz", - "integrity": "sha1-9KuZ4NKIF0yk4eUEB8VfuuRk7/8=", - "requires": { - "normalize-url": "^1.0.0", - "strip-url-auth": "^1.0.0" - } - }, - "husky": { - "version": "4.3.8", - "resolved": "https://registry.npmjs.org/husky/-/husky-4.3.8.tgz", - "integrity": "sha512-LCqqsB0PzJQ/AlCgfrfzRe3e3+NvmefAdKQhRYpxS4u6clblBoDdzzvHi8fmxKRzvMxPY/1WZWzomPZww0Anow==", - "requires": { - "chalk": "^4.0.0", - "ci-info": "^2.0.0", - "compare-versions": "^3.6.0", - "cosmiconfig": "^7.0.0", - "find-versions": "^4.0.0", - "opencollective-postinstall": "^2.0.2", - "pkg-dir": "^5.0.0", - "please-upgrade-node": "^3.2.0", - "slash": "^3.0.0", - "which-pm-runs": "^1.0.0" - }, - "dependencies": {} - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" - }, - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==" - }, - "ignore-by-default": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=" - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "import-lazy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", - "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=" - }, - "import-local": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", - "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", - "requires": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" - }, - "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==" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ini": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", - "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==" - }, - "interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==" - }, - "is-arguments": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", - "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==", - "requires": { - "call-bind": "^1.0.0" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" - }, - "is-bigint": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.1.tgz", - "integrity": "sha512-J0ELF4yHFxHy0cmSxZuheDOz2luOdVvqjwmEcj8H/L1JHeuEDSDbeRP+Dk9kFVk5RTFzbucJ2Kb9F7ixY2QaCg==" - }, - "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==", - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-boolean-object": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.0.tgz", - "integrity": "sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA==", - "requires": { - "call-bind": "^1.0.0" - } - }, - "is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==" - }, - "is-callable": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", - "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==" - }, - "is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "requires": { - "ci-info": "^2.0.0" - } - }, - "is-core-module": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", - "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", - "requires": { - "has": "^1.0.3" - } - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==" - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" - }, - "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==" - }, - "is-generator-function": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.8.tgz", - "integrity": "sha512-2Omr/twNtufVZFr1GhxjOMFPAj2sjc/dKaIqBhvo4qciXfJmITGH6ZGd8eZYNHza8t1y0e01AuqRhJwfWp26WQ==" - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-installed-globally": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", - "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", - "requires": { - "global-dirs": "^2.0.1", - "is-path-inside": "^3.0.1" - } - }, - "is-nan": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", - "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - } - }, - "is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==" - }, - "is-npm": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", - "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==" - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" - }, - "is-number-object": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz", - "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==" - }, - "is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" - }, - "is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==" - }, - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "requires": { - "isobject": "^3.0.1" - } - }, - "is-regex": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", - "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", - "requires": { - "call-bind": "^1.0.2", - "has-symbols": "^1.0.1" - } - }, - "is-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=" - }, - "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" - }, - "is-string": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", - "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==" - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typed-array": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.5.tgz", - "integrity": "sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug==", - "requires": { - "available-typed-arrays": "^1.0.2", - "call-bind": "^1.0.2", - "es-abstract": "^1.18.0-next.2", - "foreach": "^2.0.5", - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" - }, - "is-yarn-global": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", - "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - }, - "isomorphic-fetch": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", - "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", - "requires": { - "node-fetch": "^2.6.1", - "whatwg-fetch": "^3.4.1" - } - }, - "isomorphic-ws": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", - "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==" - }, - "istanbul-lib-coverage": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", - "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==" - }, - "istanbul-lib-hook": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", - "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", - "requires": { - "append-transform": "^2.0.0" - } - }, - "istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", - "requires": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - }, - "dependencies": {} - }, - "istanbul-lib-processinfo": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz", - "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==", - "requires": { - "archy": "^1.0.0", - "cross-spawn": "^7.0.0", - "istanbul-lib-coverage": "^3.0.0-alpha.1", - "make-dir": "^3.0.0", - "p-map": "^3.0.0", - "rimraf": "^3.0.0", - "uuid": "^3.3.3" - }, - "dependencies": {} - }, - "istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "requires": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - } - }, - "istanbul-lib-source-maps": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", - "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - } - }, - "istanbul-reports": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", - "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", - "requires": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - } - }, - "jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - } - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbi": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/jsbi/-/jsbi-3.1.4.tgz", - "integrity": "sha512-52QRRFSsi9impURE8ZUbzAMCLjPm4THO7H2fcuIvaaeFTbSysvkodbQQXIVsNgq/ypDbq6dJiuGKL0vZ/i9hUg==" - }, - "jsdoctypeparser": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/jsdoctypeparser/-/jsdoctypeparser-9.0.0.tgz", - "integrity": "sha512-jrTA2jJIL6/DAEILBEh2/w9QxCuwmvNXIry39Ay/HVfhE3o2yVV0U44blYkqdHA/OKloJEqvJy0xU+GSdE2SIw==" - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" - }, - "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==" - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" - }, - "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==" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=" - }, - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "requires": { - "minimist": "^1.2.5" - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "keccak": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.1.tgz", - "integrity": "sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA==", - "requires": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - } - }, - "key-encoder": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/key-encoder/-/key-encoder-2.0.3.tgz", - "integrity": "sha512-fgBtpAGIr/Fy5/+ZLQZIPPhsZEcbSlYu/Wu96tNDFNSjSACw5lEIOFeaVdQ/iwrb8oxjlWi6wmWdH76hV6GZjg==", - "requires": { - "@types/elliptic": "^6.4.9", - "asn1.js": "^5.0.1", - "bn.js": "^4.11.8", - "elliptic": "^6.4.1" - } - }, - "keyv": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.3.tgz", - "integrity": "sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA==", - "requires": { - "json-buffer": "3.0.1" - } - }, - "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==" - }, - "latest-version": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", - "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", - "requires": { - "package-json": "^6.3.0" - } - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=" - }, - "lint-staged": { - "version": "10.5.4", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-10.5.4.tgz", - "integrity": "sha512-EechC3DdFic/TdOPgj/RB3FicqE6932LTHCUm0Y2fsD9KGlLB+RwJl2q1IYBIvEsKzDOgn0D4gll+YxG5RsrKg==", - "requires": { - "chalk": "^4.1.0", - "cli-truncate": "^2.1.0", - "commander": "^6.2.0", - "cosmiconfig": "^7.0.0", - "debug": "^4.2.0", - "dedent": "^0.7.0", - "enquirer": "^2.3.6", - "execa": "^4.1.0", - "listr2": "^3.2.2", - "log-symbols": "^4.0.0", - "micromatch": "^4.0.2", - "normalize-path": "^3.0.0", - "please-upgrade-node": "^3.2.0", - "string-argv": "0.3.1", - "stringify-object": "^3.3.0" - }, - "dependencies": {} - }, - "listr2": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.7.1.tgz", - "integrity": "sha512-cNd368GTrk8351/ov/IV+BSwyf9sJRgI0UIvfORonCZA1u9UHAtAlqSEv9dgafoQIA1CgB3nu4No79pJtK2LHw==", - "requires": { - "chalk": "^4.1.0", - "cli-truncate": "^2.1.0", - "figures": "^3.2.0", - "indent-string": "^4.0.0", - "log-update": "^4.0.0", - "p-map": "^4.0.0", - "rxjs": "^6.6.7", - "through": "^2.3.8", - "wrap-ansi": "^7.0.0" - } - }, - "loader-runner": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", - "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==" - }, - "loader-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", - "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "requires": { - "p-locate": "^4.1.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=" - }, - "lodash.flattendeep": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=" - }, - "lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=" - }, - "log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "requires": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - } - }, - "log-update": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", - "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", - "requires": { - "ansi-escapes": "^4.3.0", - "cli-cursor": "^3.1.0", - "slice-ansi": "^4.0.0", - "wrap-ansi": "^6.2.0" - }, - "dependencies": {} - }, - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" - }, - "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==", - "requires": { - "yallist": "^4.0.0" - } - }, - "lunr": { - "version": "2.3.9", - "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", - "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==" - }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "requires": { - "semver": "^6.0.0" - }, - "dependencies": {} - }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" - }, - "marked": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-1.0.0.tgz", - "integrity": "sha512-Wo+L1pWTVibfrSr+TTtMuiMfNzmZWiOPeO7rZsQUY5bgsxpHesBEcIWJloWVTFnrMXnf/TL30eTFSGJddmQAng==" - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "dependencies": {} - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" - }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - } - }, - "mime-db": { - "version": "1.47.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", - "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==" - }, - "mime-types": { - "version": "2.1.30", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", - "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", - "requires": { - "mime-db": "1.47.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" - }, - "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, - "mkdirp": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz", - "integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==", - "requires": { - "minimist": "^1.2.5" - } - }, - "mocha": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.3.tgz", - "integrity": "sha512-0R/3FvjIGH3eEuG17ccFPk117XL2rWxatr81a57D+r/x2uTYZRbdZ4oVidEUMh2W2TJDa7MdAb12Lm2/qrKajg==", - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "2.2.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.4", - "ms": "2.1.1", - "node-environment-flags": "1.0.5", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "dependencies": {} - }, - "mri": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.1.6.tgz", - "integrity": "sha512-oi1b3MfbyGa7FJMP9GmLTttni5JoICpYBRlq+x5V16fZbLsnL9N3wFqqIm/nIG43FjUFkFh9Epzp/kzUGUnJxQ==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "multimatch": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-3.0.0.tgz", - "integrity": "sha512-22foS/gqQfANZ3o+W7ST2x25ueHDVNWl/b9OlGcLpy/iKxjCpvcNCM51YCenUi7Mt/jAjjqv8JwZRs8YP5sRjA==", - "requires": { - "array-differ": "^2.0.3", - "array-union": "^1.0.2", - "arrify": "^1.0.1", - "minimatch": "^3.0.4" - }, - "dependencies": {} - }, - "nan": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" - }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" - }, - "node-addon-api": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" - }, - "node-environment-flags": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", - "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==", - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": {} - }, - "node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" - }, - "node-gyp-build": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", - "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==" - }, - "node-preload": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", - "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", - "requires": { - "process-on-spawn": "^1.0.0" - } - }, - "node-releases": { - "version": "1.1.71", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz", - "integrity": "sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==" - }, - "nodemon": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.7.tgz", - "integrity": "sha512-XHzK69Awgnec9UzHr1kc8EomQh4sjTQ8oRf8TsGrSmHDx9/UmiGG9E/mM3BuTfNeFwdNBvrqQq/RHL0xIeyFOA==", - "requires": { - "chokidar": "^3.2.2", - "debug": "^3.2.6", - "ignore-by-default": "^1.0.1", - "minimatch": "^3.0.4", - "pstree.remy": "^1.1.7", - "semver": "^5.7.1", - "supports-color": "^5.5.0", - "touch": "^3.1.0", - "undefsafe": "^2.0.3", - "update-notifier": "^4.1.0" - }, - "dependencies": {} - }, - "nopt": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", - "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", - "requires": { - "abbrev": "1" - } - }, - "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==", - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - }, - "dependencies": {} - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" - }, - "normalize-url": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", - "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", - "requires": { - "object-assign": "^4.0.1", - "prepend-http": "^1.0.0", - "query-string": "^4.1.0", - "sort-keys": "^1.0.0" - } - }, - "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==", - "requires": { - "path-key": "^3.0.0" - } - }, - "nyc": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", - "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", - "requires": { - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "caching-transform": "^4.0.0", - "convert-source-map": "^1.7.0", - "decamelize": "^1.2.0", - "find-cache-dir": "^3.2.0", - "find-up": "^4.1.0", - "foreground-child": "^2.0.0", - "get-package-type": "^0.1.0", - "glob": "^7.1.6", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-hook": "^3.0.0", - "istanbul-lib-instrument": "^4.0.0", - "istanbul-lib-processinfo": "^2.0.2", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "make-dir": "^3.0.0", - "node-preload": "^0.2.1", - "p-map": "^3.0.0", - "process-on-spawn": "^1.0.0", - "resolve-from": "^5.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "spawn-wrap": "^2.0.0", - "test-exclude": "^6.0.0", - "yargs": "^15.0.2" - }, - "dependencies": {} - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "object-inspect": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.2.tgz", - "integrity": "sha512-gz58rdPpadwztRrPjZE9DZLOABUpTGdcANUgOwBFO1C+HZZhePoP83M65WGDmbpwFYJSWqavbl4SgDn4k8RYTA==" - }, - "object-is": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", - "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" - }, - "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz", - "integrity": "sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "opencollective-postinstall": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz", - "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==" - }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - } - }, - "p-cancelable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==" - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "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==", - "requires": { - "p-limit": "^2.2.0" - }, - "dependencies": {} - }, - "p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "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==" - }, - "package-hash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", - "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", - "requires": { - "graceful-fs": "^4.1.15", - "hasha": "^5.0.0", - "lodash.flattendeep": "^4.4.0", - "release-zalgo": "^1.0.0" - } - }, - "package-json": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", - "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", - "requires": { - "got": "^9.6.0", - "registry-auth-token": "^4.0.0", - "registry-url": "^5.0.0", - "semver": "^6.2.0" - }, - "dependencies": {} - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", - "requires": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "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==", - "requires": { - "@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" - } - }, - "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==" - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" - }, - "pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==" - }, - "pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "picomatch": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", - "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==" - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "requires": { - "find-up": "^4.0.0" - } - }, - "please-upgrade-node": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", - "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", - "requires": { - "semver-compare": "^1.0.0" - } - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" - }, - "prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" - }, - "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==" - }, - "prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "requires": { - "fast-diff": "^1.1.2" - } - }, - "pretty-quick": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-1.11.1.tgz", - "integrity": "sha512-kSXCkcETfak7EQXz6WOkCeCqpbC4GIzrN/vaneTGMP/fAtD8NerA9bPhCUqHAks1geo7biZNl5uEMPceeneLuA==", - "requires": { - "chalk": "^2.3.0", - "execa": "^0.8.0", - "find-up": "^2.1.0", - "ignore": "^3.3.7", - "mri": "^1.1.0", - "multimatch": "^3.0.0" - }, - "dependencies": {} - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" - }, - "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==" - }, - "process-on-spawn": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", - "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", - "requires": { - "fromentries": "^1.2.0" - } - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" - }, - "pstree.remy": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", - "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "pupa": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", - "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", - "requires": { - "escape-goat": "^2.0.0" - } - }, - "query-string": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", - "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", - "requires": { - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - } - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" - }, - "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==" - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": {} - }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - } - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", - "requires": { - "picomatch": "^2.2.1" - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "requires": { - "resolve": "^1.1.6" - } - }, - "reflect-metadata": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", - "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" - }, - "regexpp": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", - "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==" - }, - "regextras": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/regextras/-/regextras-0.7.1.tgz", - "integrity": "sha512-9YXf6xtW+qzQ+hcMQXx95MOvfqXFgsKDZodX3qZB0x2n5Z94ioetIITsBtvJbiOyxa/6s9AtyweBLCdPmPko/w==" - }, - "registry-auth-token": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", - "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", - "requires": { - "rc": "^1.2.8" - } - }, - "registry-url": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", - "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", - "requires": { - "rc": "^1.2.8" - } - }, - "release-zalgo": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", - "requires": { - "es6-error": "^4.0.1" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" - }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" - }, - "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", - "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - } - }, - "resolve-alpn": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.1.2.tgz", - "integrity": "sha512-8OyfzhAtA32LVUsJSke3auIyINcwdh5l3cvYKdKO0nvsYSKuiLfTM5i78PJswFPT8y6cPW+L1v6/hE95chcpDA==" - }, - "resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "requires": { - "resolve-from": "^5.0.0" - }, - "dependencies": {} - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" - }, - "responselike": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", - "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", - "requires": { - "lowercase-keys": "^2.0.0" - } - }, - "restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "requires": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - } - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "requires": { - "glob": "^7.1.3" - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "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==", - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "requires": { - "tslib": "^1.9.0" - } - }, - "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==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "schema-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", - "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", - "requires": { - "@types/json-schema": "^7.0.6", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - }, - "scrypt-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" - }, - "secp256k1": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz", - "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==", - "requires": { - "elliptic": "^6.5.2", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - } - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "requires": { - "lru-cache": "^6.0.0" - } - }, - "semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=" - }, - "semver-diff": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", - "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", - "requires": { - "semver": "^6.3.0" - }, - "dependencies": {} - }, - "semver-regex": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-3.1.2.tgz", - "integrity": "sha512-bXWyL6EAKOJa81XG1OZ/Yyuq+oT0b2YLlxx7c+mrdYPaPbnj6WgVULXhinMIeZGufuUBu/eVRqXEhiv4imfwxA==" - }, - "serialize-javascript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", - "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", - "requires": { - "randombytes": "^2.1.0" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "requires": { - "kind-of": "^6.0.2" - } - }, - "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==", - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" - }, - "shelljs": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz", - "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==", - "requires": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - } - }, - "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" - }, - "slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - } - }, - "sort-keys": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", - "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", - "requires": { - "is-plain-obj": "^1.0.0" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" - }, + } + } + }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==" + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "optional": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" + }, + "graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "humanize-duration": { + "version": "3.27.0", + "resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.27.0.tgz", + "integrity": "sha512-qLo/08cNc3Tb0uD7jK0jAcU5cnqCM0n568918E7R2XhMr/+7F37p4EY062W/stg7tmzvknNn9b/1+UhVRzsYrQ==" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "isomorphic-fetch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", + "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", + "requires": { + "node-fetch": "^2.6.1", + "whatwg-fetch": "^3.4.1" + } + }, + "isomorphic-ws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", + "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==" + }, + "jest-worker": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.0.6.tgz", + "integrity": "sha512-qupxcj/dRuA3xHPMUd40gr2EaAurFbkwzOh7wfPaeE9id7hyjURRQoqNfHifHK3XjJU6YJJUQKILGUnwGPEOCA==", + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + } + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "keccak": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.1.tgz", + "integrity": "sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA==", + "requires": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + } + }, + "key-encoder": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/key-encoder/-/key-encoder-2.0.3.tgz", + "integrity": "sha512-fgBtpAGIr/Fy5/+ZLQZIPPhsZEcbSlYu/Wu96tNDFNSjSACw5lEIOFeaVdQ/iwrb8oxjlWi6wmWdH76hV6GZjg==", + "requires": { + "@types/elliptic": "^6.4.9", + "asn1.js": "^5.0.1", + "bn.js": "^4.11.8", + "elliptic": "^6.4.1" + } + }, + "loader-runner": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", + "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==" + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "mime-db": { + "version": "1.48.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", + "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==" + }, + "mime-types": { + "version": "2.1.31", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", + "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", + "requires": { + "mime-db": "1.48.0" + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" + }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + }, + "node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" + }, + "node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" + }, + "node-gyp-build": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", + "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==" + }, + "node-releases": { + "version": "1.1.73", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz", + "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "requires": { + "fast-diff": "^1.1.2" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "reflect-metadata": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", + "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "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==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "schema-utils": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", + "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + }, + "scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" + }, + "secp256k1": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.7.1.tgz", + "integrity": "sha512-1cf8sbnRreXrQFdH6qsg2H71Xw91fCCS9Yp021GnUNJzWJS/py96fS4lHbnTnouLp08Xj6jBoBB6V78Tdbdu5g==", + "optional": true, + "requires": { + "bindings": "^1.5.0", + "bip66": "^1.1.5", + "bn.js": "^4.11.8", + "create-hash": "^1.2.0", + "drbg.js": "^1.0.1", + "elliptic": "^6.4.1", + "nan": "^2.14.0", + "safe-buffer": "^5.1.2" + } + }, + "serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "requires": { + "randombytes": "^2.1.0" + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "strict-event-emitter-types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strict-event-emitter-types/-/strict-event-emitter-types-2.0.0.tgz", + "integrity": "sha512-Nk/brWYpD85WlOgzw5h173aci0Teyv8YdIAEtV+N88nDB0dLlazZyJMIsN6eo1/AR61l+p6CJTG1JIyFaoNEEA==" + }, + "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==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "tapable": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", + "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==" + }, + "terser": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.7.1.tgz", + "integrity": "sha512-b3e+d5JbHAe/JSjwsC3Zn55wsBIM7AsHLjKxT31kGCldgbpFePaFo+PiddtO6uwRZWRw7sPXmAN8dTW61xmnSg==", + "requires": { + "commander": "^2.20.0", + "source-map": "~0.7.2", + "source-map-support": "~0.5.19" + }, + "dependencies": { "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "spawn-command": { - "version": "0.0.2-1", - "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", - "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=" - }, - "spawn-wrap": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", - "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", - "requires": { - "foreground-child": "^2.0.0", - "is-windows": "^1.0.2", - "make-dir": "^3.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "which": "^2.0.1" - }, - "dependencies": {} - }, - "spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==" - }, - "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==", - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz", - "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==" - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "stream-browserify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", - "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", - "requires": { - "inherits": "~2.0.4", - "readable-stream": "^3.5.0" - } - }, - "stream-http": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz", - "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==", - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "xtend": "^4.0.2" - } - }, - "strict-event-emitter-types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strict-event-emitter-types/-/strict-event-emitter-types-2.0.0.tgz", - "integrity": "sha512-Nk/brWYpD85WlOgzw5h173aci0Teyv8YdIAEtV+N88nDB0dLlazZyJMIsN6eo1/AR61l+p6CJTG1JIyFaoNEEA==" - }, - "strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" - }, - "string-argv": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", - "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==" - }, - "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "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==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "stringify-object": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", - "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", - "requires": { - "get-own-enumerable-property-symbols": "^3.0.0", - "is-obj": "^1.0.1", - "is-regexp": "^1.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "requires": { - "ansi-regex": "^5.0.0" - } - }, - "strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" - }, - "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" - }, - "strip-outer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", - "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", - "requires": { - "escape-string-regexp": "^1.0.2" - } - }, - "strip-url-auth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-url-auth/-/strip-url-auth-1.0.1.tgz", - "integrity": "sha1-IrD6OkE4WzO+PzMVUbu4N/oM164=" - }, - "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==", - "requires": { - "has-flag": "^4.0.0" - } - }, - "table": { - "version": "6.3.2", - "resolved": "https://registry.npmjs.org/table/-/table-6.3.2.tgz", - "integrity": "sha512-I9/Ca6Huf2oxFag7crD0DhA+arIdfLtWunSn0NIXSzjtUlDgIBGVZY7SsMkNPNT3Psd/z4gza0nuEpmra9eRbg==", - "requires": { - "ajv": "^8.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "lodash.clonedeep": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.0" - }, - "dependencies": {} - }, - "tapable": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", - "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==" - }, - "term-size": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", - "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==" - }, - "terser": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.6.1.tgz", - "integrity": "sha512-yv9YLFQQ+3ZqgWCUk+pvNJwgUTdlIxUk1WTN+RnaFJe2L7ipG2csPT0ra2XRm7Cs8cxN7QXmK1rFzEwYEQkzXw==", - "requires": { - "commander": "^2.20.0", - "source-map": "~0.7.2", - "source-map-support": "~0.5.19" - }, - "dependencies": {} - }, - "terser-webpack-plugin": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.1.tgz", - "integrity": "sha512-5XNNXZiR8YO6X6KhSGXfY0QrGrCRlSwAEjIIrlRQR4W8nP69TaJUlh3bkuac6zzgspiGPfKEHcY295MMVExl5Q==", - "requires": { - "jest-worker": "^26.6.2", - "p-limit": "^3.1.0", - "schema-utils": "^3.0.0", - "serialize-javascript": "^5.0.1", - "source-map": "^0.6.1", - "terser": "^5.5.1" - } - }, - "test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "requires": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" - }, - "to-readable-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==" - }, - "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==", - "requires": { - "is-number": "^7.0.0" - } - }, - "touch": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", - "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", - "requires": { - "nopt": "~1.0.10" - } - }, - "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==" - }, - "trim-repeated": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", - "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=", - "requires": { - "escape-string-regexp": "^1.0.2" - } - }, - "ts-loader": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-8.1.0.tgz", - "integrity": "sha512-YiQipGGAFj2zBfqLhp28yUvPP9jUGqHxRzrGYuc82Z2wM27YIHbElXiaZDc93c3x0mz4zvBmS6q/DgExpdj37A==", - "requires": { - "chalk": "^4.1.0", - "enhanced-resolve": "^4.0.0", - "loader-utils": "^2.0.0", - "micromatch": "^4.0.0", - "semver": "^7.3.4" - }, - "dependencies": {} - }, - "ts-node": { - "version": "8.10.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz", - "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==", - "requires": { - "arg": "^4.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "source-map-support": "^0.5.17", - "yn": "3.1.1" - }, - "dependencies": {} - }, - "ts-protoc-gen": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/ts-protoc-gen/-/ts-protoc-gen-0.10.0.tgz", - "integrity": "sha512-EEbgDWNHK3CvcNhmib94I4HMO23qLddjLRdXW8EUE11VJxbi3n5J0l2DiX/L1pijOaPTkbEoRK+zQinKgKGqsw==", - "requires": { - "google-protobuf": "^3.6.1" - } - }, - "ts-results": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ts-results/-/ts-results-3.2.1.tgz", - "integrity": "sha512-cMvWPLvxM39fSQgSHRT2d+dwQfpK+ttfj5FpPuXum9m/pm6iDmgsirpWXp/3/ErmZqx1x+rAhJi/33NQqCCM3Q==" - }, - "tsconfig-paths": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", - "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", - "requires": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.0", - "strip-bom": "^3.0.0" - }, - "dependencies": {} - }, + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" + } + } + }, + "terser-webpack-plugin": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.4.tgz", + "integrity": "sha512-C2WkFwstHDhVEmsmlCxrXUtVklS+Ir1A7twrYzrDrQQOIMOaVAYykaoo/Aq1K0QRkMoY2hhvDQY1cm4jnIMFwA==", + "requires": { + "jest-worker": "^27.0.2", + "p-limit": "^3.1.0", + "schema-utils": "^3.0.0", + "serialize-javascript": "^6.0.0", + "source-map": "^0.6.1", + "terser": "^5.7.0" + } + }, + "ts-results": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ts-results/-/ts-results-3.3.0.tgz", + "integrity": "sha512-FWqxGX2NHp5oCyaMd96o2y2uMQmSu8Dey6kvyuFdRJ2AzfmWo3kWa4UsPlCGlfQ/qu03m09ZZtppMoY8EMHuiA==" + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "tweetnacl-ts": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl-ts/-/tweetnacl-ts-1.0.3.tgz", + "integrity": "sha512-C5I/dWf6xjAXaCDlf84T4HvozU/8ycAlq5WRllF1hAeeq5390tfXD+bNas5bhEV0HMSOx8bsQYpLjPl8wfnEeQ==", + "requires": { + "tslib": "^1" + } + }, + "tweetnacl-util": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", + "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==" + }, + "typedjson": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/typedjson/-/typedjson-1.7.0.tgz", + "integrity": "sha512-MnRgQLwtEcdHqQG0FkT8ebpBG53Wgr/axYRbiD2WL5NcYx8Z2AoCpXvtTfLnuPqOBKG/9JpXq0O/nl2m4wqJYw==", + "requires": { + "tslib": "^2.0.1" + }, + "dependencies": { "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "tslint": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz", - "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==", - "requires": { - "@babel/code-frame": "^7.0.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.3.0", - "commander": "^2.12.1", - "diff": "^4.0.1", - "glob": "^7.1.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.3", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.13.0", - "tsutils": "^2.29.0" - }, - "dependencies": {} - }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "requires": { - "tslib": "^1.8.1" - } - }, - "tweetnacl-ts": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl-ts/-/tweetnacl-ts-1.0.3.tgz", - "integrity": "sha512-C5I/dWf6xjAXaCDlf84T4HvozU/8ycAlq5WRllF1hAeeq5390tfXD+bNas5bhEV0HMSOx8bsQYpLjPl8wfnEeQ==", - "requires": { - "tslib": "^1" - } - }, - "tweetnacl-util": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", - "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==" - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" - }, - "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==" - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "typedjson": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/typedjson/-/typedjson-1.7.0.tgz", - "integrity": "sha512-MnRgQLwtEcdHqQG0FkT8ebpBG53Wgr/axYRbiD2WL5NcYx8Z2AoCpXvtTfLnuPqOBKG/9JpXq0O/nl2m4wqJYw==", - "requires": { - "tslib": "^2.0.1" - }, - "dependencies": {} - }, - "typedoc": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.17.8.tgz", - "integrity": "sha512-/OyrHCJ8jtzu+QZ+771YaxQ9s4g5Z3XsQE3Ma7q+BL392xxBn4UMvvCdVnqKC2T/dz03/VXSLVKOP3lHmDdc/w==", - "requires": { - "fs-extra": "^8.1.0", - "handlebars": "^4.7.6", - "highlight.js": "^10.0.0", - "lodash": "^4.17.15", - "lunr": "^2.3.8", - "marked": "1.0.0", - "minimatch": "^3.0.0", - "progress": "^2.0.3", - "shelljs": "^0.8.4", - "typedoc-default-themes": "^0.10.2" - } - }, - "typedoc-default-themes": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/typedoc-default-themes/-/typedoc-default-themes-0.10.2.tgz", - "integrity": "sha512-zo09yRj+xwLFE3hyhJeVHWRSPuKEIAsFK5r2u47KL/HBKqpwdUSanoaz5L34IKiSATFrjG5ywmIu98hPVMfxZg==", - "requires": { - "lunr": "^2.3.8" - } - }, - "typescript": { - "version": "3.9.9", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.9.tgz", - "integrity": "sha512-kdMjTiekY+z/ubJCATUPlRDl39vXYiMV9iyeMuEuXZh2we6zz80uovNN2WlAxmmdE/Z/YQe+EbOEXB5RHEED3w==" - }, - "uglify-js": { - "version": "3.13.4", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.4.tgz", - "integrity": "sha512-kv7fCkIXyQIilD5/yQy8O+uagsYIOt5cZvs890W40/e/rvjMSzJw81o9Bg0tkURxzZBROtDQhW2LFjOGoK3RZw==", - "optional": true - }, - "unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - } - }, - "undefsafe": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz", - "integrity": "sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==", - "requires": { - "debug": "^2.2.0" - }, - "dependencies": {} - }, - "unique-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "requires": { - "crypto-random-string": "^2.0.0" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "update-notifier": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", - "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==", - "requires": { - "boxen": "^4.2.0", - "chalk": "^3.0.0", - "configstore": "^5.0.1", - "has-yarn": "^2.1.0", - "import-lazy": "^2.1.0", - "is-ci": "^2.0.0", - "is-installed-globally": "^0.3.1", - "is-npm": "^4.0.0", - "is-yarn-global": "^0.3.0", - "latest-version": "^5.0.0", - "pupa": "^2.0.1", - "semver-diff": "^3.1.1", - "xdg-basedir": "^4.0.0" - }, - "dependencies": {} - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "requires": { - "punycode": "^2.1.0" - } - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": {} - }, - "url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", - "requires": { - "prepend-http": "^2.0.0" - }, - "dependencies": {} - }, - "util": { - "version": "0.12.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.3.tgz", - "integrity": "sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog==", - "requires": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "safe-buffer": "^5.1.2", - "which-typed-array": "^1.1.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" - }, - "v8-compile-cache": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==" - }, - "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==", - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "watchpack": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.1.1.tgz", - "integrity": "sha512-Oo7LXCmc1eE1AjyuSBmtC3+Wy4HcV8PxWh2kP6fOl8yTlNS7r0K9l1ao2lrrUza7V39Y3D/BbJgY8VeSlc5JKw==", - "requires": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - } - }, - "webpack": { - "version": "5.35.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.35.0.tgz", - "integrity": "sha512-au3gu55yYF/h6NXFr0KZPZAYxS6Nlc595BzYPke8n0CSff5WXcoixtjh5LC/8mXunkRKxhymhXmBY0+kEbR6jg==", - "requires": { - "@types/eslint-scope": "^3.7.0", - "@types/estree": "^0.0.47", - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/wasm-edit": "1.11.0", - "@webassemblyjs/wasm-parser": "1.11.0", - "acorn": "^8.0.4", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.8.0", - "es-module-lexer": "^0.4.0", - "eslint-scope": "^5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.4", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.0.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.1", - "watchpack": "^2.0.0", - "webpack-sources": "^2.1.1" - } - }, - "webpack-cli": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.6.0.tgz", - "integrity": "sha512-9YV+qTcGMjQFiY7Nb1kmnupvb1x40lfpj8pwdO/bom+sQiP4OBMKjHq29YQrlDWDPZO9r/qWaRRywKaRDKqBTA==", - "requires": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^1.0.2", - "@webpack-cli/info": "^1.2.3", - "@webpack-cli/serve": "^1.3.1", - "colorette": "^1.2.1", - "commander": "^7.0.0", - "enquirer": "^2.3.6", - "execa": "^5.0.0", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^2.2.0", - "rechoir": "^0.7.0", - "v8-compile-cache": "^2.2.0", - "webpack-merge": "^5.7.3" - }, - "dependencies": {} - }, - "webpack-merge": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.7.3.tgz", - "integrity": "sha512-6/JUQv0ELQ1igjGDzHkXbVDRxkfA57Zw7PfiupdLFJYrgFqY5ZP8xxbpp2lU3EPwYx89ht5Z/aDkD40hFCm5AA==", - "requires": { - "clone-deep": "^4.0.1", - "wildcard": "^2.0.0" - } - }, - "webpack-node-externals": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/webpack-node-externals/-/webpack-node-externals-2.5.2.tgz", - "integrity": "sha512-aHdl/y2N7PW2Sx7K+r3AxpJO+aDMcYzMQd60Qxefq3+EwhewSbTBqNumOsCE1JsCUNoyfGj5465N0sSf6hc/5w==" - }, - "webpack-sources": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.2.0.tgz", - "integrity": "sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w==", - "requires": { - "source-list-map": "^2.0.1", - "source-map": "^0.6.1" - } - }, - "whatwg-fetch": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", - "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==" - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "requires": { - "isexe": "^2.0.0" - } - }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" - }, - "which-pm-runs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", - "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=" - }, - "which-typed-array": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.4.tgz", - "integrity": "sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA==", - "requires": { - "available-typed-arrays": "^1.0.2", - "call-bind": "^1.0.0", - "es-abstract": "^1.18.0-next.1", - "foreach": "^2.0.5", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.1", - "is-typed-array": "^1.1.3" - } - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": {} - }, - "widest-line": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", - "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", - "requires": { - "string-width": "^4.0.0" - } - }, - "wildcard": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", - "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==" - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" - }, - "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==", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "ws": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz", - "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==" - }, - "xdg-basedir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", - "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "requires": { - "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" - } - }, - "yargs-parser": { - "version": "20.2.7", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz", - "integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==" - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - }, - "dependencies": {} - }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" - }, - "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==" + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" + } + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "requires": { + "punycode": "^2.1.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "watchpack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.2.0.tgz", + "integrity": "sha512-up4YAn/XHgZHIxFBVCdlMiWDj6WaLKpwVeGQk2I5thdYxF/KmF0aaz6TfJZ/hfl1h/XlcDr7k1KH7ThDagpFaA==", + "requires": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + } + }, + "webpack": { + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.46.0.tgz", + "integrity": "sha512-qxD0t/KTedJbpcXUmvMxY5PUvXDbF8LsThCzqomeGaDlCA6k998D8yYVwZMvO8sSM3BTEOaD4uzFniwpHaTIJw==", + "requires": { + "@types/eslint-scope": "^3.7.0", + "@types/estree": "^0.0.50", + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/wasm-edit": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "acorn": "^8.4.1", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.8.0", + "es-module-lexer": "^0.7.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.4", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.1.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.1.3", + "watchpack": "^2.2.0", + "webpack-sources": "^2.3.1" + }, + "dependencies": { + "acorn": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", + "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==" } } + }, + "webpack-sources": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.1.tgz", + "integrity": "sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA==", + "requires": { + "source-list-map": "^2.0.1", + "source-map": "^0.6.1" + } + }, + "whatwg-fetch": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", + "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "ws": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz", + "integrity": "sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==" + }, + "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==" } } } diff --git a/dragons-nft-scripts/src/index.js b/dragons-nft-scripts/src/index.js index 4c826c8..358d372 100644 --- a/dragons-nft-scripts/src/index.js +++ b/dragons-nft-scripts/src/index.js @@ -1,15 +1,15 @@ const { CLValueBuilder, Keys, CLPublicKey } = require("casper-js-sdk"); const { CEP47Client, utils, constants } = require("casper-cep47-js-client"); -// const NODE_ADDRESS = 'http://3.143.158.19:7777/rpc'; -const NODE_ADDRESS = 'http://localhost:40101/rpc'; -const EVENT_STREAM_ADDRESS = 'http://localhost:60101/events'; +const NODE_ADDRESS = 'http://3.143.158.19:7777/rpc'; +// const NODE_ADDRESS = 'http://localhost:40101/rpc'; +const EVENT_STREAM_ADDRESS = 'http://3.143.158.19:9999/events'; const INSTALL_PAYMENT_AMOUNT = '200000000000'; const MINT_ONE_PAYMENT_AMOUNT = '2000000000'; const MINT_COPIES_PAYMENT_AMOUNT = '100000000000'; const BURN_ONE_PAYMENT_AMOUNT = '12000000000'; -// const CHAIN_NAME = 'integration-test'; -const CHAIN_NAME = 'casper-net-1'; +const CHAIN_NAME = 'integration-test'; +// const CHAIN_NAME = 'casper-net-1'; const WASM_PATH = "./../target/wasm32-unknown-unknown/release/dragons-nft.wasm"; const TOKEN_NAME = 'event_nft_3'; const TOKEN_SYMBOL = 'DRAG'; @@ -17,8 +17,8 @@ const TOKEN_META = new Map([ ['origin', 'fire'], ['lifetime', 'infinite'] ]); -// const KEY_PAIR_PATH = '/home/ziel/workspace/casperlabs/integration-key/master'; -const KEY_PAIR_PATH = '/Users/janhoffmann/casper-node/utils/nctl/assets/net-1/faucet'; +const KEY_PAIR_PATH = '/home/ziel/workspace/casperlabs/integration-key/master'; +// const KEY_PAIR_PATH = '/Users/janhoffmann/casper-node/utils/nctl/assets/net-1/faucet'; const KEYS = Keys.Ed25519.parseKeyFiles( `${KEY_PAIR_PATH}/public_key.pem`, `${KEY_PAIR_PATH}/secret_key.pem` @@ -27,7 +27,7 @@ const MINT_ONE_META_SIZE = 4; const MINT_COPIES_META_SIZE = 10; const MINT_MANY_META_SIZE = 10; const MINT_COPIES_COUNT = 5; -const CONTRACT_HASH = 'cd02755c7e42c3f191f005d2e3a42324488056be0361935bdbcb6b4722dab14b'; +const CONTRACT_HASH = '6f833eb30447e7bad2e77d7a34b1b1d3870dd1d4a38823da2a84219a05733ced'; const cep47 = new CEP47Client(NODE_ADDRESS, CHAIN_NAME, EVENT_STREAM_ADDRESS); @@ -39,8 +39,9 @@ const install = async () => { }; const mintOne = async () => { + const cep47 = new CEP47Client(NODE_ADDRESS, CHAIN_NAME, EVENT_STREAM_ADDRESS); await cep47.setContractHash(CONTRACT_HASH); - let meta = randomMetaMap(MINT_ONE_META_SIZE); + let meta = new Map([['name1', 'Medha'], ['name2', 'Maciej'], ['name3', 'Jan']]); const deployHash = await cep47.mintOne(KEYS, KEYS.publicKey, meta, MINT_ONE_PAYMENT_AMOUNT); console.log(`Mint One`); console.log(`... DeployHash: ${deployHash}`); diff --git a/dragons-nft-tests/src/cep47.rs b/dragons-nft-tests/src/cep47.rs index 042b0b3..bf655be 100644 --- a/dragons-nft-tests/src/cep47.rs +++ b/dragons-nft-tests/src/cep47.rs @@ -37,9 +37,13 @@ pub type Meta = BTreeMap; impl CasperCEP47Contract { pub fn deploy() -> Self { - let admin: PublicKey = SecretKey::ed25519_from_bytes([1u8; 32]).unwrap().into(); - let ali: PublicKey = SecretKey::ed25519_from_bytes([3u8; 32]).unwrap().into(); - let bob: PublicKey = SecretKey::ed25519_from_bytes([5u8; 32]).unwrap().into(); + let admin_secret = SecretKey::ed25519_from_bytes([1u8; 32]).unwrap(); + let ali_secret = SecretKey::ed25519_from_bytes([3u8; 32]).unwrap(); + let bob_secret = SecretKey::ed25519_from_bytes([5u8; 32]).unwrap(); + + let admin: PublicKey = (&admin_secret).into(); + let ali: PublicKey = (&ali_secret).into(); + let bob: PublicKey = (&bob_secret).into(); let mut context = TestContextBuilder::new() .with_public_key(admin.clone(), U512::from(500_000_000_000_000_000u64)) .with_public_key(ali.clone(), U512::from(500_000_000_000_000_000u64)) diff --git a/dragons-nft/Cargo.toml b/dragons-nft/Cargo.toml index 8a2c3ea..bcb1e6a 100644 --- a/dragons-nft/Cargo.toml +++ b/dragons-nft/Cargo.toml @@ -5,8 +5,8 @@ authors = ["astro019 "] edition = "2018" [dependencies] -casper-contract = "1.2.0" -casper-types = "1.2.0" +casper-contract = "1.2.1" +casper-types = "1.2.1" cep47 = { path="../cep47", features = ["no_owner_of"]} [[bin]] diff --git a/dragons-nft/src/main.rs b/dragons-nft/src/main.rs index 5c48dc8..aaa6960 100644 --- a/dragons-nft/src/main.rs +++ b/dragons-nft/src/main.rs @@ -9,7 +9,7 @@ pub extern "C" fn owner_of() {} #[no_mangle] pub extern "C" fn call() { let (contract_package_hash, _) = create_contract_package_at_hash(); - let entry_points = cep47::get_entrypoints(None); + let entry_points = cep47::get_entrypoints(Some(contract_package_hash)); cep47::deploy( get_named_arg::("token_name"), get_named_arg::("token_symbol"), From 264962df730285d008c3bf5de3ad9c2f3cb3fdb3 Mon Sep 17 00:00:00 2001 From: Maciej Zielinski Date: Thu, 22 Jul 2021 14:49:41 +0200 Subject: [PATCH 51/98] Udpate variable params. --- cep47/src/lib.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cep47/src/lib.rs b/cep47/src/lib.rs index a3a3acb..3b239ce 100644 --- a/cep47/src/lib.rs +++ b/cep47/src/lib.rs @@ -421,7 +421,7 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints let mut entry_points = EntryPoints::new(); entry_points.add_entry_point(endpoint("name", vec![], CLType::String, None)); entry_points.add_entry_point(endpoint("symbol", vec![], CLType::String, None)); - entry_points.add_entry_point(endpoint("meta", vec![], CLType::String, None)); + entry_points.add_entry_point(endpoint("meta", vec![], Meta::cl_type(), None)); entry_points.add_entry_point(endpoint("total_supply", vec![], CLType::U256, None)); entry_points.add_entry_point(endpoint("is_paused", vec![], CLType::Bool, None)); entry_points.add_entry_point(endpoint( @@ -478,7 +478,7 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints "mint_one", vec![ Parameter::new("recipient", CLType::PublicKey), - Parameter::new("token_meta", CLType::String), // TODO: + Parameter::new("token_meta", Meta::cl_type()), ], CLType::Unit, if secure { @@ -491,7 +491,7 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints "mint_many", vec![ Parameter::new("recipient", CLType::PublicKey), - Parameter::new("token_metas", CLType::List(Box::new(CLType::String))), + Parameter::new("token_metas", CLType::List(Box::new(Meta::cl_type()))), ], CLType::Unit, if secure { @@ -504,7 +504,7 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints "mint_copies", vec![ Parameter::new("recipient", CLType::PublicKey), - Parameter::new("token_meta", CLType::String), + Parameter::new("token_meta", Meta::cl_type()), Parameter::new("count", CLType::U256), ], CLType::Unit, @@ -518,7 +518,7 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints "burn_one", vec![ Parameter::new("owner", CLType::PublicKey), - Parameter::new("token_id", CLType::List(Box::new(CLType::String))), + Parameter::new("token_id", CLType::String), ], CLType::Unit, if secure { From fb29092ddc2abb56a7296aaef0a3ea742a864a2e Mon Sep 17 00:00:00 2001 From: Maciej Zielinski Date: Mon, 26 Jul 2021 11:30:45 +0200 Subject: [PATCH 52/98] Custom TokenID and update_token_metadata. --- cep47-logic/src/lib.rs | 94 +++++++++++++++---- cep47-logic/src/tests.rs | 95 ++++++++++++------- cep47/Cargo.toml | 2 + cep47/src/lib.rs | 120 ++++++++++++++++-------- dragons-nft-scripts/src/index.js | 22 ++++- dragons-nft-tests/Cargo.toml | 1 - dragons-nft-tests/src/cep47.rs | 32 ++++--- dragons-nft-tests/src/contract_tests.rs | 70 +++++++++++++- 8 files changed, 324 insertions(+), 112 deletions(-) diff --git a/cep47-logic/src/lib.rs b/cep47-logic/src/lib.rs index c3c1e56..217e90b 100644 --- a/cep47-logic/src/lib.rs +++ b/cep47-logic/src/lib.rs @@ -17,7 +17,10 @@ pub type Meta = BTreeMap; #[repr(u16)] pub enum Error { - PermissionDenied = 2, // 65538 + PermissionDenied = 1, + ArgumentsError = 2, + TokenIdAlreadyExists = 3, + TokenIdDoesntExist = 4, } impl From for ApiError { @@ -50,7 +53,7 @@ pub trait CEP47Contract: WithStorage { self.storage().balance_of(owner) } - fn owner_of(&self, token_id: TokenId) -> Option { + fn owner_of(&self, token_id: &TokenId) -> Option { self.storage().onwer_of(token_id) } @@ -80,17 +83,59 @@ pub trait CEP47Contract: WithStorage { // Minter function. // Guarded by the entrypoint group. - fn mint_one(&mut self, recipient: PublicKey, token_meta: Meta) { - self.storage_mut() - .mint_copies(recipient, token_meta, U256::one()); + fn mint_one(&mut self, recipient: PublicKey, token_id: Option, token_meta: Meta) -> Result<(), Error> { + match token_id { + Some(token_id) => { + let valid = self.storage().validate_token_ids(&vec![token_id.clone()]); + if !valid { + Err(Error::TokenIdAlreadyExists) + } else { + self.storage_mut() + .mint_many(recipient, vec![token_id],vec![token_meta]); + Ok(()) + } + }, + None => { + let token_ids = self.storage_mut().gen_token_ids(1); + self.storage_mut() + .mint_many(recipient, token_ids,vec![token_meta]); + Ok(()) + } + } } - fn mint_many(&mut self, recipient: PublicKey, token_metas: Vec) { - self.storage_mut().mint_many(recipient, token_metas); + fn mint_many(&mut self, recipient: PublicKey, token_ids: Option>, token_metas: Vec) -> Result<(), Error> { + match token_ids { + Some(token_ids) => { + if token_ids.len() != token_metas.len() { + return Err(Error::ArgumentsError); + } + let valid = self.storage().validate_token_ids(&token_ids); + if !valid { + Err(Error::TokenIdAlreadyExists) + } else { + self.storage_mut() + .mint_many(recipient, token_ids, token_metas); + Ok(()) + } + }, + None => { + let token_ids = self.storage_mut().gen_token_ids(token_metas.len() as u32); + self.storage_mut() + .mint_many(recipient, token_ids, token_metas); + Ok(()) + } + } } - fn mint_copies(&mut self, recipient: PublicKey, token_meta: Meta, count: U256) { - self.storage_mut().mint_copies(recipient, token_meta, count); + fn mint_copies(&mut self, recipient: PublicKey, token_ids: Option>, token_meta: Meta, count: u32) -> Result<(), Error> { + if let Some(token_ids) = &token_ids { + if token_ids.len() != count as usize { + return Err(Error::ArgumentsError); + }; + }; + let token_metas = vec![token_meta; count as usize]; + self.mint_many(recipient, token_ids, token_metas) } fn burn_one(&mut self, owner: PublicKey, token_id: TokenId) { @@ -108,8 +153,7 @@ pub trait CEP47Contract: WithStorage { recipient: PublicKey, token_id: TokenId, ) -> Result<(), Error> { - let paused = self.storage().is_paused(); - if paused { + if self.is_paused() { return Err(Error::PermissionDenied); } // 1. Load tokens owned by the sender. @@ -135,12 +179,10 @@ pub trait CEP47Contract: WithStorage { recipient: PublicKey, token_ids: Vec, ) -> Result<(), Error> { - let paused = self.storage().is_paused(); - if paused { + if self.is_paused() { return Err(Error::PermissionDenied); } let mut sender_tokens = self.storage().get_tokens(sender.clone()); - println!("Sender tokens: {:?}", sender_tokens); for token_id in token_ids.iter() { if !sender_tokens.contains(token_id) { @@ -160,8 +202,7 @@ pub trait CEP47Contract: WithStorage { sender: PublicKey, recipient: PublicKey, ) -> Result<(), Error> { - let paused = self.storage().is_paused(); - if paused { + if self.is_paused() { return Err(Error::PermissionDenied); } let mut sender_tokens = self.storage().get_tokens(sender.clone()); @@ -172,6 +213,18 @@ pub trait CEP47Contract: WithStorage { self.storage_mut().set_tokens(recipient, recipient_tokens); Ok(()) } + + fn update_token_metadata( + &mut self, + token_id: TokenId, + meta: Meta + ) -> Result<(), Error> { + if self.owner_of(&token_id).is_none() { + return Err(Error::TokenIdDoesntExist); + }; + self.storage_mut().update_token_metadata(token_id, meta); + Ok(()) + } } pub trait CEP47Storage { @@ -182,7 +235,7 @@ pub trait CEP47Storage { // Getters fn balance_of(&self, owner: PublicKey) -> U256; - fn onwer_of(&self, token_id: TokenId) -> Option; + fn onwer_of(&self, token_id: &TokenId) -> Option; fn total_supply(&self) -> U256; fn token_meta(&self, token_id: TokenId) -> Option; @@ -194,8 +247,11 @@ pub trait CEP47Storage { // Setters fn get_tokens(&self, owner: PublicKey) -> Vec; fn set_tokens(&mut self, owner: PublicKey, token_ids: Vec); - fn mint_many(&mut self, recipient: PublicKey, token_metas: Vec); - fn mint_copies(&mut self, recipient: PublicKey, token_metas: Meta, count: U256); + fn mint_many(&mut self, recipient: PublicKey, token_ids: Vec, token_metas: Vec); fn burn_one(&mut self, owner: PublicKey, token_id: TokenId); fn burn_many(&mut self, owner: PublicKey, token_ids: Vec); + fn update_token_metadata(&mut self, token_id: TokenId, meta: Meta); + + fn gen_token_ids(&mut self, n: u32) -> Vec; + fn validate_token_ids(&self, token_ids: &Vec) -> bool; } diff --git a/cep47-logic/src/tests.rs b/cep47-logic/src/tests.rs index d844b39..51d511a 100644 --- a/cep47-logic/src/tests.rs +++ b/cep47-logic/src/tests.rs @@ -2,7 +2,7 @@ use casper_types::AccessRights; use rand::Rng; use crate::{ - AsymmetricType, CEP47Contract, CEP47Storage, Meta, PublicKey, TokenId, URef, WithStorage, U256, + AsymmetricType, CEP47Contract, CEP47Storage, Meta, PublicKey, TokenId, URef, WithStorage, U256, Error }; use std::{ collections::{hash_map::DefaultHasher, BTreeMap}, @@ -21,6 +21,7 @@ struct TestStorage { balances: BTreeMap, belongs_to: BTreeMap, urefs: BTreeMap, + token_id_generator: u32 } impl TestStorage { @@ -36,6 +37,7 @@ impl TestStorage { belongs_to: BTreeMap::new(), token_metas: BTreeMap::new(), urefs: BTreeMap::new(), + token_id_generator: 1 } } } @@ -62,8 +64,8 @@ impl CEP47Storage for TestStorage { } } - fn onwer_of(&self, token_id: TokenId) -> Option { - let owner = self.belongs_to.get(&token_id); + fn onwer_of(&self, token_id: &TokenId) -> Option { + let owner = self.belongs_to.get(token_id); if owner.is_some() { Some(owner.unwrap().clone()) } else { @@ -120,7 +122,7 @@ impl CEP47Storage for TestStorage { self.balances.insert(owner, owner_new_balance); } - fn mint_many(&mut self, recipient: PublicKey, token_metas: Vec) { + fn mint_many(&mut self, recipient: PublicKey, token_ids: Vec, token_metas: Vec) { let recipient_balance = self.balances.get(&recipient); let recipient_tokens = self.tokens.get(&recipient); let mut recipient_new_balance = if recipient_balance.is_none() { @@ -134,15 +136,10 @@ impl CEP47Storage for TestStorage { recipient_tokens.unwrap().clone() }; - let mut hasher = DefaultHasher::new(); - - for token_meta in token_metas.clone() { - let token_info = (self.meta.clone(), token_meta.clone(), self.total_supply()); - Hash::hash(&token_info, &mut hasher); - let token_id: TokenId = TokenId::from(hasher.finish().to_string()); + for (token_id, token_meta) in token_ids.iter().zip(token_metas) { self.token_metas.insert(token_id.clone(), token_meta); recipient_new_tokens.push(token_id.clone()); - self.belongs_to.insert(token_id, recipient.clone()); + self.belongs_to.insert(token_id.clone(), recipient.clone()); recipient_new_balance = recipient_new_balance + 1; self.total_supply = self.total_supply + 1; } @@ -151,11 +148,6 @@ impl CEP47Storage for TestStorage { self.tokens.insert(recipient, recipient_new_tokens); } - fn mint_copies(&mut self, recipient: PublicKey, token_meta: Meta, count: U256) { - let token_metas: Vec = vec![token_meta; count.as_usize()]; - self.mint_many(recipient, token_metas); - } - fn burn_many(&mut self, owner: PublicKey, token_ids: Vec) { let owner_tokens = self.tokens.get(&owner); let owner_balance = self.balances.get(&owner); @@ -209,6 +201,29 @@ impl CEP47Storage for TestStorage { self.balances.insert(owner.clone(), owner_new_balance - 1); self.tokens.insert(owner, owner_new_tokens); } + + fn update_token_metadata(&mut self, token_id: TokenId, meta: Meta) { + self.token_metas.insert(token_id, meta).unwrap(); + } + + fn gen_token_ids(&mut self, n: u32) -> Vec { + let mut tokens = Vec::new(); + for _ in 0..n { + let id = format!("token_{}", &self.token_id_generator); + tokens.push(id); + self.token_id_generator += 1; + }; + tokens + } + + fn validate_token_ids(&self, token_ids: &Vec) -> bool { + for token_id in token_ids { + if self.onwer_of(token_id).is_some() { + return false; + } + } + true + } } struct TestContract { @@ -282,10 +297,13 @@ fn test_mint_many() { let mut contract = TestContract::new(); let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); + let bob_first_token_id = "banana_01".to_string(); + let bob_second_token_id = "orange_02".to_string(); + let bob_token_ids = vec![bob_first_token_id.clone(), bob_second_token_id]; assert_eq!(contract.total_supply(), U256::from(0)); - contract.mint_many(ali.clone(), vec![meta::apple()]); - contract.mint_many(bob.clone(), vec![meta::banana(), meta::orange()]); + let _: Result<(), Error> = contract.mint_many(ali.clone(), None, vec![meta::apple()]); + let _: Result<(), Error> = contract.mint_many(bob.clone(), Some(bob_token_ids.clone()), vec![meta::banana(), meta::orange()]); assert_eq!(contract.total_supply(), U256::from(3)); let ali_balance = contract.balance_of(ali.clone()); @@ -300,10 +318,11 @@ fn test_mint_many() { assert_eq!(ali_first_token_meta, meta::apple()); let bob_tokens: Vec = contract.tokens(bob); + assert_eq!(bob_token_ids, bob_tokens); let bob_first_token_meta: Meta = contract - .token_meta(bob_tokens.get(1).unwrap().clone()) + .token_meta(bob_first_token_id) .unwrap(); - assert_eq!(bob_first_token_meta, meta::orange()); + assert_eq!(bob_first_token_meta, meta::banana()); } #[test] fn test_mint_copies() { @@ -311,7 +330,7 @@ fn test_mint_copies() { let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); assert_eq!(contract.total_supply(), U256::from(0)); - contract.mint_copies(ali.clone(), meta::apple(), U256::from(7)); + let _: Result<(), Error> = contract.mint_copies(ali.clone(), None, meta::apple(), 7); assert_eq!(contract.total_supply(), U256::from(7)); let ali_balance = contract.balance_of(ali.clone()); @@ -333,8 +352,9 @@ fn test_burn_many() { let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); assert_eq!(contract.total_supply(), U256::from(0)); - contract.mint_many( + let _: Result<(), Error> = contract.mint_many( ali.clone(), + None, vec![meta::banana(), meta::orange(), meta::apple()], ); assert_eq!(contract.total_supply(), U256::from(3)); @@ -364,7 +384,7 @@ fn test_burn_one() { let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); assert_eq!(contract.total_supply(), U256::from(0)); - contract.mint_many(ali.clone(), vec![meta::banana(), meta::orange()]); + let _: Result<(), Error> = contract.mint_many(ali.clone(), None, vec![meta::banana(), meta::orange()]); assert_eq!(contract.total_supply(), U256::from(2)); let mut ali_balance = contract.balance_of(ali.clone()); @@ -390,7 +410,7 @@ fn test_transfer_token() { let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); assert_eq!(contract.total_supply(), U256::from(0)); - contract.mint_one(ali.clone(), meta::apple()); + let _: Result<(), Error> = contract.mint_one(ali.clone(), None, meta::apple()); assert_eq!(contract.total_supply(), U256::from(1)); let mut ali_balance = contract.balance_of(ali.clone()); @@ -411,7 +431,7 @@ fn test_transfer_token() { assert_eq!(ali_balance, U256::from(0)); assert_eq!(bob_balance, U256::from(1)); - let owner_of_first_token_id = contract.owner_of(ali_first_token_id); + let owner_of_first_token_id = contract.owner_of(&ali_first_token_id); assert_eq!(owner_of_first_token_id.unwrap(), bob); } #[test] @@ -421,8 +441,8 @@ fn test_transfer_all_tokens() { let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); assert_eq!(contract.total_supply(), U256::from(0)); - contract.mint_many(ali.clone(), vec![meta::apple(), meta::banana()]); - contract.mint_one(ali.clone(), meta::apple()); + let _: Result<(), Error> = contract.mint_many(ali.clone(), None, vec![meta::apple(), meta::banana()]); + let _: Result<(), Error> = contract.mint_one(ali.clone(), None, meta::apple()); assert_eq!(contract.total_supply(), U256::from(3)); let mut ali_balance = contract.balance_of(ali.clone()); @@ -443,7 +463,7 @@ fn test_transfer_all_tokens() { assert_eq!(ali_balance, U256::from(0)); assert_eq!(bob_balance, U256::from(3)); - let owner_of_second_token_id = contract.owner_of(ali_second_token_id); + let owner_of_second_token_id = contract.owner_of(&ali_second_token_id); assert_eq!(owner_of_second_token_id.unwrap(), bob); } @@ -454,8 +474,8 @@ fn test_transfer_many_tokens() { let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); assert_eq!(contract.total_supply(), U256::from(0)); - contract.mint_many(ali.clone(), vec![meta::apple(), meta::banana()]); - contract.mint_copies(ali.clone(), meta::apple(), U256::from(3)); + let _ = contract.mint_many(ali.clone(), None, vec![meta::apple(), meta::banana()]); + let _: Result<(), Error> = contract.mint_copies(ali.clone(), None, meta::apple(), 3); assert_eq!(contract.total_supply(), U256::from(5)); assert_eq!(contract.balance_of(ali.clone()), U256::from(5)); @@ -478,8 +498,19 @@ fn test_transfer_many_tokens() { assert_eq!(contract.balance_of(ali), U256::from(3)); assert_eq!(contract.balance_of(bob.clone()), U256::from(2)); - let owner_of_second_token_id = contract.owner_of(ali_second_token_id); - let owner_of_third_token_id = contract.owner_of(ali_third_token_id); + let owner_of_second_token_id = contract.owner_of(&ali_second_token_id); + let owner_of_third_token_id = contract.owner_of(&ali_third_token_id); assert_eq!(owner_of_second_token_id.unwrap(), bob); assert_eq!(owner_of_third_token_id.unwrap(), bob); } + +#[test] +fn test_update_metadata() { + let mut contract = TestContract::new(); + let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + let token_id = TokenId::from("new_token"); + let _: Result<(), Error> = contract.mint_one(ali, Some(token_id.clone()), meta::apple()); + assert_eq!(meta::apple(), contract.token_meta(token_id.clone()).unwrap()); + let _: Result<(), Error> = contract.update_token_metadata(token_id.clone(), meta::banana()); + assert_eq!(meta::banana(), contract.token_meta(token_id).unwrap()); +} \ No newline at end of file diff --git a/cep47/Cargo.toml b/cep47/Cargo.toml index dc27420..da193af 100644 --- a/cep47/Cargo.toml +++ b/cep47/Cargo.toml @@ -5,6 +5,7 @@ authors = ["astro019 "] edition = "2018" [dependencies] +hex = "0.4.3" casper-contract = "1.2.1" casper-types = "1.2.1" cep47-logic = { path = "../cep47-logic" } @@ -33,3 +34,4 @@ no_burn_one = [] no_transfer_token = [] no_transfer_many_tokens = [] no_transfer_all_tokens = [] +no_update_token_metadata = [] \ No newline at end of file diff --git a/cep47/src/lib.rs b/cep47/src/lib.rs index 3b239ce..43ff97b 100644 --- a/cep47/src/lib.rs +++ b/cep47/src/lib.rs @@ -36,6 +36,7 @@ impl CasperCEP47Storage { CasperCEP47Storage {} } } + impl CEP47Storage for CasperCEP47Storage { // Metadata. fn name(&self) -> String { @@ -60,8 +61,8 @@ impl CEP47Storage for CasperCEP47Storage { } } - fn onwer_of(&self, token_id: TokenId) -> Option { - get_key::(&owner_key(&token_id)) + fn onwer_of(&self, token_id: &TokenId) -> Option { + get_key::(&owner_key(token_id)) } fn total_supply(&self) -> U256 { @@ -114,25 +115,13 @@ impl CEP47Storage for CasperCEP47Storage { ); } - fn mint_many(&mut self, recipient: PublicKey, token_metas: Vec) { + fn mint_many(&mut self, recipient: PublicKey, token_ids: Vec, token_metas: Vec) { let mut recipient_tokens = self.get_tokens(recipient.clone()); let mut recipient_balance = self.balance_of(recipient.clone()); let mut total_supply = self.total_supply(); - let meta = self.meta(); - - let mut hasher = DefaultHasher::new(); - let mut nonce: u64 = get_event_nonce(); - let block_hash: u64 = runtime::get_blocktime().into(); - - for token_meta in token_metas.clone() { - // Derive new unique token id. - let token_info = (block_hash, nonce, meta.clone()); - Hash::hash(&token_info, &mut hasher); - let token_id = TokenId::from(hasher.finish().to_string()); - nonce = nonce + 1; + for (token_id, token_meta) in token_ids.iter().zip(token_metas) { recipient_tokens.push(token_id.clone()); - total_supply = total_supply + 1; set_key(&meta_key(&token_id), token_meta); set_key(&owner_key(&token_id), recipient.clone()); @@ -140,23 +129,18 @@ impl CEP47Storage for CasperCEP47Storage { emit_mint_one_event(&recipient, &token_id); } - // Update nonce. - set_event_nonce(nonce); + set_key(&token_key(&recipient.to_account_hash()), recipient_tokens); - recipient_balance = recipient_balance + U256::from(token_metas.len() as u64); + let new_tokens_count = U256::from(token_ids.len() as u32); + recipient_balance = recipient_balance + new_tokens_count; set_key( &balance_key(&recipient.to_account_hash()), recipient_balance, ); - set_key(&token_key(&recipient.to_account_hash()), recipient_tokens); + total_supply = total_supply + new_tokens_count; set_key("total_supply", total_supply); } - fn mint_copies(&mut self, recipient: PublicKey, token_meta: Meta, count: U256) { - let token_metas: Vec = vec![token_meta; count.as_usize()]; - self.mint_many(recipient, token_metas); - } - fn burn_many(&mut self, owner: PublicKey, token_ids: Vec) { let mut owner_tokens = self.get_tokens(owner.clone()); let mut owner_balance = self.balance_of(owner.clone()); @@ -196,6 +180,33 @@ impl CEP47Storage for CasperCEP47Storage { set_key("total_supply", total_supply - 1); emit_burn_one_event(&owner, &token_id); } + + fn update_token_metadata(&mut self, token_id: TokenId, meta: Meta) { + set_key(&meta_key(&token_id), meta); + } + + fn gen_token_ids(&mut self, n: u32) -> Vec { + let block_time = runtime::get_blocktime(); + let mut token_ids = Vec::new(); + let nonce = get_nonce(); + for i in nonce..nonce + n { + let mut bytes: Vec = block_time.to_bytes().unwrap_or_revert(); + bytes.append(&mut i.to_bytes().unwrap_or_revert()); + let hash = runtime::blake2b(bytes); + token_ids.push(hex::encode(hash)); + }; + set_nonce(nonce+n); + token_ids + } + + fn validate_token_ids(&self, token_ids: &Vec) -> bool { + for token_id in token_ids { + if self.onwer_of(token_id).is_some() { + return false; + } + } + true + } } pub struct CasperCEP47Contract { @@ -306,28 +317,31 @@ pub extern "C" fn unpause() { #[no_mangle] pub extern "C" fn mint_one() { let recipient: PublicKey = runtime::get_named_arg("recipient"); + let token_id: Option = runtime::get_named_arg("token_id"); let token_meta: Meta = runtime::get_named_arg("token_meta"); let mut contract = CasperCEP47Contract::new(); - contract.mint_one(recipient, token_meta); + contract.mint_one(recipient, token_id, token_meta).unwrap_or_revert(); } #[cfg(not(feature = "no_mint_many"))] #[no_mangle] pub extern "C" fn mint_many() { let recipient: PublicKey = runtime::get_named_arg("recipient"); + let token_ids: Option> = runtime::get_named_arg("token_ids"); let token_metas: Vec = runtime::get_named_arg("token_metas"); let mut contract = CasperCEP47Contract::new(); - contract.mint_many(recipient, token_metas); + contract.mint_many(recipient, token_ids, token_metas).unwrap_or_revert(); } #[cfg(not(feature = "no_mint_copies"))] #[no_mangle] pub extern "C" fn mint_copies() { let recipient: PublicKey = runtime::get_named_arg("recipient"); + let token_ids: Option> = runtime::get_named_arg("token_ids"); let token_meta: Meta = runtime::get_named_arg("token_meta"); - let count: U256 = runtime::get_named_arg("count"); + let count: u32 = runtime::get_named_arg("count"); let mut contract = CasperCEP47Contract::new(); - contract.mint_copies(recipient, token_meta, count); + contract.mint_copies(recipient, token_ids, token_meta, count).unwrap_or_revert(); } #[cfg(not(feature = "no_burn_many"))] @@ -403,6 +417,16 @@ pub extern "C" fn transfer_all_tokens() { res.unwrap_or_revert(); } +#[cfg(not(feature = "no_update_token_metadata"))] +#[no_mangle] +pub extern "C" fn update_token_metadata() { + let token_id: TokenId = runtime::get_named_arg("token_id"); + let meta: Meta = runtime::get_named_arg("meta"); + let mut contract = CasperCEP47Contract::new(); + let res = contract.update_token_metadata(token_id, meta); + res.unwrap_or_revert(); +} + pub fn get_entrypoints(package_hash: Option) -> EntryPoints { let secure = if let Some(contract_package_hash) = package_hash { let deployer_group = storage::create_contract_user_group( @@ -452,13 +476,13 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints )); entry_points.add_entry_point(endpoint( "owner_of", - vec![Parameter::new("token_id", CLType::String)], + vec![Parameter::new("token_id", TokenId::cl_type())], CLType::Option(Box::new(CLType::PublicKey)), None, )); entry_points.add_entry_point(endpoint( "token_meta", - vec![Parameter::new("token_id", CLType::String)], + vec![Parameter::new("token_id", TokenId::cl_type())], CLType::Option(Box::new(CLType::String)), None, )); @@ -478,6 +502,7 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints "mint_one", vec![ Parameter::new("recipient", CLType::PublicKey), + Parameter::new("token_ids", CLType::Option(Box::new(TokenId::cl_type()))), Parameter::new("token_meta", Meta::cl_type()), ], CLType::Unit, @@ -491,6 +516,7 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints "mint_many", vec![ Parameter::new("recipient", CLType::PublicKey), + Parameter::new("token_ids", CLType::Option(Box::new(CLType::List(Box::new(TokenId::cl_type()))))), Parameter::new("token_metas", CLType::List(Box::new(Meta::cl_type()))), ], CLType::Unit, @@ -504,8 +530,22 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints "mint_copies", vec![ Parameter::new("recipient", CLType::PublicKey), + Parameter::new("token_ids", CLType::Option(Box::new(CLType::List(Box::new(TokenId::cl_type()))))), Parameter::new("token_meta", Meta::cl_type()), - Parameter::new("count", CLType::U256), + Parameter::new("count", CLType::U32), + ], + CLType::Unit, + if secure { + Some("deployer") + } else { + None + }, + )); + entry_points.add_entry_point(endpoint( + "update_token_metadata", + vec![ + Parameter::new("token_id", TokenId::cl_type()), + Parameter::new("meta", Meta::cl_type()), ], CLType::Unit, if secure { @@ -518,7 +558,7 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints "burn_one", vec![ Parameter::new("owner", CLType::PublicKey), - Parameter::new("token_id", CLType::String), + Parameter::new("token_id", TokenId::cl_type()), ], CLType::Unit, if secure { @@ -531,7 +571,7 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints "burn_many", vec![ Parameter::new("owner", CLType::PublicKey), - Parameter::new("token_ids", CLType::List(Box::new(CLType::String))), + Parameter::new("token_ids", CLType::List(Box::new(TokenId::cl_type()))), ], CLType::Unit, if secure { @@ -545,7 +585,7 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints vec![ Parameter::new("sender", CLType::PublicKey), Parameter::new("recipient", CLType::PublicKey), - Parameter::new("token_id", CLType::String), + Parameter::new("token_id", TokenId::cl_type()), ], CLType::Unit, None, @@ -555,7 +595,7 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints vec![ Parameter::new("sender", CLType::PublicKey), Parameter::new("recipient", CLType::PublicKey), - Parameter::new("token_ids", CLType::List(Box::new(CLType::String))), + Parameter::new("token_ids", CLType::List(Box::new(TokenId::cl_type()))), ], CLType::Unit, None, @@ -727,10 +767,10 @@ pub fn package_hash() -> ContractPackageHash { key.into() } -fn get_event_nonce() -> u64 { - get_key("event_nonce").unwrap_or_default() +fn get_nonce() -> u32 { + get_key("nonce").unwrap_or_default() } -fn set_event_nonce(nonce: u64) { - set_key("event_nonce", nonce); +fn set_nonce(nonce: u32) { + set_key("nonce", nonce); } diff --git a/dragons-nft-scripts/src/index.js b/dragons-nft-scripts/src/index.js index 358d372..fa8927f 100644 --- a/dragons-nft-scripts/src/index.js +++ b/dragons-nft-scripts/src/index.js @@ -23,10 +23,11 @@ const KEYS = Keys.Ed25519.parseKeyFiles( `${KEY_PAIR_PATH}/public_key.pem`, `${KEY_PAIR_PATH}/secret_key.pem` ); -const MINT_ONE_META_SIZE = 4; +const MINT_ONE_META_SIZE = 1; const MINT_COPIES_META_SIZE = 10; -const MINT_MANY_META_SIZE = 10; -const MINT_COPIES_COUNT = 5; +const MINT_COPIES_COUNT = 20; +const MINT_MANY_META_SIZE = 5; +const MINT_MANY_META_COUNT = 5; const CONTRACT_HASH = '6f833eb30447e7bad2e77d7a34b1b1d3870dd1d4a38823da2a84219a05733ced'; const cep47 = new CEP47Client(NODE_ADDRESS, CHAIN_NAME, EVENT_STREAM_ADDRESS); @@ -41,7 +42,7 @@ const install = async () => { const mintOne = async () => { const cep47 = new CEP47Client(NODE_ADDRESS, CHAIN_NAME, EVENT_STREAM_ADDRESS); await cep47.setContractHash(CONTRACT_HASH); - let meta = new Map([['name1', 'Medha'], ['name2', 'Maciej'], ['name3', 'Jan']]); + let meta = randomMetaMap(MINT_ONE_META_SIZE); const deployHash = await cep47.mintOne(KEYS, KEYS.publicKey, meta, MINT_ONE_PAYMENT_AMOUNT); console.log(`Mint One`); console.log(`... DeployHash: ${deployHash}`); @@ -171,12 +172,23 @@ const randomMetaMap = (size) => { data.set(`key${i}`, `value${i}`); } return data; + + // return new Map([ + // ["patentId", "EP-3420697-B1-AL"], + // ["applicationId", "EP17707409.3"], + // ["owner", "nChain Holdings Ltd"], + // ["ownerStatus", "verified"], + // ["familyId", "55753050"], + // ["ipweFamilyRating", "AAA"], + // ["insurancePolicyId", "123"], + // ["anticipatedExpirationDate", "2037-02-14"] + // ]); } const randomMetaArray = (size) => { let arr = []; for (let i = 0; i < size; i++) { - const item = randomMetaMap(3); + const item = randomMetaMap(MINT_MANY_META_COUNT); } return arr; } diff --git a/dragons-nft-tests/Cargo.toml b/dragons-nft-tests/Cargo.toml index 90e8431..d331919 100644 --- a/dragons-nft-tests/Cargo.toml +++ b/dragons-nft-tests/Cargo.toml @@ -11,7 +11,6 @@ casper-contract = "1.2.0" casper-types = "1.2.0" casper-engine-test-support = "1.2.0" maplit = "1.0.2" -cep47-test = { path = "../cep47-test" } [features] default = ["casper-contract/std", "casper-types/std", "casper-contract/test-support"] diff --git a/dragons-nft-tests/src/cep47.rs b/dragons-nft-tests/src/cep47.rs index bf655be..d810b95 100644 --- a/dragons-nft-tests/src/cep47.rs +++ b/dragons-nft-tests/src/cep47.rs @@ -3,7 +3,7 @@ use std::collections::BTreeMap; use casper_engine_test_support::{Code, Hash, SessionBuilder, TestContext, TestContextBuilder}; use casper_types::{ account::AccountHash, bytesrepr::FromBytes, runtime_args, CLTyped, PublicKey, RuntimeArgs, - SecretKey, URef, U256, U512, + SecretKey, U256, U512, }; pub mod token_cfg { @@ -134,16 +134,13 @@ impl CasperCEP47Contract { self.query_contract(meta_key(&token_id).as_str()) } - pub fn token_uref(&self, token_id: &TokenId) -> Option { - self.query_contract(test_uref_key(&token_id).as_str()) - } - - pub fn mint_one(&mut self, recipient: PublicKey, token_meta: Meta, sender: Sender) { + pub fn mint_one(&mut self, recipient: PublicKey, token_id: Option, token_meta: Meta, sender: Sender) { self.call( sender, "mint_one", runtime_args! { "recipient" => recipient, + "token_id" => token_id, "token_meta" => token_meta }, ); @@ -152,8 +149,9 @@ impl CasperCEP47Contract { pub fn mint_copies( &mut self, recipient: PublicKey, + token_ids: Option>, token_meta: Meta, - count: U256, + count: u32, sender: Sender, ) { self.call( @@ -161,18 +159,20 @@ impl CasperCEP47Contract { "mint_copies", runtime_args! { "recipient" => recipient, + "token_ids" => token_ids, "token_meta" => token_meta, "count" => count }, ); } - pub fn mint_many(&mut self, recipient: PublicKey, token_metas: Vec, sender: Sender) { + pub fn mint_many(&mut self, recipient: PublicKey, token_ids: Option>, token_metas: Vec, sender: Sender) { self.call( sender, "mint_many", runtime_args! { "recipient" => recipient, + "token_ids" => token_ids, "token_metas" => token_metas }, ); @@ -246,6 +246,18 @@ impl CasperCEP47Contract { }, ); } + + pub fn update_token_metadata(&mut self, token_id: TokenId, meta: Meta, sender: Sender) { + self.call( + sender, + "update_token_metadata", + runtime_args! { + "token_id" => token_id, + "meta" => meta + }, + ); + } + } fn balance_key(account: &AccountHash) -> String { @@ -263,7 +275,3 @@ fn meta_key(token_id: &TokenId) -> String { fn token_key(account: &AccountHash) -> String { format!("tokens_{}", account) } - -fn test_uref_key(token_id: &TokenId) -> String { - format!("turef_{}", token_id) -} diff --git a/dragons-nft-tests/src/contract_tests.rs b/dragons-nft-tests/src/contract_tests.rs index a904585..34c23fb 100644 --- a/dragons-nft-tests/src/contract_tests.rs +++ b/dragons-nft-tests/src/contract_tests.rs @@ -46,6 +46,7 @@ fn test_token_meta() { let token_meta = meta::red_dragon(); contract.mint_one( contract.ali.clone(), + None, token_meta.clone(), Sender(contract.admin.clone().to_account_hash()), ); @@ -57,11 +58,12 @@ fn test_token_meta() { } #[test] -fn test_mint_one() { +fn test_mint_one_with_random_token_id() { let mut contract = CasperCEP47Contract::deploy(); let token_meta = meta::red_dragon(); contract.mint_one( contract.ali.clone(), + None, token_meta, Sender(contract.admin.clone().to_account_hash()), ); @@ -74,19 +76,59 @@ fn test_mint_one() { assert_eq!(contract.owner_of(&ali_tokens[0]), Some(contract.ali)); } +#[test] +fn test_mint_one_with_set_token_id() { + let mut contract = CasperCEP47Contract::deploy(); + let token_id = TokenId::from("123456"); + let token_meta = meta::red_dragon(); + contract.mint_one( + contract.ali.clone(), + Some(token_id.clone()), + token_meta, + Sender(contract.admin.clone().to_account_hash()), + ); + + let ali_tokens: Vec = contract.tokens(contract.ali.clone()); + assert_eq!(ali_tokens, vec![token_id.clone()]); + assert_eq!(contract.total_supply(), U256::one()); + assert_eq!(contract.balance_of(contract.ali.clone()), U256::one()); + assert_eq!(U256::from(ali_tokens.len() as u64), U256::one()); + assert_eq!(contract.owner_of(&token_id), Some(contract.ali)); +} + +#[test] +#[should_panic] +fn test_mint_one_with_not_unique_token_id() { + let mut contract = CasperCEP47Contract::deploy(); + let token_id = TokenId::from("123456"); + let token_meta = meta::red_dragon(); + contract.mint_one( + contract.ali.clone(), + Some(token_id.clone()), + token_meta.clone(), + Sender(contract.admin.clone().to_account_hash()), + ); + contract.mint_one( + contract.ali.clone(), + Some(token_id.clone()), + token_meta, + Sender(contract.admin.clone().to_account_hash()), + ); +} + #[test] fn test_mint_copies() { let mut contract = CasperCEP47Contract::deploy(); let token_meta = meta::gold_dragon(); contract.mint_copies( contract.ali.clone(), + None, token_meta, - U256::from(3), + 3, Sender(contract.admin.clone().to_account_hash()), ); let ali_tokens: Vec = contract.tokens(contract.ali.clone()); - assert_eq!(contract.total_supply(), U256::from(3)); assert_eq!(contract.balance_of(contract.ali.clone()), U256::from(3)); assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(3)); @@ -107,6 +149,7 @@ fn test_mint_many() { let token_metas: Vec = vec![meta::gold_dragon(), meta::red_dragon()]; contract.mint_many( contract.ali.clone(), + None, token_metas, Sender(contract.admin.clone().to_account_hash()), ); @@ -134,6 +177,7 @@ fn test_burn_many() { ]; contract.mint_many( contract.ali.clone(), + None, token_metas, Sender(contract.admin.clone().to_account_hash()), ); @@ -165,6 +209,7 @@ fn test_burn_one() { let token_metas: Vec = vec![meta::gold_dragon(), meta::red_dragon()]; contract.mint_many( contract.ali.clone(), + None, token_metas, Sender(contract.admin.clone().to_account_hash()), ); @@ -193,6 +238,7 @@ fn test_transfer_token() { let token_metas: Vec = vec![meta::gold_dragon(), meta::blue_dragon()]; contract.mint_many( contract.ali.clone(), + None, token_metas, Sender(contract.admin.clone().to_account_hash()), ); @@ -227,6 +273,7 @@ fn test_transfer_many_tokens() { ]; contract.mint_many( contract.ali.clone(), + None, token_metas, Sender(contract.admin.clone().to_account_hash()), ); @@ -261,6 +308,7 @@ fn test_transfer_all_tokens() { let token_metas: Vec = vec![meta::gold_dragon(), meta::blue_dragon()]; contract.mint_many( contract.ali.clone(), + None, token_metas, Sender(contract.admin.clone().to_account_hash()), ); @@ -293,3 +341,19 @@ fn test_transfer_all_tokens() { Some(contract.bob.clone()) ); } + +#[test] +fn test_token_metadata_update() { + let mut contract = CasperCEP47Contract::deploy(); + let token_id = TokenId::from("123456"); + let token_meta = meta::red_dragon(); + contract.mint_one( + contract.ali.clone(), + Some(token_id.clone()), + token_meta, + Sender(contract.admin.clone().to_account_hash()), + ); + + contract.update_token_metadata(token_id.clone(), meta::blue_dragon(), Sender(contract.admin.clone().to_account_hash())); + assert_eq!(contract.token_meta(token_id).unwrap(), meta::blue_dragon()); +} \ No newline at end of file From 0851b78e86904ba6831acb05582cd5b3b7660d25 Mon Sep 17 00:00:00 2001 From: Maciej Zielinski Date: Mon, 26 Jul 2021 14:59:55 +0200 Subject: [PATCH 53/98] Rename 'meta' to 'token_meta' --- cep47/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cep47/src/lib.rs b/cep47/src/lib.rs index 43ff97b..2ba5943 100644 --- a/cep47/src/lib.rs +++ b/cep47/src/lib.rs @@ -421,7 +421,7 @@ pub extern "C" fn transfer_all_tokens() { #[no_mangle] pub extern "C" fn update_token_metadata() { let token_id: TokenId = runtime::get_named_arg("token_id"); - let meta: Meta = runtime::get_named_arg("meta"); + let meta: Meta = runtime::get_named_arg("token_meta"); let mut contract = CasperCEP47Contract::new(); let res = contract.update_token_metadata(token_id, meta); res.unwrap_or_revert(); From c2d384998fdb109171f404e93ce678c5fe74ea06 Mon Sep 17 00:00:00 2001 From: Jan Hoffmann Date: Mon, 26 Jul 2021 15:19:23 +0200 Subject: [PATCH 54/98] updated js versions --- dragons-nft-scripts/log.json | 388 -------------------------- dragons-nft-scripts/package-lock.json | 299 ++++++++++++++++++-- dragons-nft-scripts/package.json | 4 +- dragons-nft-scripts/src/index.js | 39 ++- 4 files changed, 308 insertions(+), 422 deletions(-) delete mode 100644 dragons-nft-scripts/log.json diff --git a/dragons-nft-scripts/log.json b/dragons-nft-scripts/log.json deleted file mode 100644 index 9425ca0..0000000 --- a/dragons-nft-scripts/log.json +++ /dev/null @@ -1,388 +0,0 @@ -{ - "api_version": "1.0.0", - "stored_value": { - "Contract": { - "contract_package_hash": "contract-package-wasmde2e302af2be3b54419c4a6e4f61c111d45fb03afab72a62c88fa723fcb21ee8", - "contract_wasm_hash": "contract-wasm-f36d165331fcd1451fd5508713242faf6b90f8ddd38bf66c6d70d46c215dc748", - "named_keys": [ - { - "name": "balances_5ce1390973f940679134da9f0fd43920ce0d800c6480d9bd91c2dfd9b4df5147", - "key": "uref-6c24b4eedf93f7f33636506e380308995409390c03201209ff987bb2cbc6504b-007" - }, - { - "name": "contract_package_hash", - "key": "uref-3ce2d3936293a6e1ed8c42b642b736d5743a5a9fb05090302d7c16bfcb2853af-007" - }, - { - "name": "meta", - "key": "uref-0c5c957ce405fb2428b3233270fabaed5a5222b6788efc9ee9f45bf4723cafa4-007" - }, - { - "name": "metas_17533245468374124908", - "key": "uref-b6c5b203da4e6ea64c0a477e0f146fcbe8d5c63239632c49352cced7e8ffde83-007" - }, - { - "name": "name", - "key": "uref-bd7f1b143441d713d57b89c1c27455920ea2974cfeb8770af9316227cb277486-007" - }, - { - "name": "owners_17533245468374124908", - "key": "uref-ac6e00efb078f2fb5413e8087fa36f36e7c8495a07736699c9c6dd9eda6793d0-007" - }, - { - "name": "paused", - "key": "uref-61ee0b199eceef9caa519b47a246890300b1d6a5d01f48202beaa10248dd40fe-007" - }, - { - "name": "symbol", - "key": "uref-9c8883fa4ae6afeaef516e4b22c2209e26cf8d5bce545615c6ccb7a48374b2d7-007" - }, - { - "name": "tokens_5ce1390973f940679134da9f0fd43920ce0d800c6480d9bd91c2dfd9b4df5147", - "key": "uref-695b1890926765c5399c3ce6fc711e460656476c3752dfc5170767a017322693-007" - }, - { - "name": "total_supply", - "key": "uref-5e86a907b13a4a888130347b4d58c4de57ce082223bb6e807c9b7b1cd77aca22-007" - } - ], - "entry_points": [ - { - "name": "attach", - "args": [ - { - "name": "token_uref", - "cl_type": "URef" - }, - { - "name": "recipient", - "cl_type": "PublicKey" - } - ], - "ret": "Unit", - "access": "Public", - "entry_point_type": "Contract" - }, - { - "name": "balance_of", - "args": [ - { - "name": "account", - "cl_type": "PublicKey" - } - ], - "ret": "U256", - "access": "Public", - "entry_point_type": "Contract" - }, - { - "name": "burn_many", - "args": [ - { - "name": "owner", - "cl_type": "PublicKey" - }, - { - "name": "token_ids", - "cl_type": { - "List": "String" - } - } - ], - "ret": "Unit", - "access": "Public", - "entry_point_type": "Contract" - }, - { - "name": "burn_one", - "args": [ - { - "name": "owner", - "cl_type": "PublicKey" - }, - { - "name": "token_id", - "cl_type": { - "List": "String" - } - } - ], - "ret": "Unit", - "access": "Public", - "entry_point_type": "Contract" - }, - { - "name": "detach", - "args": [ - { - "name": "owner", - "cl_type": "PublicKey" - }, - { - "name": "token_id", - "cl_type": "String" - } - ], - "ret": "Unit", - "access": "Public", - "entry_point_type": "Contract" - }, - { - "name": "is_paused", - "args": [], - "ret": "Bool", - "access": "Public", - "entry_point_type": "Contract" - }, - { - "name": "meta", - "args": [], - "ret": "String", - "access": "Public", - "entry_point_type": "Contract" - }, - { - "name": "mint_copies", - "args": [ - { - "name": "recipient", - "cl_type": "PublicKey" - }, - { - "name": "token_meta", - "cl_type": "String" - }, - { - "name": "count", - "cl_type": "U256" - } - ], - "ret": "Unit", - "access": "Public", - "entry_point_type": "Contract" - }, - { - "name": "mint_many", - "args": [ - { - "name": "recipient", - "cl_type": "PublicKey" - }, - { - "name": "token_metas", - "cl_type": { - "List": "String" - } - } - ], - "ret": "Unit", - "access": "Public", - "entry_point_type": "Contract" - }, - { - "name": "mint_one", - "args": [ - { - "name": "recipient", - "cl_type": "PublicKey" - }, - { - "name": "token_meta", - "cl_type": "String" - } - ], - "ret": "Unit", - "access": "Public", - "entry_point_type": "Contract" - }, - { - "name": "name", - "args": [], - "ret": "String", - "access": "Public", - "entry_point_type": "Contract" - }, - { - "name": "owner_of", - "args": [ - { - "name": "token_id", - "cl_type": "String" - } - ], - "ret": { - "Option": "PublicKey" - }, - "access": "Public", - "entry_point_type": "Contract" - }, - { - "name": "pause", - "args": [], - "ret": "Unit", - "access": "Public", - "entry_point_type": "Contract" - }, - { - "name": "symbol", - "args": [], - "ret": "String", - "access": "Public", - "entry_point_type": "Contract" - }, - { - "name": "token_meta", - "args": [ - { - "name": "token_id", - "cl_type": "String" - } - ], - "ret": { - "Option": "String" - }, - "access": "Public", - "entry_point_type": "Contract" - }, - { - "name": "tokens", - "args": [ - { - "name": "owner", - "cl_type": "PublicKey" - } - ], - "ret": { - "List": "String" - }, - "access": "Public", - "entry_point_type": "Contract" - }, - { - "name": "total_supply", - "args": [ - { - "name": "owner", - "cl_type": "PublicKey" - } - ], - "ret": { - "List": "String" - }, - "access": "Public", - "entry_point_type": "Contract" - }, - { - "name": "transfer_all_tokens", - "args": [ - { - "name": "sender", - "cl_type": "PublicKey" - }, - { - "name": "recipient", - "cl_type": "PublicKey" - } - ], - "ret": "Unit", - "access": "Public", - "entry_point_type": "Contract" - }, - { - "name": "transfer_many_tokens", - "args": [ - { - "name": "sender", - "cl_type": "PublicKey" - }, - { - "name": "recipient", - "cl_type": "PublicKey" - }, - { - "name": "token_ids", - "cl_type": { - "List": "String" - } - } - ], - "ret": "Unit", - "access": "Public", - "entry_point_type": "Contract" - }, - { - "name": "transfer_token", - "args": [ - { - "name": "sender", - "cl_type": "PublicKey" - }, - { - "name": "recipient", - "cl_type": "PublicKey" - }, - { - "name": "token_id", - "cl_type": "String" - } - ], - "ret": "Unit", - "access": "Public", - "entry_point_type": "Contract" - }, - { - "name": "unpause", - "args": [], - "ret": "Unit", - "access": "Public", - "entry_point_type": "Contract" - } - ], - "protocol_version": "1.0.0" - } - }, - "merkle_proof": "0100000001133c24a6e7a953cec7c6dff35e1f19c6bc97a01e83f6e971c11d10151477ee8f03de2e302af2be3b54419c4a6e4f61c111d45fb03afab72a62c88fa723fcb21ee8f36d165331fcd1451fd5508713242faf6b90f8ddd38bf66c6d70d46c215dc7480a0000004900000062616c616e6365735f35636531333930393733663934303637393133346461396630666434333932306365306438303063363438306439626439316332646664396234646635313437026c24b4eedf93f7f33636506e380308995409390c03201209ff987bb2cbc6504b0715000000636f6e74726163745f7061636b6167655f68617368023ce2d3936293a6e1ed8c42b642b736d5743a5a9fb05090302d7c16bfcb2853af07040000006d657461020c5c957ce405fb2428b3233270fabaed5a5222b6788efc9ee9f45bf4723cafa4071a0000006d657461735f313735333332343534363833373431323439303802b6c5b203da4e6ea64c0a477e0f146fcbe8d5c63239632c49352cced7e8ffde8307040000006e616d6502bd7f1b143441d713d57b89c1c27455920ea2974cfeb8770af9316227cb277486071b0000006f776e6572735f313735333332343534363833373431323439303802ac6e00efb078f2fb5413e8087fa36f36e7c8495a07736699c9c6dd9eda6793d007060000007061757365640261ee0b199eceef9caa519b47a246890300b1d6a5d01f48202beaa10248dd40fe070600000073796d626f6c029c8883fa4ae6afeaef516e4b22c2209e26cf8d5bce545615c6ccb7a48374b2d70747000000746f6b656e735f3563653133393039373366393430363739313334646139663066643433393230636530643830306336343830643962643931633264666439623464663531343702695b1890926765c5399c3ce6fc711e460656476c3752dfc5170767a017322693070c000000746f74616c5f737570706c79025e86a907b13a4a888130347b4d58c4de57ce082223bb6e807c9b7b1cd77aca2207150000000600000061747461636806000000617474616368020000000a000000746f6b656e5f757265660c09000000726563697069656e74160901010a00000062616c616e63655f6f660a00000062616c616e63655f6f6601000000070000006163636f756e7416070101090000006275726e5f6d616e79090000006275726e5f6d616e7902000000050000006f776e65721609000000746f6b656e5f6964730e0a090101080000006275726e5f6f6e65080000006275726e5f6f6e6502000000050000006f776e65721608000000746f6b656e5f69640e0a090101060000006465746163680600000064657461636802000000050000006f776e65721608000000746f6b656e5f69640a0901010900000069735f7061757365640900000069735f70617573656400000000000101040000006d657461040000006d657461000000000a01010b0000006d696e745f636f706965730b0000006d696e745f636f706965730300000009000000726563697069656e74160a000000746f6b656e5f6d6574610a05000000636f756e7407090101090000006d696e745f6d616e79090000006d696e745f6d616e790200000009000000726563697069656e74160b000000746f6b656e5f6d657461730e0a090101080000006d696e745f6f6e65080000006d696e745f6f6e650200000009000000726563697069656e74160a000000746f6b656e5f6d6574610a090101040000006e616d65040000006e616d65000000000a0101080000006f776e65725f6f66080000006f776e65725f6f660100000008000000746f6b656e5f69640a0d160101050000007061757365050000007061757365000000000901010600000073796d626f6c0600000073796d626f6c000000000a01010a000000746f6b656e5f6d6574610a000000746f6b656e5f6d6574610100000008000000746f6b656e5f69640a0d0a010106000000746f6b656e7306000000746f6b656e7301000000050000006f776e6572160e0a01010c000000746f74616c5f737570706c790c000000746f74616c5f737570706c7901000000050000006f776e6572160e0a0101130000007472616e736665725f616c6c5f746f6b656e73130000007472616e736665725f616c6c5f746f6b656e73020000000600000073656e6465721609000000726563697069656e7416090101140000007472616e736665725f6d616e795f746f6b656e73140000007472616e736665725f6d616e795f746f6b656e73030000000600000073656e6465721609000000726563697069656e741609000000746f6b656e5f6964730e0a0901010e0000007472616e736665725f746f6b656e0e0000007472616e736665725f746f6b656e030000000600000073656e6465721609000000726563697069656e741608000000746f6b656e5f69640a09010107000000756e706175736507000000756e7061757365000000000901010100000000000000000000000200000000130e00000012003f5b082099df8f41592be59fdac9e0397ac1b4ba2270ec3e9cfeef7ed769a6b31f00099e755e0329106e4e618858cc1b96b1251448099080c05118e8dd846d42b90f27001c696f52a052d9a7df04c2fc622f2e0dd98688a7ec32f5bd42be9d6f844f37132a00607bfc73940a11ea03c78bf2b0e01433d5be0b7888d6f0d9adeb178a79e01e554600aff02519c89249401d7ea122db629b0fa641722352673a73ec2dc35d5cafa8e75a0079b92bfa00f5058e4fc579306405ef034155739f755059f6794405941b9734a65e0061c97301fbd4ead9fb4a8737cd816f54409fc9ed4f86ca480ee875006b28f5086b009934e9a721247e9ff5da74ba3386fda784bb27dcb09a0c4c83fd8744a4b5aa5a9a001a11b9e48a1709b3b1d75bf502d3d6b0a81e44ed88cb03ceec47308023aed319a500320c588a3fae69b918d3e213305c4b46160dd79f47d9154933592601f7859511a70003718e3338b9a532e906de6238987d014ac94aa27f8304ec009043aa79b2723dde00c8c7d3a0d03d922021bcd79c6bc93efe0aef44d651eb40f5504d057a7b7ff9c4df001c7d83f484ba65421d7b8f9ed06b86299d217c0d2e1211cad52b1883b437dee0f300ec7f76566c95fcfb783ead420c554bdbd5bfdfc23600cfcba8b321882457882e00010700000000011eb2a3081e5d3596f032b47b2acaebe37241a34209a131741d95c9fce7fdafd002015fd25d362a2b4376f9c5997ef27244134257bdfddc3e1b8ab0b283747e66208e03014634904112272b45c943106d96b1bb7f1bdddc8d21ea56caedb69bbb3e4305e804018ad5dea911b4fb12e6d95ba70df2d823ba8e0923fe5b156f1f39c6c20e1b84c705014074fbd1ea05450c65ad5f776c2983dd9ad550d328e8eab523f9f1bbe7b438a206015eacaebe1945d427b031f9ac430d23b3eb8a6d19e1a9ed7a3fb4e8ad3da47bea07012f3b47e854327d4e52030674ce47cdb54392dbac99e6fa3d4700cd47310deebd" -} -JSON undefined true -undefined -undefined -undefined -undefined -undefined -undefined -undefined -undefined -undefined -undefined -undefined -undefined -undefined -undefined -undefined -undefined -undefined -undefined -undefined -undefined -undefined -e { - Contract: e { - contractPackageHash: 'contract-package-wasmde2e302af2be3b54419c4a6e4f61c111d45fb03afab72a62c88fa723fcb21ee8', - contractWasmHash: 'contract-wasm-f36d165331fcd1451fd5508713242faf6b90f8ddd38bf66c6d70d46c215dc748', - entrypoints: [ - undefined, undefined, undefined, - undefined, undefined, undefined, - undefined, undefined, undefined, - undefined, undefined, undefined, - undefined, undefined, undefined, - undefined, undefined, undefined, - undefined, undefined, undefined - ], - protocolVersion: '1.0.0', - namedKeys: [ - [e], [e], [e], [e], - [e], [e], [e], [e], - [e], [e] - ] - } -} diff --git a/dragons-nft-scripts/package-lock.json b/dragons-nft-scripts/package-lock.json index 5ba13d1..0f11e0a 100644 --- a/dragons-nft-scripts/package-lock.json +++ b/dragons-nft-scripts/package-lock.json @@ -5,9 +5,9 @@ "requires": true, "dependencies": { "@ethersproject/bignumber": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.4.0.tgz", - "integrity": "sha512-OXUu9f9hO3vGRIPxU40cignXZVaYyfx6j9NNMjebKdnaCL3anCLSSy8/b8d03vY6dh7duCC0kW72GEC4tZer2w==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.4.1.tgz", + "integrity": "sha512-fJhdxqoQNuDOk6epfM7yD6J8Pol4NUCy1vkaGAkuujZm0+lNow//MKu1hLhRiYV4BsOHyBv5/lsTjF+7hWwhJg==", "requires": { "@ethersproject/bytes": "^5.4.0", "@ethersproject/logger": "^5.4.0", @@ -105,9 +105,9 @@ "integrity": "sha512-YSBPTLTVm2e2OoQIDYx8HaeWJ5tTToLH67kXR7zYNGupXMEHa2++G8k+DczX2cFVgalypqtyZIcU19AFcmOpmg==" }, "@types/node": { - "version": "16.4.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.4.0.tgz", - "integrity": "sha512-HrJuE7Mlqcjj+00JqMWpZ3tY8w7EUd+S0U3L1+PQSWiXZbOgyQDvi+ogoUxaHApPJq5diKxYBQwA3iIlNcPqOg==" + "version": "16.4.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.4.3.tgz", + "integrity": "sha512-GKM4FLMkWDc0sfx7tXqPWkM6NBow1kge0fgQh0bOnlqo4iT1kvTvMEKE0c1RtUGnbLlGRXiAA8SumE//90uKAg==" }, "@types/pbkdf2": { "version": "3.1.0", @@ -298,6 +298,14 @@ "safer-buffer": "^2.1.0" } }, + "axios": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", + "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "requires": { + "follow-redirects": "^1.10.0" + } + }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -407,42 +415,275 @@ "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" }, "caniuse-lite": { - "version": "1.0.30001246", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001246.tgz", - "integrity": "sha512-Tc+ff0Co/nFNbLOrziBXmMVtpt9S2c2Y+Z9Nk9Khj09J+0zR9ejvIW5qkZAErCbOrVODCx/MN+GpB5FNBs5GFA==" + "version": "1.0.30001247", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001247.tgz", + "integrity": "sha512-4rS7co+7+AoOSPRPOPUt5/GdaqZc0EsUpWk66ofE3HJTAajUK2Ss2VwoNzVN69ghg8lYYlh0an0Iy4LIHHo9UQ==" }, "casper-cep47-js-client": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/casper-cep47-js-client/-/casper-cep47-js-client-0.2.0.tgz", - "integrity": "sha512-zc+3LeDsIEzc9wp7f3Tw5+nxNJgz/WwcnZ3nmpM2LM7BCzka9y46M7ZNNVn/IVhlDme5kHhEcDTpgnWkHTdECw==", + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/casper-cep47-js-client/-/casper-cep47-js-client-0.2.3.tgz", + "integrity": "sha512-x2ecS4NTvn5w247vYX1ZA2rIH1R1Waen9B04ZVfHH5BpN8ihtYRN48otTF6OwOXqSJWEopHwjqEAyaFcY7hDdw==", "requires": { "@ethersproject/bignumber": "^5.0.8", - "casper-js-sdk": "2.2.0" + "casper-js-sdk": "2.2.3", + "ts-results": "^3.3.0" + }, + "dependencies": { + "casper-js-sdk": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/casper-js-sdk/-/casper-js-sdk-2.2.3.tgz", + "integrity": "sha512-e8vyktJBsSBh8lJzwwbWAgP7mTHGC04iE4Fhd7sdYCYClWjKv+XQ22aXNwawWYNOxHqipF7n7Z319F9dEhxQhg==", + "requires": { + "@ethersproject/bignumber": "^5.0.8", + "@ethersproject/bytes": "^5.0.5", + "@ethersproject/constants": "^5.0.5", + "@open-rpc/client-js": "^1.6.2", + "@types/eccrypto": "^1.1.2", + "blakejs": "^1.1.0", + "eccrypto": "^1.1.6", + "eslint-plugin-prettier": "^3.4.0", + "ethereum-cryptography": "^0.1.3", + "glob": "^7.1.6", + "humanize-duration": "^3.24.0", + "key-encoder": "^2.0.3", + "reflect-metadata": "^0.1.13", + "ts-results": "^3.2.1", + "tweetnacl-ts": "^1.0.3", + "tweetnacl-util": "^0.15.0", + "typedjson": "^1.6.0-rc2", + "webpack": "^5.24.3" + } + } } }, "casper-js-sdk": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/casper-js-sdk/-/casper-js-sdk-2.2.0.tgz", - "integrity": "sha512-VU2GxGHt++68IR+n2h+UiZnrwBnNVkQKAJ1RWSv3A+zqHZwTZahMF+NO5pz43xwrDBG+sET2vu8JqJ4JJ7AsnQ==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/casper-js-sdk/-/casper-js-sdk-1.4.3.tgz", + "integrity": "sha512-TtKRzeFX9mhEdsqFAt9PQlQ8Y1vS8SygO8XAviL8lXuunND/WURQKVRUbN/UQmj8Mgdx+Vo7zbJV8g9etuv26g==", "requires": { "@ethersproject/bignumber": "^5.0.8", "@ethersproject/bytes": "^5.0.5", "@ethersproject/constants": "^5.0.5", "@open-rpc/client-js": "^1.6.2", "@types/eccrypto": "^1.1.2", + "axios": "^0.21.1", "blakejs": "^1.1.0", "eccrypto": "^1.1.6", - "eslint-plugin-prettier": "^3.4.0", "ethereum-cryptography": "^0.1.3", "glob": "^7.1.6", "humanize-duration": "^3.24.0", + "jsbi": "^3.1.2", "key-encoder": "^2.0.3", "reflect-metadata": "^0.1.13", + "rxjs": "^6.5.3", "ts-results": "^3.2.1", "tweetnacl-ts": "^1.0.3", "tweetnacl-util": "^0.15.0", "typedjson": "^1.6.0-rc2", "webpack": "^5.24.3" + }, + "dependencies": { + "@ethersproject/bignumber": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.4.1.tgz", + "integrity": "sha512-fJhdxqoQNuDOk6epfM7yD6J8Pol4NUCy1vkaGAkuujZm0+lNow//MKu1hLhRiYV4BsOHyBv5/lsTjF+7hWwhJg==", + "requires": { + "@ethersproject/bytes": "^5.4.0", + "@ethersproject/logger": "^5.4.0", + "bn.js": "^4.11.9" + } + }, + "@ethersproject/bytes": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.4.0.tgz", + "integrity": "sha512-H60ceqgTHbhzOj4uRc/83SCN9d+BSUnOkrr2intevqdtEMO1JFVZ1XL84OEZV+QjV36OaZYxtnt4lGmxcGsPfA==", + "requires": { + "@ethersproject/logger": "^5.4.0" + } + }, + "@ethersproject/constants": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.4.0.tgz", + "integrity": "sha512-tzjn6S7sj9+DIIeKTJLjK9WGN2Tj0P++Z8ONEIlZjyoTkBuODN+0VfhAyYksKi43l1Sx9tX2VlFfzjfmr5Wl3Q==", + "requires": { + "@ethersproject/bignumber": "^5.4.0" + } + }, + "@open-rpc/client-js": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@open-rpc/client-js/-/client-js-1.7.0.tgz", + "integrity": "sha512-cRGJbXTgdhJNU49vWzJIATRmKBLP2x6tuHJzX9Jg3N8f1VEkge0riUEek2LFIrZiM4TdUp8XV4Ns1W0SZzdfSw==", + "requires": { + "isomorphic-fetch": "^3.0.0", + "isomorphic-ws": "^4.0.1", + "strict-event-emitter-types": "^2.0.0", + "ws": "^7.0.0" + } + }, + "@types/eccrypto": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@types/eccrypto/-/eccrypto-1.1.3.tgz", + "integrity": "sha512-3O0qER6JMYReqVbcQTGmXeMHdw3O+rVps63tlo5g5zoB3altJS8yzSvboSivwVWeYO9o5jSATu7P0UIqYZPgow==", + "requires": { + "@types/expect": "^1.20.4", + "@types/node": "*" + } + }, + "blakejs": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.1.tgz", + "integrity": "sha512-bLG6PHOCZJKNshTjGRBvET0vTciwQE6zFKOKKXPDJfwFBd4Ac0yBfPZqcGvGJap50l7ktvlpFqc2jGVaUgbJgg==" + }, + "eccrypto": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/eccrypto/-/eccrypto-1.1.6.tgz", + "integrity": "sha512-d78ivVEzu7Tn0ZphUUaL43+jVPKTMPFGtmgtz1D0LrFn7cY3K8CdrvibuLz2AAkHBLKZtR8DMbB2ukRYFk987A==", + "requires": { + "acorn": "7.1.1", + "elliptic": "6.5.4", + "es6-promise": "4.2.8", + "nan": "2.14.0", + "secp256k1": "3.7.1" + } + }, + "ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "requires": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + }, + "dependencies": { + "secp256k1": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz", + "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==", + "requires": { + "elliptic": "^6.5.2", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + } + } + } + }, + "glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "humanize-duration": { + "version": "3.27.0", + "resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.27.0.tgz", + "integrity": "sha512-qLo/08cNc3Tb0uD7jK0jAcU5cnqCM0n568918E7R2XhMr/+7F37p4EY062W/stg7tmzvknNn9b/1+UhVRzsYrQ==" + }, + "key-encoder": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/key-encoder/-/key-encoder-2.0.3.tgz", + "integrity": "sha512-fgBtpAGIr/Fy5/+ZLQZIPPhsZEcbSlYu/Wu96tNDFNSjSACw5lEIOFeaVdQ/iwrb8oxjlWi6wmWdH76hV6GZjg==", + "requires": { + "@types/elliptic": "^6.4.9", + "asn1.js": "^5.0.1", + "bn.js": "^4.11.8", + "elliptic": "^6.4.1" + } + }, + "reflect-metadata": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", + "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" + }, + "ts-results": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ts-results/-/ts-results-3.3.0.tgz", + "integrity": "sha512-FWqxGX2NHp5oCyaMd96o2y2uMQmSu8Dey6kvyuFdRJ2AzfmWo3kWa4UsPlCGlfQ/qu03m09ZZtppMoY8EMHuiA==" + }, + "tweetnacl-ts": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl-ts/-/tweetnacl-ts-1.0.3.tgz", + "integrity": "sha512-C5I/dWf6xjAXaCDlf84T4HvozU/8ycAlq5WRllF1hAeeq5390tfXD+bNas5bhEV0HMSOx8bsQYpLjPl8wfnEeQ==", + "requires": { + "tslib": "^1" + } + }, + "tweetnacl-util": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", + "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==" + }, + "typedjson": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/typedjson/-/typedjson-1.7.0.tgz", + "integrity": "sha512-MnRgQLwtEcdHqQG0FkT8ebpBG53Wgr/axYRbiD2WL5NcYx8Z2AoCpXvtTfLnuPqOBKG/9JpXq0O/nl2m4wqJYw==", + "requires": { + "tslib": "^2.0.1" + }, + "dependencies": { + "tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" + } + } + }, + "webpack": { + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.46.0.tgz", + "integrity": "sha512-qxD0t/KTedJbpcXUmvMxY5PUvXDbF8LsThCzqomeGaDlCA6k998D8yYVwZMvO8sSM3BTEOaD4uzFniwpHaTIJw==", + "requires": { + "@types/eslint-scope": "^3.7.0", + "@types/estree": "^0.0.50", + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/wasm-edit": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "acorn": "^8.4.1", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.8.0", + "es-module-lexer": "^0.7.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.4", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.1.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.1.3", + "watchpack": "^2.2.0", + "webpack-sources": "^2.3.1" + }, + "dependencies": { + "acorn": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", + "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==" + } + } + } } }, "chrome-trace-event": { @@ -523,9 +764,9 @@ } }, "electron-to-chromium": { - "version": "1.3.784", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.784.tgz", - "integrity": "sha512-JTPxdUibkefeomWNaYs8lI/x/Zb4cOhZWX+d7kpzsNKzUd07pNuo/AcHeNJ/qgEchxM1IAxda9aaGUhKN/poOg==" + "version": "1.3.786", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.786.tgz", + "integrity": "sha512-AmvbLBj3hepRk8v/DHrFF8gINxOFfDbrn6Ts3PcK46/FBdQb5OMmpamSpZQXSkfi77FfBzYtQtAk+00LCLYMVw==" }, "elliptic": { "version": "6.5.4", @@ -671,6 +912,11 @@ "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", "optional": true }, + "follow-redirects": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz", + "integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==" + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -776,6 +1022,11 @@ "supports-color": "^8.0.0" } }, + "jsbi": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/jsbi/-/jsbi-3.1.5.tgz", + "integrity": "sha512-w2BY0VOYC1ahe+w6Qhl4SFoPvPsZ9NPHY4bwass+LCgU7RK3PBoVQlQ3G1s7vI8W3CYyJiEXcbKF7FIM/L8q3Q==" + }, "json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", @@ -965,6 +1216,14 @@ "inherits": "^2.0.1" } }, + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "requires": { + "tslib": "^1.9.0" + } + }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", diff --git a/dragons-nft-scripts/package.json b/dragons-nft-scripts/package.json index ed07995..bb9fb61 100644 --- a/dragons-nft-scripts/package.json +++ b/dragons-nft-scripts/package.json @@ -16,7 +16,7 @@ "author": "", "license": "ISC", "dependencies": { - "casper-js-sdk": "2.2.0", - "casper-cep47-js-client": "0.2.0" + "casper-cep47-js-client": "^0.2.3", + "casper-js-sdk": "^1.4.3" } } diff --git a/dragons-nft-scripts/src/index.js b/dragons-nft-scripts/src/index.js index fa8927f..68509c3 100644 --- a/dragons-nft-scripts/src/index.js +++ b/dragons-nft-scripts/src/index.js @@ -1,24 +1,25 @@ -const { CLValueBuilder, Keys, CLPublicKey } = require("casper-js-sdk"); +const { CLValueBuilder, Keys, CLPublicKey, CLPublicKeyType } = require("casper-js-sdk"); const { CEP47Client, utils, constants } = require("casper-cep47-js-client"); -const NODE_ADDRESS = 'http://3.143.158.19:7777/rpc'; -// const NODE_ADDRESS = 'http://localhost:40101/rpc'; -const EVENT_STREAM_ADDRESS = 'http://3.143.158.19:9999/events'; +// const NODE_ADDRESS = 'http://3.143.158.19:7777/rpc'; +const NODE_ADDRESS = 'http://localhost:40101/rpc'; +// const EVENT_STREAM_ADDRESS = 'http://3.143.158.19:9999/events'; +const EVENT_STREAM_ADDRESS = 'http://localhost:60101/events'; const INSTALL_PAYMENT_AMOUNT = '200000000000'; const MINT_ONE_PAYMENT_AMOUNT = '2000000000'; const MINT_COPIES_PAYMENT_AMOUNT = '100000000000'; const BURN_ONE_PAYMENT_AMOUNT = '12000000000'; -const CHAIN_NAME = 'integration-test'; -// const CHAIN_NAME = 'casper-net-1'; +// const CHAIN_NAME = 'integration-test'; +const CHAIN_NAME = 'casper-net-1'; const WASM_PATH = "./../target/wasm32-unknown-unknown/release/dragons-nft.wasm"; -const TOKEN_NAME = 'event_nft_3'; +const TOKEN_NAME = 'event_nft_4'; const TOKEN_SYMBOL = 'DRAG'; const TOKEN_META = new Map([ ['origin', 'fire'], ['lifetime', 'infinite'] ]); -const KEY_PAIR_PATH = '/home/ziel/workspace/casperlabs/integration-key/master'; -// const KEY_PAIR_PATH = '/Users/janhoffmann/casper-node/utils/nctl/assets/net-1/faucet'; +// const KEY_PAIR_PATH = '/home/ziel/workspace/casperlabs/integration-key/master'; +const KEY_PAIR_PATH = '/Users/janhoffmann/casper-node/utils/nctl/assets/net-1/faucet'; const KEYS = Keys.Ed25519.parseKeyFiles( `${KEY_PAIR_PATH}/public_key.pem`, `${KEY_PAIR_PATH}/secret_key.pem` @@ -28,7 +29,7 @@ const MINT_COPIES_META_SIZE = 10; const MINT_COPIES_COUNT = 20; const MINT_MANY_META_SIZE = 5; const MINT_MANY_META_COUNT = 5; -const CONTRACT_HASH = '6f833eb30447e7bad2e77d7a34b1b1d3870dd1d4a38823da2a84219a05733ced'; +const CONTRACT_HASH = '6c0d0919acbcbe02665eb4cb32b856fd2ce5359432c0af43818d538c17de96a8'; const cep47 = new CEP47Client(NODE_ADDRESS, CHAIN_NAME, EVENT_STREAM_ADDRESS); @@ -43,7 +44,7 @@ const mintOne = async () => { const cep47 = new CEP47Client(NODE_ADDRESS, CHAIN_NAME, EVENT_STREAM_ADDRESS); await cep47.setContractHash(CONTRACT_HASH); let meta = randomMetaMap(MINT_ONE_META_SIZE); - const deployHash = await cep47.mintOne(KEYS, KEYS.publicKey, meta, MINT_ONE_PAYMENT_AMOUNT); + const deployHash = await cep47.mintOne(KEYS, KEYS.publicKey, "ABC123", meta, MINT_ONE_PAYMENT_AMOUNT); console.log(`Mint One`); console.log(`... DeployHash: ${deployHash}`); } @@ -67,8 +68,12 @@ const mintCopies = async () => { const mintMany = async () => { await cep47.setContractHash(CONTRACT_HASH); let meta = randomMetaArray(MINT_MANY_META_SIZE); + let arr = []; + for (let i = 0; i < meta.length; i++) { + arr.push(`a${i}`); + } const deployHash = await cep47.mintMany( - KEYS, KEYS.publicKey, meta, MINT_COPIES_PAYMENT_AMOUNT); + KEYS, KEYS.publicKey, meta, arr, MINT_COPIES_PAYMENT_AMOUNT); console.log(`Mint Many`); console.log(`... DeployHash: ${deployHash}`); } @@ -109,6 +114,12 @@ const tokenMeta = async (tokenId) => { console.log('Token meta', value); } +const updateTokenMetadata = async (tokenId) => { + await cep47.setContractHash(CONTRACT_HASH); + const value = await cep47.updateTokenMetadata(KEYS, tokenId, new Map([['name', 'me']]), BURN_ONE_PAYMENT_AMOUNT); + console.log('Deploy hash', value); +} + const printAccount = async () => { let account = await utils.getAccountInfo(NODE_ADDRESS, KEYS.publicKey); console.log(account); @@ -189,6 +200,7 @@ const randomMetaArray = (size) => { let arr = []; for (let i = 0; i < size; i++) { const item = randomMetaMap(MINT_MANY_META_COUNT); + arr.push(item); } return arr; } @@ -239,6 +251,9 @@ switch (command) { case 'tokens_of': tokensOf(arg1); break; + case 'update_token_metadata': + updateTokenMetadata(arg1); + break; case 'pause': pause(); break; From 943292dddae3fcbcf7df6bb934585449e0c9f01e Mon Sep 17 00:00:00 2001 From: Maciej Zielinski Date: Tue, 27 Jul 2021 09:48:10 +0200 Subject: [PATCH 55/98] owner_of fix --- cep47/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cep47/src/lib.rs b/cep47/src/lib.rs index 2ba5943..b5180c6 100644 --- a/cep47/src/lib.rs +++ b/cep47/src/lib.rs @@ -266,7 +266,7 @@ pub extern "C" fn balance_of() { pub extern "C" fn owner_of() { let token_id: TokenId = runtime::get_named_arg("token_id"); let contract = CasperCEP47Contract::new(); - ret(contract.owner_of(token_id)) + ret(contract.owner_of(&token_id)) } #[cfg(not(feature = "no_total_supply"))] From 5ae5637c8190635df149ff25db51a8f80b932087 Mon Sep 17 00:00:00 2001 From: Maciej Zielinski Date: Thu, 29 Jul 2021 03:22:47 +0200 Subject: [PATCH 56/98] Support for 1.3 features. --- cep47-logic/Cargo.toml | 2 +- cep47-logic/src/events.rs | 20 + cep47-logic/src/lib.rs | 206 ++++---- cep47-logic/src/tests.rs | 264 +++++----- cep47/Cargo.toml | 4 +- cep47/src/cep47_storage.rs | 201 ++++++++ cep47/src/data.rs | 276 +++++++++++ cep47/src/entrypoints.rs | 188 ++++++++ cep47/src/lib.rs | 609 +++--------------------- dragons-nft-scripts/package-lock.json | 278 +---------- dragons-nft-scripts/package.json | 4 +- dragons-nft-scripts/src/index.js | 44 +- dragons-nft-tests/Cargo.toml | 9 +- dragons-nft-tests/src/cep47.rs | 177 ++++--- dragons-nft-tests/src/contract_tests.rs | 215 ++++----- dragons-nft/Cargo.toml | 6 +- dragons-nft/src/main.rs | 3 - 17 files changed, 1243 insertions(+), 1263 deletions(-) create mode 100644 cep47-logic/src/events.rs create mode 100644 cep47/src/cep47_storage.rs create mode 100644 cep47/src/data.rs create mode 100644 cep47/src/entrypoints.rs diff --git a/cep47-logic/Cargo.toml b/cep47-logic/Cargo.toml index d50bd36..171bd5f 100644 --- a/cep47-logic/Cargo.toml +++ b/cep47-logic/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Maciej Zielinski "] edition = "2018" [dependencies] -casper-types = "1.2.1" +casper-types = "1.3.1" [dev-dependencies] rand = "0.7.3" diff --git a/cep47-logic/src/events.rs b/cep47-logic/src/events.rs new file mode 100644 index 0000000..0b618f3 --- /dev/null +++ b/cep47-logic/src/events.rs @@ -0,0 +1,20 @@ +use std::collections::{BTreeMap, BTreeSet}; + +use casper_types::{account::AccountHash, ContractPackageHash, Key}; + +use crate::TokenId; + +pub enum CEP47Event { + MetadataUpdate { + token_id: TokenId, + }, + Transfer { + sender: Key, + recipient: Key, + token_ids: Vec, + }, + Mint { + recipient: Key, + token_ids: Vec, + }, +} diff --git a/cep47-logic/src/lib.rs b/cep47-logic/src/lib.rs index 217e90b..c0f6a5d 100644 --- a/cep47-logic/src/lib.rs +++ b/cep47-logic/src/lib.rs @@ -3,15 +3,18 @@ use std::collections::BTreeMap; -use casper_types::{ApiError, AsymmetricType, PublicKey, URef, U256}; +use casper_types::{ApiError, AsymmetricType, ContractPackageHash, Key, URef, U256}; #[cfg(test)] #[macro_use] extern crate maplit; +pub mod events; #[cfg(test)] pub mod tests; +use events::CEP47Event; + pub type TokenId = String; pub type Meta = BTreeMap; @@ -49,11 +52,11 @@ pub trait CEP47Contract: WithStorage { } // Getters - fn balance_of(&self, owner: PublicKey) -> U256 { + fn balance_of(&self, owner: &Key) -> U256 { self.storage().balance_of(owner) } - fn owner_of(&self, token_id: &TokenId) -> Option { + fn owner_of(&self, token_id: &TokenId) -> Option { self.storage().onwer_of(token_id) } @@ -61,11 +64,11 @@ pub trait CEP47Contract: WithStorage { self.storage().total_supply() } - fn token_meta(&self, token_id: TokenId) -> Option { + fn token_meta(&self, token_id: &TokenId) -> Option { self.storage().token_meta(token_id) } - fn tokens(&self, owner: PublicKey) -> Vec { + fn tokens(&self, owner: &Key) -> Vec { self.storage().get_tokens(owner) } @@ -83,52 +86,56 @@ pub trait CEP47Contract: WithStorage { // Minter function. // Guarded by the entrypoint group. - fn mint_one(&mut self, recipient: PublicKey, token_id: Option, token_meta: Meta) -> Result<(), Error> { - match token_id { - Some(token_id) => { - let valid = self.storage().validate_token_ids(&vec![token_id.clone()]); - if !valid { - Err(Error::TokenIdAlreadyExists) - } else { - self.storage_mut() - .mint_many(recipient, vec![token_id],vec![token_meta]); - Ok(()) - } - }, - None => { - let token_ids = self.storage_mut().gen_token_ids(1); - self.storage_mut() - .mint_many(recipient, token_ids,vec![token_meta]); - Ok(()) - } - } + fn mint_one( + &mut self, + recipient: &Key, + token_id: Option, + token_meta: Meta, + ) -> Result<(), Error> { + self.mint_many(recipient, token_id.map(|id| vec![id]), vec![token_meta]) } - fn mint_many(&mut self, recipient: PublicKey, token_ids: Option>, token_metas: Vec) -> Result<(), Error> { - match token_ids { + fn mint_many( + &mut self, + recipient: &Key, + token_ids: Option>, + token_metas: Vec, + ) -> Result<(), Error> { + let unique_token_ids = match token_ids { + // Validate token_ids and metas. Some(token_ids) => { if token_ids.len() != token_metas.len() { return Err(Error::ArgumentsError); - } + }; let valid = self.storage().validate_token_ids(&token_ids); if !valid { - Err(Error::TokenIdAlreadyExists) - } else { - self.storage_mut() - .mint_many(recipient, token_ids, token_metas); - Ok(()) - } - }, - None => { - let token_ids = self.storage_mut().gen_token_ids(token_metas.len() as u32); - self.storage_mut() - .mint_many(recipient, token_ids, token_metas); - Ok(()) + return Err(Error::TokenIdAlreadyExists); + }; + Ok(token_ids) } - } + None => Ok(self.storage_mut().gen_token_ids(token_metas.len() as u32)), + }; + + unique_token_ids.map(|token_ids| { + // Mint tokens. + self.storage_mut() + .mint_many(&recipient, &token_ids, &token_metas); + + // Emit event. + self.storage_mut().emit(CEP47Event::Mint { + recipient: recipient.clone(), + token_ids, + }); + }) } - fn mint_copies(&mut self, recipient: PublicKey, token_ids: Option>, token_meta: Meta, count: u32) -> Result<(), Error> { + fn mint_copies( + &mut self, + recipient: &Key, + token_ids: Option>, + token_meta: Meta, + count: u32, + ) -> Result<(), Error> { if let Some(token_ids) = &token_ids { if token_ids.len() != count as usize { return Err(Error::ArgumentsError); @@ -138,91 +145,91 @@ pub trait CEP47Contract: WithStorage { self.mint_many(recipient, token_ids, token_metas) } - fn burn_one(&mut self, owner: PublicKey, token_id: TokenId) { - self.storage_mut().burn_one(owner, token_id); + fn burn_one(&mut self, owner: &Key, token_id: TokenId) { + self.storage_mut().burn_many(owner, &vec![token_id]); } - fn burn_many(&mut self, owner: PublicKey, token_ids: Vec) { - self.storage_mut().burn_many(owner, token_ids); + fn burn_many(&mut self, owner: &Key, token_ids: Vec) { + self.storage_mut().burn_many(owner, &token_ids); } // Transfer functions. fn transfer_token( &mut self, - sender: PublicKey, - recipient: PublicKey, - token_id: TokenId, + sender: &Key, + recipient: &Key, + token_id: &TokenId, ) -> Result<(), Error> { - if self.is_paused() { - return Err(Error::PermissionDenied); - } - // 1. Load tokens owned by the sender. - let mut sender_tokens = self.storage().get_tokens(sender.clone()); - // 2. Assert that token_id is in sender_tokens. - if !sender_tokens.contains(&token_id) { - return Err(Error::PermissionDenied); - } - // 3. Remove token_id from sender_tokens. - sender_tokens.retain(|x| x.clone() != token_id); - self.storage_mut().set_tokens(sender, sender_tokens); - - // 4. Add token_id to the recipient tokens - let mut recipient_tokens = self.storage().get_tokens(recipient.clone()); - recipient_tokens.push(token_id); - self.storage_mut().set_tokens(recipient, recipient_tokens); - Ok(()) + self.transfer_many_tokens(sender, recipient, &vec![token_id.clone()]) } fn transfer_many_tokens( &mut self, - sender: PublicKey, - recipient: PublicKey, - token_ids: Vec, + sender: &Key, + recipient: &Key, + token_ids: &Vec, ) -> Result<(), Error> { if self.is_paused() { return Err(Error::PermissionDenied); } - let mut sender_tokens = self.storage().get_tokens(sender.clone()); + let mut sender_tokens = self.storage().get_tokens(&sender); for token_id in token_ids.iter() { if !sender_tokens.contains(token_id) { return Err(Error::PermissionDenied); } - sender_tokens.retain(|x| x.clone() != token_id.clone()); + sender_tokens.retain(|x| x != token_id); } - let mut recipient_tokens = self.storage().get_tokens(recipient.clone()); + let mut recipient_tokens = self.storage().get_tokens(&recipient); recipient_tokens.append(&mut token_ids.clone()); - self.storage_mut().set_tokens(sender, sender_tokens); - self.storage_mut().set_tokens(recipient, recipient_tokens); + self.storage_mut().set_tokens(&sender, sender_tokens); + self.storage_mut().set_tokens(&recipient, recipient_tokens); + + // Emit transfer event. + let package = self.storage().contact_package_hash(); + self.storage_mut().emit(CEP47Event::Transfer { + sender: sender.clone(), + recipient: recipient.clone(), + token_ids: token_ids.clone(), + }); Ok(()) } - fn transfer_all_tokens( - &mut self, - sender: PublicKey, - recipient: PublicKey, - ) -> Result<(), Error> { + fn transfer_all_tokens(&mut self, sender: &Key, recipient: &Key) -> Result<(), Error> { if self.is_paused() { return Err(Error::PermissionDenied); } - let mut sender_tokens = self.storage().get_tokens(sender.clone()); - let mut recipient_tokens = self.storage().get_tokens(recipient.clone()); + let mut sender_tokens = self.storage().get_tokens(&sender); + let mut recipient_tokens = self.storage().get_tokens(&recipient); recipient_tokens.append(&mut sender_tokens); - self.storage_mut().set_tokens(sender, sender_tokens); - self.storage_mut().set_tokens(recipient, recipient_tokens); + self.storage_mut() + .set_tokens(&sender, sender_tokens.clone()); + self.storage_mut().set_tokens(&recipient, recipient_tokens); + + // Emit transfer event. + self.storage_mut().emit(CEP47Event::Transfer { + sender: sender.clone(), + recipient: recipient.clone(), + token_ids: sender_tokens, + }); + Ok(()) } - fn update_token_metadata( - &mut self, - token_id: TokenId, - meta: Meta - ) -> Result<(), Error> { + fn update_token_metadata(&mut self, token_id: TokenId, meta: Meta) -> Result<(), Error> { + // Assert token exists. if self.owner_of(&token_id).is_none() { return Err(Error::TokenIdDoesntExist); }; - self.storage_mut().update_token_metadata(token_id, meta); + + // Update the storage. + self.storage_mut().update_token_metadata(&token_id, meta); + + // Emit token update event. + self.storage_mut() + .emit(CEP47Event::MetadataUpdate { token_id }); + Ok(()) } } @@ -234,10 +241,10 @@ pub trait CEP47Storage { fn meta(&self) -> Meta; // Getters - fn balance_of(&self, owner: PublicKey) -> U256; - fn onwer_of(&self, token_id: &TokenId) -> Option; + fn balance_of(&self, owner: &Key) -> U256; + fn onwer_of(&self, token_id: &TokenId) -> Option; fn total_supply(&self) -> U256; - fn token_meta(&self, token_id: TokenId) -> Option; + fn token_meta(&self, token_id: &TokenId) -> Option; // Controls fn is_paused(&self) -> bool; @@ -245,13 +252,16 @@ pub trait CEP47Storage { fn unpause(&mut self); // Setters - fn get_tokens(&self, owner: PublicKey) -> Vec; - fn set_tokens(&mut self, owner: PublicKey, token_ids: Vec); - fn mint_many(&mut self, recipient: PublicKey, token_ids: Vec, token_metas: Vec); - fn burn_one(&mut self, owner: PublicKey, token_id: TokenId); - fn burn_many(&mut self, owner: PublicKey, token_ids: Vec); - fn update_token_metadata(&mut self, token_id: TokenId, meta: Meta); + fn get_tokens(&self, owner: &Key) -> Vec; + fn set_tokens(&mut self, owner: &Key, token_ids: Vec); + fn mint_many(&mut self, recipient: &Key, token_ids: &Vec, token_metas: &Vec); + // fn burn_one(&mut self, owner: &Key, token_id: &TokenId); + fn burn_many(&mut self, owner: &Key, token_ids: &Vec); + fn update_token_metadata(&mut self, token_id: &TokenId, meta: Meta); fn gen_token_ids(&mut self, n: u32) -> Vec; fn validate_token_ids(&self, token_ids: &Vec) -> bool; + + fn emit(&mut self, event: CEP47Event); + fn contact_package_hash(&self) -> ContractPackageHash; } diff --git a/cep47-logic/src/tests.rs b/cep47-logic/src/tests.rs index 51d511a..4954e1d 100644 --- a/cep47-logic/src/tests.rs +++ b/cep47-logic/src/tests.rs @@ -1,9 +1,10 @@ -use casper_types::AccessRights; +use casper_types::{AccessRights, ContractPackageHash}; use rand::Rng; use crate::{ - AsymmetricType, CEP47Contract, CEP47Storage, Meta, PublicKey, TokenId, URef, WithStorage, U256, Error + AsymmetricType, CEP47Contract, CEP47Storage, Error, Key, Meta, TokenId, URef, WithStorage, U256, }; +use casper_types::PublicKey; use std::{ collections::{hash_map::DefaultHasher, BTreeMap}, hash::{Hash, Hasher}, @@ -16,12 +17,12 @@ struct TestStorage { meta: Meta, paused: bool, total_supply: U256, - tokens: BTreeMap>, + tokens: BTreeMap>, token_metas: BTreeMap, - balances: BTreeMap, - belongs_to: BTreeMap, + balances: BTreeMap, + belongs_to: BTreeMap, urefs: BTreeMap, - token_id_generator: u32 + token_id_generator: u32, } impl TestStorage { @@ -37,7 +38,7 @@ impl TestStorage { belongs_to: BTreeMap::new(), token_metas: BTreeMap::new(), urefs: BTreeMap::new(), - token_id_generator: 1 + token_id_generator: 1, } } } @@ -55,8 +56,8 @@ impl CEP47Storage for TestStorage { self.meta.clone() } - fn balance_of(&self, owner: PublicKey) -> U256 { - let owner_balance = self.balances.get(&owner); + fn balance_of(&self, owner: &Key) -> U256 { + let owner_balance = self.balances.get(owner); if owner_balance.is_none() { U256::from(0) } else { @@ -64,7 +65,7 @@ impl CEP47Storage for TestStorage { } } - fn onwer_of(&self, token_id: &TokenId) -> Option { + fn onwer_of(&self, token_id: &TokenId) -> Option { let owner = self.belongs_to.get(token_id); if owner.is_some() { Some(owner.unwrap().clone()) @@ -77,8 +78,8 @@ impl CEP47Storage for TestStorage { self.total_supply } - fn token_meta(&self, token_id: TokenId) -> Option { - let meta = self.token_metas.get(&token_id); + fn token_meta(&self, token_id: &TokenId) -> Option { + let meta = self.token_metas.get(token_id); if meta.is_some() { Some(meta.unwrap().clone()) } else { @@ -98,7 +99,7 @@ impl CEP47Storage for TestStorage { self.paused = false; } - fn get_tokens(&self, owner: PublicKey) -> Vec { + fn get_tokens(&self, owner: &Key) -> Vec { let owner_tokens = self.tokens.get(&owner); if owner_tokens.is_none() { Vec::::new() @@ -107,10 +108,10 @@ impl CEP47Storage for TestStorage { } } - fn set_tokens(&mut self, owner: PublicKey, token_ids: Vec) { + fn set_tokens(&mut self, owner: &Key, token_ids: Vec) { let owner_new_balance = U256::from(token_ids.len() as u64); - let owner_tokens = self.get_tokens(owner.clone()); + let owner_tokens = self.get_tokens(&owner); for token_id in owner_tokens.clone() { self.belongs_to.remove(&token_id); } @@ -118,11 +119,11 @@ impl CEP47Storage for TestStorage { self.belongs_to.insert(token_id, owner.clone()); } - self.tokens.insert(owner.clone(), token_ids.clone()); - self.balances.insert(owner, owner_new_balance); + self.tokens.insert(*owner, token_ids.clone()); + self.balances.insert(*owner, owner_new_balance); } - fn mint_many(&mut self, recipient: PublicKey, token_ids: Vec, token_metas: Vec) { + fn mint_many(&mut self, recipient: &Key, token_ids: &Vec, token_metas: &Vec) { let recipient_balance = self.balances.get(&recipient); let recipient_tokens = self.tokens.get(&recipient); let mut recipient_new_balance = if recipient_balance.is_none() { @@ -137,7 +138,8 @@ impl CEP47Storage for TestStorage { }; for (token_id, token_meta) in token_ids.iter().zip(token_metas) { - self.token_metas.insert(token_id.clone(), token_meta); + self.token_metas + .insert(token_id.clone(), token_meta.clone()); recipient_new_tokens.push(token_id.clone()); self.belongs_to.insert(token_id.clone(), recipient.clone()); recipient_new_balance = recipient_new_balance + 1; @@ -145,12 +147,12 @@ impl CEP47Storage for TestStorage { } self.balances .insert(recipient.clone(), recipient_new_balance); - self.tokens.insert(recipient, recipient_new_tokens); + self.tokens.insert(*recipient, recipient_new_tokens); } - fn burn_many(&mut self, owner: PublicKey, token_ids: Vec) { - let owner_tokens = self.tokens.get(&owner); - let owner_balance = self.balances.get(&owner); + fn burn_many(&mut self, owner: &Key, token_ids: &Vec) { + let owner_tokens = self.tokens.get(owner); + let owner_balance = self.balances.get(owner); let mut owner_new_balance = if owner_balance.is_none() { U256::from(0) } else { @@ -174,36 +176,11 @@ impl CEP47Storage for TestStorage { self.total_supply = self.total_supply - 1; } self.balances.insert(owner.clone(), owner_new_balance); - self.tokens.insert(owner, owner_new_tokens); + self.tokens.insert(*owner, owner_new_tokens); } - fn burn_one(&mut self, owner: PublicKey, token_id: TokenId) { - let owner_tokens = self.tokens.get(&owner); - let owner_balance = self.balances.get(&owner); - let owner_new_balance = if owner_balance.is_none() { - U256::from(0) - } else { - owner_balance.unwrap().clone() - }; - let mut owner_new_tokens = if owner_tokens.is_none() { - Vec::::new() - } else { - owner_tokens.unwrap().clone() - }; - let index = owner_new_tokens - .iter() - .position(|x| *x == token_id.clone()) - .unwrap(); - owner_new_tokens.remove(index); - self.token_metas.remove(&token_id.clone()); - self.belongs_to.remove(&token_id.clone()); - self.total_supply = self.total_supply - 1; - self.balances.insert(owner.clone(), owner_new_balance - 1); - self.tokens.insert(owner, owner_new_tokens); - } - - fn update_token_metadata(&mut self, token_id: TokenId, meta: Meta) { - self.token_metas.insert(token_id, meta).unwrap(); + fn update_token_metadata(&mut self, token_id: &TokenId, meta: Meta) { + self.token_metas.insert(token_id.clone(), meta).unwrap(); } fn gen_token_ids(&mut self, n: u32) -> Vec { @@ -212,7 +189,7 @@ impl CEP47Storage for TestStorage { let id = format!("token_{}", &self.token_id_generator); tokens.push(id); self.token_id_generator += 1; - }; + } tokens } @@ -224,6 +201,12 @@ impl CEP47Storage for TestStorage { } true } + + fn emit(&mut self, event: crate::events::CEP47Event) {} + + fn contact_package_hash(&self) -> casper_types::ContractPackageHash { + [1u8; 32].into() + } } struct TestContract { @@ -295,139 +278,142 @@ fn test_metadata() { #[test] fn test_mint_many() { let mut contract = TestContract::new(); - let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); - let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); + let ali_pk = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + let bob_pk = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); + let ali: Key = ali_pk.to_account_hash().into(); + let bob: Key = bob_pk.to_account_hash().into(); let bob_first_token_id = "banana_01".to_string(); let bob_second_token_id = "orange_02".to_string(); let bob_token_ids = vec![bob_first_token_id.clone(), bob_second_token_id]; assert_eq!(contract.total_supply(), U256::from(0)); - let _: Result<(), Error> = contract.mint_many(ali.clone(), None, vec![meta::apple()]); - let _: Result<(), Error> = contract.mint_many(bob.clone(), Some(bob_token_ids.clone()), vec![meta::banana(), meta::orange()]); + let _: Result<(), Error> = contract.mint_many(&ali, None, vec![meta::apple()]); + let _: Result<(), Error> = contract.mint_many( + &bob, + Some(bob_token_ids.clone()), + vec![meta::banana(), meta::orange()], + ); assert_eq!(contract.total_supply(), U256::from(3)); - let ali_balance = contract.balance_of(ali.clone()); + let ali_balance = contract.balance_of(&ali); assert_eq!(ali_balance, U256::from(1)); - let bob_balance = contract.balance_of(bob.clone()); + let bob_balance = contract.balance_of(&bob); assert_eq!(bob_balance, U256::from(2)); - let ali_tokens: Vec = contract.tokens(ali); - let ali_first_token_meta: Meta = contract - .token_meta(ali_tokens.get(0).unwrap().clone()) - .unwrap(); + let ali_tokens: Vec = contract.tokens(&ali); + let ali_first_token_meta: Meta = contract.token_meta(&ali_tokens.get(0).unwrap()).unwrap(); assert_eq!(ali_first_token_meta, meta::apple()); - let bob_tokens: Vec = contract.tokens(bob); + let bob_tokens: Vec = contract.tokens(&bob); assert_eq!(bob_token_ids, bob_tokens); - let bob_first_token_meta: Meta = contract - .token_meta(bob_first_token_id) - .unwrap(); + let bob_first_token_meta: Meta = contract.token_meta(&bob_first_token_id).unwrap(); assert_eq!(bob_first_token_meta, meta::banana()); } #[test] fn test_mint_copies() { let mut contract = TestContract::new(); - let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + let ali_pk = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + let ali: Key = ali_pk.to_account_hash().into(); assert_eq!(contract.total_supply(), U256::from(0)); - let _: Result<(), Error> = contract.mint_copies(ali.clone(), None, meta::apple(), 7); + let _: Result<(), Error> = contract.mint_copies(&ali, None, meta::apple(), 7); assert_eq!(contract.total_supply(), U256::from(7)); - let ali_balance = contract.balance_of(ali.clone()); + let ali_balance = contract.balance_of(&ali); assert_eq!(ali_balance, U256::from(7)); - let ali_tokens: Vec = contract.tokens(ali); - let ali_first_token_meta: Meta = contract - .token_meta(ali_tokens.get(0).unwrap().clone()) - .unwrap(); - let ali_third_token_meta: Meta = contract - .token_meta(ali_tokens.get(2).unwrap().clone()) - .unwrap(); + let ali_tokens: Vec = contract.tokens(&ali); + let ali_first_token_meta: Meta = contract.token_meta(&ali_tokens.get(0).unwrap()).unwrap(); + let ali_third_token_meta: Meta = contract.token_meta(&ali_tokens.get(2).unwrap()).unwrap(); assert_eq!(ali_first_token_meta, meta::apple()); assert_eq!(ali_third_token_meta, meta::apple()); } #[test] fn test_burn_many() { let mut contract = TestContract::new(); - let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + let ali_pk = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + let ali: Key = ali_pk.to_account_hash().into(); + assert_eq!(contract.total_supply(), U256::from(0)); let _: Result<(), Error> = contract.mint_many( - ali.clone(), + &ali, None, vec![meta::banana(), meta::orange(), meta::apple()], ); assert_eq!(contract.total_supply(), U256::from(3)); - let ali_balance = contract.balance_of(ali.clone()); + let ali_balance = contract.balance_of(&ali); assert_eq!(ali_balance, U256::from(3)); - let ali_tokens: Vec = contract.tokens(ali.clone()); + let ali_tokens: Vec = contract.tokens(&ali); let banana = ali_tokens.get(0).unwrap().clone(); let orange = ali_tokens.get(1).unwrap().clone(); let apple = ali_tokens.get(2).unwrap().clone(); - contract.burn_many(ali.clone(), vec![banana.clone(), apple.clone()]); - let ali_tokens_after_burn = contract.tokens(ali.clone()); + contract.burn_many(&ali, vec![banana.clone(), apple.clone()]); + let ali_tokens_after_burn = contract.tokens(&ali); assert_eq!(ali_tokens_after_burn, vec![orange.clone()]); - assert!(contract.token_meta(banana.clone()).is_none()); - assert!(contract.token_meta(orange.clone()).is_some()); - assert!(contract.token_meta(apple.clone()).is_none()); + assert!(contract.token_meta(&banana).is_none()); + assert!(contract.token_meta(&orange).is_some()); + assert!(contract.token_meta(&apple).is_none()); assert_eq!(contract.total_supply(), U256::from(1)); - assert_eq!(contract.balance_of(ali), U256::from(1)); + assert_eq!(contract.balance_of(&ali), U256::from(1)); } #[test] fn test_burn_one() { let mut contract = TestContract::new(); - let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + let ali_pk = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + let ali: Key = ali_pk.to_account_hash().into(); assert_eq!(contract.total_supply(), U256::from(0)); - let _: Result<(), Error> = contract.mint_many(ali.clone(), None, vec![meta::banana(), meta::orange()]); + let _: Result<(), Error> = contract.mint_many(&ali, None, vec![meta::banana(), meta::orange()]); assert_eq!(contract.total_supply(), U256::from(2)); - let mut ali_balance = contract.balance_of(ali.clone()); + let mut ali_balance = contract.balance_of(&ali); assert_eq!(ali_balance, U256::from(2)); - let mut ali_tokens: Vec = contract.tokens(ali.clone()); - contract.burn_one(ali.clone(), ali_tokens.get(0).unwrap().clone()); - let mut ali_first_token_meta = contract.token_meta(ali_tokens.get(0).unwrap().clone()); + let mut ali_tokens: Vec = contract.tokens(&ali); + contract.burn_one(&ali, ali_tokens.get(0).unwrap().clone()); + let mut ali_first_token_meta = contract.token_meta(ali_tokens.get(0).unwrap()); assert_eq!(ali_first_token_meta, None); - ali_tokens = contract.tokens(ali.clone()); - ali_first_token_meta = contract.token_meta(ali_tokens.get(0).unwrap().clone()); + ali_tokens = contract.tokens(&ali); + ali_first_token_meta = contract.token_meta(ali_tokens.get(0).unwrap()); assert_eq!(ali_first_token_meta, Some(meta::orange())); assert_eq!(contract.total_supply(), U256::from(1)); - ali_balance = contract.balance_of(ali); + ali_balance = contract.balance_of(&ali); assert_eq!(ali_balance, U256::from(1)); } #[test] fn test_transfer_token() { let mut contract = TestContract::new(); - let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); - let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); + let ali_pk = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + let bob_pk = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); + let ali: Key = ali_pk.to_account_hash().into(); + let bob: Key = bob_pk.to_account_hash().into(); assert_eq!(contract.total_supply(), U256::from(0)); - let _: Result<(), Error> = contract.mint_one(ali.clone(), None, meta::apple()); + let _: Result<(), Error> = contract.mint_one(&ali, None, meta::apple()); assert_eq!(contract.total_supply(), U256::from(1)); - let mut ali_balance = contract.balance_of(ali.clone()); - let mut bob_balance = contract.balance_of(bob.clone()); + let mut ali_balance = contract.balance_of(&ali); + let mut bob_balance = contract.balance_of(&bob); assert_eq!(ali_balance, U256::from(1)); assert_eq!(bob_balance, U256::from(0)); - let ali_tokens: Vec = contract.tokens(ali.clone()); + let ali_tokens: Vec = contract.tokens(&ali); let ali_first_token_id: TokenId = ali_tokens.get(0).unwrap().clone(); - let ali_first_token_meta: Meta = contract.token_meta(ali_first_token_id.clone()).unwrap(); + let ali_first_token_meta: Meta = contract.token_meta(&ali_first_token_id).unwrap(); assert_eq!(ali_first_token_meta, meta::apple()); - let transfer_res = - contract.transfer_token(ali.clone(), bob.clone(), ali_first_token_id.clone()); + let transfer_res = contract.transfer_token(&ali, &bob, &ali_first_token_id); assert!(transfer_res.is_ok()); - ali_balance = contract.balance_of(ali); - bob_balance = contract.balance_of(bob.clone()); + ali_balance = contract.balance_of(&ali); + bob_balance = contract.balance_of(&bob); assert_eq!(ali_balance, U256::from(0)); assert_eq!(bob_balance, U256::from(1)); @@ -437,29 +423,31 @@ fn test_transfer_token() { #[test] fn test_transfer_all_tokens() { let mut contract = TestContract::new(); - let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); - let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); + let ali_pk = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + let bob_pk = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); + let ali: Key = ali_pk.to_account_hash().into(); + let bob: Key = bob_pk.to_account_hash().into(); assert_eq!(contract.total_supply(), U256::from(0)); - let _: Result<(), Error> = contract.mint_many(ali.clone(), None, vec![meta::apple(), meta::banana()]); - let _: Result<(), Error> = contract.mint_one(ali.clone(), None, meta::apple()); + let _: Result<(), Error> = contract.mint_many(&ali, None, vec![meta::apple(), meta::banana()]); + let _: Result<(), Error> = contract.mint_one(&ali, None, meta::apple()); assert_eq!(contract.total_supply(), U256::from(3)); - let mut ali_balance = contract.balance_of(ali.clone()); - let mut bob_balance = contract.balance_of(bob.clone()); + let mut ali_balance = contract.balance_of(&ali); + let mut bob_balance = contract.balance_of(&bob); assert_eq!(ali_balance, U256::from(3)); assert_eq!(bob_balance, U256::from(0)); - let ali_tokens: Vec = contract.tokens(ali.clone()); + let ali_tokens: Vec = contract.tokens(&ali); let ali_second_token_id: TokenId = ali_tokens.get(1).unwrap().clone(); - let ali_second_token_meta: Meta = contract.token_meta(ali_second_token_id.clone()).unwrap(); + let ali_second_token_meta: Meta = contract.token_meta(&ali_second_token_id).unwrap(); assert_eq!(ali_second_token_meta, meta::banana()); - let transfer_res = contract.transfer_all_tokens(ali.clone(), bob.clone()); + let transfer_res = contract.transfer_all_tokens(&ali, &bob); assert!(transfer_res.is_ok()); - ali_balance = contract.balance_of(ali); - bob_balance = contract.balance_of(bob.clone()); + ali_balance = contract.balance_of(&ali); + bob_balance = contract.balance_of(&bob); assert_eq!(ali_balance, U256::from(0)); assert_eq!(bob_balance, U256::from(3)); @@ -470,33 +458,35 @@ fn test_transfer_all_tokens() { #[test] fn test_transfer_many_tokens() { let mut contract = TestContract::new(); - let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); - let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); + let ali_pk = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + let bob_pk = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); + let ali: Key = ali_pk.to_account_hash().into(); + let bob: Key = bob_pk.to_account_hash().into(); assert_eq!(contract.total_supply(), U256::from(0)); - let _ = contract.mint_many(ali.clone(), None, vec![meta::apple(), meta::banana()]); - let _: Result<(), Error> = contract.mint_copies(ali.clone(), None, meta::apple(), 3); + let _ = contract.mint_many(&ali, None, vec![meta::apple(), meta::banana()]); + let _: Result<(), Error> = contract.mint_copies(&ali, None, meta::apple(), 3); assert_eq!(contract.total_supply(), U256::from(5)); - assert_eq!(contract.balance_of(ali.clone()), U256::from(5)); - assert_eq!(contract.balance_of(bob.clone()), U256::from(0)); + assert_eq!(contract.balance_of(&ali), U256::from(5)); + assert_eq!(contract.balance_of(&bob), U256::from(0)); - let ali_tokens: Vec = contract.tokens(ali.clone()); + let ali_tokens: Vec = contract.tokens(&ali); let ali_second_token_id: TokenId = ali_tokens.get(1).unwrap().clone(); - let ali_second_token_meta: Meta = contract.token_meta(ali_second_token_id.clone()).unwrap(); + let ali_second_token_meta: Meta = contract.token_meta(&ali_second_token_id).unwrap(); let ali_third_token_id: TokenId = ali_tokens.get(2).unwrap().clone(); - let ali_third_token_meta: Meta = contract.token_meta(ali_third_token_id.clone()).unwrap(); + let ali_third_token_meta: Meta = contract.token_meta(&ali_third_token_id).unwrap(); assert_eq!(ali_second_token_meta, meta::banana()); assert_eq!(ali_third_token_meta, meta::apple()); let transfer_res = contract.transfer_many_tokens( - ali.clone(), - bob.clone(), - vec![ali_second_token_id.clone(), ali_third_token_id.clone()], + &ali, + &bob, + &vec![ali_second_token_id.clone(), ali_third_token_id.clone()], ); assert!(transfer_res.is_ok()); - assert_eq!(contract.balance_of(ali), U256::from(3)); - assert_eq!(contract.balance_of(bob.clone()), U256::from(2)); + assert_eq!(contract.balance_of(&ali), U256::from(3)); + assert_eq!(contract.balance_of(&bob), U256::from(2)); let owner_of_second_token_id = contract.owner_of(&ali_second_token_id); let owner_of_third_token_id = contract.owner_of(&ali_third_token_id); @@ -507,10 +497,12 @@ fn test_transfer_many_tokens() { #[test] fn test_update_metadata() { let mut contract = TestContract::new(); - let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + let ali_pk = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); + let ali: Key = ali_pk.to_account_hash().into(); + let token_id = TokenId::from("new_token"); - let _: Result<(), Error> = contract.mint_one(ali, Some(token_id.clone()), meta::apple()); - assert_eq!(meta::apple(), contract.token_meta(token_id.clone()).unwrap()); + let _: Result<(), Error> = contract.mint_one(&ali, Some(token_id.clone()), meta::apple()); + assert_eq!(meta::apple(), contract.token_meta(&token_id).unwrap()); let _: Result<(), Error> = contract.update_token_metadata(token_id.clone(), meta::banana()); - assert_eq!(meta::banana(), contract.token_meta(token_id).unwrap()); -} \ No newline at end of file + assert_eq!(meta::banana(), contract.token_meta(&token_id).unwrap()); +} diff --git a/cep47/Cargo.toml b/cep47/Cargo.toml index da193af..fc0a308 100644 --- a/cep47/Cargo.toml +++ b/cep47/Cargo.toml @@ -6,8 +6,8 @@ edition = "2018" [dependencies] hex = "0.4.3" -casper-contract = "1.2.1" -casper-types = "1.2.1" +casper-contract = "1.3.1" +casper-types = "1.3.1" cep47-logic = { path = "../cep47-logic" } [lib] diff --git a/cep47/src/cep47_storage.rs b/cep47/src/cep47_storage.rs new file mode 100644 index 0000000..5b3e0ad --- /dev/null +++ b/cep47/src/cep47_storage.rs @@ -0,0 +1,201 @@ +use casper_contract::{contract_api::runtime, unwrap_or_revert::UnwrapOrRevert}; +use casper_types::{bytesrepr::ToBytes, ApiError, Key, U256}; +use cep47_logic::{CEP47Storage, Meta, TokenId}; + +use crate::data::{self, Balances, Metadata, OwnedTokens, Owners}; + +pub struct CasperCEP47Storage {} +impl CasperCEP47Storage { + pub fn new() -> CasperCEP47Storage { + CasperCEP47Storage {} + } +} + +impl CEP47Storage for CasperCEP47Storage { + fn name(&self) -> String { + data::name() + } + + fn symbol(&self) -> String { + data::symbol() + } + + fn meta(&self) -> Meta { + data::meta() + } + + fn total_supply(&self) -> U256 { + data::total_supply() + } + + fn balance_of(&self, owner: &Key) -> U256 { + Balances::instance().get(owner) + } + + fn onwer_of(&self, token_id: &TokenId) -> Option { + Owners::instance().get(token_id) + } + + fn token_meta(&self, token_id: &TokenId) -> Option { + Metadata::instance().get(token_id) + } + + fn is_paused(&self) -> bool { + data::is_paused() + } + + fn pause(&mut self) { + data::pause(); + } + + fn unpause(&mut self) { + data::unpause(); + } + + fn get_tokens(&self, owner: &Key) -> Vec { + OwnedTokens::instance().get(owner) + } + + fn set_tokens(&mut self, owner: &Key, token_ids: Vec) { + // Prepare dictionaries. + let owners_dict = Owners::instance(); + let owned_tokens_dict = OwnedTokens::instance(); + let balances_dict = Balances::instance(); + + // Update the owner for each token. + for token_id in &token_ids { + owners_dict.set(token_id, owner.clone()); + } + + // Update balance of the owner. + let prev_balance = balances_dict.get(&owner); + let new_balance = U256::from(token_ids.len() as u64); + balances_dict.set(owner, new_balance); + + // Update owner's list of tokens. + owned_tokens_dict.set(&owner, token_ids); + + // Update total_supply. + let new_total_supply = data::total_supply() - prev_balance + new_balance; + data::update_total_supply(new_total_supply); + } + + fn mint_many(&mut self, recipient: &Key, token_ids: &Vec, token_metas: &Vec) { + // Prepare dictionaries. + let owners_dict = Owners::instance(); + let owned_tokens_dict = OwnedTokens::instance(); + let balances_dict = Balances::instance(); + let metadata_dict = Metadata::instance(); + + // Load recipient's tokens. + let mut recipient_tokens = owned_tokens_dict.get(&recipient); + + // Create new tokens. + for (token_id, token_meta) in token_ids.iter().zip(token_metas) { + // Set metadata. + metadata_dict.set(token_id, token_meta.clone()); + + // Set token owner. + owners_dict.set(token_id, recipient.clone()); + + // Update current list of recipient's tokens. + recipient_tokens.push(token_id.clone()); + + // Emit event. + // emit_mint_one_event(&recipient, &token_id); + } + + // Update owned tokens. + owned_tokens_dict.set(recipient, recipient_tokens); + + // Update recipient's balance. + let new_tokens_count: U256 = token_ids.len().into(); + let prev_balance = balances_dict.get(recipient); + let new_balance = prev_balance + new_tokens_count; + balances_dict.set(recipient, new_balance); + + // Update total supply. + let new_total_supply = data::total_supply() + new_tokens_count; + data::update_total_supply(new_total_supply); + } + + fn burn_many(&mut self, owner: &Key, token_ids: &Vec) { + // Prepare dictionaries. + // let owners_dict = Owners::instance(); + let owned_tokens_dict = OwnedTokens::instance(); + let balances_dict = Balances::instance(); + // let metadata_dict = Metadata::instance(); + + // Load owner's tokens. + let mut owner_tokens = owned_tokens_dict.get(owner); + + // Remove tokens. + for token_id in token_ids { + // Remove token form the onwer's list. + // Make sure that token is owned by the recipient. + let index = owner_tokens + .iter() + .position(|x| x == token_id) + .unwrap_or_revert(); + owner_tokens.remove(index); + + // TODO: Remove meta. + + // TODO: Remove ownership. + + // Emit event. + // emit_burn_one_event(&owner, &token_id); + } + + // Decrement owner's balance. + balances_dict.set(owner, owner_tokens.len().into()); + + // Update owner's tokens. + owned_tokens_dict.set(owner, owner_tokens); + + // Decrement total supply. + let remove_tokens_count: U256 = token_ids.len().into(); + let new_total_supply = data::total_supply() - remove_tokens_count; + data::update_total_supply(new_total_supply); + } + + fn update_token_metadata(&mut self, token_id: &TokenId, meta: Meta) { + let metadata_dict = Metadata::instance(); + let current_meta = metadata_dict.get(token_id); + match current_meta { + None => runtime::revert(ApiError::None), + Some(_) => metadata_dict.set(token_id, meta), + }; + } + + fn gen_token_ids(&mut self, n: u32) -> Vec { + let block_time = runtime::get_blocktime(); + let mut token_ids = Vec::new(); + let nonce = data::get_nonce(); + for i in nonce..nonce + n { + let mut bytes: Vec = block_time.to_bytes().unwrap_or_revert(); + bytes.append(&mut i.to_bytes().unwrap_or_revert()); + let hash = runtime::blake2b(bytes); + token_ids.push(hex::encode(hash)); + } + data::set_nonce(nonce + n); + token_ids + } + + fn validate_token_ids(&self, token_ids: &Vec) -> bool { + for token_id in token_ids { + if self.onwer_of(token_id).is_some() { + return false; + } + } + true + } + + fn emit(&mut self, event: cep47_logic::events::CEP47Event) { + data::emit(&event) + } + + fn contact_package_hash(&self) -> casper_types::ContractPackageHash { + data::contract_package_hash() + } +} diff --git a/cep47/src/data.rs b/cep47/src/data.rs new file mode 100644 index 0000000..1ec24e3 --- /dev/null +++ b/cep47/src/data.rs @@ -0,0 +1,276 @@ +use std::{collections::BTreeMap, convert::TryInto}; + +use casper_contract::{ + contract_api::{ + runtime, + storage::{self, new_dictionary}, + }, + unwrap_or_revert::UnwrapOrRevert, +}; +use casper_types::{ + bytesrepr::{FromBytes, ToBytes}, + contracts::NamedKeys, + ApiError, CLTyped, ContractPackageHash, Key, URef, U256, +}; +use cep47_logic::{events::CEP47Event, Meta, TokenId}; + +const BALANCES_DICT: &str = "balances"; +const OWNED_TOKENS_DICT: &str = "owned_tokens"; +const TOKEN_OWNERS_DICT: &str = "owners"; +const METADATA_DICT: &str = "metadata"; + +struct Dict { + uref: URef, +} + +impl Dict { + pub fn at(name: &str) -> Dict { + let key: Key = runtime::get_key(name).unwrap_or_revert(); + let uref: URef = *key.as_uref().unwrap_or_revert(); + Dict { uref } + } + + pub fn get(&self, key: &str) -> Option { + storage::dictionary_get(self.uref, key).unwrap_or_revert() + } + + pub fn set(&self, key: &str, value: T) { + storage::dictionary_put(self.uref, key, value); + } +} + +pub struct Balances { + dict: Dict, +} + +impl Balances { + pub fn instance() -> Balances { + Balances { + dict: Dict::at(BALANCES_DICT), + } + } + + pub fn get(&self, key: &Key) -> U256 { + self.dict.get(&key_to_str(&key)).unwrap_or(U256::zero()) + } + + pub fn set(&self, key: &Key, value: U256) { + self.dict.set(&key_to_str(&key), value); + } +} + +pub struct OwnedTokens { + dict: Dict, +} + +impl OwnedTokens { + pub fn instance() -> OwnedTokens { + OwnedTokens { + dict: Dict::at(OWNED_TOKENS_DICT), + } + } + + pub fn get(&self, key: &Key) -> Vec { + self.dict.get(&key_to_str(&key)).unwrap_or(Vec::new()) + } + + pub fn set(&self, key: &Key, value: Vec) { + self.dict.set(&key_to_str(&key), value); + } +} + +pub struct Owners { + dict: Dict, +} + +impl Owners { + pub fn instance() -> Owners { + Owners { + dict: Dict::at(TOKEN_OWNERS_DICT), + } + } + + pub fn get(&self, key: &TokenId) -> Option { + self.dict.get(key) + } + + pub fn set(&self, key: &TokenId, value: Key) { + self.dict.set(key, value); + } +} +pub struct Metadata { + dict: Dict, +} + +impl Metadata { + pub fn instance() -> Metadata { + Metadata { + dict: Dict::at(METADATA_DICT), + } + } + + pub fn get(&self, key: &TokenId) -> Option { + self.dict.get(key) + } + + pub fn set(&self, key: &TokenId, value: Meta) { + self.dict.set(key, value); + } +} + +pub fn name() -> String { + get_key("name").unwrap_or_revert() +} + +pub fn symbol() -> String { + get_key("symbol").unwrap_or_revert() +} + +pub fn meta() -> Meta { + get_key("meta").unwrap_or_revert() +} + +pub fn total_supply() -> U256 { + get_key("total_supply").unwrap_or_revert() +} + +pub fn update_total_supply(total_supply: U256) { + set_key("total_supply", total_supply); +} + +pub fn is_paused() -> bool { + get_key("paused").unwrap() +} + +pub fn pause() { + set_key("paused", true); +} + +pub fn unpause() { + set_key("paused", false); +} + +pub fn get_nonce() -> u32 { + get_key("nonce").unwrap_or_default() +} + +pub fn set_nonce(nonce: u32) { + set_key("nonce", nonce); +} + +pub fn contract_package_hash() -> ContractPackageHash { + get_key("contract_package_hash").unwrap_or_revert() +} + +pub fn initial_named_keys( + package_hash: ContractPackageHash, + token_name: &str, + token_symbol: &str, + token_meta: Meta, + paused: bool, +) -> NamedKeys { + let mut named_keys = NamedKeys::new(); + named_keys.insert("name".to_string(), storage::new_uref(token_name).into()); + named_keys.insert("symbol".to_string(), storage::new_uref(token_symbol).into()); + named_keys.insert("meta".to_string(), storage::new_uref(token_meta).into()); + named_keys.insert( + "total_supply".to_string(), + storage::new_uref(U256::zero()).into(), + ); + named_keys.insert("paused".to_string(), storage::new_uref(paused).into()); + named_keys.insert( + "contract_package_hash".to_string(), + storage::new_uref(package_hash).into(), + ); + + // Add empty dictionaries. + add_empty_dict(&mut named_keys, BALANCES_DICT); + add_empty_dict(&mut named_keys, OWNED_TOKENS_DICT); + add_empty_dict(&mut named_keys, TOKEN_OWNERS_DICT); + add_empty_dict(&mut named_keys, METADATA_DICT); + + named_keys +} + +fn add_empty_dict(named_keys: &mut NamedKeys, name: &str) { + let dict = new_dictionary(name).unwrap_or_revert(); + runtime::remove_key(name); + named_keys.insert(name.to_string(), dict.into()); +} + +fn key_to_str(key: &Key) -> String { + match key { + Key::Account(account) => account.to_string(), + Key::Hash(package) => hex::encode(package), + _ => runtime::revert(ApiError::UnexpectedKeyVariant), + } +} + +pub fn emit(event: &CEP47Event) { + let mut events = Vec::new(); + let package = contract_package_hash(); + match event { + CEP47Event::MetadataUpdate { token_id } => { + let mut event = BTreeMap::new(); + event.insert("contract_package_hash", package.to_string()); + event.insert("event_type", "cep47_metadata_update".to_string()); + event.insert("token_id", token_id.to_string()); + events.push(event); + } + CEP47Event::Transfer { + sender, + recipient, + token_ids, + } => { + for token_id in token_ids { + let mut event = BTreeMap::new(); + event.insert("contract_package_hash", package.to_string()); + event.insert("event_type", "cep47_transfer_token".to_string()); + event.insert("sender", sender.to_string()); + event.insert("recipient", recipient.to_string()); + event.insert("token_id", token_id.to_string()); + events.push(event); + } + } + CEP47Event::Mint { + recipient, + token_ids, + } => { + for token_id in token_ids { + let mut event = BTreeMap::new(); + event.insert("contract_package_hash", package.to_string()); + event.insert("event_type", "cep47_mint_one".to_string()); + event.insert("recipient", recipient.to_string()); + event.insert("token_id", token_id.to_string()); + events.push(event); + } + } + }; + for event in events { + let _: URef = storage::new_uref(event); + } +} + +fn get_key(name: &str) -> Option { + match runtime::get_key(name) { + None => None, + Some(value) => { + let key = value.try_into().unwrap_or_revert(); + let value = storage::read(key).unwrap_or_revert().unwrap_or_revert(); + Some(value) + } + } +} + +fn set_key(name: &str, value: T) { + match runtime::get_key(name) { + Some(key) => { + let key_ref = key.try_into().unwrap_or_revert(); + storage::write(key_ref, value); + } + None => { + let key = storage::new_uref(value).into(); + runtime::put_key(name, key); + } + } +} diff --git a/cep47/src/entrypoints.rs b/cep47/src/entrypoints.rs new file mode 100644 index 0000000..396bb72 --- /dev/null +++ b/cep47/src/entrypoints.rs @@ -0,0 +1,188 @@ +use std::collections::BTreeSet; + +use casper_contract::{ + contract_api::{runtime, storage}, + unwrap_or_revert::UnwrapOrRevert, +}; +use casper_types::{ + CLType, CLTyped, ContractPackageHash, EntryPoint, EntryPointAccess, EntryPointType, + EntryPoints, Key, Parameter, +}; +use cep47_logic::{Meta, TokenId}; + +pub fn get_entrypoints(package_hash: Option) -> EntryPoints { + let secure = if let Some(contract_package_hash) = package_hash { + let deployer_group = storage::create_contract_user_group( + contract_package_hash, + "deployer", + 1, + BTreeSet::default(), + ) + .unwrap_or_revert(); + runtime::put_key("deployer_group_access", Key::URef(deployer_group[0])); + true + } else { + false + }; + + let mut entry_points = EntryPoints::new(); + entry_points.add_entry_point(endpoint("name", vec![], CLType::String, None)); + entry_points.add_entry_point(endpoint("symbol", vec![], CLType::String, None)); + entry_points.add_entry_point(endpoint("meta", vec![], Meta::cl_type(), None)); + entry_points.add_entry_point(endpoint("total_supply", vec![], CLType::U256, None)); + entry_points.add_entry_point(endpoint("is_paused", vec![], CLType::Bool, None)); + entry_points.add_entry_point(endpoint( + "pause", + vec![], + CLType::Unit, + if secure { Some("deployer") } else { None }, + )); + entry_points.add_entry_point(endpoint( + "unpause", + vec![], + CLType::Unit, + if secure { Some("deployer") } else { None }, + )); + entry_points.add_entry_point(endpoint( + "balance_of", + vec![Parameter::new("account", CLType::Key)], + CLType::U256, + None, + )); + entry_points.add_entry_point(endpoint( + "owner_of", + vec![Parameter::new("token_id", TokenId::cl_type())], + CLType::Option(Box::new(CLType::Key)), + None, + )); + entry_points.add_entry_point(endpoint( + "token_meta", + vec![Parameter::new("token_id", TokenId::cl_type())], + CLType::Option(Box::new(CLType::String)), + None, + )); + entry_points.add_entry_point(endpoint( + "tokens", + vec![Parameter::new("owner", CLType::Key)], + CLType::List(Box::new(CLType::String)), + None, + )); + entry_points.add_entry_point(endpoint( + "total_supply", + vec![Parameter::new("owner", CLType::Key)], + CLType::List(Box::new(CLType::String)), + None, + )); + entry_points.add_entry_point(endpoint( + "mint_one", + vec![ + Parameter::new("recipient", CLType::Key), + Parameter::new("token_ids", CLType::Option(Box::new(TokenId::cl_type()))), + Parameter::new("token_meta", Meta::cl_type()), + ], + CLType::Unit, + if secure { Some("deployer") } else { None }, + )); + entry_points.add_entry_point(endpoint( + "mint_many", + vec![ + Parameter::new("recipient", CLType::Key), + Parameter::new( + "token_ids", + CLType::Option(Box::new(CLType::List(Box::new(TokenId::cl_type())))), + ), + Parameter::new("token_metas", CLType::List(Box::new(Meta::cl_type()))), + ], + CLType::Unit, + if secure { Some("deployer") } else { None }, + )); + entry_points.add_entry_point(endpoint( + "mint_copies", + vec![ + Parameter::new("recipient", CLType::Key), + Parameter::new( + "token_ids", + CLType::Option(Box::new(CLType::List(Box::new(TokenId::cl_type())))), + ), + Parameter::new("token_meta", Meta::cl_type()), + Parameter::new("count", CLType::U32), + ], + CLType::Unit, + if secure { Some("deployer") } else { None }, + )); + entry_points.add_entry_point(endpoint( + "update_token_metadata", + vec![ + Parameter::new("token_id", TokenId::cl_type()), + Parameter::new("meta", Meta::cl_type()), + ], + CLType::Unit, + if secure { Some("deployer") } else { None }, + )); + entry_points.add_entry_point(endpoint( + "burn_one", + vec![ + Parameter::new("owner", CLType::Key), + Parameter::new("token_id", TokenId::cl_type()), + ], + CLType::Unit, + if secure { Some("deployer") } else { None }, + )); + entry_points.add_entry_point(endpoint( + "burn_many", + vec![ + Parameter::new("owner", CLType::Key), + Parameter::new("token_ids", CLType::List(Box::new(TokenId::cl_type()))), + ], + CLType::Unit, + if secure { Some("deployer") } else { None }, + )); + entry_points.add_entry_point(endpoint( + "transfer_token", + vec![ + Parameter::new("sender", CLType::Key), + Parameter::new("recipient", CLType::Key), + Parameter::new("token_id", TokenId::cl_type()), + ], + CLType::Unit, + None, + )); + entry_points.add_entry_point(endpoint( + "transfer_many_tokens", + vec![ + Parameter::new("sender", CLType::Key), + Parameter::new("recipient", CLType::Key), + Parameter::new("token_ids", CLType::List(Box::new(TokenId::cl_type()))), + ], + CLType::Unit, + None, + )); + entry_points.add_entry_point(endpoint( + "transfer_all_tokens", + vec![ + Parameter::new("sender", CLType::Key), + Parameter::new("recipient", CLType::Key), + ], + CLType::Unit, + None, + )); + entry_points +} + +pub fn endpoint( + name: &str, + param: Vec, + ret: CLType, + access: Option<&str>, +) -> EntryPoint { + EntryPoint::new( + String::from(name), + param, + ret, + match access { + None => EntryPointAccess::Public, + Some(access_key) => EntryPointAccess::groups(&[access_key]), + }, + EntryPointType::Contract, + ) +} diff --git a/cep47/src/lib.rs b/cep47/src/lib.rs index b5180c6..3046d15 100644 --- a/cep47/src/lib.rs +++ b/cep47/src/lib.rs @@ -16,9 +16,10 @@ use casper_types::{ account::AccountHash, bytesrepr::{FromBytes, ToBytes}, contracts::NamedKeys, + system::CallStackElement, AccessRights, ApiError, AsymmetricType, CLType, CLTyped, CLValue, ContractPackageHash, - EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, HashAddr, Key, Parameter, PublicKey, - URef, U256, + EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, HashAddr, Key, Parameter, URef, + U256, }; pub use cep47_logic::Meta; use cep47_logic::{CEP47Contract, CEP47Storage, TokenId, WithStorage}; @@ -30,184 +31,14 @@ use std::{ ops::AddAssign, }; -pub struct CasperCEP47Storage {} -impl CasperCEP47Storage { - pub fn new() -> CasperCEP47Storage { - CasperCEP47Storage {} - } -} - -impl CEP47Storage for CasperCEP47Storage { - // Metadata. - fn name(&self) -> String { - get_key::("name").unwrap() - } - - fn symbol(&self) -> String { - get_key::("symbol").unwrap() - } - - fn meta(&self) -> Meta { - get_key::("meta").unwrap() - } - - // Getters - fn balance_of(&self, owner: PublicKey) -> U256 { - let owner_balance = get_key::(&balance_key(&owner.to_account_hash())); - if owner_balance.is_none() { - U256::from(0) - } else { - owner_balance.unwrap() - } - } - - fn onwer_of(&self, token_id: &TokenId) -> Option { - get_key::(&owner_key(token_id)) - } - - fn total_supply(&self) -> U256 { - get_key::("total_supply").unwrap() - } - - fn token_meta(&self, token_id: TokenId) -> Option { - get_key::(&meta_key(&token_id)) - } - - fn is_paused(&self) -> bool { - get_key::("paused").unwrap() - } - - fn pause(&mut self) { - set_key("paused", true); - } - - fn unpause(&mut self) { - set_key("paused", false); - } - - // Setters - fn get_tokens(&self, owner: PublicKey) -> Vec { - let owner_tokens = get_key::>(&token_key(&owner.to_account_hash())); - if owner_tokens.is_none() { - Vec::::new() - } else { - owner_tokens.unwrap() - } - } - - fn set_tokens(&mut self, owner: PublicKey, token_ids: Vec) { - let owner_prev_balance = self.balance_of(owner.clone()); - let owner_new_balance = U256::from(token_ids.len() as u64); - let prev_total_supply = self.total_supply(); +mod cep47_storage; +mod data; +mod entrypoints; - let owner_tokens = self.get_tokens(owner.clone()); - for token_id in owner_tokens.clone() { - remove_key(&owner_key(&token_id)); - } - for token_id in token_ids.clone() { - set_key(&owner_key(&token_id), owner.clone()); - } - set_key(&token_key(&owner.to_account_hash()), token_ids); - set_key(&balance_key(&owner.to_account_hash()), owner_new_balance); - set_key( - "total_supply", - prev_total_supply - owner_prev_balance + owner_new_balance, - ); - } - - fn mint_many(&mut self, recipient: PublicKey, token_ids: Vec, token_metas: Vec) { - let mut recipient_tokens = self.get_tokens(recipient.clone()); - let mut recipient_balance = self.balance_of(recipient.clone()); - let mut total_supply = self.total_supply(); - - for (token_id, token_meta) in token_ids.iter().zip(token_metas) { - recipient_tokens.push(token_id.clone()); - set_key(&meta_key(&token_id), token_meta); - set_key(&owner_key(&token_id), recipient.clone()); - - // Emit event. - emit_mint_one_event(&recipient, &token_id); - } +pub use cep47_storage::CasperCEP47Storage; +pub use entrypoints::get_entrypoints; - set_key(&token_key(&recipient.to_account_hash()), recipient_tokens); - - let new_tokens_count = U256::from(token_ids.len() as u32); - recipient_balance = recipient_balance + new_tokens_count; - set_key( - &balance_key(&recipient.to_account_hash()), - recipient_balance, - ); - total_supply = total_supply + new_tokens_count; - set_key("total_supply", total_supply); - } - - fn burn_many(&mut self, owner: PublicKey, token_ids: Vec) { - let mut owner_tokens = self.get_tokens(owner.clone()); - let mut owner_balance = self.balance_of(owner.clone()); - let mut total_supply = self.total_supply(); - - for token_id in token_ids.clone() { - let index = owner_tokens - .iter() - .position(|x| *x == token_id.clone()) - .unwrap_or_revert(); - owner_tokens.remove(index); - remove_key(&meta_key(&token_id)); - remove_key(&owner_key(&token_id)); - owner_balance = owner_balance - 1; - total_supply = total_supply - 1; - - emit_burn_one_event(&owner, &token_id); - } - set_key(&balance_key(&owner.to_account_hash()), owner_balance); - set_key(&token_key(&owner.to_account_hash()), owner_tokens); - set_key("total_supply", total_supply); - } - - fn burn_one(&mut self, owner: PublicKey, token_id: TokenId) { - let mut owner_tokens = self.get_tokens(owner.clone()); - let owner_balance = self.balance_of(owner.clone()); - let total_supply = self.total_supply(); - let index = owner_tokens - .iter() - .position(|x| *x == token_id.clone()) - .unwrap_or_revert(); - owner_tokens.remove(index); - remove_key(&meta_key(&token_id)); - remove_key(&owner_key(&token_id)); - set_key(&balance_key(&owner.to_account_hash()), owner_balance - 1); - set_key(&token_key(&owner.to_account_hash()), owner_tokens); - set_key("total_supply", total_supply - 1); - emit_burn_one_event(&owner, &token_id); - } - - fn update_token_metadata(&mut self, token_id: TokenId, meta: Meta) { - set_key(&meta_key(&token_id), meta); - } - - fn gen_token_ids(&mut self, n: u32) -> Vec { - let block_time = runtime::get_blocktime(); - let mut token_ids = Vec::new(); - let nonce = get_nonce(); - for i in nonce..nonce + n { - let mut bytes: Vec = block_time.to_bytes().unwrap_or_revert(); - bytes.append(&mut i.to_bytes().unwrap_or_revert()); - let hash = runtime::blake2b(bytes); - token_ids.push(hex::encode(hash)); - }; - set_nonce(nonce+n); - token_ids - } - - fn validate_token_ids(&self, token_ids: &Vec) -> bool { - for token_id in token_ids { - if self.onwer_of(token_id).is_some() { - return false; - } - } - true - } -} +use data::{Balances, Metadata, OwnedTokens, Owners}; pub struct CasperCEP47Contract { storage: CasperCEP47Storage, @@ -256,9 +87,9 @@ pub extern "C" fn meta() { #[cfg(not(feature = "no_balance_of"))] #[no_mangle] pub extern "C" fn balance_of() { - let account: PublicKey = runtime::get_named_arg("account"); + let account: Key = runtime::get_named_arg("account"); let contract = CasperCEP47Contract::new(); - ret(contract.balance_of(account)) + ret(contract.balance_of(&account)) } #[cfg(not(feature = "no_owner_of"))] @@ -281,15 +112,15 @@ pub extern "C" fn total_supply() { pub extern "C" fn token_meta() { let token_id: TokenId = runtime::get_named_arg("token_id"); let contract = CasperCEP47Contract::new(); - ret(contract.token_meta(token_id)) + ret(contract.token_meta(&token_id)) } #[cfg(not(feature = "no_tokens"))] #[no_mangle] pub extern "C" fn tokens() { - let owner: PublicKey = runtime::get_named_arg("owner"); + let owner: Key = runtime::get_named_arg("owner"); let contract = CasperCEP47Contract::new(); - ret(contract.tokens(owner)) + ret(contract.tokens(&owner)) } #[cfg(not(feature = "no_is_paused"))] @@ -316,104 +147,87 @@ pub extern "C" fn unpause() { #[cfg(not(feature = "no_mint_one"))] #[no_mangle] pub extern "C" fn mint_one() { - let recipient: PublicKey = runtime::get_named_arg("recipient"); + let recipient: Key = runtime::get_named_arg("recipient"); let token_id: Option = runtime::get_named_arg("token_id"); let token_meta: Meta = runtime::get_named_arg("token_meta"); let mut contract = CasperCEP47Contract::new(); - contract.mint_one(recipient, token_id, token_meta).unwrap_or_revert(); + contract + .mint_one(&recipient, token_id, token_meta) + .unwrap_or_revert(); } #[cfg(not(feature = "no_mint_many"))] #[no_mangle] pub extern "C" fn mint_many() { - let recipient: PublicKey = runtime::get_named_arg("recipient"); + let recipient: Key = runtime::get_named_arg("recipient"); let token_ids: Option> = runtime::get_named_arg("token_ids"); let token_metas: Vec = runtime::get_named_arg("token_metas"); let mut contract = CasperCEP47Contract::new(); - contract.mint_many(recipient, token_ids, token_metas).unwrap_or_revert(); + contract + .mint_many(&recipient, token_ids, token_metas) + .unwrap_or_revert(); } #[cfg(not(feature = "no_mint_copies"))] #[no_mangle] pub extern "C" fn mint_copies() { - let recipient: PublicKey = runtime::get_named_arg("recipient"); + let recipient: Key = runtime::get_named_arg("recipient"); let token_ids: Option> = runtime::get_named_arg("token_ids"); let token_meta: Meta = runtime::get_named_arg("token_meta"); let count: u32 = runtime::get_named_arg("count"); let mut contract = CasperCEP47Contract::new(); - contract.mint_copies(recipient, token_ids, token_meta, count).unwrap_or_revert(); + contract + .mint_copies(&recipient, token_ids, token_meta, count) + .unwrap_or_revert(); } #[cfg(not(feature = "no_burn_many"))] #[no_mangle] pub extern "C" fn burn_many() { - let owner: PublicKey = runtime::get_named_arg("owner"); + let owner: Key = runtime::get_named_arg("owner"); let token_ids: Vec = runtime::get_named_arg("token_ids"); let mut contract = CasperCEP47Contract::new(); - contract.burn_many(owner, token_ids); + contract.burn_many(&owner, token_ids); } #[cfg(not(feature = "no_burn_one"))] #[no_mangle] pub extern "C" fn burn_one() { - let owner: PublicKey = runtime::get_named_arg("owner"); + let owner: Key = runtime::get_named_arg("owner"); let token_id: TokenId = runtime::get_named_arg("token_id"); let mut contract = CasperCEP47Contract::new(); - contract.burn_one(owner, token_id); + contract.burn_one(&owner, token_id); } #[cfg(not(feature = "no_transfer_token"))] #[no_mangle] pub extern "C" fn transfer_token() { - let caller: AccountHash = runtime::get_caller(); - let sender: PublicKey = runtime::get_named_arg("sender"); - if sender.to_account_hash() != caller { - runtime::revert(ApiError::PermissionDenied); - } - let recipient: PublicKey = runtime::get_named_arg("recipient"); + let sender: Key = get_caller(); + let recipient: Key = runtime::get_named_arg("recipient"); let token_id: TokenId = runtime::get_named_arg("token_id"); - - emit_transfer_token_event(&sender, &recipient, &token_id); - let mut contract = CasperCEP47Contract::new(); - let res = contract.transfer_token(sender, recipient, token_id); + let res = contract.transfer_token(&sender, &recipient, &token_id); res.unwrap_or_revert(); } #[cfg(not(feature = "no_transfer_many_tokens"))] #[no_mangle] pub extern "C" fn transfer_many_tokens() { - let caller: AccountHash = runtime::get_caller(); - let sender: PublicKey = runtime::get_named_arg("sender"); - if sender.to_account_hash() != caller { - runtime::revert(ApiError::PermissionDenied); - } - let recipient: PublicKey = runtime::get_named_arg("recipient"); + let sender: Key = get_caller(); + let recipient: Key = runtime::get_named_arg("recipient"); let token_ids: Vec = runtime::get_named_arg("token_ids"); - - for token_id in &token_ids { - emit_transfer_token_event(&sender, &recipient, &token_id); - } - let mut contract = CasperCEP47Contract::new(); - let res = contract.transfer_many_tokens(sender, recipient, token_ids); + let res = contract.transfer_many_tokens(&sender, &recipient, &token_ids); res.unwrap_or_revert(); } #[cfg(not(feature = "no_transfer_all_tokens"))] #[no_mangle] pub extern "C" fn transfer_all_tokens() { - let caller: AccountHash = runtime::get_caller(); - let sender: PublicKey = runtime::get_named_arg("sender"); - if sender.to_account_hash() != caller { - runtime::revert(ApiError::PermissionDenied); - } - let recipient: PublicKey = runtime::get_named_arg("recipient"); - - emit_transfer_all_tokens_event(&sender, &recipient); - + let sender: Key = get_caller(); + let recipient: Key = runtime::get_named_arg("recipient"); let mut contract = CasperCEP47Contract::new(); - let res = contract.transfer_all_tokens(sender, recipient); + let res = contract.transfer_all_tokens(&sender, &recipient); res.unwrap_or_revert(); } @@ -427,191 +241,6 @@ pub extern "C" fn update_token_metadata() { res.unwrap_or_revert(); } -pub fn get_entrypoints(package_hash: Option) -> EntryPoints { - let secure = if let Some(contract_package_hash) = package_hash { - let deployer_group = storage::create_contract_user_group( - contract_package_hash, - "deployer", - 1, - BTreeSet::default(), - ) - .unwrap_or_revert(); - runtime::put_key("deployer_group_access", Key::URef(deployer_group[0])); - true - } else { - false - }; - - let mut entry_points = EntryPoints::new(); - entry_points.add_entry_point(endpoint("name", vec![], CLType::String, None)); - entry_points.add_entry_point(endpoint("symbol", vec![], CLType::String, None)); - entry_points.add_entry_point(endpoint("meta", vec![], Meta::cl_type(), None)); - entry_points.add_entry_point(endpoint("total_supply", vec![], CLType::U256, None)); - entry_points.add_entry_point(endpoint("is_paused", vec![], CLType::Bool, None)); - entry_points.add_entry_point(endpoint( - "pause", - vec![], - CLType::Unit, - if secure { - Some("deployer") - } else { - None - }, - )); - entry_points.add_entry_point(endpoint( - "unpause", - vec![], - CLType::Unit, - if secure { - Some("deployer") - } else { - None - }, - )); - entry_points.add_entry_point(endpoint( - "balance_of", - vec![Parameter::new("account", CLType::PublicKey)], - CLType::U256, - None, - )); - entry_points.add_entry_point(endpoint( - "owner_of", - vec![Parameter::new("token_id", TokenId::cl_type())], - CLType::Option(Box::new(CLType::PublicKey)), - None, - )); - entry_points.add_entry_point(endpoint( - "token_meta", - vec![Parameter::new("token_id", TokenId::cl_type())], - CLType::Option(Box::new(CLType::String)), - None, - )); - entry_points.add_entry_point(endpoint( - "tokens", - vec![Parameter::new("owner", CLType::PublicKey)], - CLType::List(Box::new(CLType::String)), - None, - )); - entry_points.add_entry_point(endpoint( - "total_supply", - vec![Parameter::new("owner", CLType::PublicKey)], - CLType::List(Box::new(CLType::String)), - None, - )); - entry_points.add_entry_point(endpoint( - "mint_one", - vec![ - Parameter::new("recipient", CLType::PublicKey), - Parameter::new("token_ids", CLType::Option(Box::new(TokenId::cl_type()))), - Parameter::new("token_meta", Meta::cl_type()), - ], - CLType::Unit, - if secure { - Some("deployer") - } else { - None - }, - )); - entry_points.add_entry_point(endpoint( - "mint_many", - vec![ - Parameter::new("recipient", CLType::PublicKey), - Parameter::new("token_ids", CLType::Option(Box::new(CLType::List(Box::new(TokenId::cl_type()))))), - Parameter::new("token_metas", CLType::List(Box::new(Meta::cl_type()))), - ], - CLType::Unit, - if secure { - Some("deployer") - } else { - None - }, - )); - entry_points.add_entry_point(endpoint( - "mint_copies", - vec![ - Parameter::new("recipient", CLType::PublicKey), - Parameter::new("token_ids", CLType::Option(Box::new(CLType::List(Box::new(TokenId::cl_type()))))), - Parameter::new("token_meta", Meta::cl_type()), - Parameter::new("count", CLType::U32), - ], - CLType::Unit, - if secure { - Some("deployer") - } else { - None - }, - )); - entry_points.add_entry_point(endpoint( - "update_token_metadata", - vec![ - Parameter::new("token_id", TokenId::cl_type()), - Parameter::new("meta", Meta::cl_type()), - ], - CLType::Unit, - if secure { - Some("deployer") - } else { - None - }, - )); - entry_points.add_entry_point(endpoint( - "burn_one", - vec![ - Parameter::new("owner", CLType::PublicKey), - Parameter::new("token_id", TokenId::cl_type()), - ], - CLType::Unit, - if secure { - Some("deployer") - } else { - None - }, - )); - entry_points.add_entry_point(endpoint( - "burn_many", - vec![ - Parameter::new("owner", CLType::PublicKey), - Parameter::new("token_ids", CLType::List(Box::new(TokenId::cl_type()))), - ], - CLType::Unit, - if secure { - Some("deployer") - } else { - None - }, - )); - entry_points.add_entry_point(endpoint( - "transfer_token", - vec![ - Parameter::new("sender", CLType::PublicKey), - Parameter::new("recipient", CLType::PublicKey), - Parameter::new("token_id", TokenId::cl_type()), - ], - CLType::Unit, - None, - )); - entry_points.add_entry_point(endpoint( - "transfer_many_tokens", - vec![ - Parameter::new("sender", CLType::PublicKey), - Parameter::new("recipient", CLType::PublicKey), - Parameter::new("token_ids", CLType::List(Box::new(TokenId::cl_type()))), - ], - CLType::Unit, - None, - )); - entry_points.add_entry_point(endpoint( - "transfer_all_tokens", - vec![ - Parameter::new("sender", CLType::PublicKey), - Parameter::new("recipient", CLType::PublicKey), - ], - CLType::Unit, - None, - )); - entry_points -} - pub fn deploy( token_name: String, token_symbol: String, @@ -620,29 +249,26 @@ pub fn deploy( contract_package_hash: ContractPackageHash, paused: bool, ) { - let mut named_keys = NamedKeys::new(); - named_keys.insert( - "name".to_string(), - storage::new_uref(token_name.clone()).into(), - ); - named_keys.insert("symbol".to_string(), storage::new_uref(token_symbol).into()); - named_keys.insert("meta".to_string(), storage::new_uref(token_meta).into()); - named_keys.insert( - "total_supply".to_string(), - storage::new_uref(U256::zero()).into(), - ); - named_keys.insert("paused".to_string(), storage::new_uref(paused).into()); - named_keys.insert( - "contract_package_hash".to_string(), - storage::new_uref(contract_package_hash).into(), + // Get named keys for the contract. + let named_keys = data::initial_named_keys( + contract_package_hash, + &token_name, + &token_symbol, + token_meta, + paused, ); + // Add new version to the package. let (contract_hash, _) = storage::add_contract_version(contract_package_hash, entry_points, named_keys); + + // Save contracts. runtime::put_key( format!("{}_contract", &token_name).as_str(), contract_hash.into(), ); + + // Save contract hashs. let contract_hash_pack = storage::new_uref(contract_hash); runtime::put_key( format!("{}_contract_hash", token_name).as_str(), @@ -650,127 +276,22 @@ pub fn deploy( ); } -fn get_key(name: &str) -> Option { - match runtime::get_key(name) { - None => None, - Some(value) => { - let key = value.try_into().unwrap_or_revert(); - let value = storage::read(key).unwrap_or_revert().unwrap_or_revert(); - Some(value) - } - } -} - -fn set_key(name: &str, value: T) { - match runtime::get_key(name) { - Some(key) => { - let key_ref = key.try_into().unwrap_or_revert(); - storage::write(key_ref, value); - } - None => { - let key = storage::new_uref(value).into(); - runtime::put_key(name, key); - } - } -} - -fn remove_key(name: &str) { - match runtime::get_key(name) { - Some(_) => { - runtime::remove_key(name); - } - None => {} - } -} - -fn balance_key(account: &AccountHash) -> String { - format!("balances_{}", account) -} - -fn owner_key(token_id: &TokenId) -> String { - format!("owners_{}", token_id) -} - -fn meta_key(token_id: &TokenId) -> String { - format!("metas_{}", token_id) -} - -fn token_key(account: &AccountHash) -> String { - format!("tokens_{}", account) -} - -pub fn endpoint( - name: &str, - param: Vec, - ret: CLType, - access: Option<&str>, -) -> EntryPoint { - EntryPoint::new( - String::from(name), - param, - ret, - match access { - None => EntryPointAccess::Public, - Some(access_key) => EntryPointAccess::groups(&[access_key]), - }, - EntryPointType::Contract, - ) -} - pub fn ret(value: T) { runtime::ret(CLValue::from_t(value).unwrap_or_revert()) } -pub fn emit_mint_one_event(recipient: &PublicKey, token_id: &TokenId) { - let mut event = BTreeMap::new(); - event.insert("contract_package_hash", package_hash().to_string()); - event.insert("event_type", "cep47_mint_one".to_string()); - event.insert("recipient", recipient.to_string()); - event.insert("token_id", token_id.to_string()); - emit_event(event); -} - -pub fn emit_burn_one_event(owner: &PublicKey, token_id: &TokenId) { - let mut event = BTreeMap::new(); - event.insert("contract_package_hash", package_hash().to_string()); - event.insert("event_type", "cep47_burn_one".to_string()); - event.insert("owner", owner.to_string()); - event.insert("token_id", token_id.to_string()); - emit_event(event); -} - -pub fn emit_transfer_token_event(sender: &PublicKey, recipient: &PublicKey, token_id: &TokenId) { - let mut event = BTreeMap::new(); - event.insert("contract_package_hash", package_hash().to_string()); - event.insert("event_type", "cep47_transfer_token".to_string()); - event.insert("sender", sender.to_string()); - event.insert("recipient", recipient.to_string()); - event.insert("token_id", token_id.to_string()); - emit_event(event); -} - -pub fn emit_transfer_all_tokens_event(sender: &PublicKey, recipient: &PublicKey) { - let mut event = BTreeMap::new(); - event.insert("contract_package_hash", package_hash().to_string()); - event.insert("event_type", "cep47_transfer_all_tokens".to_string()); - event.insert("sender", sender.to_string()); - event.insert("recipient", recipient.to_string()); - emit_event(event); -} - -pub fn emit_event(event: BTreeMap<&str, String>) { - let _: URef = storage::new_uref(event); -} - -pub fn package_hash() -> ContractPackageHash { - let key: [u8; 32] = get_key("contract_package_hash").unwrap_or_revert(); - key.into() -} - -fn get_nonce() -> u32 { - get_key("nonce").unwrap_or_default() -} - -fn set_nonce(nonce: u32) { - set_key("nonce", nonce); +fn get_caller() -> Key { + match runtime::get_call_stack().first().unwrap_or_revert() { + // first or last? + CallStackElement::Session { account_hash } => (*account_hash).into(), + CallStackElement::StoredSession { + account_hash, + contract_package_hash: _, + contract_hash: _, + } => (*account_hash).into(), + CallStackElement::StoredContract { + contract_package_hash, + contract_hash: _, + } => (*contract_package_hash).into(), + } } diff --git a/dragons-nft-scripts/package-lock.json b/dragons-nft-scripts/package-lock.json index 0f11e0a..09ba30a 100644 --- a/dragons-nft-scripts/package-lock.json +++ b/dragons-nft-scripts/package-lock.json @@ -298,14 +298,6 @@ "safer-buffer": "^2.1.0" } }, - "axios": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", - "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", - "requires": { - "follow-redirects": "^1.10.0" - } - }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -420,270 +412,38 @@ "integrity": "sha512-4rS7co+7+AoOSPRPOPUt5/GdaqZc0EsUpWk66ofE3HJTAajUK2Ss2VwoNzVN69ghg8lYYlh0an0Iy4LIHHo9UQ==" }, "casper-cep47-js-client": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/casper-cep47-js-client/-/casper-cep47-js-client-0.2.3.tgz", - "integrity": "sha512-x2ecS4NTvn5w247vYX1ZA2rIH1R1Waen9B04ZVfHH5BpN8ihtYRN48otTF6OwOXqSJWEopHwjqEAyaFcY7hDdw==", + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/casper-cep47-js-client/-/casper-cep47-js-client-0.2.4.tgz", + "integrity": "sha512-zGlkfxbofwLyaNU1TzRDIv1jkySFvZphPrOPStECQtS6fjPGY2RpTJgRKmj0a6Z+Lq+403/qfQo0yBw1+gFUWQ==", "requires": { "@ethersproject/bignumber": "^5.0.8", "casper-js-sdk": "2.2.3", "ts-results": "^3.3.0" - }, - "dependencies": { - "casper-js-sdk": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/casper-js-sdk/-/casper-js-sdk-2.2.3.tgz", - "integrity": "sha512-e8vyktJBsSBh8lJzwwbWAgP7mTHGC04iE4Fhd7sdYCYClWjKv+XQ22aXNwawWYNOxHqipF7n7Z319F9dEhxQhg==", - "requires": { - "@ethersproject/bignumber": "^5.0.8", - "@ethersproject/bytes": "^5.0.5", - "@ethersproject/constants": "^5.0.5", - "@open-rpc/client-js": "^1.6.2", - "@types/eccrypto": "^1.1.2", - "blakejs": "^1.1.0", - "eccrypto": "^1.1.6", - "eslint-plugin-prettier": "^3.4.0", - "ethereum-cryptography": "^0.1.3", - "glob": "^7.1.6", - "humanize-duration": "^3.24.0", - "key-encoder": "^2.0.3", - "reflect-metadata": "^0.1.13", - "ts-results": "^3.2.1", - "tweetnacl-ts": "^1.0.3", - "tweetnacl-util": "^0.15.0", - "typedjson": "^1.6.0-rc2", - "webpack": "^5.24.3" - } - } } }, "casper-js-sdk": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/casper-js-sdk/-/casper-js-sdk-1.4.3.tgz", - "integrity": "sha512-TtKRzeFX9mhEdsqFAt9PQlQ8Y1vS8SygO8XAviL8lXuunND/WURQKVRUbN/UQmj8Mgdx+Vo7zbJV8g9etuv26g==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/casper-js-sdk/-/casper-js-sdk-2.2.3.tgz", + "integrity": "sha512-e8vyktJBsSBh8lJzwwbWAgP7mTHGC04iE4Fhd7sdYCYClWjKv+XQ22aXNwawWYNOxHqipF7n7Z319F9dEhxQhg==", "requires": { "@ethersproject/bignumber": "^5.0.8", "@ethersproject/bytes": "^5.0.5", "@ethersproject/constants": "^5.0.5", "@open-rpc/client-js": "^1.6.2", "@types/eccrypto": "^1.1.2", - "axios": "^0.21.1", "blakejs": "^1.1.0", "eccrypto": "^1.1.6", + "eslint-plugin-prettier": "^3.4.0", "ethereum-cryptography": "^0.1.3", "glob": "^7.1.6", "humanize-duration": "^3.24.0", - "jsbi": "^3.1.2", "key-encoder": "^2.0.3", "reflect-metadata": "^0.1.13", - "rxjs": "^6.5.3", "ts-results": "^3.2.1", "tweetnacl-ts": "^1.0.3", "tweetnacl-util": "^0.15.0", "typedjson": "^1.6.0-rc2", "webpack": "^5.24.3" - }, - "dependencies": { - "@ethersproject/bignumber": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.4.1.tgz", - "integrity": "sha512-fJhdxqoQNuDOk6epfM7yD6J8Pol4NUCy1vkaGAkuujZm0+lNow//MKu1hLhRiYV4BsOHyBv5/lsTjF+7hWwhJg==", - "requires": { - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "bn.js": "^4.11.9" - } - }, - "@ethersproject/bytes": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.4.0.tgz", - "integrity": "sha512-H60ceqgTHbhzOj4uRc/83SCN9d+BSUnOkrr2intevqdtEMO1JFVZ1XL84OEZV+QjV36OaZYxtnt4lGmxcGsPfA==", - "requires": { - "@ethersproject/logger": "^5.4.0" - } - }, - "@ethersproject/constants": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.4.0.tgz", - "integrity": "sha512-tzjn6S7sj9+DIIeKTJLjK9WGN2Tj0P++Z8ONEIlZjyoTkBuODN+0VfhAyYksKi43l1Sx9tX2VlFfzjfmr5Wl3Q==", - "requires": { - "@ethersproject/bignumber": "^5.4.0" - } - }, - "@open-rpc/client-js": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@open-rpc/client-js/-/client-js-1.7.0.tgz", - "integrity": "sha512-cRGJbXTgdhJNU49vWzJIATRmKBLP2x6tuHJzX9Jg3N8f1VEkge0riUEek2LFIrZiM4TdUp8XV4Ns1W0SZzdfSw==", - "requires": { - "isomorphic-fetch": "^3.0.0", - "isomorphic-ws": "^4.0.1", - "strict-event-emitter-types": "^2.0.0", - "ws": "^7.0.0" - } - }, - "@types/eccrypto": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@types/eccrypto/-/eccrypto-1.1.3.tgz", - "integrity": "sha512-3O0qER6JMYReqVbcQTGmXeMHdw3O+rVps63tlo5g5zoB3altJS8yzSvboSivwVWeYO9o5jSATu7P0UIqYZPgow==", - "requires": { - "@types/expect": "^1.20.4", - "@types/node": "*" - } - }, - "blakejs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.1.tgz", - "integrity": "sha512-bLG6PHOCZJKNshTjGRBvET0vTciwQE6zFKOKKXPDJfwFBd4Ac0yBfPZqcGvGJap50l7ktvlpFqc2jGVaUgbJgg==" - }, - "eccrypto": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/eccrypto/-/eccrypto-1.1.6.tgz", - "integrity": "sha512-d78ivVEzu7Tn0ZphUUaL43+jVPKTMPFGtmgtz1D0LrFn7cY3K8CdrvibuLz2AAkHBLKZtR8DMbB2ukRYFk987A==", - "requires": { - "acorn": "7.1.1", - "elliptic": "6.5.4", - "es6-promise": "4.2.8", - "nan": "2.14.0", - "secp256k1": "3.7.1" - } - }, - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - }, - "dependencies": { - "secp256k1": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz", - "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==", - "requires": { - "elliptic": "^6.5.2", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - } - } - } - }, - "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "humanize-duration": { - "version": "3.27.0", - "resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.27.0.tgz", - "integrity": "sha512-qLo/08cNc3Tb0uD7jK0jAcU5cnqCM0n568918E7R2XhMr/+7F37p4EY062W/stg7tmzvknNn9b/1+UhVRzsYrQ==" - }, - "key-encoder": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/key-encoder/-/key-encoder-2.0.3.tgz", - "integrity": "sha512-fgBtpAGIr/Fy5/+ZLQZIPPhsZEcbSlYu/Wu96tNDFNSjSACw5lEIOFeaVdQ/iwrb8oxjlWi6wmWdH76hV6GZjg==", - "requires": { - "@types/elliptic": "^6.4.9", - "asn1.js": "^5.0.1", - "bn.js": "^4.11.8", - "elliptic": "^6.4.1" - } - }, - "reflect-metadata": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", - "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" - }, - "ts-results": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/ts-results/-/ts-results-3.3.0.tgz", - "integrity": "sha512-FWqxGX2NHp5oCyaMd96o2y2uMQmSu8Dey6kvyuFdRJ2AzfmWo3kWa4UsPlCGlfQ/qu03m09ZZtppMoY8EMHuiA==" - }, - "tweetnacl-ts": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl-ts/-/tweetnacl-ts-1.0.3.tgz", - "integrity": "sha512-C5I/dWf6xjAXaCDlf84T4HvozU/8ycAlq5WRllF1hAeeq5390tfXD+bNas5bhEV0HMSOx8bsQYpLjPl8wfnEeQ==", - "requires": { - "tslib": "^1" - } - }, - "tweetnacl-util": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", - "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==" - }, - "typedjson": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/typedjson/-/typedjson-1.7.0.tgz", - "integrity": "sha512-MnRgQLwtEcdHqQG0FkT8ebpBG53Wgr/axYRbiD2WL5NcYx8Z2AoCpXvtTfLnuPqOBKG/9JpXq0O/nl2m4wqJYw==", - "requires": { - "tslib": "^2.0.1" - }, - "dependencies": { - "tslib": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", - "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" - } - } - }, - "webpack": { - "version": "5.46.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.46.0.tgz", - "integrity": "sha512-qxD0t/KTedJbpcXUmvMxY5PUvXDbF8LsThCzqomeGaDlCA6k998D8yYVwZMvO8sSM3BTEOaD4uzFniwpHaTIJw==", - "requires": { - "@types/eslint-scope": "^3.7.0", - "@types/estree": "^0.0.50", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "acorn": "^8.4.1", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.8.0", - "es-module-lexer": "^0.7.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.4", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", - "watchpack": "^2.2.0", - "webpack-sources": "^2.3.1" - }, - "dependencies": { - "acorn": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", - "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==" - } - } - } } }, "chrome-trace-event": { @@ -764,9 +524,9 @@ } }, "electron-to-chromium": { - "version": "1.3.786", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.786.tgz", - "integrity": "sha512-AmvbLBj3hepRk8v/DHrFF8gINxOFfDbrn6Ts3PcK46/FBdQb5OMmpamSpZQXSkfi77FfBzYtQtAk+00LCLYMVw==" + "version": "1.3.788", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.788.tgz", + "integrity": "sha512-dbMIpX4E4/Gk4gzOh1GYS7ls1vGsByWKpIqLviJi1mSmSt5BvrWLLtSqpFE5BaC7Ef4NnI0GMaiddNX2Brw6zA==" }, "elliptic": { "version": "6.5.4", @@ -912,11 +672,6 @@ "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", "optional": true }, - "follow-redirects": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz", - "integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==" - }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -1022,11 +777,6 @@ "supports-color": "^8.0.0" } }, - "jsbi": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/jsbi/-/jsbi-3.1.5.tgz", - "integrity": "sha512-w2BY0VOYC1ahe+w6Qhl4SFoPvPsZ9NPHY4bwass+LCgU7RK3PBoVQlQ3G1s7vI8W3CYyJiEXcbKF7FIM/L8q3Q==" - }, "json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", @@ -1216,14 +966,6 @@ "inherits": "^2.0.1" } }, - "rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "requires": { - "tslib": "^1.9.0" - } - }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", diff --git a/dragons-nft-scripts/package.json b/dragons-nft-scripts/package.json index bb9fb61..9b2e5a5 100644 --- a/dragons-nft-scripts/package.json +++ b/dragons-nft-scripts/package.json @@ -16,7 +16,7 @@ "author": "", "license": "ISC", "dependencies": { - "casper-cep47-js-client": "^0.2.3", - "casper-js-sdk": "^1.4.3" + "casper-cep47-js-client": "0.2.4", + "casper-js-sdk": "^2.2.3" } } diff --git a/dragons-nft-scripts/src/index.js b/dragons-nft-scripts/src/index.js index 68509c3..8ffec34 100644 --- a/dragons-nft-scripts/src/index.js +++ b/dragons-nft-scripts/src/index.js @@ -11,15 +11,15 @@ const MINT_COPIES_PAYMENT_AMOUNT = '100000000000'; const BURN_ONE_PAYMENT_AMOUNT = '12000000000'; // const CHAIN_NAME = 'integration-test'; const CHAIN_NAME = 'casper-net-1'; -const WASM_PATH = "./../target/wasm32-unknown-unknown/release/dragons-nft.wasm"; -const TOKEN_NAME = 'event_nft_4'; -const TOKEN_SYMBOL = 'DRAG'; +const WASM_PATH = "/home/ziel/workspace/casperlabs/ipwe-nft-contract/target/wasm32-unknown-unknown/release/ipwe-nft-contract.wasm"; +const TOKEN_NAME = 'test_nft'; +const TOKEN_SYMBOL = 'tnft'; const TOKEN_META = new Map([ ['origin', 'fire'], ['lifetime', 'infinite'] ]); // const KEY_PAIR_PATH = '/home/ziel/workspace/casperlabs/integration-key/master'; -const KEY_PAIR_PATH = '/Users/janhoffmann/casper-node/utils/nctl/assets/net-1/faucet'; +const KEY_PAIR_PATH = '/home/ziel/workspace/casperlabs/casper-node/utils/nctl/assets/net-1/faucet'; const KEYS = Keys.Ed25519.parseKeyFiles( `${KEY_PAIR_PATH}/public_key.pem`, `${KEY_PAIR_PATH}/secret_key.pem` @@ -29,7 +29,7 @@ const MINT_COPIES_META_SIZE = 10; const MINT_COPIES_COUNT = 20; const MINT_MANY_META_SIZE = 5; const MINT_MANY_META_COUNT = 5; -const CONTRACT_HASH = '6c0d0919acbcbe02665eb4cb32b856fd2ce5359432c0af43818d538c17de96a8'; +const CONTRACT_HASH = '1f7112e5424d206be8b3c63774726347a03bd692327b4207148cb237b43ec5ea'; const cep47 = new CEP47Client(NODE_ADDRESS, CHAIN_NAME, EVENT_STREAM_ADDRESS); @@ -43,8 +43,8 @@ const install = async () => { const mintOne = async () => { const cep47 = new CEP47Client(NODE_ADDRESS, CHAIN_NAME, EVENT_STREAM_ADDRESS); await cep47.setContractHash(CONTRACT_HASH); - let meta = randomMetaMap(MINT_ONE_META_SIZE); - const deployHash = await cep47.mintOne(KEYS, KEYS.publicKey, "ABC123", meta, MINT_ONE_PAYMENT_AMOUNT); + let meta = randomMetaMap(4); + const deployHash = await cep47.mintOne(KEYS, KEYS.publicKey, "ABC123456", meta, MINT_ONE_PAYMENT_AMOUNT); console.log(`Mint One`); console.log(`... DeployHash: ${deployHash}`); } @@ -91,10 +91,10 @@ const getName = async () => { console.log(`Contract Name: ${value}`); } -const balanceOf = async () => { +const balanceOf = async (publicKeyHex) => { await cep47.setContractHash(CONTRACT_HASH); - const balance = await cep47.balanceOf(CLPublicKey.fromHex("01694a09937e05f5a60b5f56d1d108f65ae716c45879fca79fca89ec1c20e15431")); - console.log(`Balance: ${balance.value()}`); + const balance = await cep47.balanceOf(CLPublicKey.fromHex(publicKeyHex)); + console.log(`Balance: ${balance}`); } const tokensOf = async (publicKeyHex) => { @@ -102,12 +102,25 @@ const tokensOf = async (publicKeyHex) => { const value = await cep47.getTokensOf(CLPublicKey.fromHex(publicKeyHex)); console.log(`Tokens: ${JSON.stringify(value, null, 2)}`); } + const ownerOf = async (tokenId) => { await cep47.setContractHash(CONTRACT_HASH); const value = await cep47.getOwnerOf(tokenId); console.log(`Owner public key hex: ${value}`); } +const totalSupply = async (tokenId) => { + await cep47.setContractHash(CONTRACT_HASH); + const value = await cep47.totalSupply(); + console.log(`Total supply: ${value}`); +} + +const meta = async () => { + await cep47.setContractHash(CONTRACT_HASH); + const value = await cep47.meta(); + console.log(`Owner public key hex: ${value}`); +} + const tokenMeta = async (tokenId) => { await cep47.setContractHash(CONTRACT_HASH); const value = await cep47.getTokenMeta(tokenId); @@ -133,12 +146,15 @@ const getContractData = async () => { const transferToken = async () => { await cep47.setContractHash(CONTRACT_HASH); - await cep47.transferToken( + const deployHash = await cep47.transferToken( KEYS, KEYS.publicKey, - CLPublicKey.fromHex('017b4822b849f197acf4f49d91315887f913128a9673a2d7ea834cf13c2e6fc606'), '17873237509455618405', + CLPublicKey.fromHex('017b4822b849f197acf4f49d91315887f913128a9673a2d7ea834cf13c2e6fc606'), + '52a9b6b34ec2cf6c1767b9c6678a23aeacaa9c17145c379525cce6ac2e649e1f', MINT_ONE_PAYMENT_AMOUNT * 100 ); + console.log(`Transfer one`); + console.log(`... DeployHash: ${deployHash}`); } const transferAll = async () => { @@ -237,10 +253,10 @@ switch (command) { burnOne(arg1); break; case 'total_supply': - getSimpleValue("totalSupply"); + totalSupply(); break; case 'balance_of': - balanceOf(); + balanceOf(arg1); break; case 'owner_of': ownerOf(arg1); diff --git a/dragons-nft-tests/Cargo.toml b/dragons-nft-tests/Cargo.toml index d331919..e53562b 100644 --- a/dragons-nft-tests/Cargo.toml +++ b/dragons-nft-tests/Cargo.toml @@ -4,13 +4,12 @@ version = "0.1.0" authors = ["astro019 "] edition = "2018" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] -casper-contract = "1.2.0" -casper-types = "1.2.0" -casper-engine-test-support = "1.2.0" +casper-contract = "1.3.1" +casper-types = "1.3.1" +casper-engine-test-support = "1.3.1" maplit = "1.0.2" +hex = "0.4.3" [features] default = ["casper-contract/std", "casper-types/std", "casper-contract/test-support"] diff --git a/dragons-nft-tests/src/cep47.rs b/dragons-nft-tests/src/cep47.rs index d810b95..ee56bb6 100644 --- a/dragons-nft-tests/src/cep47.rs +++ b/dragons-nft-tests/src/cep47.rs @@ -2,7 +2,7 @@ use std::collections::BTreeMap; use casper_engine_test_support::{Code, Hash, SessionBuilder, TestContext, TestContextBuilder}; use casper_types::{ - account::AccountHash, bytesrepr::FromBytes, runtime_args, CLTyped, PublicKey, RuntimeArgs, + account::AccountHash, bytesrepr::FromBytes, runtime_args, CLTyped, Key, PublicKey, RuntimeArgs, SecretKey, U256, U512, }; @@ -23,13 +23,17 @@ pub mod token_cfg { pub const CONTRACT_KEY: &str = "DragonsNFT_contract"; pub const CONTRACT_HASH_KEY: &str = "DragonsNFT_contract_hash"; -pub struct Sender(pub AccountHash); +const BALANCES_DICT: &str = "balances"; +const OWNED_TOKENS_DICT: &str = "owned_tokens"; +const TOKEN_OWNERS_DICT: &str = "owners"; +const METADATA_DICT: &str = "metadata"; + pub struct CasperCEP47Contract { pub context: TestContext, pub hash: Hash, - pub admin: PublicKey, - pub ali: PublicKey, - pub bob: PublicKey, + pub admin: AccountHash, + pub ali: AccountHash, + pub bob: AccountHash, } pub type TokenId = String; @@ -69,27 +73,27 @@ impl CasperCEP47Contract { Self { context, hash, - admin: admin, - ali: ali, - bob: bob, + admin: admin.to_account_hash(), + ali: ali.to_account_hash(), + bob: bob.to_account_hash(), } } - fn call(&mut self, sender: Sender, method: &str, args: RuntimeArgs) { - let Sender(address) = sender; + fn call(&mut self, sender: &AccountHash, method: &str, args: RuntimeArgs) { + let account = *sender; let code = Code::Hash(self.hash, method.to_string()); let session = SessionBuilder::new(code, args) - .with_address(address) - .with_authorization_keys(&[address]) + .with_address(account) + .with_authorization_keys(&[account]) .build(); self.context.run(session); } fn query_contract(&self, name: &str) -> Option { - match self.context.query( - self.admin.to_account_hash(), - &[CONTRACT_KEY.to_string(), name.to_string()], - ) { + match self + .context + .query(self.admin, &[CONTRACT_KEY.to_string(), name.to_string()]) + { Err(_) => None, Ok(maybe_value) => { let value = maybe_value @@ -100,6 +104,26 @@ impl CasperCEP47Contract { } } + fn query_dictionary_value( + &self, + dict_name: &str, + key: String, + ) -> Option { + match self.context.query_dictionary_item( + Key::Hash(self.hash), + Some(dict_name.to_string()), + key, + ) { + Err(_) => None, + Ok(maybe_value) => { + let value = maybe_value + .into_t() + .unwrap_or_else(|_| panic!("is not expected type.")); + Some(value) + } + } + } + pub fn name(&self) -> String { self.query_contract("name").unwrap() } @@ -116,148 +140,163 @@ impl CasperCEP47Contract { self.query_contract("total_supply").unwrap_or_default() } - pub fn owner_of(&self, token_id: &TokenId) -> Option { - self.query_contract(owner_key(&token_id).as_str()) + pub fn owner_of(&self, token_id: &TokenId) -> Option { + let key: Key = self + .query_dictionary_value(TOKEN_OWNERS_DICT, token_id.clone()) + .unwrap(); + key.into_account() } - pub fn balance_of(&self, owner: PublicKey) -> U256 { - self.query_contract(balance_key(&owner.to_account_hash()).as_str()) - .unwrap_or_default() + pub fn balance_of(&self, owner: &AccountHash) -> U256 { + let value: Option = self.query_dictionary_value(BALANCES_DICT, owner.to_string()); + value.unwrap_or(U256::zero()) } - pub fn tokens(&self, owner: PublicKey) -> Vec { - self.query_contract::>(token_key(&owner.to_account_hash()).as_str()) - .unwrap_or_default() + pub fn tokens(&self, owner: &AccountHash) -> Vec { + let value: Option> = + self.query_dictionary_value(OWNED_TOKENS_DICT, owner.to_string()); + value.unwrap_or(Vec::new()) } - pub fn token_meta(&self, token_id: TokenId) -> Option { - self.query_contract(meta_key(&token_id).as_str()) + pub fn token_meta(&self, token_id: &TokenId) -> Option { + self.query_dictionary_value(METADATA_DICT, token_id.clone()) } - pub fn mint_one(&mut self, recipient: PublicKey, token_id: Option, token_meta: Meta, sender: Sender) { + pub fn mint_one( + &mut self, + recipient: &AccountHash, + token_id: Option<&TokenId>, + token_meta: &Meta, + sender: &AccountHash, + ) { self.call( sender, "mint_one", runtime_args! { - "recipient" => recipient, - "token_id" => token_id, - "token_meta" => token_meta + "recipient" => Key::from(*recipient), + "token_id" => token_id.map(|id| id.clone()), + "token_meta" => token_meta.clone() }, ); } pub fn mint_copies( &mut self, - recipient: PublicKey, - token_ids: Option>, - token_meta: Meta, + recipient: &AccountHash, + token_ids: Option<&Vec>, + token_meta: &Meta, count: u32, - sender: Sender, + sender: &AccountHash, ) { self.call( sender, "mint_copies", runtime_args! { - "recipient" => recipient, - "token_ids" => token_ids, - "token_meta" => token_meta, + "recipient" => Key::from(*recipient), + "token_ids" => token_ids.map(|ids| ids.clone()), + "token_meta" => token_meta.clone(), "count" => count }, ); } - pub fn mint_many(&mut self, recipient: PublicKey, token_ids: Option>, token_metas: Vec, sender: Sender) { + pub fn mint_many( + &mut self, + recipient: &AccountHash, + token_ids: Option<&Vec>, + token_metas: &Vec, + sender: &AccountHash, + ) { self.call( sender, "mint_many", runtime_args! { - "recipient" => recipient, - "token_ids" => token_ids, - "token_metas" => token_metas + "recipient" => Key::from(*recipient), + "token_ids" => token_ids.map(|ids| ids.clone()), + "token_metas" => token_metas.clone(), }, ); } - pub fn burn_many(&mut self, owner: PublicKey, token_ids: Vec, sender: Sender) { + pub fn burn_many( + &mut self, + owner: &AccountHash, + token_ids: &Vec, + sender: &AccountHash, + ) { self.call( sender, "burn_many", runtime_args! { - "owner" => owner, - "token_ids" => token_ids + "owner" => Key::from(*owner), + "token_ids" => token_ids.clone() }, ); } - pub fn burn_one(&mut self, owner: PublicKey, token_id: TokenId, sender: Sender) { + pub fn burn_one(&mut self, owner: &AccountHash, token_id: &TokenId, sender: &AccountHash) { self.call( sender, "burn_one", runtime_args! { - "owner" => owner, - "token_id" => token_id + "owner" => Key::from(*owner), + "token_id" => token_id.clone() }, ); } pub fn transfer_token( &mut self, - owner: PublicKey, - recipient: PublicKey, - token_id: TokenId, - sender: Sender, + recipient: &AccountHash, + token_id: &TokenId, + sender: &AccountHash, ) { self.call( sender, "transfer_token", runtime_args! { - "sender" => owner, - "recipient" => recipient, - "token_id" => token_id + "recipient" => Key::from(*recipient), + "token_id" => token_id.clone() }, ); } pub fn transfer_many_tokens( &mut self, - owner: PublicKey, - recipient: PublicKey, - token_ids: Vec, - sender: Sender, + recipient: &AccountHash, + token_ids: &Vec, + sender: &AccountHash, ) { self.call( sender, "transfer_many_tokens", runtime_args! { - "sender" => owner, - "recipient" => recipient, - "token_ids" => token_ids + "recipient" => Key::from(*recipient), + "token_ids" => token_ids.clone() }, ); } - pub fn transfer_all_tokens(&mut self, owner: PublicKey, recipient: PublicKey, sender: Sender) { + pub fn transfer_all_tokens(&mut self, recipient: &AccountHash, sender: &AccountHash) { self.call( sender, "transfer_all_tokens", runtime_args! { - "sender" => owner, - "recipient" => recipient + "recipient" => Key::from(*recipient) }, ); } - - pub fn update_token_metadata(&mut self, token_id: TokenId, meta: Meta, sender: Sender) { + + pub fn update_token_metadata(&mut self, token_id: &TokenId, meta: &Meta, sender: &AccountHash) { self.call( sender, "update_token_metadata", runtime_args! { - "token_id" => token_id, - "meta" => meta + "token_id" => token_id.clone(), + "token_meta" => meta.clone() }, ); } - } fn balance_key(account: &AccountHash) -> String { diff --git a/dragons-nft-tests/src/contract_tests.rs b/dragons-nft-tests/src/contract_tests.rs index 34c23fb..5f0f264 100644 --- a/dragons-nft-tests/src/contract_tests.rs +++ b/dragons-nft-tests/src/contract_tests.rs @@ -1,4 +1,4 @@ -use crate::cep47::{token_cfg, CasperCEP47Contract, Meta, Sender, TokenId}; +use crate::cep47::{token_cfg, CasperCEP47Contract, Meta, TokenId}; use casper_types::U256; mod meta { @@ -43,18 +43,21 @@ fn test_deploy() { #[test] fn test_token_meta() { let mut contract = CasperCEP47Contract::deploy(); + let token_id = String::from("custom_token_id"); let token_meta = meta::red_dragon(); + contract.mint_one( - contract.ali.clone(), - None, - token_meta.clone(), - Sender(contract.admin.clone().to_account_hash()), + &contract.ali.clone(), + Some(&token_id), + &token_meta, + &contract.admin.clone(), ); - let ali_tokens: Vec = contract.tokens(contract.ali.clone()); - let ali_token_meta = contract.token_meta(ali_tokens[0].clone()); + let ali_token_meta = contract.token_meta(&token_id).unwrap(); + assert_eq!(ali_token_meta, token_meta); - assert_eq!(ali_token_meta, Some(token_meta)); + let ali_tokens: Vec = contract.tokens(&contract.ali); + assert_eq!(ali_tokens, vec![token_id]); } #[test] @@ -62,16 +65,16 @@ fn test_mint_one_with_random_token_id() { let mut contract = CasperCEP47Contract::deploy(); let token_meta = meta::red_dragon(); contract.mint_one( - contract.ali.clone(), + &contract.ali.clone(), None, - token_meta, - Sender(contract.admin.clone().to_account_hash()), + &token_meta, + &contract.admin.clone(), ); - let ali_tokens: Vec = contract.tokens(contract.ali.clone()); - assert_eq!(contract.total_supply(), U256::one()); - assert_eq!(contract.balance_of(contract.ali.clone()), U256::one()); + assert_eq!(contract.balance_of(&contract.ali), U256::one()); + + let ali_tokens: Vec = contract.tokens(&contract.ali); assert_eq!(U256::from(ali_tokens.len() as u64), U256::one()); assert_eq!(contract.owner_of(&ali_tokens[0]), Some(contract.ali)); } @@ -82,16 +85,16 @@ fn test_mint_one_with_set_token_id() { let token_id = TokenId::from("123456"); let token_meta = meta::red_dragon(); contract.mint_one( - contract.ali.clone(), - Some(token_id.clone()), - token_meta, - Sender(contract.admin.clone().to_account_hash()), + &contract.ali.clone(), + Some(&token_id), + &token_meta, + &contract.admin.clone(), ); - let ali_tokens: Vec = contract.tokens(contract.ali.clone()); + let ali_tokens: Vec = contract.tokens(&contract.ali); assert_eq!(ali_tokens, vec![token_id.clone()]); assert_eq!(contract.total_supply(), U256::one()); - assert_eq!(contract.balance_of(contract.ali.clone()), U256::one()); + assert_eq!(contract.balance_of(&contract.ali), U256::one()); assert_eq!(U256::from(ali_tokens.len() as u64), U256::one()); assert_eq!(contract.owner_of(&token_id), Some(contract.ali)); } @@ -103,16 +106,16 @@ fn test_mint_one_with_not_unique_token_id() { let token_id = TokenId::from("123456"); let token_meta = meta::red_dragon(); contract.mint_one( - contract.ali.clone(), - Some(token_id.clone()), - token_meta.clone(), - Sender(contract.admin.clone().to_account_hash()), + &contract.ali.clone(), + Some(&token_id), + &token_meta, + &contract.admin.clone(), ); contract.mint_one( - contract.ali.clone(), - Some(token_id.clone()), - token_meta, - Sender(contract.admin.clone().to_account_hash()), + &contract.ali.clone(), + Some(&token_id), + &token_meta, + &contract.admin.clone(), ); } @@ -121,16 +124,16 @@ fn test_mint_copies() { let mut contract = CasperCEP47Contract::deploy(); let token_meta = meta::gold_dragon(); contract.mint_copies( - contract.ali.clone(), + &contract.ali.clone(), None, - token_meta, + &token_meta, 3, - Sender(contract.admin.clone().to_account_hash()), + &contract.admin.clone(), ); - let ali_tokens: Vec = contract.tokens(contract.ali.clone()); + let ali_tokens: Vec = contract.tokens(&contract.ali); assert_eq!(contract.total_supply(), U256::from(3)); - assert_eq!(contract.balance_of(contract.ali.clone()), U256::from(3)); + assert_eq!(contract.balance_of(&contract.ali), U256::from(3)); assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(3)); assert_eq!( contract.owner_of(&ali_tokens[0]), @@ -148,21 +151,18 @@ fn test_mint_many() { let mut contract = CasperCEP47Contract::deploy(); let token_metas: Vec = vec![meta::gold_dragon(), meta::red_dragon()]; contract.mint_many( - contract.ali.clone(), + &contract.ali.clone(), None, - token_metas, - Sender(contract.admin.clone().to_account_hash()), + &token_metas, + &contract.admin.clone(), ); - let ali_tokens: Vec = contract.tokens(contract.ali.clone()); + let ali_tokens: Vec = contract.tokens(&contract.ali); assert_eq!(contract.total_supply(), U256::from(2)); - assert_eq!(contract.balance_of(contract.ali.clone()), U256::from(2)); + assert_eq!(contract.balance_of(&contract.ali), U256::from(2)); assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(2)); - assert_eq!( - contract.owner_of(&ali_tokens[0]), - Some(contract.ali.clone()) - ); + assert_eq!(contract.owner_of(&ali_tokens[0]), Some(contract.ali)); assert_eq!(contract.owner_of(&ali_tokens[1]), Some(contract.ali)); } @@ -176,30 +176,29 @@ fn test_burn_many() { meta::red_dragon(), ]; contract.mint_many( - contract.ali.clone(), + &contract.ali.clone(), None, - token_metas, - Sender(contract.admin.clone().to_account_hash()), + &token_metas, + &contract.admin.clone(), ); - let mut ali_tokens: Vec = contract.tokens(contract.ali.clone()); - - assert_eq!(contract.total_supply(), U256::from(4)); - assert_eq!(contract.balance_of(contract.ali.clone()), U256::from(4)); - assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(4)); + let ali_tokens: Vec = contract.tokens(&contract.ali); + println!("{:?}", ali_tokens); + println!("{:?}", ali_tokens.first().unwrap().clone()); contract.burn_many( - contract.ali.clone(), - vec![ + &contract.ali.clone(), + &vec![ ali_tokens.first().unwrap().clone(), ali_tokens.last().unwrap().clone(), ], - Sender(contract.admin.clone().to_account_hash()), + &contract.admin.clone(), ); assert_eq!(contract.total_supply(), U256::from(2)); - assert_eq!(contract.balance_of(contract.ali.clone()), U256::from(2)); + assert_eq!(contract.balance_of(&contract.ali), U256::from(2)); - ali_tokens = contract.tokens(contract.ali.clone()); + let ali_tokens = contract.tokens(&contract.ali); + println!("{:?}", ali_tokens); assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(2)); } @@ -208,27 +207,23 @@ fn test_burn_one() { let mut contract = CasperCEP47Contract::deploy(); let token_metas: Vec = vec![meta::gold_dragon(), meta::red_dragon()]; contract.mint_many( - contract.ali.clone(), + &contract.ali.clone(), None, - token_metas, - Sender(contract.admin.clone().to_account_hash()), + &token_metas, + &contract.admin.clone(), ); - let mut ali_tokens: Vec = contract.tokens(contract.ali.clone()); - - assert_eq!(contract.total_supply(), U256::from(2)); - assert_eq!(contract.balance_of(contract.ali.clone()), U256::from(2)); - assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(2)); + let ali_tokens = contract.tokens(&contract.ali); contract.burn_one( - contract.ali.clone(), - ali_tokens.first().unwrap().clone(), - Sender(contract.admin.clone().to_account_hash()), + &contract.ali.clone(), + &ali_tokens.first().unwrap(), + &contract.admin.clone(), ); assert_eq!(contract.total_supply(), U256::from(1)); - assert_eq!(contract.balance_of(contract.ali.clone()), U256::from(1)); + assert_eq!(contract.balance_of(&contract.ali), U256::from(1)); - ali_tokens = contract.tokens(contract.ali.clone()); + let ali_tokens = contract.tokens(&contract.ali); assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(1)); } @@ -237,21 +232,18 @@ fn test_transfer_token() { let mut contract = CasperCEP47Contract::deploy(); let token_metas: Vec = vec![meta::gold_dragon(), meta::blue_dragon()]; contract.mint_many( - contract.ali.clone(), + &contract.ali.clone(), None, - token_metas, - Sender(contract.admin.clone().to_account_hash()), - ); - let ali_tokens: Vec = contract.tokens(contract.ali.clone()); - contract.transfer_token( - contract.ali.clone(), - contract.bob.clone(), - ali_tokens[1].clone(), - Sender(contract.ali.clone().to_account_hash()), + &token_metas, + &contract.admin.clone(), ); - assert_eq!(contract.balance_of(contract.ali.clone()), U256::from(1)); - assert_eq!(contract.balance_of(contract.bob.clone()), U256::from(1)); + let ali_tokens: Vec = contract.tokens(&contract.ali); + + contract.transfer_token(&contract.bob.clone(), &ali_tokens[1], &contract.ali.clone()); + + assert_eq!(contract.balance_of(&contract.ali), U256::from(1)); + assert_eq!(contract.balance_of(&contract.bob), U256::from(1)); assert_eq!(contract.total_supply(), U256::from(2)); assert_eq!( contract.owner_of(&ali_tokens[0]), @@ -272,21 +264,20 @@ fn test_transfer_many_tokens() { meta::black_dragon(), ]; contract.mint_many( - contract.ali.clone(), + &contract.ali.clone(), None, - token_metas, - Sender(contract.admin.clone().to_account_hash()), + &token_metas, + &contract.admin.clone(), ); - let ali_tokens: Vec = contract.tokens(contract.ali.clone()); + let ali_tokens: Vec = contract.tokens(&contract.ali); contract.transfer_many_tokens( - contract.ali.clone(), - contract.bob.clone(), - ali_tokens[..2].to_vec(), - Sender(contract.ali.clone().to_account_hash()), + &contract.bob.clone(), + &ali_tokens[..2].to_vec(), + &contract.ali.clone(), ); - assert_eq!(contract.balance_of(contract.ali.clone()), U256::from(1)); - assert_eq!(contract.balance_of(contract.bob.clone()), U256::from(2)); + assert_eq!(contract.balance_of(&contract.ali), U256::from(1)); + assert_eq!(contract.balance_of(&contract.bob), U256::from(2)); assert_eq!(contract.total_supply(), U256::from(3)); assert_eq!( contract.owner_of(&ali_tokens[0]), @@ -307,31 +298,19 @@ fn test_transfer_all_tokens() { let mut contract = CasperCEP47Contract::deploy(); let token_metas: Vec = vec![meta::gold_dragon(), meta::blue_dragon()]; contract.mint_many( - contract.ali.clone(), + &contract.ali.clone(), None, - token_metas, - Sender(contract.admin.clone().to_account_hash()), - ); - let ali_tokens: Vec = contract.tokens(contract.ali.clone()); - assert_eq!(contract.balance_of(contract.ali.clone()), U256::from(2)); - assert_eq!(contract.balance_of(contract.bob.clone()), U256::from(0)); - assert_eq!( - contract.owner_of(&ali_tokens[0]), - Some(contract.ali.clone()) - ); - assert_eq!( - contract.owner_of(&ali_tokens[1]), - Some(contract.ali.clone()) + &token_metas, + &contract.admin.clone(), ); - contract.transfer_all_tokens( - contract.ali.clone(), - contract.bob.clone(), - Sender(contract.ali.clone().to_account_hash()), - ); - assert_eq!(contract.balance_of(contract.ali.clone()), U256::from(0)); - assert_eq!(contract.balance_of(contract.bob.clone()), U256::from(2)); + let ali_tokens: Vec = contract.tokens(&contract.ali); + + contract.transfer_all_tokens(&contract.bob.clone(), &contract.ali.clone()); + assert_eq!(contract.balance_of(&contract.ali), U256::from(0)); + assert_eq!(contract.balance_of(&contract.bob), U256::from(2)); assert_eq!(contract.total_supply(), U256::from(2)); + assert_eq!( contract.owner_of(&ali_tokens[0]), Some(contract.bob.clone()) @@ -348,12 +327,12 @@ fn test_token_metadata_update() { let token_id = TokenId::from("123456"); let token_meta = meta::red_dragon(); contract.mint_one( - contract.ali.clone(), - Some(token_id.clone()), - token_meta, - Sender(contract.admin.clone().to_account_hash()), + &contract.ali.clone(), + Some(&token_id), + &token_meta, + &contract.admin.clone(), ); - contract.update_token_metadata(token_id.clone(), meta::blue_dragon(), Sender(contract.admin.clone().to_account_hash())); - assert_eq!(contract.token_meta(token_id).unwrap(), meta::blue_dragon()); -} \ No newline at end of file + contract.update_token_metadata(&token_id, &meta::blue_dragon(), &contract.admin.clone()); + assert_eq!(contract.token_meta(&token_id).unwrap(), meta::blue_dragon()); +} diff --git a/dragons-nft/Cargo.toml b/dragons-nft/Cargo.toml index bcb1e6a..32f8ffd 100644 --- a/dragons-nft/Cargo.toml +++ b/dragons-nft/Cargo.toml @@ -5,9 +5,9 @@ authors = ["astro019 "] edition = "2018" [dependencies] -casper-contract = "1.2.1" -casper-types = "1.2.1" -cep47 = { path="../cep47", features = ["no_owner_of"]} +casper-contract = "1.3.1" +casper-types = "1.3.1" +cep47 = { path="../cep47"} [[bin]] name = "dragons-nft" diff --git a/dragons-nft/src/main.rs b/dragons-nft/src/main.rs index aaa6960..be930a5 100644 --- a/dragons-nft/src/main.rs +++ b/dragons-nft/src/main.rs @@ -3,9 +3,6 @@ use casper_contract::contract_api::runtime::get_named_arg; use casper_contract::contract_api::storage::create_contract_package_at_hash; -#[no_mangle] -pub extern "C" fn owner_of() {} - #[no_mangle] pub extern "C" fn call() { let (contract_package_hash, _) = create_contract_package_at_hash(); From 5ef1a5d2553da79994e0b84cea2c2ed4873ab74f Mon Sep 17 00:00:00 2001 From: Maciej Zielinski Date: Thu, 29 Jul 2021 10:58:07 +0200 Subject: [PATCH 57/98] Remove element from dict. --- cep47/src/cep47_storage.rs | 14 +++++--------- cep47/src/data.rs | 30 +++++++++++++++++++++++++++--- dragons-nft-tests/src/cep47.rs | 20 ++------------------ 3 files changed, 34 insertions(+), 30 deletions(-) diff --git a/cep47/src/cep47_storage.rs b/cep47/src/cep47_storage.rs index 5b3e0ad..dab8586 100644 --- a/cep47/src/cep47_storage.rs +++ b/cep47/src/cep47_storage.rs @@ -100,9 +100,6 @@ impl CEP47Storage for CasperCEP47Storage { // Update current list of recipient's tokens. recipient_tokens.push(token_id.clone()); - - // Emit event. - // emit_mint_one_event(&recipient, &token_id); } // Update owned tokens. @@ -121,10 +118,10 @@ impl CEP47Storage for CasperCEP47Storage { fn burn_many(&mut self, owner: &Key, token_ids: &Vec) { // Prepare dictionaries. - // let owners_dict = Owners::instance(); + let owners_dict = Owners::instance(); let owned_tokens_dict = OwnedTokens::instance(); let balances_dict = Balances::instance(); - // let metadata_dict = Metadata::instance(); + let metadata_dict = Metadata::instance(); // Load owner's tokens. let mut owner_tokens = owned_tokens_dict.get(owner); @@ -140,11 +137,10 @@ impl CEP47Storage for CasperCEP47Storage { owner_tokens.remove(index); // TODO: Remove meta. - + metadata_dict.remove(&token_id); + // TODO: Remove ownership. - - // Emit event. - // emit_burn_one_event(&owner, &token_id); + owners_dict.remove(&token_id); } // Decrement owner's balance. diff --git a/cep47/src/data.rs b/cep47/src/data.rs index 1ec24e3..7a24c3b 100644 --- a/cep47/src/data.rs +++ b/cep47/src/data.rs @@ -31,12 +31,19 @@ impl Dict { } pub fn get(&self, key: &str) -> Option { - storage::dictionary_get(self.uref, key).unwrap_or_revert() + storage::dictionary_get(self.uref, key) + .unwrap_or_revert() + .unwrap_or_default() } pub fn set(&self, key: &str, value: T) { - storage::dictionary_put(self.uref, key, value); + storage::dictionary_put(self.uref, key, Some(value)); } + + pub fn remove(&self, key: &str) { + storage::dictionary_put(self.uref, key, Option::::None); + } + } pub struct Balances { @@ -51,12 +58,16 @@ impl Balances { } pub fn get(&self, key: &Key) -> U256 { - self.dict.get(&key_to_str(&key)).unwrap_or(U256::zero()) + self.dict.get(&key_to_str(&key)).unwrap_or_default() } pub fn set(&self, key: &Key, value: U256) { self.dict.set(&key_to_str(&key), value); } + + pub fn remove(&self, key: &Key) { + self.dict.remove::(&key_to_str(&key)); + } } pub struct OwnedTokens { @@ -77,6 +88,10 @@ impl OwnedTokens { pub fn set(&self, key: &Key, value: Vec) { self.dict.set(&key_to_str(&key), value); } + + pub fn remove(&self, key: &Key) { + self.dict.remove::(&key_to_str(&key)); + } } pub struct Owners { @@ -97,7 +112,12 @@ impl Owners { pub fn set(&self, key: &TokenId, value: Key) { self.dict.set(key, value); } + + pub fn remove(&self, key: &TokenId) { + self.dict.remove::(key); + } } + pub struct Metadata { dict: Dict, } @@ -116,6 +136,10 @@ impl Metadata { pub fn set(&self, key: &TokenId, value: Meta) { self.dict.set(key, value); } + + pub fn remove(&self, key: &TokenId) { + self.dict.remove::(key); + } } pub fn name() -> String { diff --git a/dragons-nft-tests/src/cep47.rs b/dragons-nft-tests/src/cep47.rs index ee56bb6..e392d39 100644 --- a/dragons-nft-tests/src/cep47.rs +++ b/dragons-nft-tests/src/cep47.rs @@ -116,10 +116,10 @@ impl CasperCEP47Contract { ) { Err(_) => None, Ok(maybe_value) => { - let value = maybe_value + let value: Option = maybe_value .into_t() .unwrap_or_else(|_| panic!("is not expected type.")); - Some(value) + value } } } @@ -298,19 +298,3 @@ impl CasperCEP47Contract { ); } } - -fn balance_key(account: &AccountHash) -> String { - format!("balances_{}", account) -} - -fn owner_key(token_id: &TokenId) -> String { - format!("owners_{}", token_id) -} - -fn meta_key(token_id: &TokenId) -> String { - format!("metas_{}", token_id) -} - -fn token_key(account: &AccountHash) -> String { - format!("tokens_{}", account) -} From f7123f21a381271653cbd613bf4ec257787bf9cd Mon Sep 17 00:00:00 2001 From: Maciej Zielinski Date: Fri, 30 Jul 2021 11:05:40 +0200 Subject: [PATCH 58/98] Burn event, remove dragon-scripts --- cep47-logic/src/events.rs | 4 + cep47-logic/src/lib.rs | 6 + cep47/src/data.rs | 25 +- cep47/src/lib.rs | 3 +- dragons-nft-scripts/.env | 0 dragons-nft-scripts/.gitignore | 2 - dragons-nft-scripts/package-lock.json | 1234 ------------------------- dragons-nft-scripts/package.json | 22 - dragons-nft-scripts/src/index.js | 293 ------ 9 files changed, 30 insertions(+), 1559 deletions(-) delete mode 100644 dragons-nft-scripts/.env delete mode 100644 dragons-nft-scripts/.gitignore delete mode 100644 dragons-nft-scripts/package-lock.json delete mode 100644 dragons-nft-scripts/package.json delete mode 100644 dragons-nft-scripts/src/index.js diff --git a/cep47-logic/src/events.rs b/cep47-logic/src/events.rs index 0b618f3..ec16f6e 100644 --- a/cep47-logic/src/events.rs +++ b/cep47-logic/src/events.rs @@ -17,4 +17,8 @@ pub enum CEP47Event { recipient: Key, token_ids: Vec, }, + Burn { + owner: Key, + token_ids: Vec, + }, } diff --git a/cep47-logic/src/lib.rs b/cep47-logic/src/lib.rs index c0f6a5d..5341c51 100644 --- a/cep47-logic/src/lib.rs +++ b/cep47-logic/src/lib.rs @@ -151,6 +151,12 @@ pub trait CEP47Contract: WithStorage { fn burn_many(&mut self, owner: &Key, token_ids: Vec) { self.storage_mut().burn_many(owner, &token_ids); + + // Emit burn event. + self.storage_mut().emit(CEP47Event::Burn { + owner: owner.clone(), + token_ids: token_ids.clone(), + }); } // Transfer functions. diff --git a/cep47/src/data.rs b/cep47/src/data.rs index 7a24c3b..ed3ae89 100644 --- a/cep47/src/data.rs +++ b/cep47/src/data.rs @@ -65,9 +65,9 @@ impl Balances { self.dict.set(&key_to_str(&key), value); } - pub fn remove(&self, key: &Key) { - self.dict.remove::(&key_to_str(&key)); - } + // pub fn remove(&self, key: &Key) { + // self.dict.remove::(&key_to_str(&key)); + // } } pub struct OwnedTokens { @@ -89,9 +89,9 @@ impl OwnedTokens { self.dict.set(&key_to_str(&key), value); } - pub fn remove(&self, key: &Key) { - self.dict.remove::(&key_to_str(&key)); - } + // pub fn remove(&self, key: &Key) { + // self.dict.remove::(&key_to_str(&key)); + // } } pub struct Owners { @@ -268,6 +268,19 @@ pub fn emit(event: &CEP47Event) { event.insert("token_id", token_id.to_string()); events.push(event); } + }, + CEP47Event::Burn { + owner, + token_ids + } => { + for token_id in token_ids { + let mut event = BTreeMap::new(); + event.insert("contract_package_hash", package.to_string()); + event.insert("event_type", "cep47_burn_one".to_string()); + event.insert("owner", owner.to_string()); + event.insert("token_id", token_id.to_string()); + events.push(event); + } } }; for event in events { diff --git a/cep47/src/lib.rs b/cep47/src/lib.rs index 3046d15..93ebc16 100644 --- a/cep47/src/lib.rs +++ b/cep47/src/lib.rs @@ -74,7 +74,7 @@ pub extern "C" fn name() { #[no_mangle] pub extern "C" fn symbol() { let contract = CasperCEP47Contract::new(); - ret(contract.symbol()) + ret((contract.symbol(), 42u8)) } #[cfg(not(feature = "no_meta"))] @@ -282,7 +282,6 @@ pub fn ret(value: T) { fn get_caller() -> Key { match runtime::get_call_stack().first().unwrap_or_revert() { - // first or last? CallStackElement::Session { account_hash } => (*account_hash).into(), CallStackElement::StoredSession { account_hash, diff --git a/dragons-nft-scripts/.env b/dragons-nft-scripts/.env deleted file mode 100644 index e69de29..0000000 diff --git a/dragons-nft-scripts/.gitignore b/dragons-nft-scripts/.gitignore deleted file mode 100644 index b947077..0000000 --- a/dragons-nft-scripts/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules/ -dist/ diff --git a/dragons-nft-scripts/package-lock.json b/dragons-nft-scripts/package-lock.json deleted file mode 100644 index 09ba30a..0000000 --- a/dragons-nft-scripts/package-lock.json +++ /dev/null @@ -1,1234 +0,0 @@ -{ - "name": "dragons-nft-scripts", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@ethersproject/bignumber": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.4.1.tgz", - "integrity": "sha512-fJhdxqoQNuDOk6epfM7yD6J8Pol4NUCy1vkaGAkuujZm0+lNow//MKu1hLhRiYV4BsOHyBv5/lsTjF+7hWwhJg==", - "requires": { - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "bn.js": "^4.11.9" - } - }, - "@ethersproject/bytes": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.4.0.tgz", - "integrity": "sha512-H60ceqgTHbhzOj4uRc/83SCN9d+BSUnOkrr2intevqdtEMO1JFVZ1XL84OEZV+QjV36OaZYxtnt4lGmxcGsPfA==", - "requires": { - "@ethersproject/logger": "^5.4.0" - } - }, - "@ethersproject/constants": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.4.0.tgz", - "integrity": "sha512-tzjn6S7sj9+DIIeKTJLjK9WGN2Tj0P++Z8ONEIlZjyoTkBuODN+0VfhAyYksKi43l1Sx9tX2VlFfzjfmr5Wl3Q==", - "requires": { - "@ethersproject/bignumber": "^5.4.0" - } - }, - "@ethersproject/logger": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.4.0.tgz", - "integrity": "sha512-xYdWGGQ9P2cxBayt64d8LC8aPFJk6yWCawQi/4eJ4+oJdMMjEBMrIcIMZ9AxhwpPVmnBPrsB10PcXGmGAqgUEQ==" - }, - "@open-rpc/client-js": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@open-rpc/client-js/-/client-js-1.7.0.tgz", - "integrity": "sha512-cRGJbXTgdhJNU49vWzJIATRmKBLP2x6tuHJzX9Jg3N8f1VEkge0riUEek2LFIrZiM4TdUp8XV4Ns1W0SZzdfSw==", - "requires": { - "isomorphic-fetch": "^3.0.0", - "isomorphic-ws": "^4.0.1", - "strict-event-emitter-types": "^2.0.0", - "ws": "^7.0.0" - } - }, - "@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", - "requires": { - "@types/node": "*" - } - }, - "@types/eccrypto": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@types/eccrypto/-/eccrypto-1.1.3.tgz", - "integrity": "sha512-3O0qER6JMYReqVbcQTGmXeMHdw3O+rVps63tlo5g5zoB3altJS8yzSvboSivwVWeYO9o5jSATu7P0UIqYZPgow==", - "requires": { - "@types/expect": "^1.20.4", - "@types/node": "*" - } - }, - "@types/elliptic": { - "version": "6.4.13", - "resolved": "https://registry.npmjs.org/@types/elliptic/-/elliptic-6.4.13.tgz", - "integrity": "sha512-e8iyLJ8vMLpWxXpVWrIt0ujqsfHWgVe5XAz9IMhBYoDirK6th7J+mHjzp797OLc62ZX419nrlwwzsNAA0a0mKg==", - "requires": { - "@types/bn.js": "*" - } - }, - "@types/eslint": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.28.0.tgz", - "integrity": "sha512-07XlgzX0YJUn4iG1ocY4IX9DzKSmMGUs6ESKlxWhZRaa0fatIWaHWUVapcuGa8r5HFnTqzj+4OCjd5f7EZ/i/A==", - "requires": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "@types/eslint-scope": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.1.tgz", - "integrity": "sha512-SCFeogqiptms4Fg29WpOTk5nHIzfpKCemSN63ksBQYKTcXoJEmJagV+DhVmbapZzY4/5YaOV1nZwrsU79fFm1g==", - "requires": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "@types/estree": { - "version": "0.0.50", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz", - "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==" - }, - "@types/expect": { - "version": "1.20.4", - "resolved": "https://registry.npmjs.org/@types/expect/-/expect-1.20.4.tgz", - "integrity": "sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg==" - }, - "@types/json-schema": { - "version": "7.0.8", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.8.tgz", - "integrity": "sha512-YSBPTLTVm2e2OoQIDYx8HaeWJ5tTToLH67kXR7zYNGupXMEHa2++G8k+DczX2cFVgalypqtyZIcU19AFcmOpmg==" - }, - "@types/node": { - "version": "16.4.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.4.3.tgz", - "integrity": "sha512-GKM4FLMkWDc0sfx7tXqPWkM6NBow1kge0fgQh0bOnlqo4iT1kvTvMEKE0c1RtUGnbLlGRXiAA8SumE//90uKAg==" - }, - "@types/pbkdf2": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", - "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", - "requires": { - "@types/node": "*" - } - }, - "@types/secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==", - "requires": { - "@types/node": "*" - } - }, - "@webassemblyjs/ast": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", - "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", - "requires": { - "@webassemblyjs/helper-numbers": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", - "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==" - }, - "@webassemblyjs/helper-api-error": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", - "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==" - }, - "@webassemblyjs/helper-buffer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", - "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==" - }, - "@webassemblyjs/helper-numbers": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", - "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", - "requires": { - "@webassemblyjs/floating-point-hex-parser": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", - "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==" - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", - "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", - "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", - "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", - "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", - "requires": { - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/utf8": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", - "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==" - }, - "@webassemblyjs/wasm-edit": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", - "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", - "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/helper-wasm-section": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-opt": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "@webassemblyjs/wast-printer": "1.11.1" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", - "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", - "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", - "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", - "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", - "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", - "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", - "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", - "requires": { - "@webassemblyjs/ast": "1.11.1", - "@xtuc/long": "4.2.2" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" - }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" - }, - "acorn": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", - "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==" - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==" - }, - "asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "base-x": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz", - "integrity": "sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bip66": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", - "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", - "optional": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "blakejs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.1.tgz", - "integrity": "sha512-bLG6PHOCZJKNshTjGRBvET0vTciwQE6zFKOKKXPDJfwFBd4Ac0yBfPZqcGvGJap50l7ktvlpFqc2jGVaUgbJgg==" - }, - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserslist": { - "version": "4.16.6", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", - "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", - "requires": { - "caniuse-lite": "^1.0.30001219", - "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.723", - "escalade": "^3.1.1", - "node-releases": "^1.1.71" - } - }, - "bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", - "requires": { - "base-x": "^3.0.2" - } - }, - "bs58check": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", - "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", - "requires": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" - } - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" - }, - "caniuse-lite": { - "version": "1.0.30001247", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001247.tgz", - "integrity": "sha512-4rS7co+7+AoOSPRPOPUt5/GdaqZc0EsUpWk66ofE3HJTAajUK2Ss2VwoNzVN69ghg8lYYlh0an0Iy4LIHHo9UQ==" - }, - "casper-cep47-js-client": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/casper-cep47-js-client/-/casper-cep47-js-client-0.2.4.tgz", - "integrity": "sha512-zGlkfxbofwLyaNU1TzRDIv1jkySFvZphPrOPStECQtS6fjPGY2RpTJgRKmj0a6Z+Lq+403/qfQo0yBw1+gFUWQ==", - "requires": { - "@ethersproject/bignumber": "^5.0.8", - "casper-js-sdk": "2.2.3", - "ts-results": "^3.3.0" - } - }, - "casper-js-sdk": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/casper-js-sdk/-/casper-js-sdk-2.2.3.tgz", - "integrity": "sha512-e8vyktJBsSBh8lJzwwbWAgP7mTHGC04iE4Fhd7sdYCYClWjKv+XQ22aXNwawWYNOxHqipF7n7Z319F9dEhxQhg==", - "requires": { - "@ethersproject/bignumber": "^5.0.8", - "@ethersproject/bytes": "^5.0.5", - "@ethersproject/constants": "^5.0.5", - "@open-rpc/client-js": "^1.6.2", - "@types/eccrypto": "^1.1.2", - "blakejs": "^1.1.0", - "eccrypto": "^1.1.6", - "eslint-plugin-prettier": "^3.4.0", - "ethereum-cryptography": "^0.1.3", - "glob": "^7.1.6", - "humanize-duration": "^3.24.0", - "key-encoder": "^2.0.3", - "reflect-metadata": "^0.1.13", - "ts-results": "^3.2.1", - "tweetnacl-ts": "^1.0.3", - "tweetnacl-util": "^0.15.0", - "typedjson": "^1.6.0-rc2", - "webpack": "^5.24.3" - } - }, - "chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==" - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "colorette": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", - "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==" - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "drbg.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", - "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", - "optional": true, - "requires": { - "browserify-aes": "^1.0.6", - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4" - } - }, - "eccrypto": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/eccrypto/-/eccrypto-1.1.6.tgz", - "integrity": "sha512-d78ivVEzu7Tn0ZphUUaL43+jVPKTMPFGtmgtz1D0LrFn7cY3K8CdrvibuLz2AAkHBLKZtR8DMbB2ukRYFk987A==", - "requires": { - "acorn": "7.1.1", - "elliptic": "6.5.4", - "es6-promise": "4.2.8", - "nan": "2.14.0", - "secp256k1": "3.7.1" - } - }, - "electron-to-chromium": { - "version": "1.3.788", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.788.tgz", - "integrity": "sha512-dbMIpX4E4/Gk4gzOh1GYS7ls1vGsByWKpIqLviJi1mSmSt5BvrWLLtSqpFE5BaC7Ef4NnI0GMaiddNX2Brw6zA==" - }, - "elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "requires": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "enhanced-resolve": { - "version": "5.8.2", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz", - "integrity": "sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==", - "requires": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - } - }, - "es-module-lexer": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.7.1.tgz", - "integrity": "sha512-MgtWFl5No+4S3TmhDmCz2ObFGm6lEpTnzbQi+Dd+pw4mlTIZTmM2iAs5gRlmx5zS9luzobCSBSI90JM/1/JgOw==" - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" - }, - "eslint-plugin-prettier": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.0.tgz", - "integrity": "sha512-UDK6rJT6INSfcOo545jiaOwB701uAIt2/dR7WnFQoGCVl1/EMqdANBmwUaqqQ45aXprsTGzSa39LI1PyuRBxxw==", - "requires": { - "prettier-linter-helpers": "^1.0.0" - } - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "requires": { - "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==" - } - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" - }, - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - }, - "dependencies": { - "secp256k1": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz", - "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==", - "requires": { - "elliptic": "^6.5.2", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - } - } - } - }, - "events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==" - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "optional": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" - }, - "graceful-fs": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "humanize-duration": { - "version": "3.27.0", - "resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.27.0.tgz", - "integrity": "sha512-qLo/08cNc3Tb0uD7jK0jAcU5cnqCM0n568918E7R2XhMr/+7F37p4EY062W/stg7tmzvknNn9b/1+UhVRzsYrQ==" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "isomorphic-fetch": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", - "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", - "requires": { - "node-fetch": "^2.6.1", - "whatwg-fetch": "^3.4.1" - } - }, - "isomorphic-ws": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", - "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==" - }, - "jest-worker": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.0.6.tgz", - "integrity": "sha512-qupxcj/dRuA3xHPMUd40gr2EaAurFbkwzOh7wfPaeE9id7hyjURRQoqNfHifHK3XjJU6YJJUQKILGUnwGPEOCA==", - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - } - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "keccak": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.1.tgz", - "integrity": "sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA==", - "requires": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - } - }, - "key-encoder": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/key-encoder/-/key-encoder-2.0.3.tgz", - "integrity": "sha512-fgBtpAGIr/Fy5/+ZLQZIPPhsZEcbSlYu/Wu96tNDFNSjSACw5lEIOFeaVdQ/iwrb8oxjlWi6wmWdH76hV6GZjg==", - "requires": { - "@types/elliptic": "^6.4.9", - "asn1.js": "^5.0.1", - "bn.js": "^4.11.8", - "elliptic": "^6.4.1" - } - }, - "loader-runner": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", - "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==" - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, - "mime-db": { - "version": "1.48.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", - "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==" - }, - "mime-types": { - "version": "2.1.31", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", - "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", - "requires": { - "mime-db": "1.48.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "nan": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" - }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" - }, - "node-addon-api": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" - }, - "node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" - }, - "node-gyp-build": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", - "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==" - }, - "node-releases": { - "version": "1.1.73", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz", - "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==" - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "requires": { - "fast-diff": "^1.1.2" - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "reflect-metadata": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", - "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "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==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", - "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - }, - "scrypt-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" - }, - "secp256k1": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.7.1.tgz", - "integrity": "sha512-1cf8sbnRreXrQFdH6qsg2H71Xw91fCCS9Yp021GnUNJzWJS/py96fS4lHbnTnouLp08Xj6jBoBB6V78Tdbdu5g==", - "optional": true, - "requires": { - "bindings": "^1.5.0", - "bip66": "^1.1.5", - "bn.js": "^4.11.8", - "create-hash": "^1.2.0", - "drbg.js": "^1.0.1", - "elliptic": "^6.4.1", - "nan": "^2.14.0", - "safe-buffer": "^5.1.2" - } - }, - "serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "requires": { - "randombytes": "^2.1.0" - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "strict-event-emitter-types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strict-event-emitter-types/-/strict-event-emitter-types-2.0.0.tgz", - "integrity": "sha512-Nk/brWYpD85WlOgzw5h173aci0Teyv8YdIAEtV+N88nDB0dLlazZyJMIsN6eo1/AR61l+p6CJTG1JIyFaoNEEA==" - }, - "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==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "requires": { - "has-flag": "^4.0.0" - } - }, - "tapable": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", - "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==" - }, - "terser": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.7.1.tgz", - "integrity": "sha512-b3e+d5JbHAe/JSjwsC3Zn55wsBIM7AsHLjKxT31kGCldgbpFePaFo+PiddtO6uwRZWRw7sPXmAN8dTW61xmnSg==", - "requires": { - "commander": "^2.20.0", - "source-map": "~0.7.2", - "source-map-support": "~0.5.19" - }, - "dependencies": { - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" - } - } - }, - "terser-webpack-plugin": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.4.tgz", - "integrity": "sha512-C2WkFwstHDhVEmsmlCxrXUtVklS+Ir1A7twrYzrDrQQOIMOaVAYykaoo/Aq1K0QRkMoY2hhvDQY1cm4jnIMFwA==", - "requires": { - "jest-worker": "^27.0.2", - "p-limit": "^3.1.0", - "schema-utils": "^3.0.0", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1", - "terser": "^5.7.0" - } - }, - "ts-results": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/ts-results/-/ts-results-3.3.0.tgz", - "integrity": "sha512-FWqxGX2NHp5oCyaMd96o2y2uMQmSu8Dey6kvyuFdRJ2AzfmWo3kWa4UsPlCGlfQ/qu03m09ZZtppMoY8EMHuiA==" - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "tweetnacl-ts": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl-ts/-/tweetnacl-ts-1.0.3.tgz", - "integrity": "sha512-C5I/dWf6xjAXaCDlf84T4HvozU/8ycAlq5WRllF1hAeeq5390tfXD+bNas5bhEV0HMSOx8bsQYpLjPl8wfnEeQ==", - "requires": { - "tslib": "^1" - } - }, - "tweetnacl-util": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", - "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==" - }, - "typedjson": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/typedjson/-/typedjson-1.7.0.tgz", - "integrity": "sha512-MnRgQLwtEcdHqQG0FkT8ebpBG53Wgr/axYRbiD2WL5NcYx8Z2AoCpXvtTfLnuPqOBKG/9JpXq0O/nl2m4wqJYw==", - "requires": { - "tslib": "^2.0.1" - }, - "dependencies": { - "tslib": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", - "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" - } - } - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "requires": { - "punycode": "^2.1.0" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "watchpack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.2.0.tgz", - "integrity": "sha512-up4YAn/XHgZHIxFBVCdlMiWDj6WaLKpwVeGQk2I5thdYxF/KmF0aaz6TfJZ/hfl1h/XlcDr7k1KH7ThDagpFaA==", - "requires": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - } - }, - "webpack": { - "version": "5.46.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.46.0.tgz", - "integrity": "sha512-qxD0t/KTedJbpcXUmvMxY5PUvXDbF8LsThCzqomeGaDlCA6k998D8yYVwZMvO8sSM3BTEOaD4uzFniwpHaTIJw==", - "requires": { - "@types/eslint-scope": "^3.7.0", - "@types/estree": "^0.0.50", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "acorn": "^8.4.1", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.8.0", - "es-module-lexer": "^0.7.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.4", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", - "watchpack": "^2.2.0", - "webpack-sources": "^2.3.1" - }, - "dependencies": { - "acorn": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", - "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==" - } - } - }, - "webpack-sources": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.1.tgz", - "integrity": "sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA==", - "requires": { - "source-list-map": "^2.0.1", - "source-map": "^0.6.1" - } - }, - "whatwg-fetch": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", - "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==" - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "ws": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz", - "integrity": "sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==" - }, - "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==" - } - } -} diff --git a/dragons-nft-scripts/package.json b/dragons-nft-scripts/package.json deleted file mode 100644 index 9b2e5a5..0000000 --- a/dragons-nft-scripts/package.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "dragons-nft-scripts", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "install_contract": "node src/index.js install_contract", - "mint_one": "node src/index.js mint_one", - "mint_copies": "node src/index.js mint_copies", - "name": "node src/index.js name", - "total_supply": "node src/index.js total_supply", - "print_account": "node src/index.js print_account", - "balance_of": "node src/index.js balance_of", - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "", - "license": "ISC", - "dependencies": { - "casper-cep47-js-client": "0.2.4", - "casper-js-sdk": "^2.2.3" - } -} diff --git a/dragons-nft-scripts/src/index.js b/dragons-nft-scripts/src/index.js deleted file mode 100644 index 8ffec34..0000000 --- a/dragons-nft-scripts/src/index.js +++ /dev/null @@ -1,293 +0,0 @@ -const { CLValueBuilder, Keys, CLPublicKey, CLPublicKeyType } = require("casper-js-sdk"); -const { CEP47Client, utils, constants } = require("casper-cep47-js-client"); - -// const NODE_ADDRESS = 'http://3.143.158.19:7777/rpc'; -const NODE_ADDRESS = 'http://localhost:40101/rpc'; -// const EVENT_STREAM_ADDRESS = 'http://3.143.158.19:9999/events'; -const EVENT_STREAM_ADDRESS = 'http://localhost:60101/events'; -const INSTALL_PAYMENT_AMOUNT = '200000000000'; -const MINT_ONE_PAYMENT_AMOUNT = '2000000000'; -const MINT_COPIES_PAYMENT_AMOUNT = '100000000000'; -const BURN_ONE_PAYMENT_AMOUNT = '12000000000'; -// const CHAIN_NAME = 'integration-test'; -const CHAIN_NAME = 'casper-net-1'; -const WASM_PATH = "/home/ziel/workspace/casperlabs/ipwe-nft-contract/target/wasm32-unknown-unknown/release/ipwe-nft-contract.wasm"; -const TOKEN_NAME = 'test_nft'; -const TOKEN_SYMBOL = 'tnft'; -const TOKEN_META = new Map([ - ['origin', 'fire'], - ['lifetime', 'infinite'] -]); -// const KEY_PAIR_PATH = '/home/ziel/workspace/casperlabs/integration-key/master'; -const KEY_PAIR_PATH = '/home/ziel/workspace/casperlabs/casper-node/utils/nctl/assets/net-1/faucet'; -const KEYS = Keys.Ed25519.parseKeyFiles( - `${KEY_PAIR_PATH}/public_key.pem`, - `${KEY_PAIR_PATH}/secret_key.pem` -); -const MINT_ONE_META_SIZE = 1; -const MINT_COPIES_META_SIZE = 10; -const MINT_COPIES_COUNT = 20; -const MINT_MANY_META_SIZE = 5; -const MINT_MANY_META_COUNT = 5; -const CONTRACT_HASH = '1f7112e5424d206be8b3c63774726347a03bd692327b4207148cb237b43ec5ea'; - -const cep47 = new CEP47Client(NODE_ADDRESS, CHAIN_NAME, EVENT_STREAM_ADDRESS); - -const install = async () => { - const deployHash = await cep47.install( - KEYS, TOKEN_NAME, TOKEN_SYMBOL, TOKEN_META, INSTALL_PAYMENT_AMOUNT, WASM_PATH); - console.log(`Contract Installed`); - console.log(`... DeployHash: ${deployHash}`); -}; - -const mintOne = async () => { - const cep47 = new CEP47Client(NODE_ADDRESS, CHAIN_NAME, EVENT_STREAM_ADDRESS); - await cep47.setContractHash(CONTRACT_HASH); - let meta = randomMetaMap(4); - const deployHash = await cep47.mintOne(KEYS, KEYS.publicKey, "ABC123456", meta, MINT_ONE_PAYMENT_AMOUNT); - console.log(`Mint One`); - console.log(`... DeployHash: ${deployHash}`); -} - -const pause = async () => { - await cep47.setContractHash(CONTRACT_HASH); - const deployHash = await cep47.pause(KEYS, MINT_ONE_PAYMENT_AMOUNT); - console.log(`Pause`); - console.log(`... DeployHash: ${deployHash}`); -} - -const mintCopies = async () => { - await cep47.setContractHash(CONTRACT_HASH); - let meta = randomMetaMap(MINT_COPIES_META_SIZE); - const deployHash = await cep47.mintCopies( - KEYS, KEYS.publicKey, meta, MINT_COPIES_COUNT, MINT_COPIES_PAYMENT_AMOUNT); - console.log(`Mint Copies`); - console.log(`... DeployHash: ${deployHash}`); -} - -const mintMany = async () => { - await cep47.setContractHash(CONTRACT_HASH); - let meta = randomMetaArray(MINT_MANY_META_SIZE); - let arr = []; - for (let i = 0; i < meta.length; i++) { - arr.push(`a${i}`); - } - const deployHash = await cep47.mintMany( - KEYS, KEYS.publicKey, meta, arr, MINT_COPIES_PAYMENT_AMOUNT); - console.log(`Mint Many`); - console.log(`... DeployHash: ${deployHash}`); -} - -const burnOne = async (tokenId) => { - await cep47.setContractHash(CONTRACT_HASH); - const deployHash = await cep47.burnOne(KEYS, KEYS.publicKey, tokenId, BURN_ONE_PAYMENT_AMOUNT); - console.log(`Burn One`); - console.log(`... DeployHash: ${deployHash}`); -} - -const getName = async () => { - await cep47.setContractHash(CONTRACT_HASH); - const value = await cep47.name(); - console.log(`Contract Name: ${value}`); -} - -const balanceOf = async (publicKeyHex) => { - await cep47.setContractHash(CONTRACT_HASH); - const balance = await cep47.balanceOf(CLPublicKey.fromHex(publicKeyHex)); - console.log(`Balance: ${balance}`); -} - -const tokensOf = async (publicKeyHex) => { - await cep47.setContractHash(CONTRACT_HASH); - const value = await cep47.getTokensOf(CLPublicKey.fromHex(publicKeyHex)); - console.log(`Tokens: ${JSON.stringify(value, null, 2)}`); -} - -const ownerOf = async (tokenId) => { - await cep47.setContractHash(CONTRACT_HASH); - const value = await cep47.getOwnerOf(tokenId); - console.log(`Owner public key hex: ${value}`); -} - -const totalSupply = async (tokenId) => { - await cep47.setContractHash(CONTRACT_HASH); - const value = await cep47.totalSupply(); - console.log(`Total supply: ${value}`); -} - -const meta = async () => { - await cep47.setContractHash(CONTRACT_HASH); - const value = await cep47.meta(); - console.log(`Owner public key hex: ${value}`); -} - -const tokenMeta = async (tokenId) => { - await cep47.setContractHash(CONTRACT_HASH); - const value = await cep47.getTokenMeta(tokenId); - console.log('Token meta', value); -} - -const updateTokenMetadata = async (tokenId) => { - await cep47.setContractHash(CONTRACT_HASH); - const value = await cep47.updateTokenMetadata(KEYS, tokenId, new Map([['name', 'me']]), BURN_ONE_PAYMENT_AMOUNT); - console.log('Deploy hash', value); -} - -const printAccount = async () => { - let account = await utils.getAccountInfo(NODE_ADDRESS, KEYS.publicKey); - console.log(account); -} - -const getContractData = async () => { - const stateRootHash = await utils.getStateRootHash(NODE_ADDRESS); - const contractData = await utils.getContractData(NODE_ADDRESS, stateRootHash, CONTRACT_HASH); - console.log(contractData); -} - -const transferToken = async () => { - await cep47.setContractHash(CONTRACT_HASH); - const deployHash = await cep47.transferToken( - KEYS, - KEYS.publicKey, - CLPublicKey.fromHex('017b4822b849f197acf4f49d91315887f913128a9673a2d7ea834cf13c2e6fc606'), - '52a9b6b34ec2cf6c1767b9c6678a23aeacaa9c17145c379525cce6ac2e649e1f', - MINT_ONE_PAYMENT_AMOUNT * 100 - ); - console.log(`Transfer one`); - console.log(`... DeployHash: ${deployHash}`); -} - -const transferAll = async () => { - await cep47.setContractHash(CONTRACT_HASH); - await cep47.transferAllTokens( - KEYS, - KEYS.publicKey, - CLPublicKey.fromHex('017b4822b849f197acf4f49d91315887f913128a9673a2d7ea834cf13c2e6fc606'), - MINT_ONE_PAYMENT_AMOUNT * 100 - ); -} - -const listenTo = async () => { - await cep47.setContractHash(CONTRACT_HASH); - const { stopListening } = cep47.onEvent( - [ - constants.CEP47Events.Mint, - constants.CEP47Events.TransferToken, - constants.CEP47Events.TransferAllTokens, - constants.CEP47Events.BurnOne - ], - (eventName, data) => { - console.log("+", eventName, data); - }) - - console.log('Listening to...'); - // setTimeout(() => { - // console.log("Stopping"); - // stopListening(); - // }, 10000); -} - -const getSimpleValue = async (name) => { - await cep47.setContractHash(CONTRACT_HASH); - const value = await cep47[name](); - console.log(name, value); -}; - -const randomMetaMap = (size) => { - let data = new Map(); - for (let i = 0; i < size; i++) { - data.set(`key${i}`, `value${i}`); - } - return data; - - // return new Map([ - // ["patentId", "EP-3420697-B1-AL"], - // ["applicationId", "EP17707409.3"], - // ["owner", "nChain Holdings Ltd"], - // ["ownerStatus", "verified"], - // ["familyId", "55753050"], - // ["ipweFamilyRating", "AAA"], - // ["insurancePolicyId", "123"], - // ["anticipatedExpirationDate", "2037-02-14"] - // ]); -} - -const randomMetaArray = (size) => { - let arr = []; - for (let i = 0; i < size; i++) { - const item = randomMetaMap(MINT_MANY_META_COUNT); - arr.push(item); - } - return arr; -} - -const command = process.argv.slice(2)[0]; -const arg1 = process.argv.slice(2)[1]; - -switch (command) { - case 'install_contract': - install(); - break; - case 'mint_one': - mintOne(); - break; - case 'mint_copies': - mintCopies(); - break; - case 'mint_many': - mintMany(); - break; - case 'name': - getSimpleValue("name"); - break; - case 'symbol': - getSimpleValue("symbol"); - break; - case 'meta': - getSimpleValue("meta"); - break; - case 'is_paused': - getSimpleValue("isPaused"); - break; - case 'burn_one': - burnOne(arg1); - break; - case 'total_supply': - totalSupply(); - break; - case 'balance_of': - balanceOf(arg1); - break; - case 'owner_of': - ownerOf(arg1); - break; - case 'get_token_meta': - tokenMeta(arg1); - break; - case 'tokens_of': - tokensOf(arg1); - break; - case 'update_token_metadata': - updateTokenMetadata(arg1); - break; - case 'pause': - pause(); - break; - case 'print_account': - printAccount(); - break; - case 'get_contract': - getContractData(); - break; - case 'transfer_token': - transferToken(); - break; - case 'transfer_all': - transferAll(); - break; - case 'listen_to': - listenTo(); - break; - default: - console.log(`Command unknown ${command}`) -} From 10c756456eb64fd05ab0b68e2e988c72f7460d40 Mon Sep 17 00:00:00 2001 From: Maciej Zielinski Date: Fri, 30 Jul 2021 11:34:53 +0200 Subject: [PATCH 59/98] Lints --- cep47-logic/src/lib.rs | 36 ++++++------ cep47-logic/src/tests.rs | 77 ++++++++----------------- cep47/src/cep47_storage.rs | 17 +++--- cep47/src/data.rs | 20 +++---- cep47/src/lib.rs | 1 + dragons-nft-tests/src/cep47.rs | 10 ++-- dragons-nft-tests/src/contract_tests.rs | 47 ++++----------- 7 files changed, 73 insertions(+), 135 deletions(-) diff --git a/cep47-logic/src/lib.rs b/cep47-logic/src/lib.rs index 5341c51..4131719 100644 --- a/cep47-logic/src/lib.rs +++ b/cep47-logic/src/lib.rs @@ -119,11 +119,11 @@ pub trait CEP47Contract: WithStorage { unique_token_ids.map(|token_ids| { // Mint tokens. self.storage_mut() - .mint_many(&recipient, &token_ids, &token_metas); + .mint_many(recipient, &token_ids, &token_metas); // Emit event. self.storage_mut().emit(CEP47Event::Mint { - recipient: recipient.clone(), + recipient: *recipient, token_ids, }); }) @@ -151,11 +151,11 @@ pub trait CEP47Contract: WithStorage { fn burn_many(&mut self, owner: &Key, token_ids: Vec) { self.storage_mut().burn_many(owner, &token_ids); - + // Emit burn event. self.storage_mut().emit(CEP47Event::Burn { - owner: owner.clone(), - token_ids: token_ids.clone(), + owner: *owner, + token_ids, }); } @@ -178,7 +178,7 @@ pub trait CEP47Contract: WithStorage { if self.is_paused() { return Err(Error::PermissionDenied); } - let mut sender_tokens = self.storage().get_tokens(&sender); + let mut sender_tokens = self.storage().get_tokens(sender); for token_id in token_ids.iter() { if !sender_tokens.contains(token_id) { @@ -186,16 +186,15 @@ pub trait CEP47Contract: WithStorage { } sender_tokens.retain(|x| x != token_id); } - let mut recipient_tokens = self.storage().get_tokens(&recipient); + let mut recipient_tokens = self.storage().get_tokens(recipient); recipient_tokens.append(&mut token_ids.clone()); - self.storage_mut().set_tokens(&sender, sender_tokens); - self.storage_mut().set_tokens(&recipient, recipient_tokens); + self.storage_mut().set_tokens(sender, sender_tokens); + self.storage_mut().set_tokens(recipient, recipient_tokens); // Emit transfer event. - let package = self.storage().contact_package_hash(); self.storage_mut().emit(CEP47Event::Transfer { - sender: sender.clone(), - recipient: recipient.clone(), + sender: *sender, + recipient: *recipient, token_ids: token_ids.clone(), }); Ok(()) @@ -205,18 +204,17 @@ pub trait CEP47Contract: WithStorage { if self.is_paused() { return Err(Error::PermissionDenied); } - let mut sender_tokens = self.storage().get_tokens(&sender); - let mut recipient_tokens = self.storage().get_tokens(&recipient); + let mut sender_tokens = self.storage().get_tokens(sender); + let mut recipient_tokens = self.storage().get_tokens(recipient); recipient_tokens.append(&mut sender_tokens); - self.storage_mut() - .set_tokens(&sender, sender_tokens.clone()); - self.storage_mut().set_tokens(&recipient, recipient_tokens); + self.storage_mut().set_tokens(sender, sender_tokens.clone()); + self.storage_mut().set_tokens(recipient, recipient_tokens); // Emit transfer event. self.storage_mut().emit(CEP47Event::Transfer { - sender: sender.clone(), - recipient: recipient.clone(), + sender: *sender, + recipient: *recipient, token_ids: sender_tokens, }); diff --git a/cep47-logic/src/tests.rs b/cep47-logic/src/tests.rs index 4954e1d..cc80a37 100644 --- a/cep47-logic/src/tests.rs +++ b/cep47-logic/src/tests.rs @@ -58,20 +58,12 @@ impl CEP47Storage for TestStorage { fn balance_of(&self, owner: &Key) -> U256 { let owner_balance = self.balances.get(owner); - if owner_balance.is_none() { - U256::from(0) - } else { - owner_balance.unwrap().clone() - } + owner_balance.cloned().unwrap_or_default() } fn onwer_of(&self, token_id: &TokenId) -> Option { let owner = self.belongs_to.get(token_id); - if owner.is_some() { - Some(owner.unwrap().clone()) - } else { - None - } + owner.cloned() } fn total_supply(&self) -> U256 { @@ -80,11 +72,7 @@ impl CEP47Storage for TestStorage { fn token_meta(&self, token_id: &TokenId) -> Option { let meta = self.token_metas.get(token_id); - if meta.is_some() { - Some(meta.unwrap().clone()) - } else { - None - } + meta.cloned() } fn is_paused(&self) -> bool { @@ -100,69 +88,50 @@ impl CEP47Storage for TestStorage { } fn get_tokens(&self, owner: &Key) -> Vec { - let owner_tokens = self.tokens.get(&owner); - if owner_tokens.is_none() { - Vec::::new() - } else { - owner_tokens.unwrap().clone() - } + let owner_tokens = self.tokens.get(owner); + owner_tokens.cloned().unwrap_or_default() } fn set_tokens(&mut self, owner: &Key, token_ids: Vec) { let owner_new_balance = U256::from(token_ids.len() as u64); - let owner_tokens = self.get_tokens(&owner); + let owner_tokens = self.get_tokens(owner); for token_id in owner_tokens.clone() { self.belongs_to.remove(&token_id); } for token_id in token_ids.clone() { - self.belongs_to.insert(token_id, owner.clone()); + self.belongs_to.insert(token_id, *owner); } - self.tokens.insert(*owner, token_ids.clone()); + self.tokens.insert(*owner, token_ids); self.balances.insert(*owner, owner_new_balance); } fn mint_many(&mut self, recipient: &Key, token_ids: &Vec, token_metas: &Vec) { - let recipient_balance = self.balances.get(&recipient); - let recipient_tokens = self.tokens.get(&recipient); - let mut recipient_new_balance = if recipient_balance.is_none() { - U256::from(0) - } else { - recipient_balance.unwrap().clone() - }; - let mut recipient_new_tokens = if recipient_tokens.is_none() { - Vec::::new() - } else { - recipient_tokens.unwrap().clone() - }; + let recipient_balance = self.balances.get(recipient); + let recipient_tokens = self.tokens.get(recipient); + + let mut recipient_new_balance = recipient_balance.copied().unwrap_or_default(); + let mut recipient_new_tokens = recipient_tokens.cloned().unwrap_or_default(); for (token_id, token_meta) in token_ids.iter().zip(token_metas) { self.token_metas .insert(token_id.clone(), token_meta.clone()); recipient_new_tokens.push(token_id.clone()); - self.belongs_to.insert(token_id.clone(), recipient.clone()); + self.belongs_to.insert(token_id.clone(), *recipient); recipient_new_balance = recipient_new_balance + 1; self.total_supply = self.total_supply + 1; } - self.balances - .insert(recipient.clone(), recipient_new_balance); + self.balances.insert(*recipient, recipient_new_balance); self.tokens.insert(*recipient, recipient_new_tokens); } fn burn_many(&mut self, owner: &Key, token_ids: &Vec) { let owner_tokens = self.tokens.get(owner); let owner_balance = self.balances.get(owner); - let mut owner_new_balance = if owner_balance.is_none() { - U256::from(0) - } else { - owner_balance.unwrap().clone() - }; - let mut owner_new_tokens = if owner_tokens.is_none() { - Vec::::new() - } else { - owner_tokens.unwrap().clone() - }; + + let mut owner_new_balance = owner_balance.copied().unwrap_or_default(); + let mut owner_new_tokens = owner_tokens.cloned().unwrap_or_default(); for token_id in token_ids.clone() { let index = owner_new_tokens @@ -175,7 +144,7 @@ impl CEP47Storage for TestStorage { owner_new_balance = owner_new_balance - 1; self.total_supply = self.total_supply - 1; } - self.balances.insert(owner.clone(), owner_new_balance); + self.balances.insert(*owner, owner_new_balance); self.tokens.insert(*owner, owner_new_tokens); } @@ -202,7 +171,7 @@ impl CEP47Storage for TestStorage { true } - fn emit(&mut self, event: crate::events::CEP47Event) {} + fn emit(&mut self, _event: crate::events::CEP47Event) {} fn contact_package_hash(&self) -> casper_types::ContractPackageHash { [1u8; 32].into() @@ -301,7 +270,7 @@ fn test_mint_many() { assert_eq!(bob_balance, U256::from(2)); let ali_tokens: Vec = contract.tokens(&ali); - let ali_first_token_meta: Meta = contract.token_meta(&ali_tokens.get(0).unwrap()).unwrap(); + let ali_first_token_meta: Meta = contract.token_meta(ali_tokens.get(0).unwrap()).unwrap(); assert_eq!(ali_first_token_meta, meta::apple()); let bob_tokens: Vec = contract.tokens(&bob); @@ -323,8 +292,8 @@ fn test_mint_copies() { assert_eq!(ali_balance, U256::from(7)); let ali_tokens: Vec = contract.tokens(&ali); - let ali_first_token_meta: Meta = contract.token_meta(&ali_tokens.get(0).unwrap()).unwrap(); - let ali_third_token_meta: Meta = contract.token_meta(&ali_tokens.get(2).unwrap()).unwrap(); + let ali_first_token_meta: Meta = contract.token_meta(ali_tokens.get(0).unwrap()).unwrap(); + let ali_third_token_meta: Meta = contract.token_meta(ali_tokens.get(2).unwrap()).unwrap(); assert_eq!(ali_first_token_meta, meta::apple()); assert_eq!(ali_third_token_meta, meta::apple()); } diff --git a/cep47/src/cep47_storage.rs b/cep47/src/cep47_storage.rs index dab8586..143c942 100644 --- a/cep47/src/cep47_storage.rs +++ b/cep47/src/cep47_storage.rs @@ -4,6 +4,7 @@ use cep47_logic::{CEP47Storage, Meta, TokenId}; use crate::data::{self, Balances, Metadata, OwnedTokens, Owners}; +#[derive(Default)] pub struct CasperCEP47Storage {} impl CasperCEP47Storage { pub fn new() -> CasperCEP47Storage { @@ -64,16 +65,16 @@ impl CEP47Storage for CasperCEP47Storage { // Update the owner for each token. for token_id in &token_ids { - owners_dict.set(token_id, owner.clone()); + owners_dict.set(token_id, *owner); } // Update balance of the owner. - let prev_balance = balances_dict.get(&owner); + let prev_balance = balances_dict.get(owner); let new_balance = U256::from(token_ids.len() as u64); balances_dict.set(owner, new_balance); // Update owner's list of tokens. - owned_tokens_dict.set(&owner, token_ids); + owned_tokens_dict.set(owner, token_ids); // Update total_supply. let new_total_supply = data::total_supply() - prev_balance + new_balance; @@ -88,7 +89,7 @@ impl CEP47Storage for CasperCEP47Storage { let metadata_dict = Metadata::instance(); // Load recipient's tokens. - let mut recipient_tokens = owned_tokens_dict.get(&recipient); + let mut recipient_tokens = owned_tokens_dict.get(recipient); // Create new tokens. for (token_id, token_meta) in token_ids.iter().zip(token_metas) { @@ -96,7 +97,7 @@ impl CEP47Storage for CasperCEP47Storage { metadata_dict.set(token_id, token_meta.clone()); // Set token owner. - owners_dict.set(token_id, recipient.clone()); + owners_dict.set(token_id, *recipient); // Update current list of recipient's tokens. recipient_tokens.push(token_id.clone()); @@ -137,10 +138,10 @@ impl CEP47Storage for CasperCEP47Storage { owner_tokens.remove(index); // TODO: Remove meta. - metadata_dict.remove(&token_id); - + metadata_dict.remove(token_id); + // TODO: Remove ownership. - owners_dict.remove(&token_id); + owners_dict.remove(token_id); } // Decrement owner's balance. diff --git a/cep47/src/data.rs b/cep47/src/data.rs index ed3ae89..378b6b5 100644 --- a/cep47/src/data.rs +++ b/cep47/src/data.rs @@ -43,7 +43,6 @@ impl Dict { pub fn remove(&self, key: &str) { storage::dictionary_put(self.uref, key, Option::::None); } - } pub struct Balances { @@ -58,15 +57,15 @@ impl Balances { } pub fn get(&self, key: &Key) -> U256 { - self.dict.get(&key_to_str(&key)).unwrap_or_default() + self.dict.get(&key_to_str(key)).unwrap_or_default() } pub fn set(&self, key: &Key, value: U256) { - self.dict.set(&key_to_str(&key), value); + self.dict.set(&key_to_str(key), value); } // pub fn remove(&self, key: &Key) { - // self.dict.remove::(&key_to_str(&key)); + // self.dict.remove::(&key_to_str(key)); // } } @@ -82,15 +81,15 @@ impl OwnedTokens { } pub fn get(&self, key: &Key) -> Vec { - self.dict.get(&key_to_str(&key)).unwrap_or(Vec::new()) + self.dict.get(&key_to_str(key)).unwrap_or_default() } pub fn set(&self, key: &Key, value: Vec) { - self.dict.set(&key_to_str(&key), value); + self.dict.set(&key_to_str(key), value); } // pub fn remove(&self, key: &Key) { - // self.dict.remove::(&key_to_str(&key)); + // self.dict.remove::(&key_to_str(key)); // } } @@ -268,11 +267,8 @@ pub fn emit(event: &CEP47Event) { event.insert("token_id", token_id.to_string()); events.push(event); } - }, - CEP47Event::Burn { - owner, - token_ids - } => { + } + CEP47Event::Burn { owner, token_ids } => { for token_id in token_ids { let mut event = BTreeMap::new(); event.insert("contract_package_hash", package.to_string()); diff --git a/cep47/src/lib.rs b/cep47/src/lib.rs index 93ebc16..234dc1b 100644 --- a/cep47/src/lib.rs +++ b/cep47/src/lib.rs @@ -40,6 +40,7 @@ pub use entrypoints::get_entrypoints; use data::{Balances, Metadata, OwnedTokens, Owners}; +#[derive(Default)] pub struct CasperCEP47Contract { storage: CasperCEP47Storage, } diff --git a/dragons-nft-tests/src/cep47.rs b/dragons-nft-tests/src/cep47.rs index e392d39..15eaf81 100644 --- a/dragons-nft-tests/src/cep47.rs +++ b/dragons-nft-tests/src/cep47.rs @@ -149,13 +149,13 @@ impl CasperCEP47Contract { pub fn balance_of(&self, owner: &AccountHash) -> U256 { let value: Option = self.query_dictionary_value(BALANCES_DICT, owner.to_string()); - value.unwrap_or(U256::zero()) + value.unwrap_or_default() } pub fn tokens(&self, owner: &AccountHash) -> Vec { let value: Option> = self.query_dictionary_value(OWNED_TOKENS_DICT, owner.to_string()); - value.unwrap_or(Vec::new()) + value.unwrap_or_default() } pub fn token_meta(&self, token_id: &TokenId) -> Option { @@ -174,7 +174,7 @@ impl CasperCEP47Contract { "mint_one", runtime_args! { "recipient" => Key::from(*recipient), - "token_id" => token_id.map(|id| id.clone()), + "token_id" => token_id.cloned(), "token_meta" => token_meta.clone() }, ); @@ -193,7 +193,7 @@ impl CasperCEP47Contract { "mint_copies", runtime_args! { "recipient" => Key::from(*recipient), - "token_ids" => token_ids.map(|ids| ids.clone()), + "token_ids" => token_ids.cloned(), "token_meta" => token_meta.clone(), "count" => count }, @@ -212,7 +212,7 @@ impl CasperCEP47Contract { "mint_many", runtime_args! { "recipient" => Key::from(*recipient), - "token_ids" => token_ids.map(|ids| ids.clone()), + "token_ids" => token_ids.cloned(), "token_metas" => token_metas.clone(), }, ); diff --git a/dragons-nft-tests/src/contract_tests.rs b/dragons-nft-tests/src/contract_tests.rs index 5f0f264..0471782 100644 --- a/dragons-nft-tests/src/contract_tests.rs +++ b/dragons-nft-tests/src/contract_tests.rs @@ -135,14 +135,8 @@ fn test_mint_copies() { assert_eq!(contract.total_supply(), U256::from(3)); assert_eq!(contract.balance_of(&contract.ali), U256::from(3)); assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(3)); - assert_eq!( - contract.owner_of(&ali_tokens[0]), - Some(contract.ali.clone()) - ); - assert_eq!( - contract.owner_of(&ali_tokens[1]), - Some(contract.ali.clone()) - ); + assert_eq!(contract.owner_of(&ali_tokens[0]), Some(contract.ali)); + assert_eq!(contract.owner_of(&ali_tokens[1]), Some(contract.ali)); assert_eq!(contract.owner_of(&ali_tokens[2]), Some(contract.ali)); } @@ -217,7 +211,7 @@ fn test_burn_one() { contract.burn_one( &contract.ali.clone(), - &ali_tokens.first().unwrap(), + ali_tokens.first().unwrap(), &contract.admin.clone(), ); assert_eq!(contract.total_supply(), U256::from(1)); @@ -245,14 +239,8 @@ fn test_transfer_token() { assert_eq!(contract.balance_of(&contract.ali), U256::from(1)); assert_eq!(contract.balance_of(&contract.bob), U256::from(1)); assert_eq!(contract.total_supply(), U256::from(2)); - assert_eq!( - contract.owner_of(&ali_tokens[0]), - Some(contract.ali.clone()) - ); - assert_eq!( - contract.owner_of(&ali_tokens[1]), - Some(contract.bob.clone()) - ); + assert_eq!(contract.owner_of(&ali_tokens[0]), Some(contract.ali)); + assert_eq!(contract.owner_of(&ali_tokens[1]), Some(contract.bob)); } #[test] @@ -279,18 +267,9 @@ fn test_transfer_many_tokens() { assert_eq!(contract.balance_of(&contract.ali), U256::from(1)); assert_eq!(contract.balance_of(&contract.bob), U256::from(2)); assert_eq!(contract.total_supply(), U256::from(3)); - assert_eq!( - contract.owner_of(&ali_tokens[0]), - Some(contract.bob.clone()) - ); - assert_eq!( - contract.owner_of(&ali_tokens[1]), - Some(contract.bob.clone()) - ); - assert_eq!( - contract.owner_of(&ali_tokens[2]), - Some(contract.ali.clone()) - ); + assert_eq!(contract.owner_of(&ali_tokens[0]), Some(contract.bob)); + assert_eq!(contract.owner_of(&ali_tokens[1]), Some(contract.bob)); + assert_eq!(contract.owner_of(&ali_tokens[2]), Some(contract.ali)); } #[test] @@ -311,14 +290,8 @@ fn test_transfer_all_tokens() { assert_eq!(contract.balance_of(&contract.bob), U256::from(2)); assert_eq!(contract.total_supply(), U256::from(2)); - assert_eq!( - contract.owner_of(&ali_tokens[0]), - Some(contract.bob.clone()) - ); - assert_eq!( - contract.owner_of(&ali_tokens[1]), - Some(contract.bob.clone()) - ); + assert_eq!(contract.owner_of(&ali_tokens[0]), Some(contract.bob)); + assert_eq!(contract.owner_of(&ali_tokens[1]), Some(contract.bob)); } #[test] From 60362884b84698f87d7b0063b9e3776700028d96 Mon Sep 17 00:00:00 2001 From: Maciej Zielinski Date: Fri, 30 Jul 2021 12:07:32 +0200 Subject: [PATCH 60/98] Repo cleanups --- .gitignore | 4 +- Cargo.lock | 1520 +++++++++++++++++ Cargo.toml | 4 +- Makefile | 10 +- {dragons-nft-tests => cep47-tests}/Cargo.toml | 2 +- .../src/cep47.rs | 0 .../src/contract_tests.rs | 0 {dragons-nft-tests => cep47-tests}/src/lib.rs | 0 .../wasm/.gitkeep | 0 {dragons-nft => test-contracts}/Cargo.toml | 4 +- .../src/dragons-nft.rs | 0 11 files changed, 1531 insertions(+), 13 deletions(-) create mode 100644 Cargo.lock rename {dragons-nft-tests => cep47-tests}/Cargo.toml (92%) rename {dragons-nft-tests => cep47-tests}/src/cep47.rs (100%) rename {dragons-nft-tests => cep47-tests}/src/contract_tests.rs (100%) rename {dragons-nft-tests => cep47-tests}/src/lib.rs (100%) rename {dragons-nft-tests => cep47-tests}/wasm/.gitkeep (100%) rename {dragons-nft => test-contracts}/Cargo.toml (86%) rename dragons-nft/src/main.rs => test-contracts/src/dragons-nft.rs (100%) diff --git a/.gitignore b/.gitignore index 1d85916..968f290 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,3 @@ target -Cargo.lock -dragons-nft-tests/wasm/*.wasm +cep47-tests/wasm/*.wasm node_modules -cep47-test \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..0901962 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,1520 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "anyhow" +version = "1.0.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "595d3cfa7a60d4555cb5067b99f07142a08ea778de5cf993f7b75c7d8fabc486" + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "base16" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d27c3610c36aee21ce8ac510e6224498de4228ad772a171ed65643a24693a5a8" + +[[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + +[[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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e11e16035ea35e4e5997b393eacbf6f63983188f7a2ad25bfb13465f5ad59de" +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.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + +[[package]] +name = "bitvec" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98fcd36dda4e17b7d7abc64cb549bf0201f4ab71e00700c798ca7e62ed3761fa" +dependencies = [ + "funty", + "radium", + "wyz", +] + +[[package]] +name = "blake2" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a5720225ef5daecf08657f23791354e1685a8c91a4c60c7f3d3b2892f978f4" +dependencies = [ + "crypto-mac 0.8.0", + "digest", + "opaque-debug", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "casper-contract" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1625570af44e0594de76aa929fcde9a9e1093b41fd97fd5fea411e5e8859d8a8" +dependencies = [ + "casper-types", + "hex_fmt", + "thiserror", + "version-sync", + "wee_alloc", +] + +[[package]] +name = "casper-engine-test-support" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "047da2f4ca94f60ed02d94db5c9ab408a2046c7b3a7a227e5a191983fe4ab3bd" +dependencies = [ + "casper-contract", + "casper-execution-engine", + "casper-types", + "lmdb", + "log", + "num-rational 0.4.0", + "num-traits", + "once_cell", + "rand 0.8.4", +] + +[[package]] +name = "casper-execution-engine" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "333345fdc7ffca762bbc8d59e4947e84f3636326ad765ec06c223750810d6ba8" +dependencies = [ + "anyhow", + "base16", + "bincode", + "blake2", + "casper-types", + "chrono", + "datasize", + "hex", + "hex-buffer-serde", + "hex_fmt", + "hostname", + "itertools", + "libc", + "linked-hash-map", + "lmdb", + "log", + "num", + "num-derive", + "num-rational 0.4.0", + "num-traits", + "once_cell", + "parity-wasm", + "proptest", + "pwasm-utils", + "rand 0.8.4", + "rand_chacha 0.3.1", + "schemars", + "serde", + "serde_bytes", + "serde_json", + "thiserror", + "tracing", + "uint", + "uuid", + "wasmi", +] + +[[package]] +name = "casper-types" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6895fc78e2922b4eaf2ec2830685a0fa19ec83bd0b96feec359ec1291b7eeec3" +dependencies = [ + "base16", + "base64", + "bitflags", + "blake2", + "datasize", + "displaydoc", + "ed25519-dalek", + "hex", + "hex_fmt", + "k256", + "num-derive", + "num-integer", + "num-rational 0.4.0", + "num-traits", + "once_cell", + "proptest", + "rand 0.8.4", + "schemars", + "serde", + "serde_json", + "thiserror", + "uint", +] + +[[package]] +name = "cc" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2" + +[[package]] +name = "cep47" +version = "0.2.0" +dependencies = [ + "casper-contract", + "casper-types", + "cep47-logic", + "hex", +] + +[[package]] +name = "cep47-logic" +version = "0.1.0" +dependencies = [ + "casper-types", + "maplit", + "rand 0.7.3", +] + +[[package]] +name = "cep47-tests" +version = "0.1.0" +dependencies = [ + "casper-contract", + "casper-engine-test-support", + "casper-types", + "hex", + "maplit", +] + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[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.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +dependencies = [ + "libc", + "num-integer", + "num-traits", + "time", + "winapi", +] + +[[package]] +name = "cpufeatures" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66c99696f6c9dd7f35d486b9d04d7e6e202aa3e8c40d553f2fdf5e7e0c6a71ef" +dependencies = [ + "libc", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-mac" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "crypto-mac" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bff07008ec701e8028e2ceb8f83f0e4274ee62bd2dbdc4fefff2e9a91824081a" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "ctor" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e98e2ad1a782e33928b96fc3948e7c355e5af34ba4de7670fe8bac2a3b2006d" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "curve25519-dalek" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "639891fde0dbea823fc3d798a0fdf9d2f9440a42d64a78ab3488b0ca025117b3" +dependencies = [ + "byteorder", + "digest", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + +[[package]] +name = "datasize" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cfa50a16bc31c1e8d1682876a26aa205e6669ac65645ae484064cbbc5263abc" +dependencies = [ + "datasize_derive", +] + +[[package]] +name = "datasize_derive" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ebcbe9ac751b6e1700a10201b44ae32fa36396b46849fdb4f7ec5fb86326de3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "displaydoc" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc2ab4d5a16117f9029e9a6b5e4e79f4c67f6519bc134210d4d4a04ba31f41b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "downcast-rs" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" + +[[package]] +name = "dyn-clone" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee2626afccd7561a06cf1367e2950c4718ea04565e20fb5029b6c7d8ad09abcf" + +[[package]] +name = "ecdsa" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fbdb4ff710acb4db8ca29f93b897529ea6d6a45626d5183b47e012aa6ae7e4" +dependencies = [ + "elliptic-curve", + "hmac", + "signature", +] + +[[package]] +name = "ed25519" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4620d40f6d2601794401d6dd95a5cf69b6c157852539470eeda433a99b3c0efc" +dependencies = [ + "serde", + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek", + "ed25519", + "rand 0.7.3", + "serde", + "serde_bytes", + "sha2", + "zeroize", +] + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "elliptic-curve" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2db227e61a43a34915680bdda462ec0e212095518020a88a1f91acd16092c39" +dependencies = [ + "bitvec", + "digest", + "ff", + "funty", + "generic-array", + "group", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + +[[package]] +name = "ff" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01646e077d4ebda82b73f1bca002ea1e91561a77df2431a9e79729bcc31950ef" +dependencies = [ + "bitvec", + "rand_core 0.5.1", + "subtle", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +dependencies = [ + "matches", + "percent-encoding", +] + +[[package]] +name = "funty" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" + +[[package]] +name = "generic-array" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi 0.10.2+wasi-snapshot-preview1", +] + +[[package]] +name = "group" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc11f9f5fbf1943b48ae7c2bf6846e7d827a512d1be4f23af708f5ca5d01dde1" +dependencies = [ + "ff", + "rand_core 0.5.1", + "subtle", +] + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +dependencies = [ + "serde", +] + +[[package]] +name = "hex-buffer-serde" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "310e9578ff64e65a3a18e0624609f6833ee4a20503ef38eebb48430cf8ac3ab8" +dependencies = [ + "hex", + "serde", +] + +[[package]] +name = "hex_fmt" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b07f60793ff0a4d9cef0f18e63b5357e06209987153a64648c972c1e5aff336f" + +[[package]] +name = "hmac" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1441c6b1e930e2817404b5046f1f989899143a12bf92de603b69f4e0aee1e15" +dependencies = [ + "crypto-mac 0.10.1", + "digest", +] + +[[package]] +name = "hostname" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +dependencies = [ + "libc", + "match_cfg", + "winapi", +] + +[[package]] +name = "idna" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" +dependencies = [ + "autocfg", + "hashbrown", + "serde", +] + +[[package]] +name = "itertools" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" + +[[package]] +name = "k256" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4476a0808212a9e81ce802eb1a0cfc60e73aea296553bacc0fac7e1268bc572a" +dependencies = [ + "cfg-if 1.0.0", + "ecdsa", + "elliptic-curve", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790" + +[[package]] +name = "linked-hash-map" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" + +[[package]] +name = "lmdb" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0908efb5d6496aa977d96f91413da2635a902e5e31dbef0bfb88986c248539" +dependencies = [ + "bitflags", + "libc", + "lmdb-sys", +] + +[[package]] +name = "lmdb-sys" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5b392838cfe8858e86fac37cf97a0e8c55cc60ba0a18365cadc33092f128ce9" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if 1.0.0", + "serde", + "value-bag", +] + +[[package]] +name = "maplit" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" + +[[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" + +[[package]] +name = "matches" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" + +[[package]] +name = "memchr" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" + +[[package]] +name = "memory_units" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" + +[[package]] +name = "memory_units" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" + +[[package]] +name = "num" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43db66d1170d347f9a065114077f7dccb00c1b9478c89384490a3425279a4606" +dependencies = [ + "num-complex", + "num-integer", + "num-iter", + "num-rational 0.4.0", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e0d047c1062aa51e256408c560894e5251f08925980e53cf1aa5bd00eec6512" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26873667bbbb7c5182d4a37c1add32cdf09f841af72da53318fdb81543c15085" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-derive" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" +dependencies = [ + "autocfg", + "num-bigint 0.2.6", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d41702bd167c2df5520b384281bc111a4b5efcf7fbc4c9c222c815b07e0a6a6a" +dependencies = [ + "autocfg", + "num-bigint 0.4.0", + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "parity-wasm" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc878dac00da22f8f61e7af3157988424567ab01d9920b962ef7dcbd7cd865" + +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" + +[[package]] +name = "pin-project-lite" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" + +[[package]] +name = "pkg-config" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" + +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + +[[package]] +name = "proc-macro2" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "proptest" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0d9cc07f18492d879586c92b485def06bc850da3118075cd45d50e9c95b0e5" +dependencies = [ + "bit-set", + "bitflags", + "byteorder", + "lazy_static", + "num-traits", + "quick-error 2.0.1", + "rand 0.8.4", + "rand_chacha 0.3.1", + "rand_xorshift", + "regex-syntax", + "rusty-fork", + "tempfile", +] + +[[package]] +name = "pulldown-cmark" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffade02495f22453cd593159ea2f59827aae7f53fa8323f756799b670881dcf8" +dependencies = [ + "bitflags", + "memchr", + "unicase", +] + +[[package]] +name = "pwasm-utils" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c8ac87af529432d3a4f0e2b3bbf08af49f28f09cc73ed7e551161bdaef5f78d" +dependencies = [ + "byteorder", + "log", + "parity-wasm", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + +[[package]] +name = "quote" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "def50a86306165861203e7f84ecffbbdfdea79f0e51039b33de1e952358c47ac" + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc 0.2.0", +] + +[[package]] +name = "rand" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.3", + "rand_hc 0.3.1", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.3", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom 0.2.3", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_hc" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" +dependencies = [ + "rand_core 0.6.3", +] + +[[package]] +name = "rand_xorshift" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" +dependencies = [ + "rand_core 0.6.3", +] + +[[package]] +name = "redox_syscall" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ab49abadf3f9e1c4bc499e8845e152ad87d2ad2d30371841171169e9d75feee" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + +[[package]] +name = "rusty-fork" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" +dependencies = [ + "fnv", + "quick-error 1.2.3", + "tempfile", + "wait-timeout", +] + +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + +[[package]] +name = "schemars" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6ab463ae35acccb5cba66c0084c985257b797d288b6050cc2f6ac1b266cb78" +dependencies = [ + "dyn-clone", + "indexmap", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "902fdfbcf871ae8f653bddf4b2c05905ddaabc08f69d32a915787e3be0d31356" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn", +] + +[[package]] +name = "semver-parser" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b46e1121e8180c12ff69a742aabc4f310542b6ccb69f1691689ac17fdf8618aa" + +[[package]] +name = "serde" +version = "1.0.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_bytes" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16ae07dd2f88a366f15bd0632ba725227018c69a1c8550a927324f8eb8368bb9" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_derive_internals" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dbab34ca63057a1f15280bdf3c39f2b1eb1b54c17e98360e511637aef7418c6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b362ae5752fd2137731f9fa25fd4d9058af34666ca1966fb969119cc35719f12" +dependencies = [ + "block-buffer", + "cfg-if 1.0.0", + "cpufeatures", + "digest", + "opaque-debug", +] + +[[package]] +name = "signature" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29f060a7d147e33490ec10da418795238fd7545bba241504d6b31a409f2e6210" +dependencies = [ + "digest", + "rand_core 0.5.1", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "1.0.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "synstructure" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "474aaa926faa1603c40b7885a9eaea29b444d1cb2850cb7c0e37bb1a4182f4fa" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "unicode-xid", +] + +[[package]] +name = "tempfile" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "rand 0.8.4", + "redox_syscall", + "remove_dir_all", + "winapi", +] + +[[package]] +name = "test-contracts" +version = "0.1.0" +dependencies = [ + "casper-contract", + "casper-types", + "cep47", +] + +[[package]] +name = "thiserror" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "time" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "tinyvec" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "848a1e1181b9f6753b5e96a092749e29b11d19ede67dfbbd6c7dc7e0f49b5338" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + +[[package]] +name = "toml" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +dependencies = [ + "serde", +] + +[[package]] +name = "tracing" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d" +dependencies = [ + "cfg-if 1.0.0", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c42e6fa53307c8a17e4ccd4dc81cf5ec38db9209f59b222210375b54ee40d1e2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9ff14f98b1a4b289c6248a023c1c2fa1491062964e9fed67ab29c4e4da4a052" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "typenum" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" + +[[package]] +name = "uint" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6470ab50f482bde894a037a57064480a246dbfdd5960bd65a44824693f08da5f" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unicase" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +dependencies = [ + "version_check", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eeb8be209bb1c96b7c177c7420d26e04eccacb0eeae6b980e35fcb74678107e0" +dependencies = [ + "matches", +] + +[[package]] +name = "unicode-normalization" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "url" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +dependencies = [ + "form_urlencoded", + "idna", + "matches", + "percent-encoding", +] + +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +dependencies = [ + "getrandom 0.2.3", + "serde", +] + +[[package]] +name = "value-bag" +version = "1.0.0-alpha.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd320e1520f94261153e96f7534476ad869c14022aee1e59af7c778075d840ae" +dependencies = [ + "ctor", + "version_check", +] + +[[package]] +name = "version-sync" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cb94ca10ca0cf44f5d926ac977f0cac2d13e9789aa4bbe9d9388de445e61028" +dependencies = [ + "proc-macro2", + "pulldown-cmark", + "regex", + "semver-parser", + "syn", + "toml", + "url", +] + +[[package]] +name = "version_check" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" + +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "wasmi" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ad7e265153e1010a73e595eef3e2fd2a1fd644ba4e2dd3af4dd6bd7ec692342" +dependencies = [ + "downcast-rs", + "libc", + "memory_units 0.3.0", + "num-rational 0.2.4", + "num-traits", + "parity-wasm", + "wasmi-validation", +] + +[[package]] +name = "wasmi-validation" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea78c597064ba73596099281e2f4cfc019075122a65cdda3205af94f0b264d93" +dependencies = [ + "parity-wasm", +] + +[[package]] +name = "wee_alloc" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e" +dependencies = [ + "cfg-if 0.1.10", + "libc", + "memory_units 0.4.0", + "winapi", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "wyz" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" + +[[package]] +name = "zeroize" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "377db0846015f7ae377174787dd452e1c5f5a9050bc6f954911d01f116daa0cd" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2c1e130bebaeab2f23886bf9acbaca14b092408c452543c857f66399cd6dab1" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] diff --git a/Cargo.toml b/Cargo.toml index 4186153..b28f68b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,8 +3,8 @@ members = [ "cep47", "cep47-logic", - "dragons-nft", - "dragons-nft-tests" + "cep47-tests", + "test-contracts" ] [profile.release] diff --git a/Makefile b/Makefile index 4680782..3fcec18 100644 --- a/Makefile +++ b/Makefile @@ -2,15 +2,15 @@ prepare: rustup target add wasm32-unknown-unknown build-contract: - cargo build --release -p dragons-nft --target wasm32-unknown-unknown + cargo build --release -p test-contracts --target wasm32-unknown-unknown test-only: cargo test -p cep47-logic - cargo test -p dragons-nft-tests + cargo test -p cep47-tests copy-wasm-file-to-test: - mkdir -p dragons-nft-tests/wasm - cp target/wasm32-unknown-unknown/release/*.wasm dragons-nft-tests/wasm + mkdir -p cep47-tests/wasm + cp target/wasm32-unknown-unknown/release/*.wasm cep47-tests/wasm test: build-contract copy-wasm-file-to-test test-only @@ -27,4 +27,4 @@ lint: clippy format clean: cargo clean - rm -rf dragons-nft-tests/wasm/*.wasm + rm -rf cep47-tests/wasm/*.wasm diff --git a/dragons-nft-tests/Cargo.toml b/cep47-tests/Cargo.toml similarity index 92% rename from dragons-nft-tests/Cargo.toml rename to cep47-tests/Cargo.toml index e53562b..68d40e1 100644 --- a/dragons-nft-tests/Cargo.toml +++ b/cep47-tests/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "dragons-nft-tests" +name = "cep47-tests" version = "0.1.0" authors = ["astro019 "] edition = "2018" diff --git a/dragons-nft-tests/src/cep47.rs b/cep47-tests/src/cep47.rs similarity index 100% rename from dragons-nft-tests/src/cep47.rs rename to cep47-tests/src/cep47.rs diff --git a/dragons-nft-tests/src/contract_tests.rs b/cep47-tests/src/contract_tests.rs similarity index 100% rename from dragons-nft-tests/src/contract_tests.rs rename to cep47-tests/src/contract_tests.rs diff --git a/dragons-nft-tests/src/lib.rs b/cep47-tests/src/lib.rs similarity index 100% rename from dragons-nft-tests/src/lib.rs rename to cep47-tests/src/lib.rs diff --git a/dragons-nft-tests/wasm/.gitkeep b/cep47-tests/wasm/.gitkeep similarity index 100% rename from dragons-nft-tests/wasm/.gitkeep rename to cep47-tests/wasm/.gitkeep diff --git a/dragons-nft/Cargo.toml b/test-contracts/Cargo.toml similarity index 86% rename from dragons-nft/Cargo.toml rename to test-contracts/Cargo.toml index 32f8ffd..00e1e89 100644 --- a/dragons-nft/Cargo.toml +++ b/test-contracts/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "dragons-nft" +name = "test-contracts" version = "0.1.0" authors = ["astro019 "] edition = "2018" @@ -11,7 +11,7 @@ cep47 = { path="../cep47"} [[bin]] name = "dragons-nft" -path = "src/main.rs" +path = "src/dragons-nft.rs" bench = false doctest = false test = false diff --git a/dragons-nft/src/main.rs b/test-contracts/src/dragons-nft.rs similarity index 100% rename from dragons-nft/src/main.rs rename to test-contracts/src/dragons-nft.rs From 6d9cf6a3db49a119857b259139942908cfb6d2a4 Mon Sep 17 00:00:00 2001 From: Deusz Date: Fri, 30 Jul 2021 15:10:40 +0200 Subject: [PATCH 61/98] onwer->owner --- cep47-logic/src/lib.rs | 4 ++-- cep47-logic/src/tests.rs | 4 ++-- cep47/src/cep47_storage.rs | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cep47-logic/src/lib.rs b/cep47-logic/src/lib.rs index 4131719..e6ae74c 100644 --- a/cep47-logic/src/lib.rs +++ b/cep47-logic/src/lib.rs @@ -57,7 +57,7 @@ pub trait CEP47Contract: WithStorage { } fn owner_of(&self, token_id: &TokenId) -> Option { - self.storage().onwer_of(token_id) + self.storage().owner_of(token_id) } fn total_supply(&self) -> U256 { @@ -246,7 +246,7 @@ pub trait CEP47Storage { // Getters fn balance_of(&self, owner: &Key) -> U256; - fn onwer_of(&self, token_id: &TokenId) -> Option; + fn owner_of(&self, token_id: &TokenId) -> Option; fn total_supply(&self) -> U256; fn token_meta(&self, token_id: &TokenId) -> Option; diff --git a/cep47-logic/src/tests.rs b/cep47-logic/src/tests.rs index cc80a37..25af9d6 100644 --- a/cep47-logic/src/tests.rs +++ b/cep47-logic/src/tests.rs @@ -61,7 +61,7 @@ impl CEP47Storage for TestStorage { owner_balance.cloned().unwrap_or_default() } - fn onwer_of(&self, token_id: &TokenId) -> Option { + fn owner_of(&self, token_id: &TokenId) -> Option { let owner = self.belongs_to.get(token_id); owner.cloned() } @@ -164,7 +164,7 @@ impl CEP47Storage for TestStorage { fn validate_token_ids(&self, token_ids: &Vec) -> bool { for token_id in token_ids { - if self.onwer_of(token_id).is_some() { + if self.owner_of(token_id).is_some() { return false; } } diff --git a/cep47/src/cep47_storage.rs b/cep47/src/cep47_storage.rs index 143c942..c496451 100644 --- a/cep47/src/cep47_storage.rs +++ b/cep47/src/cep47_storage.rs @@ -33,7 +33,7 @@ impl CEP47Storage for CasperCEP47Storage { Balances::instance().get(owner) } - fn onwer_of(&self, token_id: &TokenId) -> Option { + fn owner_of(&self, token_id: &TokenId) -> Option { Owners::instance().get(token_id) } @@ -129,7 +129,7 @@ impl CEP47Storage for CasperCEP47Storage { // Remove tokens. for token_id in token_ids { - // Remove token form the onwer's list. + // Remove token from the owner's list. // Make sure that token is owned by the recipient. let index = owner_tokens .iter() @@ -181,7 +181,7 @@ impl CEP47Storage for CasperCEP47Storage { fn validate_token_ids(&self, token_ids: &Vec) -> bool { for token_id in token_ids { - if self.onwer_of(token_id).is_some() { + if self.owner_of(token_id).is_some() { return false; } } From 267b694344a9d0e25b3b2b68f10598c64012cec1 Mon Sep 17 00:00:00 2001 From: Deusz Date: Fri, 30 Jul 2021 15:27:28 +0200 Subject: [PATCH 62/98] first round of test of contracts owning tokens --- cep47-tests/src/cep47.rs | 44 +++++++--- cep47-tests/src/contract_tests.rs | 112 +++++++++++++++----------- test-contracts/Cargo.toml | 7 ++ test-contracts/src/owning_contract.rs | 48 +++++++++++ 4 files changed, 155 insertions(+), 56 deletions(-) create mode 100644 test-contracts/src/owning_contract.rs diff --git a/cep47-tests/src/cep47.rs b/cep47-tests/src/cep47.rs index 15eaf81..95c9fa8 100644 --- a/cep47-tests/src/cep47.rs +++ b/cep47-tests/src/cep47.rs @@ -79,6 +79,20 @@ impl CasperCEP47Contract { } } + pub fn deploy_secondary_contract(&mut self, wasm: &str, contract_hash_name: &str ,args: RuntimeArgs) -> Hash{ + let session_code = Code::from(wasm); + let session = SessionBuilder::new(session_code, args) + .with_address(self.admin) + .with_authorization_keys(&[self.admin]) + .build(); + self.context.run(session); + self.context + .query(self.admin, &[contract_hash_name.to_string()]) + .unwrap() + .into_t() + .unwrap() + } + fn call(&mut self, sender: &AccountHash, method: &str, args: RuntimeArgs) { let account = *sender; let code = Code::Hash(self.hash, method.to_string()); @@ -140,21 +154,20 @@ impl CasperCEP47Contract { self.query_contract("total_supply").unwrap_or_default() } - pub fn owner_of(&self, token_id: &TokenId) -> Option { - let key: Key = self - .query_dictionary_value(TOKEN_OWNERS_DICT, token_id.clone()) - .unwrap(); - key.into_account() + pub fn owner_of(&self, token_id: &TokenId) -> Key { + self + .query_dictionary_value::(TOKEN_OWNERS_DICT, token_id.clone()) + .unwrap() } - pub fn balance_of(&self, owner: &AccountHash) -> U256 { - let value: Option = self.query_dictionary_value(BALANCES_DICT, owner.to_string()); + pub fn balance_of(&self, owner: &Key) -> U256 { + let value: Option = self.query_dictionary_value(BALANCES_DICT, Self::key_to_str(owner)); value.unwrap_or_default() } - pub fn tokens(&self, owner: &AccountHash) -> Vec { + pub fn tokens(&self, owner: &Key) -> Vec { let value: Option> = - self.query_dictionary_value(OWNED_TOKENS_DICT, owner.to_string()); + self.query_dictionary_value(OWNED_TOKENS_DICT, Self::key_to_str(owner)); value.unwrap_or_default() } @@ -164,7 +177,7 @@ impl CasperCEP47Contract { pub fn mint_one( &mut self, - recipient: &AccountHash, + recipient: &Key, token_id: Option<&TokenId>, token_meta: &Meta, sender: &AccountHash, @@ -173,7 +186,7 @@ impl CasperCEP47Contract { sender, "mint_one", runtime_args! { - "recipient" => Key::from(*recipient), + "recipient" => *recipient, "token_id" => token_id.cloned(), "token_meta" => token_meta.clone() }, @@ -297,4 +310,13 @@ impl CasperCEP47Contract { }, ); } + + + fn key_to_str(key: &Key) -> String { + match key { + Key::Account(account) => account.to_string(), + Key::Hash(package) => hex::encode(package), + _ => panic!(), + } + } } diff --git a/cep47-tests/src/contract_tests.rs b/cep47-tests/src/contract_tests.rs index 0471782..07aaffa 100644 --- a/cep47-tests/src/contract_tests.rs +++ b/cep47-tests/src/contract_tests.rs @@ -1,5 +1,6 @@ use crate::cep47::{token_cfg, CasperCEP47Contract, Meta, TokenId}; -use casper_types::U256; +use casper_engine_test_support::Hash; +use casper_types::{Key, U256, runtime_args, RuntimeArgs}; mod meta { use super::Meta; @@ -47,7 +48,7 @@ fn test_token_meta() { let token_meta = meta::red_dragon(); contract.mint_one( - &contract.ali.clone(), + &Key::Account(contract.ali), Some(&token_id), &token_meta, &contract.admin.clone(), @@ -56,7 +57,7 @@ fn test_token_meta() { let ali_token_meta = contract.token_meta(&token_id).unwrap(); assert_eq!(ali_token_meta, token_meta); - let ali_tokens: Vec = contract.tokens(&contract.ali); + let ali_tokens: Vec = contract.tokens(&Key::Account(contract.ali)); assert_eq!(ali_tokens, vec![token_id]); } @@ -65,18 +66,18 @@ fn test_mint_one_with_random_token_id() { let mut contract = CasperCEP47Contract::deploy(); let token_meta = meta::red_dragon(); contract.mint_one( - &contract.ali.clone(), + &Key::Account(contract.ali), None, &token_meta, &contract.admin.clone(), ); assert_eq!(contract.total_supply(), U256::one()); - assert_eq!(contract.balance_of(&contract.ali), U256::one()); + assert_eq!(contract.balance_of(&Key::Account(contract.ali)), U256::one()); - let ali_tokens: Vec = contract.tokens(&contract.ali); + let ali_tokens: Vec = contract.tokens(&Key::Account(contract.ali)); assert_eq!(U256::from(ali_tokens.len() as u64), U256::one()); - assert_eq!(contract.owner_of(&ali_tokens[0]), Some(contract.ali)); + assert_eq!(contract.owner_of(&ali_tokens[0]), Key::Account(contract.ali)); } #[test] @@ -85,18 +86,18 @@ fn test_mint_one_with_set_token_id() { let token_id = TokenId::from("123456"); let token_meta = meta::red_dragon(); contract.mint_one( - &contract.ali.clone(), + &Key::Account(contract.ali), Some(&token_id), &token_meta, &contract.admin.clone(), ); - let ali_tokens: Vec = contract.tokens(&contract.ali); + let ali_tokens: Vec = contract.tokens(&Key::Account(contract.ali)); assert_eq!(ali_tokens, vec![token_id.clone()]); assert_eq!(contract.total_supply(), U256::one()); - assert_eq!(contract.balance_of(&contract.ali), U256::one()); + assert_eq!(contract.balance_of(&Key::Account(contract.ali)), U256::one()); assert_eq!(U256::from(ali_tokens.len() as u64), U256::one()); - assert_eq!(contract.owner_of(&token_id), Some(contract.ali)); + assert_eq!(contract.owner_of(&token_id), Key::Account(contract.ali)); } #[test] @@ -106,13 +107,13 @@ fn test_mint_one_with_not_unique_token_id() { let token_id = TokenId::from("123456"); let token_meta = meta::red_dragon(); contract.mint_one( - &contract.ali.clone(), + &Key::Account(contract.ali), Some(&token_id), &token_meta, &contract.admin.clone(), ); contract.mint_one( - &contract.ali.clone(), + &Key::Account(contract.ali), Some(&token_id), &token_meta, &contract.admin.clone(), @@ -131,13 +132,13 @@ fn test_mint_copies() { &contract.admin.clone(), ); - let ali_tokens: Vec = contract.tokens(&contract.ali); + let ali_tokens: Vec = contract.tokens(&Key::Account(contract.ali)); assert_eq!(contract.total_supply(), U256::from(3)); - assert_eq!(contract.balance_of(&contract.ali), U256::from(3)); + assert_eq!(contract.balance_of(&Key::Account(contract.ali)), U256::from(3)); assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(3)); - assert_eq!(contract.owner_of(&ali_tokens[0]), Some(contract.ali)); - assert_eq!(contract.owner_of(&ali_tokens[1]), Some(contract.ali)); - assert_eq!(contract.owner_of(&ali_tokens[2]), Some(contract.ali)); + assert_eq!(contract.owner_of(&ali_tokens[0]), Key::Account(contract.ali)); + assert_eq!(contract.owner_of(&ali_tokens[1]), Key::Account(contract.ali)); + assert_eq!(contract.owner_of(&ali_tokens[2]), Key::Account(contract.ali)); } #[test] @@ -151,13 +152,13 @@ fn test_mint_many() { &contract.admin.clone(), ); - let ali_tokens: Vec = contract.tokens(&contract.ali); + let ali_tokens: Vec = contract.tokens(&Key::Account(contract.ali)); assert_eq!(contract.total_supply(), U256::from(2)); - assert_eq!(contract.balance_of(&contract.ali), U256::from(2)); + assert_eq!(contract.balance_of(&Key::Account(contract.ali)), U256::from(2)); assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(2)); - assert_eq!(contract.owner_of(&ali_tokens[0]), Some(contract.ali)); - assert_eq!(contract.owner_of(&ali_tokens[1]), Some(contract.ali)); + assert_eq!(contract.owner_of(&ali_tokens[0]), Key::Account(contract.ali)); + assert_eq!(contract.owner_of(&ali_tokens[1]), Key::Account(contract.ali)); } #[test] @@ -176,7 +177,7 @@ fn test_burn_many() { &contract.admin.clone(), ); - let ali_tokens: Vec = contract.tokens(&contract.ali); + let ali_tokens: Vec = contract.tokens(&Key::Account(contract.ali)); println!("{:?}", ali_tokens); println!("{:?}", ali_tokens.first().unwrap().clone()); @@ -189,9 +190,9 @@ fn test_burn_many() { &contract.admin.clone(), ); assert_eq!(contract.total_supply(), U256::from(2)); - assert_eq!(contract.balance_of(&contract.ali), U256::from(2)); + assert_eq!(contract.balance_of(&Key::Account(contract.ali)), U256::from(2)); - let ali_tokens = contract.tokens(&contract.ali); + let ali_tokens = contract.tokens(&Key::Account(contract.ali)); println!("{:?}", ali_tokens); assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(2)); } @@ -207,7 +208,7 @@ fn test_burn_one() { &contract.admin.clone(), ); - let ali_tokens = contract.tokens(&contract.ali); + let ali_tokens = contract.tokens(&Key::Account(contract.ali)); contract.burn_one( &contract.ali.clone(), @@ -215,9 +216,9 @@ fn test_burn_one() { &contract.admin.clone(), ); assert_eq!(contract.total_supply(), U256::from(1)); - assert_eq!(contract.balance_of(&contract.ali), U256::from(1)); + assert_eq!(contract.balance_of(&Key::Account(contract.ali)), U256::from(1)); - let ali_tokens = contract.tokens(&contract.ali); + let ali_tokens = contract.tokens(&Key::Account(contract.ali)); assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(1)); } @@ -232,15 +233,15 @@ fn test_transfer_token() { &contract.admin.clone(), ); - let ali_tokens: Vec = contract.tokens(&contract.ali); + let ali_tokens: Vec = contract.tokens(&Key::Account(contract.ali)); contract.transfer_token(&contract.bob.clone(), &ali_tokens[1], &contract.ali.clone()); - assert_eq!(contract.balance_of(&contract.ali), U256::from(1)); - assert_eq!(contract.balance_of(&contract.bob), U256::from(1)); + assert_eq!(contract.balance_of(&Key::Account(contract.ali)), U256::from(1)); + assert_eq!(contract.balance_of(&Key::Account(contract.bob)), U256::from(1)); assert_eq!(contract.total_supply(), U256::from(2)); - assert_eq!(contract.owner_of(&ali_tokens[0]), Some(contract.ali)); - assert_eq!(contract.owner_of(&ali_tokens[1]), Some(contract.bob)); + assert_eq!(contract.owner_of(&ali_tokens[0]), Key::Account(contract.ali)); + assert_eq!(contract.owner_of(&ali_tokens[1]), Key::Account(contract.bob)); } #[test] @@ -257,19 +258,19 @@ fn test_transfer_many_tokens() { &token_metas, &contract.admin.clone(), ); - let ali_tokens: Vec = contract.tokens(&contract.ali); + let ali_tokens: Vec = contract.tokens(&Key::Account(contract.ali)); contract.transfer_many_tokens( &contract.bob.clone(), &ali_tokens[..2].to_vec(), &contract.ali.clone(), ); - assert_eq!(contract.balance_of(&contract.ali), U256::from(1)); - assert_eq!(contract.balance_of(&contract.bob), U256::from(2)); + assert_eq!(contract.balance_of(&Key::Account(contract.ali)), U256::from(1)); + assert_eq!(contract.balance_of(&Key::Account(contract.bob)), U256::from(2)); assert_eq!(contract.total_supply(), U256::from(3)); - assert_eq!(contract.owner_of(&ali_tokens[0]), Some(contract.bob)); - assert_eq!(contract.owner_of(&ali_tokens[1]), Some(contract.bob)); - assert_eq!(contract.owner_of(&ali_tokens[2]), Some(contract.ali)); + assert_eq!(contract.owner_of(&ali_tokens[0]), Key::Account(contract.bob)); + assert_eq!(contract.owner_of(&ali_tokens[1]), Key::Account(contract.bob)); + assert_eq!(contract.owner_of(&ali_tokens[2]), Key::Account(contract.ali)); } #[test] @@ -283,15 +284,15 @@ fn test_transfer_all_tokens() { &contract.admin.clone(), ); - let ali_tokens: Vec = contract.tokens(&contract.ali); + let ali_tokens: Vec = contract.tokens(&Key::Account(contract.ali)); contract.transfer_all_tokens(&contract.bob.clone(), &contract.ali.clone()); - assert_eq!(contract.balance_of(&contract.ali), U256::from(0)); - assert_eq!(contract.balance_of(&contract.bob), U256::from(2)); + assert_eq!(contract.balance_of(&Key::Account(contract.ali)), U256::from(0)); + assert_eq!(contract.balance_of(&Key::Account(contract.bob)), U256::from(2)); assert_eq!(contract.total_supply(), U256::from(2)); - assert_eq!(contract.owner_of(&ali_tokens[0]), Some(contract.bob)); - assert_eq!(contract.owner_of(&ali_tokens[1]), Some(contract.bob)); + assert_eq!(contract.owner_of(&ali_tokens[0]), Key::Account(contract.bob)); + assert_eq!(contract.owner_of(&ali_tokens[1]), Key::Account(contract.bob)); } #[test] @@ -300,7 +301,7 @@ fn test_token_metadata_update() { let token_id = TokenId::from("123456"); let token_meta = meta::red_dragon(); contract.mint_one( - &contract.ali.clone(), + &Key::Account(contract.ali), Some(&token_id), &token_meta, &contract.admin.clone(), @@ -309,3 +310,24 @@ fn test_token_metadata_update() { contract.update_token_metadata(&token_id, &meta::blue_dragon(), &contract.admin.clone()); assert_eq!(contract.token_meta(&token_id).unwrap(), meta::blue_dragon()); } + +#[test] +fn test_contract_owning_token() { + let mut contract = CasperCEP47Contract::deploy(); + let contract_hash: Hash = contract.deploy_secondary_contract("owning-contract.wasm", "owning_contract_hash", runtime_args!{}); + let token_id = TokenId::from("123456"); + let token_meta = meta::red_dragon(); + contract.mint_one( + &Key::Hash(contract_hash), + Some(&token_id), + &token_meta, + &contract.admin.clone(), + ); + + assert_eq!(contract.total_supply(), U256::from(1)); + assert_eq!(contract.balance_of(&Key::Hash(contract_hash)), U256::from(1)); + + let contracts_tokens: Vec = contract.tokens(&Key::Hash(contract_hash)); + println!("{:?}", contracts_tokens); + assert_eq!(contract.owner_of(&contracts_tokens[0]), Key::Hash(contract_hash)); +} \ No newline at end of file diff --git a/test-contracts/Cargo.toml b/test-contracts/Cargo.toml index 00e1e89..e7bcd67 100644 --- a/test-contracts/Cargo.toml +++ b/test-contracts/Cargo.toml @@ -16,6 +16,13 @@ bench = false doctest = false test = false +[[bin]] +name = "owning-contract" +path = "src/owning_contract.rs" +bench = false +doctest = false +test = false + [features] default = ["casper-contract/std", "casper-types/std"] diff --git a/test-contracts/src/owning_contract.rs b/test-contracts/src/owning_contract.rs new file mode 100644 index 0000000..3923105 --- /dev/null +++ b/test-contracts/src/owning_contract.rs @@ -0,0 +1,48 @@ +#![no_main] + +use casper_contract::{ + contract_api::{ + runtime::{self}, + storage, + }, + unwrap_or_revert::UnwrapOrRevert, +}; +use casper_types::{ + contracts::NamedKeys, CLType, EntryPoint, EntryPointAccess, EntryPoints, Key, Parameter, +}; + +#[no_mangle] +pub extern "C" fn call_back() { +} + +#[no_mangle] +pub extern "C" fn call() { + let (contract_package_hash, _access) = storage::create_contract_package_at_hash(); + let entry_points = { + let mut eps = EntryPoints::new(); + eps.add_entry_point(EntryPoint::new( + "call_back", + vec![], + CLType::Unit, + EntryPointAccess::Public, + casper_types::EntryPointType::Contract, + )); + eps + }; + let named_keys = { + let mut nk = NamedKeys::new(); + nk + }; + + let (contract_hash, _) = + storage::add_contract_version(contract_package_hash, entry_points, named_keys); + // wrap the contract hash so that it can be reached from the test environment + runtime::put_key( + "owning_contract_hash", + storage::new_uref(contract_hash).into(), + ); + runtime::put_key( + "owning_contract_package", + storage::new_uref(contract_package_hash).into(), + ); +} From c00544a5ded17bae131199bf09550cd780e71b27 Mon Sep 17 00:00:00 2001 From: Deusz Date: Fri, 30 Jul 2021 17:04:46 +0200 Subject: [PATCH 63/98] contract package hashes now are able to hold tokens --- cep47-tests/src/cep47.rs | 59 +++++++--- cep47-tests/src/contract_tests.rs | 159 ++++++++++++++++++++------ cep47/src/lib.rs | 9 +- test-contracts/src/owning_contract.rs | 33 +++--- 4 files changed, 193 insertions(+), 67 deletions(-) diff --git a/cep47-tests/src/cep47.rs b/cep47-tests/src/cep47.rs index 95c9fa8..e9f7e1d 100644 --- a/cep47-tests/src/cep47.rs +++ b/cep47-tests/src/cep47.rs @@ -2,8 +2,8 @@ use std::collections::BTreeMap; use casper_engine_test_support::{Code, Hash, SessionBuilder, TestContext, TestContextBuilder}; use casper_types::{ - account::AccountHash, bytesrepr::FromBytes, runtime_args, CLTyped, Key, PublicKey, RuntimeArgs, - SecretKey, U256, U512, + account::AccountHash, bytesrepr::FromBytes, runtime_args, CLTyped, ContractPackageHash, + HashAddr, Key, PublicKey, RuntimeArgs, SecretKey, U256, U512, }; pub mod token_cfg { @@ -79,18 +79,26 @@ impl CasperCEP47Contract { } } - pub fn deploy_secondary_contract(&mut self, wasm: &str, contract_hash_name: &str ,args: RuntimeArgs) -> Hash{ + pub fn deploy_secondary_contract(&mut self, wasm: &str, args: RuntimeArgs) -> (Hash, HashAddr) { let session_code = Code::from(wasm); let session = SessionBuilder::new(session_code, args) .with_address(self.admin) .with_authorization_keys(&[self.admin]) .build(); self.context.run(session); - self.context - .query(self.admin, &[contract_hash_name.to_string()]) + let hash = self + .context + .query(self.admin, &["owning_contract_hash".to_string()]) .unwrap() .into_t() + .unwrap(); + let package = self + .context + .query(self.admin, &["owning_contract_pack".to_string()]) .unwrap() + .into_t() + .unwrap(); + (hash, package) } fn call(&mut self, sender: &AccountHash, method: &str, args: RuntimeArgs) { @@ -155,13 +163,13 @@ impl CasperCEP47Contract { } pub fn owner_of(&self, token_id: &TokenId) -> Key { - self - .query_dictionary_value::(TOKEN_OWNERS_DICT, token_id.clone()) + self.query_dictionary_value::(TOKEN_OWNERS_DICT, token_id.clone()) .unwrap() } pub fn balance_of(&self, owner: &Key) -> U256 { - let value: Option = self.query_dictionary_value(BALANCES_DICT, Self::key_to_str(owner)); + let value: Option = + self.query_dictionary_value(BALANCES_DICT, Self::key_to_str(owner)); value.unwrap_or_default() } @@ -258,22 +266,42 @@ impl CasperCEP47Contract { ); } - pub fn transfer_token( - &mut self, - recipient: &AccountHash, - token_id: &TokenId, - sender: &AccountHash, - ) { + pub fn transfer_token(&mut self, recipient: &Key, token_id: &TokenId, sender: &AccountHash) { self.call( sender, "transfer_token", runtime_args! { - "recipient" => Key::from(*recipient), + "recipient" => *recipient, "token_id" => token_id.clone() }, ); } + pub fn transfer_token_from_contract( + &mut self, + contract_manager: &AccountHash, + contract_hash: &Hash, + recipient: &Key, + token_id: &TokenId, + ) { + let code = Code::Hash(*contract_hash, "transfer_token".to_string()); + let nft_package: ContractPackageHash = + self.query_contract("contract_package_hash").unwrap(); + let session = SessionBuilder::new( + code, + runtime_args! { + "nft" => nft_package, + "sender" => Key::Hash(*contract_hash), + "recipient" => *recipient, + "token_id" => token_id.clone() + }, + ) + .with_address(*contract_manager) + .with_authorization_keys(&[*contract_manager]) + .build(); + self.context.run(session); + } + pub fn transfer_many_tokens( &mut self, recipient: &AccountHash, @@ -311,7 +339,6 @@ impl CasperCEP47Contract { ); } - fn key_to_str(key: &Key) -> String { match key { Key::Account(account) => account.to_string(), diff --git a/cep47-tests/src/contract_tests.rs b/cep47-tests/src/contract_tests.rs index 07aaffa..e5f4a76 100644 --- a/cep47-tests/src/contract_tests.rs +++ b/cep47-tests/src/contract_tests.rs @@ -1,6 +1,5 @@ use crate::cep47::{token_cfg, CasperCEP47Contract, Meta, TokenId}; -use casper_engine_test_support::Hash; -use casper_types::{Key, U256, runtime_args, RuntimeArgs}; +use casper_types::{runtime_args, Key, RuntimeArgs, U256}; mod meta { use super::Meta; @@ -73,11 +72,17 @@ fn test_mint_one_with_random_token_id() { ); assert_eq!(contract.total_supply(), U256::one()); - assert_eq!(contract.balance_of(&Key::Account(contract.ali)), U256::one()); + assert_eq!( + contract.balance_of(&Key::Account(contract.ali)), + U256::one() + ); let ali_tokens: Vec = contract.tokens(&Key::Account(contract.ali)); assert_eq!(U256::from(ali_tokens.len() as u64), U256::one()); - assert_eq!(contract.owner_of(&ali_tokens[0]), Key::Account(contract.ali)); + assert_eq!( + contract.owner_of(&ali_tokens[0]), + Key::Account(contract.ali) + ); } #[test] @@ -95,7 +100,10 @@ fn test_mint_one_with_set_token_id() { let ali_tokens: Vec = contract.tokens(&Key::Account(contract.ali)); assert_eq!(ali_tokens, vec![token_id.clone()]); assert_eq!(contract.total_supply(), U256::one()); - assert_eq!(contract.balance_of(&Key::Account(contract.ali)), U256::one()); + assert_eq!( + contract.balance_of(&Key::Account(contract.ali)), + U256::one() + ); assert_eq!(U256::from(ali_tokens.len() as u64), U256::one()); assert_eq!(contract.owner_of(&token_id), Key::Account(contract.ali)); } @@ -134,11 +142,23 @@ fn test_mint_copies() { let ali_tokens: Vec = contract.tokens(&Key::Account(contract.ali)); assert_eq!(contract.total_supply(), U256::from(3)); - assert_eq!(contract.balance_of(&Key::Account(contract.ali)), U256::from(3)); + assert_eq!( + contract.balance_of(&Key::Account(contract.ali)), + U256::from(3) + ); assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(3)); - assert_eq!(contract.owner_of(&ali_tokens[0]), Key::Account(contract.ali)); - assert_eq!(contract.owner_of(&ali_tokens[1]), Key::Account(contract.ali)); - assert_eq!(contract.owner_of(&ali_tokens[2]), Key::Account(contract.ali)); + assert_eq!( + contract.owner_of(&ali_tokens[0]), + Key::Account(contract.ali) + ); + assert_eq!( + contract.owner_of(&ali_tokens[1]), + Key::Account(contract.ali) + ); + assert_eq!( + contract.owner_of(&ali_tokens[2]), + Key::Account(contract.ali) + ); } #[test] @@ -155,10 +175,19 @@ fn test_mint_many() { let ali_tokens: Vec = contract.tokens(&Key::Account(contract.ali)); assert_eq!(contract.total_supply(), U256::from(2)); - assert_eq!(contract.balance_of(&Key::Account(contract.ali)), U256::from(2)); + assert_eq!( + contract.balance_of(&Key::Account(contract.ali)), + U256::from(2) + ); assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(2)); - assert_eq!(contract.owner_of(&ali_tokens[0]), Key::Account(contract.ali)); - assert_eq!(contract.owner_of(&ali_tokens[1]), Key::Account(contract.ali)); + assert_eq!( + contract.owner_of(&ali_tokens[0]), + Key::Account(contract.ali) + ); + assert_eq!( + contract.owner_of(&ali_tokens[1]), + Key::Account(contract.ali) + ); } #[test] @@ -190,7 +219,10 @@ fn test_burn_many() { &contract.admin.clone(), ); assert_eq!(contract.total_supply(), U256::from(2)); - assert_eq!(contract.balance_of(&Key::Account(contract.ali)), U256::from(2)); + assert_eq!( + contract.balance_of(&Key::Account(contract.ali)), + U256::from(2) + ); let ali_tokens = contract.tokens(&Key::Account(contract.ali)); println!("{:?}", ali_tokens); @@ -216,7 +248,10 @@ fn test_burn_one() { &contract.admin.clone(), ); assert_eq!(contract.total_supply(), U256::from(1)); - assert_eq!(contract.balance_of(&Key::Account(contract.ali)), U256::from(1)); + assert_eq!( + contract.balance_of(&Key::Account(contract.ali)), + U256::from(1) + ); let ali_tokens = contract.tokens(&Key::Account(contract.ali)); assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(1)); @@ -235,13 +270,29 @@ fn test_transfer_token() { let ali_tokens: Vec = contract.tokens(&Key::Account(contract.ali)); - contract.transfer_token(&contract.bob.clone(), &ali_tokens[1], &contract.ali.clone()); + contract.transfer_token( + &Key::Account(contract.bob), + &ali_tokens[1], + &contract.ali.clone(), + ); - assert_eq!(contract.balance_of(&Key::Account(contract.ali)), U256::from(1)); - assert_eq!(contract.balance_of(&Key::Account(contract.bob)), U256::from(1)); + assert_eq!( + contract.balance_of(&Key::Account(contract.ali)), + U256::from(1) + ); + assert_eq!( + contract.balance_of(&Key::Account(contract.bob)), + U256::from(1) + ); assert_eq!(contract.total_supply(), U256::from(2)); - assert_eq!(contract.owner_of(&ali_tokens[0]), Key::Account(contract.ali)); - assert_eq!(contract.owner_of(&ali_tokens[1]), Key::Account(contract.bob)); + assert_eq!( + contract.owner_of(&ali_tokens[0]), + Key::Account(contract.ali) + ); + assert_eq!( + contract.owner_of(&ali_tokens[1]), + Key::Account(contract.bob) + ); } #[test] @@ -265,12 +316,27 @@ fn test_transfer_many_tokens() { &contract.ali.clone(), ); - assert_eq!(contract.balance_of(&Key::Account(contract.ali)), U256::from(1)); - assert_eq!(contract.balance_of(&Key::Account(contract.bob)), U256::from(2)); + assert_eq!( + contract.balance_of(&Key::Account(contract.ali)), + U256::from(1) + ); + assert_eq!( + contract.balance_of(&Key::Account(contract.bob)), + U256::from(2) + ); assert_eq!(contract.total_supply(), U256::from(3)); - assert_eq!(contract.owner_of(&ali_tokens[0]), Key::Account(contract.bob)); - assert_eq!(contract.owner_of(&ali_tokens[1]), Key::Account(contract.bob)); - assert_eq!(contract.owner_of(&ali_tokens[2]), Key::Account(contract.ali)); + assert_eq!( + contract.owner_of(&ali_tokens[0]), + Key::Account(contract.bob) + ); + assert_eq!( + contract.owner_of(&ali_tokens[1]), + Key::Account(contract.bob) + ); + assert_eq!( + contract.owner_of(&ali_tokens[2]), + Key::Account(contract.ali) + ); } #[test] @@ -287,12 +353,24 @@ fn test_transfer_all_tokens() { let ali_tokens: Vec = contract.tokens(&Key::Account(contract.ali)); contract.transfer_all_tokens(&contract.bob.clone(), &contract.ali.clone()); - assert_eq!(contract.balance_of(&Key::Account(contract.ali)), U256::from(0)); - assert_eq!(contract.balance_of(&Key::Account(contract.bob)), U256::from(2)); + assert_eq!( + contract.balance_of(&Key::Account(contract.ali)), + U256::from(0) + ); + assert_eq!( + contract.balance_of(&Key::Account(contract.bob)), + U256::from(2) + ); assert_eq!(contract.total_supply(), U256::from(2)); - assert_eq!(contract.owner_of(&ali_tokens[0]), Key::Account(contract.bob)); - assert_eq!(contract.owner_of(&ali_tokens[1]), Key::Account(contract.bob)); + assert_eq!( + contract.owner_of(&ali_tokens[0]), + Key::Account(contract.bob) + ); + assert_eq!( + contract.owner_of(&ali_tokens[1]), + Key::Account(contract.bob) + ); } #[test] @@ -314,20 +392,31 @@ fn test_token_metadata_update() { #[test] fn test_contract_owning_token() { let mut contract = CasperCEP47Contract::deploy(); - let contract_hash: Hash = contract.deploy_secondary_contract("owning-contract.wasm", "owning_contract_hash", runtime_args!{}); + let (contract_hash, package) = + contract.deploy_secondary_contract("owning-contract.wasm", runtime_args! {}); let token_id = TokenId::from("123456"); let token_meta = meta::red_dragon(); + let owning_hash_key = Key::Hash(package); contract.mint_one( - &Key::Hash(contract_hash), + &owning_hash_key, Some(&token_id), &token_meta, &contract.admin.clone(), ); assert_eq!(contract.total_supply(), U256::from(1)); - assert_eq!(contract.balance_of(&Key::Hash(contract_hash)), U256::from(1)); + assert_eq!(contract.balance_of(&owning_hash_key), U256::from(1)); + + let contracts_tokens: Vec = contract.tokens(&owning_hash_key); + assert_eq!(contract.owner_of(&contracts_tokens[0]), owning_hash_key); - let contracts_tokens: Vec = contract.tokens(&Key::Hash(contract_hash)); - println!("{:?}", contracts_tokens); - assert_eq!(contract.owner_of(&contracts_tokens[0]), Key::Hash(contract_hash)); -} \ No newline at end of file + let admin = contract.admin; + let ali = Key::Account(contract.ali.to_owned()); + contract.transfer_token_from_contract(&admin, &contract_hash, &ali, &token_id); + + assert_eq!(contract.balance_of(&owning_hash_key), U256::from(0)); + assert_eq!( + contract.balance_of(&Key::Account(contract.ali)), + U256::from(1) + ); +} diff --git a/cep47/src/lib.rs b/cep47/src/lib.rs index 234dc1b..11671c5 100644 --- a/cep47/src/lib.rs +++ b/cep47/src/lib.rs @@ -9,7 +9,10 @@ use alloc::{ string::String, }; use casper_contract::{ - contract_api::{runtime, storage}, + contract_api::{ + runtime::{self, revert}, + storage, + }, unwrap_or_revert::UnwrapOrRevert, }; use casper_types::{ @@ -282,7 +285,9 @@ pub fn ret(value: T) { } fn get_caller() -> Key { - match runtime::get_call_stack().first().unwrap_or_revert() { + let mut callstack = runtime::get_call_stack(); + callstack.pop(); + match callstack.last().unwrap_or_revert() { CallStackElement::Session { account_hash } => (*account_hash).into(), CallStackElement::StoredSession { account_hash, diff --git a/test-contracts/src/owning_contract.rs b/test-contracts/src/owning_contract.rs index 3923105..f2a48e7 100644 --- a/test-contracts/src/owning_contract.rs +++ b/test-contracts/src/owning_contract.rs @@ -1,18 +1,26 @@ #![no_main] -use casper_contract::{ - contract_api::{ - runtime::{self}, - storage, - }, - unwrap_or_revert::UnwrapOrRevert, +use casper_contract::contract_api::{ + runtime::{self, call_versioned_contract}, + storage, }; use casper_types::{ - contracts::NamedKeys, CLType, EntryPoint, EntryPointAccess, EntryPoints, Key, Parameter, + contracts::NamedKeys, runtime_args, CLType, EntryPoint, EntryPointAccess, EntryPoints, Key, + RuntimeArgs, }; #[no_mangle] -pub extern "C" fn call_back() { +pub extern "C" fn transfer_token() { + call_versioned_contract( + runtime::get_named_arg("nft"), + None, + "transfer_token", + runtime_args! { + "sender" => runtime::get_named_arg::("sender"), + "recipient"=>runtime::get_named_arg::("recipient"), + "token_id"=>runtime::get_named_arg::("token_id") + }, + ) } #[no_mangle] @@ -21,7 +29,7 @@ pub extern "C" fn call() { let entry_points = { let mut eps = EntryPoints::new(); eps.add_entry_point(EntryPoint::new( - "call_back", + "transfer_token", vec![], CLType::Unit, EntryPointAccess::Public, @@ -29,10 +37,7 @@ pub extern "C" fn call() { )); eps }; - let named_keys = { - let mut nk = NamedKeys::new(); - nk - }; + let named_keys = NamedKeys::new(); let (contract_hash, _) = storage::add_contract_version(contract_package_hash, entry_points, named_keys); @@ -42,7 +47,7 @@ pub extern "C" fn call() { storage::new_uref(contract_hash).into(), ); runtime::put_key( - "owning_contract_package", + "owning_contract_pack", storage::new_uref(contract_package_hash).into(), ); } From 615c84723ac515245e117d438815d5b18b2dd9f9 Mon Sep 17 00:00:00 2001 From: Deusz Date: Wed, 11 Aug 2021 12:45:17 +0200 Subject: [PATCH 64/98] pause tests, wasm size decrease --- Cargo.toml | 1 + Makefile | 2 + cep47-tests/src/cep47.rs | 14 ++++- cep47-tests/src/contract_tests.rs | 90 +++++++++++++++++++++++++++++++ 4 files changed, 106 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index b28f68b..d8ce49d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,3 +9,4 @@ members = [ [profile.release] lto = true +codegen-units = 1 \ No newline at end of file diff --git a/Makefile b/Makefile index 3fcec18..8d3bef4 100644 --- a/Makefile +++ b/Makefile @@ -3,6 +3,8 @@ prepare: build-contract: cargo build --release -p test-contracts --target wasm32-unknown-unknown + wasm-strip target/wasm32-unknown-unknown/release/dragons-nft.wasm 2>/dev/null | true + wasm-strip target/wasm32-unknown-unknown/release/owning-contract.wasm 2>/dev/null | true test-only: cargo test -p cep47-logic diff --git a/cep47-tests/src/cep47.rs b/cep47-tests/src/cep47.rs index e9f7e1d..308c90f 100644 --- a/cep47-tests/src/cep47.rs +++ b/cep47-tests/src/cep47.rs @@ -159,7 +159,7 @@ impl CasperCEP47Contract { } pub fn total_supply(&self) -> U256 { - self.query_contract("total_supply").unwrap_or_default() + self.query_contract("total_supply").unwrap() } pub fn owner_of(&self, token_id: &TokenId) -> Key { @@ -339,6 +339,18 @@ impl CasperCEP47Contract { ); } + pub fn pause(&mut self, sender: &AccountHash) { + self.call(sender, "pause", runtime_args! {}); + } + + pub fn unpause(&mut self, sender: &AccountHash) { + self.call(sender, "unpause", runtime_args! {}); + } + + pub fn is_paused(&mut self) -> bool { + self.query_contract("paused").unwrap() + } + fn key_to_str(key: &Key) -> String { match key { Key::Account(account) => account.to_string(), diff --git a/cep47-tests/src/contract_tests.rs b/cep47-tests/src/contract_tests.rs index e5f4a76..406ae02 100644 --- a/cep47-tests/src/contract_tests.rs +++ b/cep47-tests/src/contract_tests.rs @@ -420,3 +420,93 @@ fn test_contract_owning_token() { U256::from(1) ); } + +#[test] +#[should_panic = "ApiError::User(1)"] +fn test_pausing_contract() { + let mut contract = CasperCEP47Contract::deploy(); + let token_metas: Vec = vec![meta::gold_dragon(), meta::red_dragon()]; + contract.mint_many( + &contract.ali.clone(), + None, + &token_metas, + &contract.admin.clone(), + ); + contract.pause(&contract.admin.clone()); + let ali_tokens = contract.tokens(&Key::Account(contract.ali)); + + // Test panics here, since contract is paused and a generic user is trying to call a non-admin function + contract.transfer_token( + &Key::Account(contract.bob), + &ali_tokens[1], + &contract.ali.clone(), + ); +} + +#[test] +fn test_pausing_and_unpausing_contract() { + let mut contract = CasperCEP47Contract::deploy(); + let token_metas: Vec = vec![meta::gold_dragon(), meta::red_dragon()]; + contract.mint_many( + &contract.ali.clone(), + None, + &token_metas, + &contract.admin.clone(), + ); + // deployer can pause the contract + contract.pause(&contract.admin.clone()); + + let ali_tokens = contract.tokens(&Key::Account(contract.ali)); + // admin functions still work even while paused + contract.burn_one( + &contract.ali.clone(), + &ali_tokens[1], + &contract.admin.clone(), + ); + // only deployer can unpause + contract.unpause(&contract.admin.clone()); + // then normal function can continue + contract.transfer_token( + &Key::Account(contract.bob), + &ali_tokens[0], + &contract.ali.clone(), + ); + + assert_eq!(contract.total_supply(), U256::from(1)); + assert_eq!( + contract.balance_of(&Key::Account(contract.ali)), + U256::from(0) + ); + + let ali_tokens = contract.tokens(&Key::Account(contract.ali)); + let bob_tokens = contract.tokens(&Key::Account(contract.bob)); + assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(0)); + assert_eq!(U256::from(bob_tokens.len() as u64), U256::from(1)); +} + +#[test] +#[should_panic = "InvalidContext"] +fn test_pausing_contract_unauthorized() { + // generic user cannot pause the contract + let mut contract = CasperCEP47Contract::deploy(); + contract.pause(&contract.ali.clone()); +} + +#[test] +#[should_panic = "InvalidContext"] +fn test_unpausing_contract_unauthorized() { + // admin can pause the contract, but generic user cannot unpause + let mut contract = CasperCEP47Contract::deploy(); + contract.pause(&contract.admin.clone()); + contract.unpause(&contract.ali.clone()); +} + +#[test] +fn test_paused_field() { + let mut contract = CasperCEP47Contract::deploy(); + assert!(!contract.is_paused()); + contract.pause(&contract.admin.clone()); + assert!(contract.is_paused()); + contract.unpause(&contract.admin.clone()); + assert!(!contract.is_paused()); +} From c5d43d5d8191309dc2a6d6337fb7b131ead7bc0e Mon Sep 17 00:00:00 2001 From: Maciej Zielinski Date: Thu, 12 Aug 2021 21:05:32 +0200 Subject: [PATCH 65/98] Events via dicts --- cep47-logic/src/lib.rs | 2 +- cep47/src/data.rs | 54 ++++++++++++++++++++++++------- test-contracts/src/dragons-nft.rs | 21 +++++++++--- 3 files changed, 59 insertions(+), 18 deletions(-) diff --git a/cep47-logic/src/lib.rs b/cep47-logic/src/lib.rs index e6ae74c..40b699e 100644 --- a/cep47-logic/src/lib.rs +++ b/cep47-logic/src/lib.rs @@ -146,7 +146,7 @@ pub trait CEP47Contract: WithStorage { } fn burn_one(&mut self, owner: &Key, token_id: TokenId) { - self.storage_mut().burn_many(owner, &vec![token_id]); + self.burn_many(owner, vec![token_id]); } fn burn_many(&mut self, owner: &Key, token_ids: Vec) { diff --git a/cep47/src/data.rs b/cep47/src/data.rs index 378b6b5..3cc52c8 100644 --- a/cep47/src/data.rs +++ b/cep47/src/data.rs @@ -18,6 +18,7 @@ const BALANCES_DICT: &str = "balances"; const OWNED_TOKENS_DICT: &str = "owned_tokens"; const TOKEN_OWNERS_DICT: &str = "owners"; const METADATA_DICT: &str = "metadata"; +const EVENTS_DICT: &str = "events"; struct Dict { uref: URef, @@ -181,6 +182,14 @@ pub fn set_nonce(nonce: u32) { set_key("nonce", nonce); } +pub fn get_events_count() -> u32 { + get_key("events_count").unwrap_or_revert() +} + +pub fn set_events_count(events_count: u32) { + set_key("events_count", events_count); +} + pub fn contract_package_hash() -> ContractPackageHash { get_key("contract_package_hash").unwrap_or_revert() } @@ -211,6 +220,10 @@ pub fn initial_named_keys( add_empty_dict(&mut named_keys, OWNED_TOKENS_DICT); add_empty_dict(&mut named_keys, TOKEN_OWNERS_DICT); add_empty_dict(&mut named_keys, METADATA_DICT); + add_empty_dict(&mut named_keys, EVENTS_DICT); + + // Set events count. + named_keys.insert("events_count".to_string(), storage::new_uref(0u32).into()); named_keys } @@ -232,13 +245,18 @@ fn key_to_str(key: &Key) -> String { pub fn emit(event: &CEP47Event) { let mut events = Vec::new(); let package = contract_package_hash(); + let mut events_count = get_events_count(); + match event { CEP47Event::MetadataUpdate { token_id } => { let mut event = BTreeMap::new(); - event.insert("contract_package_hash", package.to_string()); + let event_id = events_count.to_string(); + event.insert("event_id", event_id.clone()); + event.insert("contract_package_hash", package.to_formatted_string()); event.insert("event_type", "cep47_metadata_update".to_string()); event.insert("token_id", token_id.to_string()); - events.push(event); + events.push((event_id, event)); + events_count += 1; } CEP47Event::Transfer { sender, @@ -247,12 +265,15 @@ pub fn emit(event: &CEP47Event) { } => { for token_id in token_ids { let mut event = BTreeMap::new(); - event.insert("contract_package_hash", package.to_string()); + let event_id = events_count.to_string(); + event.insert("event_id", event_id.clone()); + event.insert("contract_package_hash", package.to_formatted_string()); event.insert("event_type", "cep47_transfer_token".to_string()); - event.insert("sender", sender.to_string()); - event.insert("recipient", recipient.to_string()); + event.insert("sender", sender.to_formatted_string()); + event.insert("recipient", recipient.to_formatted_string()); event.insert("token_id", token_id.to_string()); - events.push(event); + events.push((event_id, event)); + events_count += 1; } } CEP47Event::Mint { @@ -261,27 +282,36 @@ pub fn emit(event: &CEP47Event) { } => { for token_id in token_ids { let mut event = BTreeMap::new(); - event.insert("contract_package_hash", package.to_string()); + let event_id = events_count.to_string(); + event.insert("event_id", event_id.clone()); + event.insert("contract_package_hash", package.to_formatted_string()); event.insert("event_type", "cep47_mint_one".to_string()); - event.insert("recipient", recipient.to_string()); + event.insert("recipient", recipient.to_formatted_string()); event.insert("token_id", token_id.to_string()); - events.push(event); + events.push((event_id, event)); + events_count += 1; } } CEP47Event::Burn { owner, token_ids } => { for token_id in token_ids { let mut event = BTreeMap::new(); + let event_id = events_count.to_string(); + event.insert("event_id", event_id.clone()); event.insert("contract_package_hash", package.to_string()); event.insert("event_type", "cep47_burn_one".to_string()); event.insert("owner", owner.to_string()); event.insert("token_id", token_id.to_string()); - events.push(event); + events.push((event_id, event)); + events_count += 1; } } }; - for event in events { - let _: URef = storage::new_uref(event); + + let events_dict = Dict::at(EVENTS_DICT); + for (event_id, event) in events { + events_dict.set(&event_id, event); } + set_events_count(events_count); } fn get_key(name: &str) -> Option { diff --git a/test-contracts/src/dragons-nft.rs b/test-contracts/src/dragons-nft.rs index be930a5..07eb5ba 100644 --- a/test-contracts/src/dragons-nft.rs +++ b/test-contracts/src/dragons-nft.rs @@ -1,18 +1,29 @@ #![no_main] -use casper_contract::contract_api::runtime::get_named_arg; +use casper_contract::contract_api::runtime::{self, get_named_arg}; use casper_contract::contract_api::storage::create_contract_package_at_hash; #[no_mangle] pub extern "C" fn call() { - let (contract_package_hash, _) = create_contract_package_at_hash(); + let token_name: String = get_named_arg("token_name"); + let token_symbol: String = get_named_arg("token_symbol"); + let token_meta: cep47::Meta = get_named_arg("token_meta"); + + let (contract_package_hash, access_token) = create_contract_package_at_hash(); let entry_points = cep47::get_entrypoints(Some(contract_package_hash)); + cep47::deploy( - get_named_arg::("token_name"), - get_named_arg::("token_symbol"), - get_named_arg::("token_meta"), + token_name.clone(), + token_symbol, + token_meta, entry_points, contract_package_hash, false, ); + + runtime::put_key( + &format!("{}_package_hash", token_name), + contract_package_hash.into(), + ); + runtime::put_key(&format!("{}_access_token", token_name), access_token.into()); } From 81a774ac2af52337c4dd51ac4f0c5d7b99222cbf Mon Sep 17 00:00:00 2001 From: Maciej Zielinski Date: Thu, 19 Aug 2021 17:11:39 +0200 Subject: [PATCH 66/98] Remove tokens() and transfer_all_tokens(). --- cep47-logic/src/lib.rs | 64 ++--- cep47-logic/src/tests.rs | 375 ++++++++++++------------ cep47-tests/src/cep47.rs | 45 +-- cep47-tests/src/contract_tests.rs | 456 +++++++++++------------------- cep47/Cargo.toml | 3 - cep47/src/cep47_storage.rs | 85 ++---- cep47/src/data.rs | 26 -- cep47/src/entrypoints.rs | 15 - cep47/src/lib.rs | 39 +-- 9 files changed, 425 insertions(+), 683 deletions(-) diff --git a/cep47-logic/src/lib.rs b/cep47-logic/src/lib.rs index 40b699e..e170aba 100644 --- a/cep47-logic/src/lib.rs +++ b/cep47-logic/src/lib.rs @@ -18,12 +18,14 @@ use events::CEP47Event; pub type TokenId = String; pub type Meta = BTreeMap; +#[derive(Debug)] #[repr(u16)] pub enum Error { PermissionDenied = 1, ArgumentsError = 2, TokenIdAlreadyExists = 3, TokenIdDoesntExist = 4, + NotAnOwner = 5, } impl From for ApiError { @@ -68,10 +70,6 @@ pub trait CEP47Contract: WithStorage { self.storage().token_meta(token_id) } - fn tokens(&self, owner: &Key) -> Vec { - self.storage().get_tokens(owner) - } - fn is_paused(&self) -> bool { self.storage().is_paused() } @@ -145,11 +143,20 @@ pub trait CEP47Contract: WithStorage { self.mint_many(recipient, token_ids, token_metas) } - fn burn_one(&mut self, owner: &Key, token_id: TokenId) { - self.burn_many(owner, vec![token_id]); + fn burn_one(&mut self, owner: &Key, token_id: TokenId) -> Result<(), Error> { + self.burn_many(owner, vec![token_id]) } - fn burn_many(&mut self, owner: &Key, token_ids: Vec) { + fn burn_many(&mut self, owner: &Key, token_ids: Vec) -> Result<(), Error> { + for token_id in token_ids.iter() { + let token_owner = self.storage().owner_of(token_id); + if let Some(token_owner) = token_owner { + if &token_owner != owner { + return Err(Error::NotAnOwner); + } + } + } + self.storage_mut().burn_many(owner, &token_ids); // Emit burn event. @@ -157,6 +164,8 @@ pub trait CEP47Contract: WithStorage { owner: *owner, token_ids, }); + + Ok(()) } // Transfer functions. @@ -178,46 +187,25 @@ pub trait CEP47Contract: WithStorage { if self.is_paused() { return Err(Error::PermissionDenied); } - let mut sender_tokens = self.storage().get_tokens(sender); for token_id in token_ids.iter() { - if !sender_tokens.contains(token_id) { - return Err(Error::PermissionDenied); + let token_owner = self.storage().owner_of(token_id); + if let Some(token_owner) = token_owner { + if &token_owner != sender { + return Err(Error::NotAnOwner); + } } - sender_tokens.retain(|x| x != token_id); - } - let mut recipient_tokens = self.storage().get_tokens(recipient); - recipient_tokens.append(&mut token_ids.clone()); - self.storage_mut().set_tokens(sender, sender_tokens); - self.storage_mut().set_tokens(recipient, recipient_tokens); - - // Emit transfer event. - self.storage_mut().emit(CEP47Event::Transfer { - sender: *sender, - recipient: *recipient, - token_ids: token_ids.clone(), - }); - Ok(()) - } - - fn transfer_all_tokens(&mut self, sender: &Key, recipient: &Key) -> Result<(), Error> { - if self.is_paused() { - return Err(Error::PermissionDenied); } - let mut sender_tokens = self.storage().get_tokens(sender); - let mut recipient_tokens = self.storage().get_tokens(recipient); - recipient_tokens.append(&mut sender_tokens); - self.storage_mut().set_tokens(sender, sender_tokens.clone()); - self.storage_mut().set_tokens(recipient, recipient_tokens); + self.storage_mut() + .transfer_many(sender, recipient, token_ids); // Emit transfer event. self.storage_mut().emit(CEP47Event::Transfer { sender: *sender, recipient: *recipient, - token_ids: sender_tokens, + token_ids: token_ids.clone(), }); - Ok(()) } @@ -256,10 +244,8 @@ pub trait CEP47Storage { fn unpause(&mut self); // Setters - fn get_tokens(&self, owner: &Key) -> Vec; - fn set_tokens(&mut self, owner: &Key, token_ids: Vec); fn mint_many(&mut self, recipient: &Key, token_ids: &Vec, token_metas: &Vec); - // fn burn_one(&mut self, owner: &Key, token_id: &TokenId); + fn transfer_many(&mut self, sender: &Key, recipient: &Key, token_ids: &Vec); fn burn_many(&mut self, owner: &Key, token_ids: &Vec); fn update_token_metadata(&mut self, token_id: &TokenId, meta: Meta); diff --git a/cep47-logic/src/tests.rs b/cep47-logic/src/tests.rs index 25af9d6..14df69b 100644 --- a/cep47-logic/src/tests.rs +++ b/cep47-logic/src/tests.rs @@ -87,65 +87,50 @@ impl CEP47Storage for TestStorage { self.paused = false; } - fn get_tokens(&self, owner: &Key) -> Vec { - let owner_tokens = self.tokens.get(owner); - owner_tokens.cloned().unwrap_or_default() - } - - fn set_tokens(&mut self, owner: &Key, token_ids: Vec) { - let owner_new_balance = U256::from(token_ids.len() as u64); - - let owner_tokens = self.get_tokens(owner); - for token_id in owner_tokens.clone() { - self.belongs_to.remove(&token_id); - } - for token_id in token_ids.clone() { - self.belongs_to.insert(token_id, *owner); - } - - self.tokens.insert(*owner, token_ids); - self.balances.insert(*owner, owner_new_balance); - } - fn mint_many(&mut self, recipient: &Key, token_ids: &Vec, token_metas: &Vec) { - let recipient_balance = self.balances.get(recipient); - let recipient_tokens = self.tokens.get(recipient); + let amount = token_ids.len(); - let mut recipient_new_balance = recipient_balance.copied().unwrap_or_default(); - let mut recipient_new_tokens = recipient_tokens.cloned().unwrap_or_default(); + // Update balance. + let recipient_balance = self.balances.get(recipient).copied().unwrap_or_default(); + let recipient_new_balance = recipient_balance + amount; + self.balances.insert(*recipient, recipient_new_balance); + self.total_supply = self.total_supply + amount; + + // Mint tokens. for (token_id, token_meta) in token_ids.iter().zip(token_metas) { self.token_metas .insert(token_id.clone(), token_meta.clone()); - recipient_new_tokens.push(token_id.clone()); self.belongs_to.insert(token_id.clone(), *recipient); - recipient_new_balance = recipient_new_balance + 1; - self.total_supply = self.total_supply + 1; } - self.balances.insert(*recipient, recipient_new_balance); - self.tokens.insert(*recipient, recipient_new_tokens); + } + + fn transfer_many(&mut self, sender: &Key, recipient: &Key, token_ids: &Vec) { + let amount = token_ids.len(); + let sender_balance = self.balances.get(sender).copied().unwrap_or_default(); + let recipient_balance = self.balances.get(recipient).copied().unwrap_or_default(); + self.balances.insert(*sender, sender_balance - amount); + self.balances.insert(*recipient, recipient_balance + amount); + + for token_id in token_ids.iter() { + self.belongs_to.insert(token_id.clone(), *recipient); + } } fn burn_many(&mut self, owner: &Key, token_ids: &Vec) { - let owner_tokens = self.tokens.get(owner); - let owner_balance = self.balances.get(owner); + let amount = token_ids.len(); + + // Update balance. + let recipient_balance = self.balances.get(owner).copied().unwrap_or_default(); + let recipient_new_balance = recipient_balance - amount; + self.balances.insert(*owner, recipient_new_balance); + + self.total_supply = self.total_supply - amount; - let mut owner_new_balance = owner_balance.copied().unwrap_or_default(); - let mut owner_new_tokens = owner_tokens.cloned().unwrap_or_default(); - - for token_id in token_ids.clone() { - let index = owner_new_tokens - .iter() - .position(|x| *x == token_id.clone()) - .unwrap(); - owner_new_tokens.remove(index); - self.token_metas.remove(&token_id.clone()); - self.belongs_to.remove(&token_id.clone()); - owner_new_balance = owner_new_balance - 1; - self.total_supply = self.total_supply - 1; + for token_id in token_ids.iter() { + self.belongs_to.remove(token_id); + self.token_metas.remove(token_id); } - self.balances.insert(*owner, owner_new_balance); - self.tokens.insert(*owner, owner_new_tokens); } fn update_token_metadata(&mut self, token_id: &TokenId, meta: Meta) { @@ -250,112 +235,154 @@ fn test_mint_many() { let ali_pk = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); let bob_pk = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); let ali: Key = ali_pk.to_account_hash().into(); + let ali_first_token_id = "banana_01".to_string(); + let ali_second_token_id = "orange_01".to_string(); + let ali_token_ids = vec![ali_first_token_id.clone(), ali_second_token_id.clone()]; + let bob: Key = bob_pk.to_account_hash().into(); - let bob_first_token_id = "banana_01".to_string(); - let bob_second_token_id = "orange_02".to_string(); - let bob_token_ids = vec![bob_first_token_id.clone(), bob_second_token_id]; + let bob_first_token_id = "banana_02".to_string(); + let bob_second_token_id = "apple_02".to_string(); + let bob_token_ids = vec![bob_first_token_id.clone(), bob_second_token_id.clone()]; assert_eq!(contract.total_supply(), U256::from(0)); - let _: Result<(), Error> = contract.mint_many(&ali, None, vec![meta::apple()]); - let _: Result<(), Error> = contract.mint_many( - &bob, - Some(bob_token_ids.clone()), - vec![meta::banana(), meta::orange()], - ); - assert_eq!(contract.total_supply(), U256::from(3)); - - let ali_balance = contract.balance_of(&ali); - assert_eq!(ali_balance, U256::from(1)); - let bob_balance = contract.balance_of(&bob); - assert_eq!(bob_balance, U256::from(2)); + contract + .mint_many( + &ali, + Some(ali_token_ids), + vec![meta::banana(), meta::orange()], + ) + .unwrap(); + contract + .mint_many( + &bob, + Some(bob_token_ids), + vec![meta::banana(), meta::apple()], + ) + .unwrap(); + + // Check total balance. + assert_eq!(contract.total_supply(), U256::from(4)); + + // Check balances + assert_eq!(contract.balance_of(&ali), U256::from(2)); + assert_eq!(contract.balance_of(&bob), U256::from(2)); - let ali_tokens: Vec = contract.tokens(&ali); - let ali_first_token_meta: Meta = contract.token_meta(ali_tokens.get(0).unwrap()).unwrap(); - assert_eq!(ali_first_token_meta, meta::apple()); + // Check ownership + assert_eq!(&contract.owner_of(&ali_first_token_id).unwrap(), &ali); + assert_eq!(&contract.owner_of(&ali_second_token_id).unwrap(), &ali); + assert_eq!(&contract.owner_of(&bob_first_token_id).unwrap(), &bob); + assert_eq!(&contract.owner_of(&bob_second_token_id).unwrap(), &bob); - let bob_tokens: Vec = contract.tokens(&bob); - assert_eq!(bob_token_ids, bob_tokens); - let bob_first_token_meta: Meta = contract.token_meta(&bob_first_token_id).unwrap(); - assert_eq!(bob_first_token_meta, meta::banana()); + // Check metas. + assert_eq!( + contract.token_meta(&ali_first_token_id).unwrap(), + meta::banana() + ); + assert_eq!( + contract.token_meta(&ali_second_token_id).unwrap(), + meta::orange() + ); + assert_eq!( + contract.token_meta(&bob_first_token_id).unwrap(), + meta::banana() + ); + assert_eq!( + contract.token_meta(&bob_second_token_id).unwrap(), + meta::apple() + ); } + #[test] fn test_mint_copies() { let mut contract = TestContract::new(); let ali_pk = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); let ali: Key = ali_pk.to_account_hash().into(); + let token_ids: Vec = vec!["a", "b", "c", "d", "e", "f", "g"] + .into_iter() + .map(String::from) + .collect(); - assert_eq!(contract.total_supply(), U256::from(0)); - let _: Result<(), Error> = contract.mint_copies(&ali, None, meta::apple(), 7); - assert_eq!(contract.total_supply(), U256::from(7)); + contract + .mint_copies(&ali, Some(token_ids.clone()), meta::apple(), 7) + .unwrap(); - let ali_balance = contract.balance_of(&ali); - assert_eq!(ali_balance, U256::from(7)); + assert_eq!(contract.total_supply(), U256::from(7)); + assert_eq!(contract.balance_of(&ali), U256::from(7)); - let ali_tokens: Vec = contract.tokens(&ali); - let ali_first_token_meta: Meta = contract.token_meta(ali_tokens.get(0).unwrap()).unwrap(); - let ali_third_token_meta: Meta = contract.token_meta(ali_tokens.get(2).unwrap()).unwrap(); - assert_eq!(ali_first_token_meta, meta::apple()); - assert_eq!(ali_third_token_meta, meta::apple()); + for token_id in &token_ids { + assert_eq!(contract.owner_of(token_id).unwrap(), ali); + assert_eq!(contract.token_meta(token_id).unwrap(), meta::apple()); + } } + #[test] fn test_burn_many() { let mut contract = TestContract::new(); let ali_pk = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); let ali: Key = ali_pk.to_account_hash().into(); + let tokens_to_burn = vec!["a".to_string(), "b".to_string()]; + let tokens_to_remain = vec!["c".to_string(), "d".to_string(), "e".to_string()]; + let token_ids: Vec = tokens_to_burn + .iter() + .cloned() + .chain(tokens_to_remain.iter().cloned()) + .collect(); - assert_eq!(contract.total_supply(), U256::from(0)); - - let _: Result<(), Error> = contract.mint_many( - &ali, - None, - vec![meta::banana(), meta::orange(), meta::apple()], - ); - assert_eq!(contract.total_supply(), U256::from(3)); + contract + .mint_copies(&ali, Some(token_ids), meta::banana(), 5) + .unwrap(); - let ali_balance = contract.balance_of(&ali); - assert_eq!(ali_balance, U256::from(3)); + contract.burn_many(&ali, tokens_to_burn.clone()).unwrap(); - let ali_tokens: Vec = contract.tokens(&ali); - let banana = ali_tokens.get(0).unwrap().clone(); - let orange = ali_tokens.get(1).unwrap().clone(); - let apple = ali_tokens.get(2).unwrap().clone(); - - contract.burn_many(&ali, vec![banana.clone(), apple.clone()]); - let ali_tokens_after_burn = contract.tokens(&ali); - assert_eq!(ali_tokens_after_burn, vec![orange.clone()]); + // Check balances + assert_eq!(contract.total_supply(), U256::from(3)); + assert_eq!(contract.balance_of(&ali), U256::from(3)); - assert!(contract.token_meta(&banana).is_none()); - assert!(contract.token_meta(&orange).is_some()); - assert!(contract.token_meta(&apple).is_none()); + // Check burned tokens + for token_id in &tokens_to_burn { + assert!(contract.owner_of(token_id).is_none()); + assert!(contract.token_meta(token_id).is_none()); + } - assert_eq!(contract.total_supply(), U256::from(1)); - assert_eq!(contract.balance_of(&ali), U256::from(1)); + // Check rest of tokens. + for token_id in &tokens_to_remain { + assert_eq!(&contract.owner_of(token_id).unwrap(), &ali); + assert_eq!(&contract.token_meta(token_id).unwrap(), &meta::banana()); + } } + #[test] fn test_burn_one() { let mut contract = TestContract::new(); let ali_pk = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); let ali: Key = ali_pk.to_account_hash().into(); + let token_to_burn = "a".to_string(); + let tokens_to_remain = vec!["c".to_string(), "d".to_string(), "e".to_string()]; + let token_ids: Vec = vec![token_to_burn.clone()] + .iter() + .cloned() + .chain(tokens_to_remain.iter().cloned()) + .collect(); - assert_eq!(contract.total_supply(), U256::from(0)); - let _: Result<(), Error> = contract.mint_many(&ali, None, vec![meta::banana(), meta::orange()]); - assert_eq!(contract.total_supply(), U256::from(2)); + contract + .mint_copies(&ali, Some(token_ids), meta::banana(), 4) + .unwrap(); - let mut ali_balance = contract.balance_of(&ali); - assert_eq!(ali_balance, U256::from(2)); + contract.burn_one(&ali, token_to_burn.clone()).unwrap(); - let mut ali_tokens: Vec = contract.tokens(&ali); - contract.burn_one(&ali, ali_tokens.get(0).unwrap().clone()); - let mut ali_first_token_meta = contract.token_meta(ali_tokens.get(0).unwrap()); - assert_eq!(ali_first_token_meta, None); + // Check balances + assert_eq!(contract.total_supply(), U256::from(3)); + assert_eq!(contract.balance_of(&ali), U256::from(3)); - ali_tokens = contract.tokens(&ali); - ali_first_token_meta = contract.token_meta(ali_tokens.get(0).unwrap()); - assert_eq!(ali_first_token_meta, Some(meta::orange())); + // Check burned tokens + assert!(contract.owner_of(&token_to_burn).is_none()); + assert!(contract.token_meta(&token_to_burn).is_none()); - assert_eq!(contract.total_supply(), U256::from(1)); - ali_balance = contract.balance_of(&ali); - assert_eq!(ali_balance, U256::from(1)); + // Check rest of tokens. + for token_id in &tokens_to_remain { + assert_eq!(&contract.owner_of(token_id).unwrap(), &ali); + assert_eq!(&contract.token_meta(token_id).unwrap(), &meta::banana()); + } } #[test] fn test_transfer_token() { @@ -364,64 +391,21 @@ fn test_transfer_token() { let bob_pk = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); let ali: Key = ali_pk.to_account_hash().into(); let bob: Key = bob_pk.to_account_hash().into(); + let token_id: TokenId = "apple".to_string(); - assert_eq!(contract.total_supply(), U256::from(0)); - let _: Result<(), Error> = contract.mint_one(&ali, None, meta::apple()); - assert_eq!(contract.total_supply(), U256::from(1)); + contract + .mint_one(&ali, Some(token_id.clone()), meta::apple()) + .unwrap(); - let mut ali_balance = contract.balance_of(&ali); - let mut bob_balance = contract.balance_of(&bob); - assert_eq!(ali_balance, U256::from(1)); - assert_eq!(bob_balance, U256::from(0)); - - let ali_tokens: Vec = contract.tokens(&ali); - let ali_first_token_id: TokenId = ali_tokens.get(0).unwrap().clone(); - let ali_first_token_meta: Meta = contract.token_meta(&ali_first_token_id).unwrap(); - assert_eq!(ali_first_token_meta, meta::apple()); - - let transfer_res = contract.transfer_token(&ali, &bob, &ali_first_token_id); - assert!(transfer_res.is_ok()); - ali_balance = contract.balance_of(&ali); - bob_balance = contract.balance_of(&bob); - assert_eq!(ali_balance, U256::from(0)); - assert_eq!(bob_balance, U256::from(1)); - - let owner_of_first_token_id = contract.owner_of(&ali_first_token_id); - assert_eq!(owner_of_first_token_id.unwrap(), bob); -} -#[test] -fn test_transfer_all_tokens() { - let mut contract = TestContract::new(); - let ali_pk = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); - let bob_pk = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); - let ali: Key = ali_pk.to_account_hash().into(); - let bob: Key = bob_pk.to_account_hash().into(); - - assert_eq!(contract.total_supply(), U256::from(0)); - let _: Result<(), Error> = contract.mint_many(&ali, None, vec![meta::apple(), meta::banana()]); - let _: Result<(), Error> = contract.mint_one(&ali, None, meta::apple()); - assert_eq!(contract.total_supply(), U256::from(3)); - - let mut ali_balance = contract.balance_of(&ali); - let mut bob_balance = contract.balance_of(&bob); - assert_eq!(ali_balance, U256::from(3)); - assert_eq!(bob_balance, U256::from(0)); - - let ali_tokens: Vec = contract.tokens(&ali); - let ali_second_token_id: TokenId = ali_tokens.get(1).unwrap().clone(); - let ali_second_token_meta: Meta = contract.token_meta(&ali_second_token_id).unwrap(); - assert_eq!(ali_second_token_meta, meta::banana()); - - let transfer_res = contract.transfer_all_tokens(&ali, &bob); - assert!(transfer_res.is_ok()); + assert_eq!(contract.total_supply(), U256::from(1)); + assert_eq!(contract.balance_of(&ali), U256::from(1)); + assert_eq!(contract.balance_of(&bob), U256::from(0)); - ali_balance = contract.balance_of(&ali); - bob_balance = contract.balance_of(&bob); - assert_eq!(ali_balance, U256::from(0)); - assert_eq!(bob_balance, U256::from(3)); + contract.transfer_token(&ali, &bob, &token_id).unwrap(); - let owner_of_second_token_id = contract.owner_of(&ali_second_token_id); - assert_eq!(owner_of_second_token_id.unwrap(), bob); + assert_eq!(contract.balance_of(&ali), U256::from(0)); + assert_eq!(contract.balance_of(&bob), U256::from(1)); + assert_eq!(contract.owner_of(&token_id).unwrap(), bob); } #[test] @@ -431,36 +415,35 @@ fn test_transfer_many_tokens() { let bob_pk = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); let ali: Key = ali_pk.to_account_hash().into(); let bob: Key = bob_pk.to_account_hash().into(); + let tokens_to_transfer = vec!["a".to_string(), "b".to_string()]; + let tokens_to_remain = vec!["c".to_string(), "d".to_string(), "e".to_string()]; + let token_ids: Vec = tokens_to_transfer + .iter() + .cloned() + .chain(tokens_to_remain.iter().cloned()) + .collect(); + + contract + .mint_copies(&ali, Some(token_ids), meta::banana(), 5) + .unwrap(); + + contract + .transfer_many_tokens(&ali, &bob, &tokens_to_transfer) + .unwrap(); - assert_eq!(contract.total_supply(), U256::from(0)); - let _ = contract.mint_many(&ali, None, vec![meta::apple(), meta::banana()]); - let _: Result<(), Error> = contract.mint_copies(&ali, None, meta::apple(), 3); - assert_eq!(contract.total_supply(), U256::from(5)); - - assert_eq!(contract.balance_of(&ali), U256::from(5)); - assert_eq!(contract.balance_of(&bob), U256::from(0)); - - let ali_tokens: Vec = contract.tokens(&ali); - let ali_second_token_id: TokenId = ali_tokens.get(1).unwrap().clone(); - let ali_second_token_meta: Meta = contract.token_meta(&ali_second_token_id).unwrap(); - let ali_third_token_id: TokenId = ali_tokens.get(2).unwrap().clone(); - let ali_third_token_meta: Meta = contract.token_meta(&ali_third_token_id).unwrap(); - assert_eq!(ali_second_token_meta, meta::banana()); - assert_eq!(ali_third_token_meta, meta::apple()); - - let transfer_res = contract.transfer_many_tokens( - &ali, - &bob, - &vec![ali_second_token_id.clone(), ali_third_token_id.clone()], - ); - assert!(transfer_res.is_ok()); assert_eq!(contract.balance_of(&ali), U256::from(3)); assert_eq!(contract.balance_of(&bob), U256::from(2)); + assert_eq!(contract.total_supply(), U256::from(5)); - let owner_of_second_token_id = contract.owner_of(&ali_second_token_id); - let owner_of_third_token_id = contract.owner_of(&ali_third_token_id); - assert_eq!(owner_of_second_token_id.unwrap(), bob); - assert_eq!(owner_of_third_token_id.unwrap(), bob); + // Check ali tokens. + for token_id in &tokens_to_remain { + assert_eq!(&contract.owner_of(token_id).unwrap(), &ali); + } + + // Check bob tokens. + for token_id in &tokens_to_transfer { + assert_eq!(&contract.owner_of(token_id).unwrap(), &bob); + } } #[test] diff --git a/cep47-tests/src/cep47.rs b/cep47-tests/src/cep47.rs index 308c90f..37fd06e 100644 --- a/cep47-tests/src/cep47.rs +++ b/cep47-tests/src/cep47.rs @@ -24,7 +24,6 @@ pub const CONTRACT_KEY: &str = "DragonsNFT_contract"; pub const CONTRACT_HASH_KEY: &str = "DragonsNFT_contract_hash"; const BALANCES_DICT: &str = "balances"; -const OWNED_TOKENS_DICT: &str = "owned_tokens"; const TOKEN_OWNERS_DICT: &str = "owners"; const METADATA_DICT: &str = "metadata"; @@ -162,9 +161,8 @@ impl CasperCEP47Contract { self.query_contract("total_supply").unwrap() } - pub fn owner_of(&self, token_id: &TokenId) -> Key { + pub fn owner_of(&self, token_id: &TokenId) -> Option { self.query_dictionary_value::(TOKEN_OWNERS_DICT, token_id.clone()) - .unwrap() } pub fn balance_of(&self, owner: &Key) -> U256 { @@ -173,12 +171,6 @@ impl CasperCEP47Contract { value.unwrap_or_default() } - pub fn tokens(&self, owner: &Key) -> Vec { - let value: Option> = - self.query_dictionary_value(OWNED_TOKENS_DICT, Self::key_to_str(owner)); - value.unwrap_or_default() - } - pub fn token_meta(&self, token_id: &TokenId) -> Option { self.query_dictionary_value(METADATA_DICT, token_id.clone()) } @@ -203,7 +195,7 @@ impl CasperCEP47Contract { pub fn mint_copies( &mut self, - recipient: &AccountHash, + recipient: &Key, token_ids: Option<&Vec>, token_meta: &Meta, count: u32, @@ -213,7 +205,7 @@ impl CasperCEP47Contract { sender, "mint_copies", runtime_args! { - "recipient" => Key::from(*recipient), + "recipient" => *recipient, "token_ids" => token_ids.cloned(), "token_meta" => token_meta.clone(), "count" => count @@ -223,7 +215,7 @@ impl CasperCEP47Contract { pub fn mint_many( &mut self, - recipient: &AccountHash, + recipient: &Key, token_ids: Option<&Vec>, token_metas: &Vec, sender: &AccountHash, @@ -232,35 +224,30 @@ impl CasperCEP47Contract { sender, "mint_many", runtime_args! { - "recipient" => Key::from(*recipient), + "recipient" => *recipient, "token_ids" => token_ids.cloned(), "token_metas" => token_metas.clone(), }, ); } - pub fn burn_many( - &mut self, - owner: &AccountHash, - token_ids: &Vec, - sender: &AccountHash, - ) { + pub fn burn_many(&mut self, owner: &Key, token_ids: &Vec, sender: &AccountHash) { self.call( sender, "burn_many", runtime_args! { - "owner" => Key::from(*owner), + "owner" => *owner, "token_ids" => token_ids.clone() }, ); } - pub fn burn_one(&mut self, owner: &AccountHash, token_id: &TokenId, sender: &AccountHash) { + pub fn burn_one(&mut self, owner: &Key, token_id: &TokenId, sender: &AccountHash) { self.call( sender, "burn_one", runtime_args! { - "owner" => Key::from(*owner), + "owner" => *owner, "token_id" => token_id.clone() }, ); @@ -304,7 +291,7 @@ impl CasperCEP47Contract { pub fn transfer_many_tokens( &mut self, - recipient: &AccountHash, + recipient: &Key, token_ids: &Vec, sender: &AccountHash, ) { @@ -312,22 +299,12 @@ impl CasperCEP47Contract { sender, "transfer_many_tokens", runtime_args! { - "recipient" => Key::from(*recipient), + "recipient" => *recipient, "token_ids" => token_ids.clone() }, ); } - pub fn transfer_all_tokens(&mut self, recipient: &AccountHash, sender: &AccountHash) { - self.call( - sender, - "transfer_all_tokens", - runtime_args! { - "recipient" => Key::from(*recipient) - }, - ); - } - pub fn update_token_metadata(&mut self, token_id: &TokenId, meta: &Meta, sender: &AccountHash) { self.call( sender, diff --git a/cep47-tests/src/contract_tests.rs b/cep47-tests/src/contract_tests.rs index 406ae02..ba2cd88 100644 --- a/cep47-tests/src/contract_tests.rs +++ b/cep47-tests/src/contract_tests.rs @@ -45,44 +45,24 @@ fn test_token_meta() { let mut contract = CasperCEP47Contract::deploy(); let token_id = String::from("custom_token_id"); let token_meta = meta::red_dragon(); + let ali = Key::Account(contract.ali); - contract.mint_one( - &Key::Account(contract.ali), - Some(&token_id), - &token_meta, - &contract.admin.clone(), - ); - - let ali_token_meta = contract.token_meta(&token_id).unwrap(); - assert_eq!(ali_token_meta, token_meta); + contract.mint_one(&ali, Some(&token_id), &token_meta, &contract.admin.clone()); - let ali_tokens: Vec = contract.tokens(&Key::Account(contract.ali)); - assert_eq!(ali_tokens, vec![token_id]); + assert_eq!(contract.token_meta(&token_id).unwrap(), token_meta); + assert_eq!(contract.owner_of(&token_id).unwrap(), ali); } #[test] fn test_mint_one_with_random_token_id() { let mut contract = CasperCEP47Contract::deploy(); let token_meta = meta::red_dragon(); - contract.mint_one( - &Key::Account(contract.ali), - None, - &token_meta, - &contract.admin.clone(), - ); + let ali = Key::Account(contract.ali); - assert_eq!(contract.total_supply(), U256::one()); - assert_eq!( - contract.balance_of(&Key::Account(contract.ali)), - U256::one() - ); + contract.mint_one(&ali, None, &token_meta, &contract.admin.clone()); - let ali_tokens: Vec = contract.tokens(&Key::Account(contract.ali)); - assert_eq!(U256::from(ali_tokens.len() as u64), U256::one()); - assert_eq!( - contract.owner_of(&ali_tokens[0]), - Key::Account(contract.ali) - ); + assert_eq!(contract.total_supply(), U256::one()); + assert_eq!(contract.balance_of(&ali), U256::one()); } #[test] @@ -90,22 +70,13 @@ fn test_mint_one_with_set_token_id() { let mut contract = CasperCEP47Contract::deploy(); let token_id = TokenId::from("123456"); let token_meta = meta::red_dragon(); - contract.mint_one( - &Key::Account(contract.ali), - Some(&token_id), - &token_meta, - &contract.admin.clone(), - ); + let ali = Key::Account(contract.ali); + + contract.mint_one(&ali, Some(&token_id), &token_meta, &contract.admin.clone()); - let ali_tokens: Vec = contract.tokens(&Key::Account(contract.ali)); - assert_eq!(ali_tokens, vec![token_id.clone()]); assert_eq!(contract.total_supply(), U256::one()); - assert_eq!( - contract.balance_of(&Key::Account(contract.ali)), - U256::one() - ); - assert_eq!(U256::from(ali_tokens.len() as u64), U256::one()); - assert_eq!(contract.owner_of(&token_id), Key::Account(contract.ali)); + assert_eq!(contract.balance_of(&ali), U256::one()); + assert_eq!(contract.owner_of(&token_id).unwrap(), ali); } #[test] @@ -132,245 +103,185 @@ fn test_mint_one_with_not_unique_token_id() { fn test_mint_copies() { let mut contract = CasperCEP47Contract::deploy(); let token_meta = meta::gold_dragon(); + let token_ids = vec![TokenId::from("a"), TokenId::from("b")]; + let ali = Key::Account(contract.ali); contract.mint_copies( - &contract.ali.clone(), - None, + &ali, + Some(&token_ids), &token_meta, - 3, + 2, &contract.admin.clone(), ); - let ali_tokens: Vec = contract.tokens(&Key::Account(contract.ali)); - assert_eq!(contract.total_supply(), U256::from(3)); - assert_eq!( - contract.balance_of(&Key::Account(contract.ali)), - U256::from(3) - ); - assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(3)); - assert_eq!( - contract.owner_of(&ali_tokens[0]), - Key::Account(contract.ali) - ); - assert_eq!( - contract.owner_of(&ali_tokens[1]), - Key::Account(contract.ali) - ); - assert_eq!( - contract.owner_of(&ali_tokens[2]), - Key::Account(contract.ali) - ); + assert_eq!(contract.total_supply(), U256::from(2)); + assert_eq!(contract.balance_of(&ali), U256::from(2)); + + for token_id in token_ids { + assert_eq!(&contract.owner_of(&token_id).unwrap(), &ali); + assert_eq!(&contract.token_meta(&token_id).unwrap(), &token_meta); + } } #[test] fn test_mint_many() { let mut contract = CasperCEP47Contract::deploy(); - let token_metas: Vec = vec![meta::gold_dragon(), meta::red_dragon()]; + let token_metas = vec![meta::gold_dragon(), meta::black_dragon()]; + let token_ids = vec![TokenId::from("a"), TokenId::from("b")]; + let ali = Key::Account(contract.ali); contract.mint_many( - &contract.ali.clone(), - None, + &ali, + Some(&token_ids), &token_metas, &contract.admin.clone(), ); - let ali_tokens: Vec = contract.tokens(&Key::Account(contract.ali)); - assert_eq!(contract.total_supply(), U256::from(2)); - assert_eq!( - contract.balance_of(&Key::Account(contract.ali)), - U256::from(2) - ); - assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(2)); - assert_eq!( - contract.owner_of(&ali_tokens[0]), - Key::Account(contract.ali) - ); - assert_eq!( - contract.owner_of(&ali_tokens[1]), - Key::Account(contract.ali) - ); -} + assert_eq!(contract.balance_of(&ali), U256::from(2)); + for (token_id, token_meta) in token_ids.iter().zip(token_metas) { + assert_eq!(&contract.owner_of(token_id).unwrap(), &ali); + assert_eq!(&contract.token_meta(token_id).unwrap(), &token_meta); + } +} #[test] fn test_burn_many() { let mut contract = CasperCEP47Contract::deploy(); - let token_metas: Vec = vec![ - meta::gold_dragon(), - meta::blue_dragon(), - meta::black_dragon(), - meta::red_dragon(), - ]; - contract.mint_many( - &contract.ali.clone(), - None, - &token_metas, + let tokens_to_burn = vec![TokenId::from("a"), TokenId::from("b")]; + let tokens_to_keep = vec![TokenId::from("c"), TokenId::from("d"), TokenId::from("e")]; + let token_ids = tokens_to_burn + .iter() + .cloned() + .chain(tokens_to_keep.iter().cloned()) + .collect(); + let token_meta = meta::black_dragon(); + let ali = Key::Account(contract.ali); + + contract.mint_copies( + &ali, + Some(&token_ids), + &token_meta, + 5, &contract.admin.clone(), ); - let ali_tokens: Vec = contract.tokens(&Key::Account(contract.ali)); - println!("{:?}", ali_tokens); - println!("{:?}", ali_tokens.first().unwrap().clone()); + contract.burn_many(&ali, &tokens_to_burn, &contract.admin.clone()); - contract.burn_many( - &contract.ali.clone(), - &vec![ - ali_tokens.first().unwrap().clone(), - ali_tokens.last().unwrap().clone(), - ], - &contract.admin.clone(), - ); - assert_eq!(contract.total_supply(), U256::from(2)); - assert_eq!( - contract.balance_of(&Key::Account(contract.ali)), - U256::from(2) - ); + assert_eq!(contract.total_supply(), U256::from(3)); + assert_eq!(contract.balance_of(&ali), U256::from(3)); - let ali_tokens = contract.tokens(&Key::Account(contract.ali)); - println!("{:?}", ali_tokens); - assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(2)); + for token_id in tokens_to_burn { + assert!(&contract.owner_of(&token_id).is_none()); + assert!(&contract.token_meta(&token_id).is_none()); + } + + for token_id in tokens_to_keep { + assert_eq!(&contract.owner_of(&token_id).unwrap(), &ali); + assert_eq!(&contract.token_meta(&token_id).unwrap(), &token_meta); + } } #[test] fn test_burn_one() { let mut contract = CasperCEP47Contract::deploy(); - let token_metas: Vec = vec![meta::gold_dragon(), meta::red_dragon()]; - contract.mint_many( - &contract.ali.clone(), - None, - &token_metas, + let token_to_burn = TokenId::from("a"); + let tokens_to_keep = vec![TokenId::from("c"), TokenId::from("d"), TokenId::from("e")]; + let token_ids = vec![token_to_burn.clone()] + .into_iter() + .chain(tokens_to_keep.iter().cloned()) + .collect(); + let token_meta = meta::black_dragon(); + let ali = Key::Account(contract.ali); + + contract.mint_copies( + &ali, + Some(&token_ids), + &token_meta, + 4, &contract.admin.clone(), ); - let ali_tokens = contract.tokens(&Key::Account(contract.ali)); + contract.burn_one(&ali, &token_to_burn, &contract.admin.clone()); - contract.burn_one( - &contract.ali.clone(), - ali_tokens.first().unwrap(), - &contract.admin.clone(), - ); - assert_eq!(contract.total_supply(), U256::from(1)); - assert_eq!( - contract.balance_of(&Key::Account(contract.ali)), - U256::from(1) - ); + assert_eq!(contract.total_supply(), U256::from(3)); + assert_eq!(contract.balance_of(&ali), U256::from(3)); + + assert!(&contract.owner_of(&token_to_burn).is_none()); + assert!(&contract.token_meta(&token_to_burn).is_none()); - let ali_tokens = contract.tokens(&Key::Account(contract.ali)); - assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(1)); + for token_id in tokens_to_keep { + assert_eq!(&contract.owner_of(&token_id).unwrap(), &ali); + assert_eq!(&contract.token_meta(&token_id).unwrap(), &token_meta); + } } #[test] fn test_transfer_token() { let mut contract = CasperCEP47Contract::deploy(); - let token_metas: Vec = vec![meta::gold_dragon(), meta::blue_dragon()]; - contract.mint_many( - &contract.ali.clone(), - None, - &token_metas, + let token_to_transfer = TokenId::from("a"); + let tokens_to_keep = vec![TokenId::from("c"), TokenId::from("d"), TokenId::from("e")]; + let token_ids = vec![token_to_transfer.clone()] + .into_iter() + .chain(tokens_to_keep.iter().cloned()) + .collect(); + let token_meta = meta::black_dragon(); + let ali = Key::Account(contract.ali); + let bob = Key::Account(contract.bob); + + contract.mint_copies( + &ali, + Some(&token_ids), + &token_meta, + 4, &contract.admin.clone(), ); - let ali_tokens: Vec = contract.tokens(&Key::Account(contract.ali)); + contract.transfer_token(&bob, &token_to_transfer, &contract.ali.clone()); - contract.transfer_token( - &Key::Account(contract.bob), - &ali_tokens[1], - &contract.ali.clone(), - ); + assert_eq!(contract.total_supply(), U256::from(4)); + assert_eq!(contract.balance_of(&ali), U256::from(3)); + assert_eq!(contract.balance_of(&bob), U256::from(1)); + assert_eq!(&contract.owner_of(&token_to_transfer).unwrap(), &bob); - assert_eq!( - contract.balance_of(&Key::Account(contract.ali)), - U256::from(1) - ); - assert_eq!( - contract.balance_of(&Key::Account(contract.bob)), - U256::from(1) - ); - assert_eq!(contract.total_supply(), U256::from(2)); - assert_eq!( - contract.owner_of(&ali_tokens[0]), - Key::Account(contract.ali) - ); - assert_eq!( - contract.owner_of(&ali_tokens[1]), - Key::Account(contract.bob) - ); + for token_id in tokens_to_keep { + assert_eq!(&contract.owner_of(&token_id).unwrap(), &ali); + } } #[test] fn test_transfer_many_tokens() { let mut contract = CasperCEP47Contract::deploy(); - let token_metas: Vec = vec![ - meta::gold_dragon(), - meta::black_dragon(), - meta::black_dragon(), - ]; - contract.mint_many( - &contract.ali.clone(), - None, - &token_metas, - &contract.admin.clone(), - ); - let ali_tokens: Vec = contract.tokens(&Key::Account(contract.ali)); - contract.transfer_many_tokens( - &contract.bob.clone(), - &ali_tokens[..2].to_vec(), - &contract.ali.clone(), - ); + let tokens_to_transfer = vec![TokenId::from("a"), TokenId::from("b")]; + let tokens_to_keep = vec![TokenId::from("c"), TokenId::from("d"), TokenId::from("e")]; + let token_ids = tokens_to_transfer + .iter() + .cloned() + .chain(tokens_to_keep.iter().cloned()) + .collect(); + let token_meta = meta::black_dragon(); + let ali = Key::Account(contract.ali); + let bob = Key::Account(contract.bob); - assert_eq!( - contract.balance_of(&Key::Account(contract.ali)), - U256::from(1) - ); - assert_eq!( - contract.balance_of(&Key::Account(contract.bob)), - U256::from(2) - ); - assert_eq!(contract.total_supply(), U256::from(3)); - assert_eq!( - contract.owner_of(&ali_tokens[0]), - Key::Account(contract.bob) - ); - assert_eq!( - contract.owner_of(&ali_tokens[1]), - Key::Account(contract.bob) - ); - assert_eq!( - contract.owner_of(&ali_tokens[2]), - Key::Account(contract.ali) - ); -} - -#[test] -fn test_transfer_all_tokens() { - let mut contract = CasperCEP47Contract::deploy(); - let token_metas: Vec = vec![meta::gold_dragon(), meta::blue_dragon()]; - contract.mint_many( - &contract.ali.clone(), - None, - &token_metas, + contract.mint_copies( + &ali, + Some(&token_ids), + &token_meta, + 5, &contract.admin.clone(), ); - let ali_tokens: Vec = contract.tokens(&Key::Account(contract.ali)); + contract.transfer_many_tokens(&bob, &tokens_to_transfer, &contract.ali.clone()); - contract.transfer_all_tokens(&contract.bob.clone(), &contract.ali.clone()); - assert_eq!( - contract.balance_of(&Key::Account(contract.ali)), - U256::from(0) - ); - assert_eq!( - contract.balance_of(&Key::Account(contract.bob)), - U256::from(2) - ); - assert_eq!(contract.total_supply(), U256::from(2)); + assert_eq!(contract.total_supply(), U256::from(5)); + assert_eq!(contract.balance_of(&ali), U256::from(3)); + assert_eq!(contract.balance_of(&bob), U256::from(2)); - assert_eq!( - contract.owner_of(&ali_tokens[0]), - Key::Account(contract.bob) - ); - assert_eq!( - contract.owner_of(&ali_tokens[1]), - Key::Account(contract.bob) - ); + for token_id in tokens_to_keep { + assert_eq!(&contract.owner_of(&token_id).unwrap(), &ali); + } + + for token_id in tokens_to_transfer { + assert_eq!(&contract.owner_of(&token_id).unwrap(), &bob); + } } #[test] @@ -396,92 +307,69 @@ fn test_contract_owning_token() { contract.deploy_secondary_contract("owning-contract.wasm", runtime_args! {}); let token_id = TokenId::from("123456"); let token_meta = meta::red_dragon(); - let owning_hash_key = Key::Hash(package); + let contract_address = Key::Hash(package); + let ali = Key::Account(contract.ali); + contract.mint_one( - &owning_hash_key, + &contract_address, Some(&token_id), &token_meta, &contract.admin.clone(), ); assert_eq!(contract.total_supply(), U256::from(1)); - assert_eq!(contract.balance_of(&owning_hash_key), U256::from(1)); + assert_eq!(contract.balance_of(&contract_address), U256::from(1)); + assert_eq!(&contract.owner_of(&token_id).unwrap(), &contract_address); - let contracts_tokens: Vec = contract.tokens(&owning_hash_key); - assert_eq!(contract.owner_of(&contracts_tokens[0]), owning_hash_key); - - let admin = contract.admin; - let ali = Key::Account(contract.ali.to_owned()); - contract.transfer_token_from_contract(&admin, &contract_hash, &ali, &token_id); + contract.transfer_token_from_contract(&contract.admin.clone(), &contract_hash, &ali, &token_id); - assert_eq!(contract.balance_of(&owning_hash_key), U256::from(0)); - assert_eq!( - contract.balance_of(&Key::Account(contract.ali)), - U256::from(1) - ); + assert_eq!(contract.balance_of(&contract_address), U256::from(0)); + assert_eq!(contract.balance_of(&ali), U256::from(1)); + assert_eq!(&contract.owner_of(&token_id).unwrap(), &ali); } #[test] #[should_panic = "ApiError::User(1)"] -fn test_pausing_contract() { +fn test_transfer_when_paused() { let mut contract = CasperCEP47Contract::deploy(); - let token_metas: Vec = vec![meta::gold_dragon(), meta::red_dragon()]; - contract.mint_many( - &contract.ali.clone(), - None, - &token_metas, + let token_id = TokenId::from("123456"); + let ali = Key::Account(contract.ali); + let bob = Key::Account(contract.bob); + + contract.mint_one( + &ali, + Some(&token_id), + &meta::black_dragon(), &contract.admin.clone(), ); contract.pause(&contract.admin.clone()); - let ali_tokens = contract.tokens(&Key::Account(contract.ali)); // Test panics here, since contract is paused and a generic user is trying to call a non-admin function - contract.transfer_token( - &Key::Account(contract.bob), - &ali_tokens[1], - &contract.ali.clone(), - ); + contract.transfer_token(&bob, &token_id, &contract.ali.clone()); } - #[test] fn test_pausing_and_unpausing_contract() { let mut contract = CasperCEP47Contract::deploy(); - let token_metas: Vec = vec![meta::gold_dragon(), meta::red_dragon()]; - contract.mint_many( - &contract.ali.clone(), - None, - &token_metas, - &contract.admin.clone(), - ); - // deployer can pause the contract - contract.pause(&contract.admin.clone()); + let token_id = TokenId::from("123456"); + let ali = Key::Account(contract.ali); + let bob = Key::Account(contract.bob); + let admin = contract.admin; + + contract.pause(&admin); + contract.mint_one(&ali, Some(&token_id), &meta::black_dragon(), &admin); + + assert_eq!(contract.balance_of(&ali), U256::from(1)); - let ali_tokens = contract.tokens(&Key::Account(contract.ali)); // admin functions still work even while paused - contract.burn_one( - &contract.ali.clone(), - &ali_tokens[1], - &contract.admin.clone(), - ); - // only deployer can unpause - contract.unpause(&contract.admin.clone()); - // then normal function can continue - contract.transfer_token( - &Key::Account(contract.bob), - &ali_tokens[0], - &contract.ali.clone(), - ); + contract.burn_one(&ali, &token_id, &admin); + contract.mint_one(&bob, Some(&token_id), &meta::black_dragon(), &admin); - assert_eq!(contract.total_supply(), U256::from(1)); - assert_eq!( - contract.balance_of(&Key::Account(contract.ali)), - U256::from(0) - ); + assert_eq!(contract.balance_of(&ali), U256::from(0)); + assert_eq!(contract.balance_of(&bob), U256::from(1)); - let ali_tokens = contract.tokens(&Key::Account(contract.ali)); - let bob_tokens = contract.tokens(&Key::Account(contract.bob)); - assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(0)); - assert_eq!(U256::from(bob_tokens.len() as u64), U256::from(1)); + // Transfer works after unpausing. + contract.unpause(&admin); + contract.transfer_token(&ali, &token_id, &contract.bob.clone()); } #[test] diff --git a/cep47/Cargo.toml b/cep47/Cargo.toml index fc0a308..c5fe8dd 100644 --- a/cep47/Cargo.toml +++ b/cep47/Cargo.toml @@ -21,8 +21,6 @@ no_meta = [] no_balance_of = [] no_owner_of = [] no_total_supply = [] -no_token_uri = [] -no_tokens = [] no_is_paused = [] no_pause = [] no_unpause = [] @@ -33,5 +31,4 @@ no_burn_many = [] no_burn_one = [] no_transfer_token = [] no_transfer_many_tokens = [] -no_transfer_all_tokens = [] no_update_token_metadata = [] \ No newline at end of file diff --git a/cep47/src/cep47_storage.rs b/cep47/src/cep47_storage.rs index c496451..a5c1f76 100644 --- a/cep47/src/cep47_storage.rs +++ b/cep47/src/cep47_storage.rs @@ -2,7 +2,7 @@ use casper_contract::{contract_api::runtime, unwrap_or_revert::UnwrapOrRevert}; use casper_types::{bytesrepr::ToBytes, ApiError, Key, U256}; use cep47_logic::{CEP47Storage, Meta, TokenId}; -use crate::data::{self, Balances, Metadata, OwnedTokens, Owners}; +use crate::data::{self, Balances, Metadata, Owners}; #[derive(Default)] pub struct CasperCEP47Storage {} @@ -53,44 +53,12 @@ impl CEP47Storage for CasperCEP47Storage { data::unpause(); } - fn get_tokens(&self, owner: &Key) -> Vec { - OwnedTokens::instance().get(owner) - } - - fn set_tokens(&mut self, owner: &Key, token_ids: Vec) { - // Prepare dictionaries. - let owners_dict = Owners::instance(); - let owned_tokens_dict = OwnedTokens::instance(); - let balances_dict = Balances::instance(); - - // Update the owner for each token. - for token_id in &token_ids { - owners_dict.set(token_id, *owner); - } - - // Update balance of the owner. - let prev_balance = balances_dict.get(owner); - let new_balance = U256::from(token_ids.len() as u64); - balances_dict.set(owner, new_balance); - - // Update owner's list of tokens. - owned_tokens_dict.set(owner, token_ids); - - // Update total_supply. - let new_total_supply = data::total_supply() - prev_balance + new_balance; - data::update_total_supply(new_total_supply); - } - fn mint_many(&mut self, recipient: &Key, token_ids: &Vec, token_metas: &Vec) { // Prepare dictionaries. let owners_dict = Owners::instance(); - let owned_tokens_dict = OwnedTokens::instance(); let balances_dict = Balances::instance(); let metadata_dict = Metadata::instance(); - // Load recipient's tokens. - let mut recipient_tokens = owned_tokens_dict.get(recipient); - // Create new tokens. for (token_id, token_meta) in token_ids.iter().zip(token_metas) { // Set metadata. @@ -98,14 +66,8 @@ impl CEP47Storage for CasperCEP47Storage { // Set token owner. owners_dict.set(token_id, *recipient); - - // Update current list of recipient's tokens. - recipient_tokens.push(token_id.clone()); } - // Update owned tokens. - owned_tokens_dict.set(recipient, recipient_tokens); - // Update recipient's balance. let new_tokens_count: U256 = token_ids.len().into(); let prev_balance = balances_dict.get(recipient); @@ -117,42 +79,47 @@ impl CEP47Storage for CasperCEP47Storage { data::update_total_supply(new_total_supply); } + fn transfer_many(&mut self, sender: &Key, recipient: &Key, token_ids: &Vec) { + // Prepare dictionaries. + let owners_dict = Owners::instance(); + let balances_dict = Balances::instance(); + + // Update ownerships. + for token_id in token_ids { + owners_dict.set(token_id, *recipient); + } + + // Update balances. + let amount = token_ids.len(); + let sender_balance = balances_dict.get(sender); + let recipient_balance = balances_dict.get(recipient); + balances_dict.set(sender, sender_balance - amount); + balances_dict.set(recipient, recipient_balance + amount); + } + fn burn_many(&mut self, owner: &Key, token_ids: &Vec) { // Prepare dictionaries. let owners_dict = Owners::instance(); - let owned_tokens_dict = OwnedTokens::instance(); let balances_dict = Balances::instance(); let metadata_dict = Metadata::instance(); - // Load owner's tokens. - let mut owner_tokens = owned_tokens_dict.get(owner); - // Remove tokens. for token_id in token_ids { - // Remove token from the owner's list. - // Make sure that token is owned by the recipient. - let index = owner_tokens - .iter() - .position(|x| x == token_id) - .unwrap_or_revert(); - owner_tokens.remove(index); - - // TODO: Remove meta. + // Remove meta. metadata_dict.remove(token_id); - // TODO: Remove ownership. + // Remove ownership. owners_dict.remove(token_id); } // Decrement owner's balance. - balances_dict.set(owner, owner_tokens.len().into()); - - // Update owner's tokens. - owned_tokens_dict.set(owner, owner_tokens); + let amount: U256 = token_ids.len().into(); + let prev_balance = balances_dict.get(owner); + let new_balance = prev_balance - amount; + balances_dict.set(owner, new_balance); // Decrement total supply. - let remove_tokens_count: U256 = token_ids.len().into(); - let new_total_supply = data::total_supply() - remove_tokens_count; + let new_total_supply = data::total_supply() - amount; data::update_total_supply(new_total_supply); } diff --git a/cep47/src/data.rs b/cep47/src/data.rs index 3cc52c8..889c548 100644 --- a/cep47/src/data.rs +++ b/cep47/src/data.rs @@ -15,7 +15,6 @@ use casper_types::{ use cep47_logic::{events::CEP47Event, Meta, TokenId}; const BALANCES_DICT: &str = "balances"; -const OWNED_TOKENS_DICT: &str = "owned_tokens"; const TOKEN_OWNERS_DICT: &str = "owners"; const METADATA_DICT: &str = "metadata"; const EVENTS_DICT: &str = "events"; @@ -70,30 +69,6 @@ impl Balances { // } } -pub struct OwnedTokens { - dict: Dict, -} - -impl OwnedTokens { - pub fn instance() -> OwnedTokens { - OwnedTokens { - dict: Dict::at(OWNED_TOKENS_DICT), - } - } - - pub fn get(&self, key: &Key) -> Vec { - self.dict.get(&key_to_str(key)).unwrap_or_default() - } - - pub fn set(&self, key: &Key, value: Vec) { - self.dict.set(&key_to_str(key), value); - } - - // pub fn remove(&self, key: &Key) { - // self.dict.remove::(&key_to_str(key)); - // } -} - pub struct Owners { dict: Dict, } @@ -217,7 +192,6 @@ pub fn initial_named_keys( // Add empty dictionaries. add_empty_dict(&mut named_keys, BALANCES_DICT); - add_empty_dict(&mut named_keys, OWNED_TOKENS_DICT); add_empty_dict(&mut named_keys, TOKEN_OWNERS_DICT); add_empty_dict(&mut named_keys, METADATA_DICT); add_empty_dict(&mut named_keys, EVENTS_DICT); diff --git a/cep47/src/entrypoints.rs b/cep47/src/entrypoints.rs index 396bb72..d427821 100644 --- a/cep47/src/entrypoints.rs +++ b/cep47/src/entrypoints.rs @@ -61,12 +61,6 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints CLType::Option(Box::new(CLType::String)), None, )); - entry_points.add_entry_point(endpoint( - "tokens", - vec![Parameter::new("owner", CLType::Key)], - CLType::List(Box::new(CLType::String)), - None, - )); entry_points.add_entry_point(endpoint( "total_supply", vec![Parameter::new("owner", CLType::Key)], @@ -157,15 +151,6 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints CLType::Unit, None, )); - entry_points.add_entry_point(endpoint( - "transfer_all_tokens", - vec![ - Parameter::new("sender", CLType::Key), - Parameter::new("recipient", CLType::Key), - ], - CLType::Unit, - None, - )); entry_points } diff --git a/cep47/src/lib.rs b/cep47/src/lib.rs index 11671c5..6b37cd2 100644 --- a/cep47/src/lib.rs +++ b/cep47/src/lib.rs @@ -41,7 +41,7 @@ mod entrypoints; pub use cep47_storage::CasperCEP47Storage; pub use entrypoints::get_entrypoints; -use data::{Balances, Metadata, OwnedTokens, Owners}; +use data::{Balances, Metadata, Owners}; #[derive(Default)] pub struct CasperCEP47Contract { @@ -119,14 +119,6 @@ pub extern "C" fn token_meta() { ret(contract.token_meta(&token_id)) } -#[cfg(not(feature = "no_tokens"))] -#[no_mangle] -pub extern "C" fn tokens() { - let owner: Key = runtime::get_named_arg("owner"); - let contract = CasperCEP47Contract::new(); - ret(contract.tokens(&owner)) -} - #[cfg(not(feature = "no_is_paused"))] #[no_mangle] pub extern "C" fn is_paused() { @@ -191,7 +183,7 @@ pub extern "C" fn burn_many() { let owner: Key = runtime::get_named_arg("owner"); let token_ids: Vec = runtime::get_named_arg("token_ids"); let mut contract = CasperCEP47Contract::new(); - contract.burn_many(&owner, token_ids); + contract.burn_many(&owner, token_ids).unwrap_or_revert(); } #[cfg(not(feature = "no_burn_one"))] @@ -200,7 +192,7 @@ pub extern "C" fn burn_one() { let owner: Key = runtime::get_named_arg("owner"); let token_id: TokenId = runtime::get_named_arg("token_id"); let mut contract = CasperCEP47Contract::new(); - contract.burn_one(&owner, token_id); + contract.burn_one(&owner, token_id).unwrap_or_revert(); } #[cfg(not(feature = "no_transfer_token"))] @@ -210,8 +202,9 @@ pub extern "C" fn transfer_token() { let recipient: Key = runtime::get_named_arg("recipient"); let token_id: TokenId = runtime::get_named_arg("token_id"); let mut contract = CasperCEP47Contract::new(); - let res = contract.transfer_token(&sender, &recipient, &token_id); - res.unwrap_or_revert(); + contract + .transfer_token(&sender, &recipient, &token_id) + .unwrap_or_revert(); } #[cfg(not(feature = "no_transfer_many_tokens"))] @@ -221,18 +214,9 @@ pub extern "C" fn transfer_many_tokens() { let recipient: Key = runtime::get_named_arg("recipient"); let token_ids: Vec = runtime::get_named_arg("token_ids"); let mut contract = CasperCEP47Contract::new(); - let res = contract.transfer_many_tokens(&sender, &recipient, &token_ids); - res.unwrap_or_revert(); -} - -#[cfg(not(feature = "no_transfer_all_tokens"))] -#[no_mangle] -pub extern "C" fn transfer_all_tokens() { - let sender: Key = get_caller(); - let recipient: Key = runtime::get_named_arg("recipient"); - let mut contract = CasperCEP47Contract::new(); - let res = contract.transfer_all_tokens(&sender, &recipient); - res.unwrap_or_revert(); + contract + .transfer_many_tokens(&sender, &recipient, &token_ids) + .unwrap_or_revert(); } #[cfg(not(feature = "no_update_token_metadata"))] @@ -241,8 +225,9 @@ pub extern "C" fn update_token_metadata() { let token_id: TokenId = runtime::get_named_arg("token_id"); let meta: Meta = runtime::get_named_arg("token_meta"); let mut contract = CasperCEP47Contract::new(); - let res = contract.update_token_metadata(token_id, meta); - res.unwrap_or_revert(); + contract + .update_token_metadata(token_id, meta) + .unwrap_or_revert(); } pub fn deploy( From 4940b9eb59b9351aa098ac025646acaa05da036e Mon Sep 17 00:00:00 2001 From: astro019 Date: Fri, 20 Aug 2021 13:28:19 +1000 Subject: [PATCH 67/98] wip: reorganize cep47 lib --- .DS_Store | Bin 0 -> 6148 bytes Cargo.lock | 97 ++-- Cargo.toml | 5 +- Makefile | 11 +- cep47-logic/Cargo.toml | 12 - cep47-logic/src/lib.rs | 271 ---------- cep47-logic/src/tests.rs | 477 ------------------ cep47-tests/Cargo.toml | 13 +- cep47-tests/src/cep47.rs | 300 ----------- cep47-tests/src/cep47_instance.rs | 233 +++++++++ cep47-tests/src/cep47_tests.rs | 476 +++++++++++++++++ cep47-tests/src/contract_tests.rs | 311 ------------ cep47-tests/src/lib.rs | 4 +- cep47-tests/wasm/.gitkeep | 0 cep47/Cargo.toml | 39 +- cep47/bin/cep47_token.rs | 352 +++++++++++++ cep47/src/cep47.rs | 332 ++++++++++++ cep47/src/cep47_storage.rs | 198 -------- cep47/src/data.rs | 347 ++++++------- cep47/src/entrypoints.rs | 188 ------- .../src/events.rs => cep47/src/event.rs | 26 +- cep47/src/lib.rs | 302 +---------- test-contracts/Cargo.toml | 21 - test-contracts/src/dragons-nft.rs | 18 - utils/contract-utils/Cargo.toml | 11 + utils/contract-utils/src/admin_control.rs | 63 +++ utils/contract-utils/src/contract_context.rs | 34 ++ utils/contract-utils/src/contract_storage.rs | 21 + utils/contract-utils/src/data.rs | 121 +++++ utils/contract-utils/src/lib.rs | 14 + utils/test-env/Cargo.toml | 13 + utils/test-env/src/lib.rs | 7 + utils/test-env/src/test_contract.rs | 61 +++ utils/test-env/src/test_env.rs | 120 +++++ 34 files changed, 2109 insertions(+), 2389 deletions(-) create mode 100644 .DS_Store delete mode 100644 cep47-logic/Cargo.toml delete mode 100644 cep47-logic/src/lib.rs delete mode 100644 cep47-logic/src/tests.rs delete mode 100644 cep47-tests/src/cep47.rs create mode 100644 cep47-tests/src/cep47_instance.rs create mode 100644 cep47-tests/src/cep47_tests.rs delete mode 100644 cep47-tests/src/contract_tests.rs delete mode 100644 cep47-tests/wasm/.gitkeep create mode 100644 cep47/bin/cep47_token.rs create mode 100644 cep47/src/cep47.rs delete mode 100644 cep47/src/cep47_storage.rs delete mode 100644 cep47/src/entrypoints.rs rename cep47-logic/src/events.rs => cep47/src/event.rs (71%) delete mode 100644 test-contracts/Cargo.toml delete mode 100644 test-contracts/src/dragons-nft.rs create mode 100644 utils/contract-utils/Cargo.toml create mode 100644 utils/contract-utils/src/admin_control.rs create mode 100644 utils/contract-utils/src/contract_context.rs create mode 100644 utils/contract-utils/src/contract_storage.rs create mode 100644 utils/contract-utils/src/data.rs create mode 100644 utils/contract-utils/src/lib.rs create mode 100644 utils/test-env/Cargo.toml create mode 100644 utils/test-env/src/lib.rs create mode 100644 utils/test-env/src/test_contract.rs create mode 100644 utils/test-env/src/test_env.rs diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0/dev/null | true test-only: - cargo test -p cep47-logic cargo test -p cep47-tests copy-wasm-file-to-test: - mkdir -p cep47-tests/wasm cp target/wasm32-unknown-unknown/release/*.wasm cep47-tests/wasm test: build-contract copy-wasm-file-to-test test-only clippy: - cargo clippy --all-targets --all -- -A clippy::ptr_arg + cargo clippy --all-targets --all -- -D warnings check-lint: clippy cargo fmt --all -- --check -format: +lint: clippy cargo fmt --all -lint: clippy format - clean: cargo clean rm -rf cep47-tests/wasm/*.wasm diff --git a/cep47-logic/Cargo.toml b/cep47-logic/Cargo.toml deleted file mode 100644 index 171bd5f..0000000 --- a/cep47-logic/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "cep47-logic" -version = "0.1.0" -authors = ["Maciej Zielinski "] -edition = "2018" - -[dependencies] -casper-types = "1.3.1" - -[dev-dependencies] -rand = "0.7.3" -maplit = "1.0.2" \ No newline at end of file diff --git a/cep47-logic/src/lib.rs b/cep47-logic/src/lib.rs deleted file mode 100644 index 4131719..0000000 --- a/cep47-logic/src/lib.rs +++ /dev/null @@ -1,271 +0,0 @@ -#![allow(dead_code)] -#![allow(unused_imports)] - -use std::collections::BTreeMap; - -use casper_types::{ApiError, AsymmetricType, ContractPackageHash, Key, URef, U256}; - -#[cfg(test)] -#[macro_use] -extern crate maplit; - -pub mod events; -#[cfg(test)] -pub mod tests; - -use events::CEP47Event; - -pub type TokenId = String; -pub type Meta = BTreeMap; - -#[repr(u16)] -pub enum Error { - PermissionDenied = 1, - ArgumentsError = 2, - TokenIdAlreadyExists = 3, - TokenIdDoesntExist = 4, -} - -impl From for ApiError { - fn from(error: Error) -> ApiError { - ApiError::User(error as u16) - } -} - -pub trait WithStorage { - fn storage(&self) -> &Storage; - fn storage_mut(&mut self) -> &mut Storage; -} - -pub trait CEP47Contract: WithStorage { - // Metadata - fn name(&self) -> String { - self.storage().name() - } - - fn symbol(&self) -> String { - self.storage().symbol() - } - - fn meta(&self) -> Meta { - self.storage().meta() - } - - // Getters - fn balance_of(&self, owner: &Key) -> U256 { - self.storage().balance_of(owner) - } - - fn owner_of(&self, token_id: &TokenId) -> Option { - self.storage().onwer_of(token_id) - } - - fn total_supply(&self) -> U256 { - self.storage().total_supply() - } - - fn token_meta(&self, token_id: &TokenId) -> Option { - self.storage().token_meta(token_id) - } - - fn tokens(&self, owner: &Key) -> Vec { - self.storage().get_tokens(owner) - } - - fn is_paused(&self) -> bool { - self.storage().is_paused() - } - - fn pause(&mut self) { - self.storage_mut().pause(); - } - - fn unpause(&mut self) { - self.storage_mut().unpause(); - } - - // Minter function. - // Guarded by the entrypoint group. - fn mint_one( - &mut self, - recipient: &Key, - token_id: Option, - token_meta: Meta, - ) -> Result<(), Error> { - self.mint_many(recipient, token_id.map(|id| vec![id]), vec![token_meta]) - } - - fn mint_many( - &mut self, - recipient: &Key, - token_ids: Option>, - token_metas: Vec, - ) -> Result<(), Error> { - let unique_token_ids = match token_ids { - // Validate token_ids and metas. - Some(token_ids) => { - if token_ids.len() != token_metas.len() { - return Err(Error::ArgumentsError); - }; - let valid = self.storage().validate_token_ids(&token_ids); - if !valid { - return Err(Error::TokenIdAlreadyExists); - }; - Ok(token_ids) - } - None => Ok(self.storage_mut().gen_token_ids(token_metas.len() as u32)), - }; - - unique_token_ids.map(|token_ids| { - // Mint tokens. - self.storage_mut() - .mint_many(recipient, &token_ids, &token_metas); - - // Emit event. - self.storage_mut().emit(CEP47Event::Mint { - recipient: *recipient, - token_ids, - }); - }) - } - - fn mint_copies( - &mut self, - recipient: &Key, - token_ids: Option>, - token_meta: Meta, - count: u32, - ) -> Result<(), Error> { - if let Some(token_ids) = &token_ids { - if token_ids.len() != count as usize { - return Err(Error::ArgumentsError); - }; - }; - let token_metas = vec![token_meta; count as usize]; - self.mint_many(recipient, token_ids, token_metas) - } - - fn burn_one(&mut self, owner: &Key, token_id: TokenId) { - self.storage_mut().burn_many(owner, &vec![token_id]); - } - - fn burn_many(&mut self, owner: &Key, token_ids: Vec) { - self.storage_mut().burn_many(owner, &token_ids); - - // Emit burn event. - self.storage_mut().emit(CEP47Event::Burn { - owner: *owner, - token_ids, - }); - } - - // Transfer functions. - fn transfer_token( - &mut self, - sender: &Key, - recipient: &Key, - token_id: &TokenId, - ) -> Result<(), Error> { - self.transfer_many_tokens(sender, recipient, &vec![token_id.clone()]) - } - - fn transfer_many_tokens( - &mut self, - sender: &Key, - recipient: &Key, - token_ids: &Vec, - ) -> Result<(), Error> { - if self.is_paused() { - return Err(Error::PermissionDenied); - } - let mut sender_tokens = self.storage().get_tokens(sender); - - for token_id in token_ids.iter() { - if !sender_tokens.contains(token_id) { - return Err(Error::PermissionDenied); - } - sender_tokens.retain(|x| x != token_id); - } - let mut recipient_tokens = self.storage().get_tokens(recipient); - recipient_tokens.append(&mut token_ids.clone()); - self.storage_mut().set_tokens(sender, sender_tokens); - self.storage_mut().set_tokens(recipient, recipient_tokens); - - // Emit transfer event. - self.storage_mut().emit(CEP47Event::Transfer { - sender: *sender, - recipient: *recipient, - token_ids: token_ids.clone(), - }); - Ok(()) - } - - fn transfer_all_tokens(&mut self, sender: &Key, recipient: &Key) -> Result<(), Error> { - if self.is_paused() { - return Err(Error::PermissionDenied); - } - let mut sender_tokens = self.storage().get_tokens(sender); - let mut recipient_tokens = self.storage().get_tokens(recipient); - recipient_tokens.append(&mut sender_tokens); - - self.storage_mut().set_tokens(sender, sender_tokens.clone()); - self.storage_mut().set_tokens(recipient, recipient_tokens); - - // Emit transfer event. - self.storage_mut().emit(CEP47Event::Transfer { - sender: *sender, - recipient: *recipient, - token_ids: sender_tokens, - }); - - Ok(()) - } - - fn update_token_metadata(&mut self, token_id: TokenId, meta: Meta) -> Result<(), Error> { - // Assert token exists. - if self.owner_of(&token_id).is_none() { - return Err(Error::TokenIdDoesntExist); - }; - - // Update the storage. - self.storage_mut().update_token_metadata(&token_id, meta); - - // Emit token update event. - self.storage_mut() - .emit(CEP47Event::MetadataUpdate { token_id }); - - Ok(()) - } -} - -pub trait CEP47Storage { - // Metadata. - fn name(&self) -> String; - fn symbol(&self) -> String; - fn meta(&self) -> Meta; - - // Getters - fn balance_of(&self, owner: &Key) -> U256; - fn onwer_of(&self, token_id: &TokenId) -> Option; - fn total_supply(&self) -> U256; - fn token_meta(&self, token_id: &TokenId) -> Option; - - // Controls - fn is_paused(&self) -> bool; - fn pause(&mut self); - fn unpause(&mut self); - - // Setters - fn get_tokens(&self, owner: &Key) -> Vec; - fn set_tokens(&mut self, owner: &Key, token_ids: Vec); - fn mint_many(&mut self, recipient: &Key, token_ids: &Vec, token_metas: &Vec); - // fn burn_one(&mut self, owner: &Key, token_id: &TokenId); - fn burn_many(&mut self, owner: &Key, token_ids: &Vec); - fn update_token_metadata(&mut self, token_id: &TokenId, meta: Meta); - - fn gen_token_ids(&mut self, n: u32) -> Vec; - fn validate_token_ids(&self, token_ids: &Vec) -> bool; - - fn emit(&mut self, event: CEP47Event); - fn contact_package_hash(&self) -> ContractPackageHash; -} diff --git a/cep47-logic/src/tests.rs b/cep47-logic/src/tests.rs deleted file mode 100644 index cc80a37..0000000 --- a/cep47-logic/src/tests.rs +++ /dev/null @@ -1,477 +0,0 @@ -use casper_types::{AccessRights, ContractPackageHash}; -use rand::Rng; - -use crate::{ - AsymmetricType, CEP47Contract, CEP47Storage, Error, Key, Meta, TokenId, URef, WithStorage, U256, -}; -use casper_types::PublicKey; -use std::{ - collections::{hash_map::DefaultHasher, BTreeMap}, - hash::{Hash, Hasher}, - sync::Mutex, -}; - -struct TestStorage { - name: String, - symbol: String, - meta: Meta, - paused: bool, - total_supply: U256, - tokens: BTreeMap>, - token_metas: BTreeMap, - balances: BTreeMap, - belongs_to: BTreeMap, - urefs: BTreeMap, - token_id_generator: u32, -} - -impl TestStorage { - pub fn new() -> TestStorage { - TestStorage { - name: String::from("Casper Enhancement Proposal 47"), - symbol: String::from("CEP47"), - meta: meta::contract_info(), - paused: false, - total_supply: U256::from(0), - tokens: BTreeMap::new(), - balances: BTreeMap::new(), - belongs_to: BTreeMap::new(), - token_metas: BTreeMap::new(), - urefs: BTreeMap::new(), - token_id_generator: 1, - } - } -} - -impl CEP47Storage for TestStorage { - fn name(&self) -> String { - self.name.clone() - } - - fn symbol(&self) -> String { - self.symbol.clone() - } - - fn meta(&self) -> Meta { - self.meta.clone() - } - - fn balance_of(&self, owner: &Key) -> U256 { - let owner_balance = self.balances.get(owner); - owner_balance.cloned().unwrap_or_default() - } - - fn onwer_of(&self, token_id: &TokenId) -> Option { - let owner = self.belongs_to.get(token_id); - owner.cloned() - } - - fn total_supply(&self) -> U256 { - self.total_supply - } - - fn token_meta(&self, token_id: &TokenId) -> Option { - let meta = self.token_metas.get(token_id); - meta.cloned() - } - - fn is_paused(&self) -> bool { - self.paused - } - - fn pause(&mut self) { - self.paused = true; - } - - fn unpause(&mut self) { - self.paused = false; - } - - fn get_tokens(&self, owner: &Key) -> Vec { - let owner_tokens = self.tokens.get(owner); - owner_tokens.cloned().unwrap_or_default() - } - - fn set_tokens(&mut self, owner: &Key, token_ids: Vec) { - let owner_new_balance = U256::from(token_ids.len() as u64); - - let owner_tokens = self.get_tokens(owner); - for token_id in owner_tokens.clone() { - self.belongs_to.remove(&token_id); - } - for token_id in token_ids.clone() { - self.belongs_to.insert(token_id, *owner); - } - - self.tokens.insert(*owner, token_ids); - self.balances.insert(*owner, owner_new_balance); - } - - fn mint_many(&mut self, recipient: &Key, token_ids: &Vec, token_metas: &Vec) { - let recipient_balance = self.balances.get(recipient); - let recipient_tokens = self.tokens.get(recipient); - - let mut recipient_new_balance = recipient_balance.copied().unwrap_or_default(); - let mut recipient_new_tokens = recipient_tokens.cloned().unwrap_or_default(); - - for (token_id, token_meta) in token_ids.iter().zip(token_metas) { - self.token_metas - .insert(token_id.clone(), token_meta.clone()); - recipient_new_tokens.push(token_id.clone()); - self.belongs_to.insert(token_id.clone(), *recipient); - recipient_new_balance = recipient_new_balance + 1; - self.total_supply = self.total_supply + 1; - } - self.balances.insert(*recipient, recipient_new_balance); - self.tokens.insert(*recipient, recipient_new_tokens); - } - - fn burn_many(&mut self, owner: &Key, token_ids: &Vec) { - let owner_tokens = self.tokens.get(owner); - let owner_balance = self.balances.get(owner); - - let mut owner_new_balance = owner_balance.copied().unwrap_or_default(); - let mut owner_new_tokens = owner_tokens.cloned().unwrap_or_default(); - - for token_id in token_ids.clone() { - let index = owner_new_tokens - .iter() - .position(|x| *x == token_id.clone()) - .unwrap(); - owner_new_tokens.remove(index); - self.token_metas.remove(&token_id.clone()); - self.belongs_to.remove(&token_id.clone()); - owner_new_balance = owner_new_balance - 1; - self.total_supply = self.total_supply - 1; - } - self.balances.insert(*owner, owner_new_balance); - self.tokens.insert(*owner, owner_new_tokens); - } - - fn update_token_metadata(&mut self, token_id: &TokenId, meta: Meta) { - self.token_metas.insert(token_id.clone(), meta).unwrap(); - } - - fn gen_token_ids(&mut self, n: u32) -> Vec { - let mut tokens = Vec::new(); - for _ in 0..n { - let id = format!("token_{}", &self.token_id_generator); - tokens.push(id); - self.token_id_generator += 1; - } - tokens - } - - fn validate_token_ids(&self, token_ids: &Vec) -> bool { - for token_id in token_ids { - if self.onwer_of(token_id).is_some() { - return false; - } - } - true - } - - fn emit(&mut self, _event: crate::events::CEP47Event) {} - - fn contact_package_hash(&self) -> casper_types::ContractPackageHash { - [1u8; 32].into() - } -} - -struct TestContract { - storage: TestStorage, -} - -impl TestContract { - pub fn new() -> TestContract { - TestContract { - storage: TestStorage::new(), - } - } -} - -impl WithStorage for TestContract { - fn storage(&self) -> &TestStorage { - &self.storage - } - - fn storage_mut(&mut self) -> &mut TestStorage { - &mut self.storage - } -} - -impl CEP47Contract for TestContract {} - -mod meta { - use super::BTreeMap; - - pub fn contract_info() -> BTreeMap { - btreemap! { - "github".to_string() => "https://github.com/casper-ecosystem/casper-nft-cep47".to_string() - } - } - - pub fn apple() -> BTreeMap { - btreemap! { - "fruit".to_string() => "Apple".to_string(), - "size".to_string() => "A".to_string() - } - } - - pub fn orange() -> BTreeMap { - btreemap! { - "fruit".to_string() => "Orange".to_string(), - "size".to_string() => "B".to_string() - } - } - - pub fn banana() -> BTreeMap { - btreemap! { - "fruit".to_string() => "Banana".to_string(), - "size".to_string() => "B".to_string() - } - } -} - -#[test] -fn test_metadata() { - let contract = TestContract::new(); - assert_eq!( - contract.name(), - String::from("Casper Enhancement Proposal 47") - ); - assert_eq!(contract.symbol(), String::from("CEP47")); - assert_eq!(contract.meta(), meta::contract_info()); -} - -#[test] -fn test_mint_many() { - let mut contract = TestContract::new(); - let ali_pk = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); - let bob_pk = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); - let ali: Key = ali_pk.to_account_hash().into(); - let bob: Key = bob_pk.to_account_hash().into(); - let bob_first_token_id = "banana_01".to_string(); - let bob_second_token_id = "orange_02".to_string(); - let bob_token_ids = vec![bob_first_token_id.clone(), bob_second_token_id]; - - assert_eq!(contract.total_supply(), U256::from(0)); - let _: Result<(), Error> = contract.mint_many(&ali, None, vec![meta::apple()]); - let _: Result<(), Error> = contract.mint_many( - &bob, - Some(bob_token_ids.clone()), - vec![meta::banana(), meta::orange()], - ); - assert_eq!(contract.total_supply(), U256::from(3)); - - let ali_balance = contract.balance_of(&ali); - assert_eq!(ali_balance, U256::from(1)); - let bob_balance = contract.balance_of(&bob); - assert_eq!(bob_balance, U256::from(2)); - - let ali_tokens: Vec = contract.tokens(&ali); - let ali_first_token_meta: Meta = contract.token_meta(ali_tokens.get(0).unwrap()).unwrap(); - assert_eq!(ali_first_token_meta, meta::apple()); - - let bob_tokens: Vec = contract.tokens(&bob); - assert_eq!(bob_token_ids, bob_tokens); - let bob_first_token_meta: Meta = contract.token_meta(&bob_first_token_id).unwrap(); - assert_eq!(bob_first_token_meta, meta::banana()); -} -#[test] -fn test_mint_copies() { - let mut contract = TestContract::new(); - let ali_pk = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); - let ali: Key = ali_pk.to_account_hash().into(); - - assert_eq!(contract.total_supply(), U256::from(0)); - let _: Result<(), Error> = contract.mint_copies(&ali, None, meta::apple(), 7); - assert_eq!(contract.total_supply(), U256::from(7)); - - let ali_balance = contract.balance_of(&ali); - assert_eq!(ali_balance, U256::from(7)); - - let ali_tokens: Vec = contract.tokens(&ali); - let ali_first_token_meta: Meta = contract.token_meta(ali_tokens.get(0).unwrap()).unwrap(); - let ali_third_token_meta: Meta = contract.token_meta(ali_tokens.get(2).unwrap()).unwrap(); - assert_eq!(ali_first_token_meta, meta::apple()); - assert_eq!(ali_third_token_meta, meta::apple()); -} -#[test] -fn test_burn_many() { - let mut contract = TestContract::new(); - let ali_pk = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); - let ali: Key = ali_pk.to_account_hash().into(); - - assert_eq!(contract.total_supply(), U256::from(0)); - - let _: Result<(), Error> = contract.mint_many( - &ali, - None, - vec![meta::banana(), meta::orange(), meta::apple()], - ); - assert_eq!(contract.total_supply(), U256::from(3)); - - let ali_balance = contract.balance_of(&ali); - assert_eq!(ali_balance, U256::from(3)); - - let ali_tokens: Vec = contract.tokens(&ali); - let banana = ali_tokens.get(0).unwrap().clone(); - let orange = ali_tokens.get(1).unwrap().clone(); - let apple = ali_tokens.get(2).unwrap().clone(); - - contract.burn_many(&ali, vec![banana.clone(), apple.clone()]); - let ali_tokens_after_burn = contract.tokens(&ali); - assert_eq!(ali_tokens_after_burn, vec![orange.clone()]); - - assert!(contract.token_meta(&banana).is_none()); - assert!(contract.token_meta(&orange).is_some()); - assert!(contract.token_meta(&apple).is_none()); - - assert_eq!(contract.total_supply(), U256::from(1)); - assert_eq!(contract.balance_of(&ali), U256::from(1)); -} -#[test] -fn test_burn_one() { - let mut contract = TestContract::new(); - let ali_pk = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); - let ali: Key = ali_pk.to_account_hash().into(); - - assert_eq!(contract.total_supply(), U256::from(0)); - let _: Result<(), Error> = contract.mint_many(&ali, None, vec![meta::banana(), meta::orange()]); - assert_eq!(contract.total_supply(), U256::from(2)); - - let mut ali_balance = contract.balance_of(&ali); - assert_eq!(ali_balance, U256::from(2)); - - let mut ali_tokens: Vec = contract.tokens(&ali); - contract.burn_one(&ali, ali_tokens.get(0).unwrap().clone()); - let mut ali_first_token_meta = contract.token_meta(ali_tokens.get(0).unwrap()); - assert_eq!(ali_first_token_meta, None); - - ali_tokens = contract.tokens(&ali); - ali_first_token_meta = contract.token_meta(ali_tokens.get(0).unwrap()); - assert_eq!(ali_first_token_meta, Some(meta::orange())); - - assert_eq!(contract.total_supply(), U256::from(1)); - ali_balance = contract.balance_of(&ali); - assert_eq!(ali_balance, U256::from(1)); -} -#[test] -fn test_transfer_token() { - let mut contract = TestContract::new(); - let ali_pk = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); - let bob_pk = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); - let ali: Key = ali_pk.to_account_hash().into(); - let bob: Key = bob_pk.to_account_hash().into(); - - assert_eq!(contract.total_supply(), U256::from(0)); - let _: Result<(), Error> = contract.mint_one(&ali, None, meta::apple()); - assert_eq!(contract.total_supply(), U256::from(1)); - - let mut ali_balance = contract.balance_of(&ali); - let mut bob_balance = contract.balance_of(&bob); - assert_eq!(ali_balance, U256::from(1)); - assert_eq!(bob_balance, U256::from(0)); - - let ali_tokens: Vec = contract.tokens(&ali); - let ali_first_token_id: TokenId = ali_tokens.get(0).unwrap().clone(); - let ali_first_token_meta: Meta = contract.token_meta(&ali_first_token_id).unwrap(); - assert_eq!(ali_first_token_meta, meta::apple()); - - let transfer_res = contract.transfer_token(&ali, &bob, &ali_first_token_id); - assert!(transfer_res.is_ok()); - ali_balance = contract.balance_of(&ali); - bob_balance = contract.balance_of(&bob); - assert_eq!(ali_balance, U256::from(0)); - assert_eq!(bob_balance, U256::from(1)); - - let owner_of_first_token_id = contract.owner_of(&ali_first_token_id); - assert_eq!(owner_of_first_token_id.unwrap(), bob); -} -#[test] -fn test_transfer_all_tokens() { - let mut contract = TestContract::new(); - let ali_pk = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); - let bob_pk = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); - let ali: Key = ali_pk.to_account_hash().into(); - let bob: Key = bob_pk.to_account_hash().into(); - - assert_eq!(contract.total_supply(), U256::from(0)); - let _: Result<(), Error> = contract.mint_many(&ali, None, vec![meta::apple(), meta::banana()]); - let _: Result<(), Error> = contract.mint_one(&ali, None, meta::apple()); - assert_eq!(contract.total_supply(), U256::from(3)); - - let mut ali_balance = contract.balance_of(&ali); - let mut bob_balance = contract.balance_of(&bob); - assert_eq!(ali_balance, U256::from(3)); - assert_eq!(bob_balance, U256::from(0)); - - let ali_tokens: Vec = contract.tokens(&ali); - let ali_second_token_id: TokenId = ali_tokens.get(1).unwrap().clone(); - let ali_second_token_meta: Meta = contract.token_meta(&ali_second_token_id).unwrap(); - assert_eq!(ali_second_token_meta, meta::banana()); - - let transfer_res = contract.transfer_all_tokens(&ali, &bob); - assert!(transfer_res.is_ok()); - - ali_balance = contract.balance_of(&ali); - bob_balance = contract.balance_of(&bob); - assert_eq!(ali_balance, U256::from(0)); - assert_eq!(bob_balance, U256::from(3)); - - let owner_of_second_token_id = contract.owner_of(&ali_second_token_id); - assert_eq!(owner_of_second_token_id.unwrap(), bob); -} - -#[test] -fn test_transfer_many_tokens() { - let mut contract = TestContract::new(); - let ali_pk = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); - let bob_pk = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); - let ali: Key = ali_pk.to_account_hash().into(); - let bob: Key = bob_pk.to_account_hash().into(); - - assert_eq!(contract.total_supply(), U256::from(0)); - let _ = contract.mint_many(&ali, None, vec![meta::apple(), meta::banana()]); - let _: Result<(), Error> = contract.mint_copies(&ali, None, meta::apple(), 3); - assert_eq!(contract.total_supply(), U256::from(5)); - - assert_eq!(contract.balance_of(&ali), U256::from(5)); - assert_eq!(contract.balance_of(&bob), U256::from(0)); - - let ali_tokens: Vec = contract.tokens(&ali); - let ali_second_token_id: TokenId = ali_tokens.get(1).unwrap().clone(); - let ali_second_token_meta: Meta = contract.token_meta(&ali_second_token_id).unwrap(); - let ali_third_token_id: TokenId = ali_tokens.get(2).unwrap().clone(); - let ali_third_token_meta: Meta = contract.token_meta(&ali_third_token_id).unwrap(); - assert_eq!(ali_second_token_meta, meta::banana()); - assert_eq!(ali_third_token_meta, meta::apple()); - - let transfer_res = contract.transfer_many_tokens( - &ali, - &bob, - &vec![ali_second_token_id.clone(), ali_third_token_id.clone()], - ); - assert!(transfer_res.is_ok()); - assert_eq!(contract.balance_of(&ali), U256::from(3)); - assert_eq!(contract.balance_of(&bob), U256::from(2)); - - let owner_of_second_token_id = contract.owner_of(&ali_second_token_id); - let owner_of_third_token_id = contract.owner_of(&ali_third_token_id); - assert_eq!(owner_of_second_token_id.unwrap(), bob); - assert_eq!(owner_of_third_token_id.unwrap(), bob); -} - -#[test] -fn test_update_metadata() { - let mut contract = TestContract::new(); - let ali_pk = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); - let ali: Key = ali_pk.to_account_hash().into(); - - let token_id = TokenId::from("new_token"); - let _: Result<(), Error> = contract.mint_one(&ali, Some(token_id.clone()), meta::apple()); - assert_eq!(meta::apple(), contract.token_meta(&token_id).unwrap()); - let _: Result<(), Error> = contract.update_token_metadata(token_id.clone(), meta::banana()); - assert_eq!(meta::banana(), contract.token_meta(&token_id).unwrap()); -} diff --git a/cep47-tests/Cargo.toml b/cep47-tests/Cargo.toml index 68d40e1..60dd240 100644 --- a/cep47-tests/Cargo.toml +++ b/cep47-tests/Cargo.toml @@ -1,15 +1,18 @@ [package] name = "cep47-tests" version = "0.1.0" -authors = ["astro019 "] edition = "2018" +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + [dependencies] -casper-contract = "1.3.1" -casper-types = "1.3.1" -casper-engine-test-support = "1.3.1" -maplit = "1.0.2" +casper-contract = "1.3.2" +casper-types = "1.3.2" +casper-engine-test-support = "1.3.2" +test-env = { path = "../utils/test-env" } +contract-utils = { path = "../utils/contract-utils" } hex = "0.4.3" +blake2 = "0.9.1" [features] default = ["casper-contract/std", "casper-types/std", "casper-contract/test-support"] diff --git a/cep47-tests/src/cep47.rs b/cep47-tests/src/cep47.rs deleted file mode 100644 index 15eaf81..0000000 --- a/cep47-tests/src/cep47.rs +++ /dev/null @@ -1,300 +0,0 @@ -use std::collections::BTreeMap; - -use casper_engine_test_support::{Code, Hash, SessionBuilder, TestContext, TestContextBuilder}; -use casper_types::{ - account::AccountHash, bytesrepr::FromBytes, runtime_args, CLTyped, Key, PublicKey, RuntimeArgs, - SecretKey, U256, U512, -}; - -pub mod token_cfg { - use super::Meta; - use maplit::btreemap; - - pub const NAME: &str = "DragonsNFT"; - pub const SYMBOL: &str = "DRAG"; - - pub fn contract_meta() -> Meta { - btreemap! { - "origin".to_string() => "fire".to_string() - } - } -} - -pub const CONTRACT_KEY: &str = "DragonsNFT_contract"; -pub const CONTRACT_HASH_KEY: &str = "DragonsNFT_contract_hash"; - -const BALANCES_DICT: &str = "balances"; -const OWNED_TOKENS_DICT: &str = "owned_tokens"; -const TOKEN_OWNERS_DICT: &str = "owners"; -const METADATA_DICT: &str = "metadata"; - -pub struct CasperCEP47Contract { - pub context: TestContext, - pub hash: Hash, - pub admin: AccountHash, - pub ali: AccountHash, - pub bob: AccountHash, -} - -pub type TokenId = String; -pub type Meta = BTreeMap; - -impl CasperCEP47Contract { - pub fn deploy() -> Self { - let admin_secret = SecretKey::ed25519_from_bytes([1u8; 32]).unwrap(); - let ali_secret = SecretKey::ed25519_from_bytes([3u8; 32]).unwrap(); - let bob_secret = SecretKey::ed25519_from_bytes([5u8; 32]).unwrap(); - - let admin: PublicKey = (&admin_secret).into(); - let ali: PublicKey = (&ali_secret).into(); - let bob: PublicKey = (&bob_secret).into(); - let mut context = TestContextBuilder::new() - .with_public_key(admin.clone(), U512::from(500_000_000_000_000_000u64)) - .with_public_key(ali.clone(), U512::from(500_000_000_000_000_000u64)) - .with_public_key(bob.clone(), U512::from(500_000_000_000_000_000u64)) - .build(); - let session_code = Code::from("dragons-nft.wasm"); - let session_args = runtime_args! { - "token_name" => token_cfg::NAME, - "token_symbol" => token_cfg::SYMBOL, - "token_meta" => token_cfg::contract_meta() - }; - let session = SessionBuilder::new(session_code, session_args) - .with_address(admin.to_account_hash()) - .with_authorization_keys(&[admin.to_account_hash()]) - .build(); - context.run(session); - let hash = context - .query(admin.to_account_hash(), &[CONTRACT_HASH_KEY.to_string()]) - .unwrap() - .into_t() - .unwrap(); - - Self { - context, - hash, - admin: admin.to_account_hash(), - ali: ali.to_account_hash(), - bob: bob.to_account_hash(), - } - } - - fn call(&mut self, sender: &AccountHash, method: &str, args: RuntimeArgs) { - let account = *sender; - let code = Code::Hash(self.hash, method.to_string()); - let session = SessionBuilder::new(code, args) - .with_address(account) - .with_authorization_keys(&[account]) - .build(); - self.context.run(session); - } - - fn query_contract(&self, name: &str) -> Option { - match self - .context - .query(self.admin, &[CONTRACT_KEY.to_string(), name.to_string()]) - { - Err(_) => None, - Ok(maybe_value) => { - let value = maybe_value - .into_t() - .unwrap_or_else(|_| panic!("{} is not expected type.", name)); - Some(value) - } - } - } - - fn query_dictionary_value( - &self, - dict_name: &str, - key: String, - ) -> Option { - match self.context.query_dictionary_item( - Key::Hash(self.hash), - Some(dict_name.to_string()), - key, - ) { - Err(_) => None, - Ok(maybe_value) => { - let value: Option = maybe_value - .into_t() - .unwrap_or_else(|_| panic!("is not expected type.")); - value - } - } - } - - pub fn name(&self) -> String { - self.query_contract("name").unwrap() - } - - pub fn symbol(&self) -> String { - self.query_contract("symbol").unwrap() - } - - pub fn meta(&self) -> Meta { - self.query_contract("meta").unwrap() - } - - pub fn total_supply(&self) -> U256 { - self.query_contract("total_supply").unwrap_or_default() - } - - pub fn owner_of(&self, token_id: &TokenId) -> Option { - let key: Key = self - .query_dictionary_value(TOKEN_OWNERS_DICT, token_id.clone()) - .unwrap(); - key.into_account() - } - - pub fn balance_of(&self, owner: &AccountHash) -> U256 { - let value: Option = self.query_dictionary_value(BALANCES_DICT, owner.to_string()); - value.unwrap_or_default() - } - - pub fn tokens(&self, owner: &AccountHash) -> Vec { - let value: Option> = - self.query_dictionary_value(OWNED_TOKENS_DICT, owner.to_string()); - value.unwrap_or_default() - } - - pub fn token_meta(&self, token_id: &TokenId) -> Option { - self.query_dictionary_value(METADATA_DICT, token_id.clone()) - } - - pub fn mint_one( - &mut self, - recipient: &AccountHash, - token_id: Option<&TokenId>, - token_meta: &Meta, - sender: &AccountHash, - ) { - self.call( - sender, - "mint_one", - runtime_args! { - "recipient" => Key::from(*recipient), - "token_id" => token_id.cloned(), - "token_meta" => token_meta.clone() - }, - ); - } - - pub fn mint_copies( - &mut self, - recipient: &AccountHash, - token_ids: Option<&Vec>, - token_meta: &Meta, - count: u32, - sender: &AccountHash, - ) { - self.call( - sender, - "mint_copies", - runtime_args! { - "recipient" => Key::from(*recipient), - "token_ids" => token_ids.cloned(), - "token_meta" => token_meta.clone(), - "count" => count - }, - ); - } - - pub fn mint_many( - &mut self, - recipient: &AccountHash, - token_ids: Option<&Vec>, - token_metas: &Vec, - sender: &AccountHash, - ) { - self.call( - sender, - "mint_many", - runtime_args! { - "recipient" => Key::from(*recipient), - "token_ids" => token_ids.cloned(), - "token_metas" => token_metas.clone(), - }, - ); - } - - pub fn burn_many( - &mut self, - owner: &AccountHash, - token_ids: &Vec, - sender: &AccountHash, - ) { - self.call( - sender, - "burn_many", - runtime_args! { - "owner" => Key::from(*owner), - "token_ids" => token_ids.clone() - }, - ); - } - - pub fn burn_one(&mut self, owner: &AccountHash, token_id: &TokenId, sender: &AccountHash) { - self.call( - sender, - "burn_one", - runtime_args! { - "owner" => Key::from(*owner), - "token_id" => token_id.clone() - }, - ); - } - - pub fn transfer_token( - &mut self, - recipient: &AccountHash, - token_id: &TokenId, - sender: &AccountHash, - ) { - self.call( - sender, - "transfer_token", - runtime_args! { - "recipient" => Key::from(*recipient), - "token_id" => token_id.clone() - }, - ); - } - - pub fn transfer_many_tokens( - &mut self, - recipient: &AccountHash, - token_ids: &Vec, - sender: &AccountHash, - ) { - self.call( - sender, - "transfer_many_tokens", - runtime_args! { - "recipient" => Key::from(*recipient), - "token_ids" => token_ids.clone() - }, - ); - } - - pub fn transfer_all_tokens(&mut self, recipient: &AccountHash, sender: &AccountHash) { - self.call( - sender, - "transfer_all_tokens", - runtime_args! { - "recipient" => Key::from(*recipient) - }, - ); - } - - pub fn update_token_metadata(&mut self, token_id: &TokenId, meta: &Meta, sender: &AccountHash) { - self.call( - sender, - "update_token_metadata", - runtime_args! { - "token_id" => token_id.clone(), - "token_meta" => meta.clone() - }, - ); - } -} diff --git a/cep47-tests/src/cep47_instance.rs b/cep47-tests/src/cep47_instance.rs new file mode 100644 index 0000000..cafdfc3 --- /dev/null +++ b/cep47-tests/src/cep47_instance.rs @@ -0,0 +1,233 @@ +use std::collections::BTreeMap; + +use blake2::{ + digest::{Update, VariableOutput}, + VarBlake2b, +}; +use casper_types::{bytesrepr::ToBytes, runtime_args, CLTyped, Key, RuntimeArgs, U256}; +use test_env::{Sender, TestContract, TestEnv}; + +pub type TokenId = String; +pub type Meta = BTreeMap; + +pub struct CEP47Instance(TestContract); + +impl CEP47Instance { + pub fn new( + env: &TestEnv, + contract_name: &str, + sender: Sender, + name: &str, + symbol: &str, + meta: Meta, + ) -> CEP47Instance { + CEP47Instance(TestContract::new( + env, + "cep47-token.wasm", + contract_name, + sender, + runtime_args! { + "name" => name, + "symbol" => symbol, + "meta" => meta + }, + )) + } + + pub fn constructor(&self, sender: Sender, name: &str, symbol: &str, meta: Meta) { + self.0.call_contract( + sender, + "constructor", + runtime_args! { + "name" => name, + "symbol" => symbol, + "meta" => meta}, + ); + } + + pub fn mint_one>( + &self, + sender: Sender, + recipient: T, + token_id: Option, + token_meta: Meta, + ) { + self.0.call_contract( + sender, + "mint", + runtime_args! { + "recipient" => recipient.into(), + "token_ids" => token_id.map(|x| vec![x]), + "token_metas" => vec![token_meta] + }, + ) + } + + pub fn mint_copies>( + &self, + sender: Sender, + recipient: T, + token_ids: Option>, + token_meta: Meta, + count: u32, + ) { + self.0.call_contract( + sender, + "mint_copies", + runtime_args! { + "recipient" => recipient.into(), + "token_ids" => token_ids, + "token_meta" => token_meta, + "count" => count + }, + ) + } + + pub fn mint_many>( + &self, + sender: Sender, + recipient: T, + token_ids: Option>, + token_metas: Vec, + ) { + self.0.call_contract( + sender, + "mint", + runtime_args! { + "recipient" => recipient.into(), + "token_ids" => token_ids, + "token_metas" => token_metas + }, + ) + } + + pub fn burn_one>(&self, sender: Sender, owner: T, token_id: TokenId) { + self.0.call_contract( + sender, + "burn", + runtime_args! { + "owner" => owner.into(), + "token_ids" => vec![token_id] + }, + ) + } + + pub fn burn_many>(&self, sender: Sender, owner: T, token_ids: Vec) { + self.0.call_contract( + sender, + "burn", + runtime_args! { + "owner" => owner.into(), + "token_ids" => token_ids + }, + ) + } + + pub fn transfer>(&self, sender: Sender, recipient: T, token_ids: Vec) { + self.0.call_contract( + sender, + "transfer", + runtime_args! { + "recipient" => recipient.into(), + "token_ids" => token_ids + }, + ) + } + + pub fn transfer_from>( + &self, + sender: Sender, + owner: T, + recipient: T, + token_ids: Vec, + ) { + self.0.call_contract( + sender, + "transfer_from", + runtime_args! { + "sender" => owner.into(), + "recipient" => recipient.into(), + "token_ids" => token_ids + }, + ) + } + + pub fn approve>(&self, sender: Sender, spender: T, token_ids: Vec) { + self.0.call_contract( + sender, + "approve", + runtime_args! {"spender" => spender.into(), "token_ids" => token_ids}, + ) + } + + pub fn get_approved>(&self, owner: T, token_id: TokenId) -> Option { + self.0.query_dictionary( + "allowances", + key_and_value_to_str::(&owner.into(), &token_id), + ) + } + + pub fn update_token_meta(&self, sender: Sender, token_id: TokenId, token_meta: Meta) { + self.0.call_contract( + sender, + "update_token_meta", + runtime_args! { + "token_id" => token_id, + "token_meta" => token_meta + }, + ) + } + + pub fn tokens>(&self, account: T) -> Vec { + self.0 + .query_dictionary("owned_tokens", key_to_str(&account.into())) + .unwrap_or_default() + } + + pub fn balance_of>(&self, account: T) -> U256 { + self.0 + .query_dictionary("balances", key_to_str(&account.into())) + .unwrap_or_default() + } + + pub fn owner_of(&self, token_id: TokenId) -> Option { + self.0.query_dictionary("owners", token_id) + } + + pub fn token_meta(&self, token_id: TokenId) -> Option { + self.0.query_dictionary("metadata", token_id) + } + + pub fn name(&self) -> String { + self.0.query_named_key(String::from("name")) + } + + pub fn symbol(&self) -> String { + self.0.query_named_key(String::from("symbol")) + } + + pub fn total_supply(&self) -> U256 { + self.0.query_named_key(String::from("total_supply")) + } + + pub fn meta(&self) -> Meta { + self.0.query_named_key(String::from("meta")) + } +} + +pub fn key_to_str(key: &Key) -> String { + match key { + Key::Account(account) => account.to_string(), + Key::Hash(package) => hex::encode(package), + _ => panic!("Unexpected key type"), + } +} + +pub fn key_and_value_to_str(key: &Key, value: &T) -> String { + let mut hasher = VarBlake2b::new(32).unwrap(); + hasher.update(key.to_bytes().unwrap()); + hasher.update(value.to_bytes().unwrap()); + let mut ret = [0u8; 32]; + hasher.finalize_variable(|hash| ret.clone_from_slice(hash)); + hex::encode(ret) +} diff --git a/cep47-tests/src/cep47_tests.rs b/cep47-tests/src/cep47_tests.rs new file mode 100644 index 0000000..24f3793 --- /dev/null +++ b/cep47-tests/src/cep47_tests.rs @@ -0,0 +1,476 @@ +use std::collections::BTreeMap; + +use casper_engine_test_support::AccountHash; +use casper_types::{Key, U256}; +use test_env::{Sender, TestEnv}; + +use crate::cep47_instance::{CEP47Instance, Meta, TokenId}; + +const NAME: &str = "DragonsNFT"; +const SYMBOL: &str = "DGNFT"; + +mod meta { + use super::{BTreeMap, Meta}; + pub fn contract_meta() -> Meta { + let mut meta = BTreeMap::new(); + meta.insert("origin".to_string(), "fire".to_string()); + meta + } + + pub fn red_dragon() -> Meta { + let mut meta = BTreeMap::new(); + meta.insert("color".to_string(), "red".to_string()); + meta + } + + pub fn blue_dragon() -> Meta { + let mut meta = BTreeMap::new(); + meta.insert("color".to_string(), "blue".to_string()); + meta + } + + pub fn black_dragon() -> Meta { + let mut meta = BTreeMap::new(); + meta.insert("color".to_string(), "black".to_string()); + meta + } + + pub fn gold_dragon() -> Meta { + let mut meta = BTreeMap::new(); + meta.insert("color".to_string(), "gold".to_string()); + meta + } +} + +fn deploy() -> (TestEnv, CEP47Instance, AccountHash) { + let env = TestEnv::new(); + let owner = env.next_user(); + let token = CEP47Instance::new( + &env, + NAME, + Sender(owner), + NAME, + SYMBOL, + meta::contract_meta(), + ); + (env, token, owner) +} + +#[test] +fn test_deploy() { + let (_, token, _) = deploy(); + assert_eq!(token.name(), NAME); + assert_eq!(token.symbol(), SYMBOL); + assert_eq!(token.meta(), meta::contract_meta()); + assert_eq!(token.total_supply(), U256::zero()); +} + +#[test] +fn test_token_meta() { + let (env, token, owner) = deploy(); + let user = env.next_user(); + let token_id = TokenId::from("custom_token_id"); + let token_meta = meta::red_dragon(); + + token.mint_one( + Sender(owner), + user, + Some(token_id.clone()), + token_meta.clone(), + ); + + let user_token_meta = token.token_meta(token_id.clone()); + assert_eq!(user_token_meta.unwrap(), token_meta); + + let user_tokens = token.tokens(Key::Account(user)); + assert_eq!(user_tokens, vec![token_id]); +} + +#[test] +fn test_mint_one_with_random_token_id() { + let (env, token, owner) = deploy(); + let user = env.next_user(); + token.mint_one(Sender(owner), user, None, meta::red_dragon()); + + assert_eq!(token.total_supply(), U256::one()); + assert_eq!(token.balance_of(user), U256::one()); + + let user_tokens: Vec = token.tokens(Key::Account(user)); + assert_eq!(U256::from(user_tokens.len() as u64), U256::one()); + assert_eq!( + token.owner_of(user_tokens.get(0).unwrap().clone()).unwrap(), + Key::Account(user) + ); +} + +#[test] +fn test_mint_one_with_set_token_id() { + let (env, token, owner) = deploy(); + let user = env.next_user(); + let token_id = TokenId::from("123456"); + let token_meta = meta::red_dragon(); + + token.mint_one( + Sender(owner), + user, + Some(token_id.clone()), + token_meta.clone(), + ); + let user_tokens = token.tokens(Key::Account(user)); + assert_eq!(user_tokens, vec![token_id.clone()]); + assert_eq!(token.total_supply(), U256::one()); + assert_eq!(token.balance_of(Key::Account(user)), U256::one()); + assert_eq!(U256::from(user_tokens.len() as u64), U256::one()); + assert_eq!(token.owner_of(token_id).unwrap(), Key::Account(user)); +} + +#[test] +#[should_panic] +fn test_mint_one_with_not_unique_token_id() { + let (env, token, owner) = deploy(); + let user = env.next_user(); + let token_id = TokenId::from("123456"); + let token_meta = meta::red_dragon(); + + token.mint_one( + Sender(owner), + user, + Some(token_id.clone()), + token_meta.clone(), + ); + + token.mint_one( + Sender(owner), + user, + Some(token_id.clone()), + token_meta.clone(), + ); +} + +#[test] +fn test_mint_copies() { + let (env, token, owner) = deploy(); + let user = env.next_user(); + let token_meta = meta::red_dragon(); + + token.mint_copies(Sender(owner), user, None, token_meta.clone(), 3); + + let user_tokens = token.tokens(Key::Account(user)); + assert_eq!(token.total_supply(), U256::from(3)); + assert_eq!(token.balance_of(Key::Account(user)), U256::from(3)); + assert_eq!(U256::from(user_tokens.len() as u64), U256::from(3)); + assert_eq!( + token.owner_of(user_tokens.get(0).unwrap().clone()).unwrap(), + Key::Account(user) + ); + assert_eq!( + token.owner_of(user_tokens.get(1).unwrap().clone()).unwrap(), + Key::Account(user) + ); + assert_eq!( + token.owner_of(user_tokens.get(2).unwrap().clone()).unwrap(), + Key::Account(user) + ); +} + +#[test] +fn test_mint_many() { + let (env, token, owner) = deploy(); + let user = env.next_user(); + let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; + + token.mint_many(Sender(owner), user, None, token_metas.clone()); + let user_tokens = token.tokens(Key::Account(user)); + assert_eq!(token.total_supply(), U256::from(2)); + assert_eq!(token.balance_of(Key::Account(user)), U256::from(2)); + assert_eq!(U256::from(user_tokens.len() as u64), U256::from(2)); + assert_eq!( + token.owner_of(user_tokens.get(0).unwrap().clone()).unwrap(), + Key::Account(user) + ); + assert_eq!( + token.owner_of(user_tokens.get(1).unwrap().clone()).unwrap(), + Key::Account(user) + ); +} + +#[test] +fn test_burn_many() { + // TODO: the sender should be owner of nft item or allowed party + let (env, token, owner) = deploy(); + let user = env.next_user(); + let token_metas = vec![ + meta::red_dragon(), + meta::blue_dragon(), + meta::black_dragon(), + meta::gold_dragon(), + ]; + + token.mint_many(Sender(owner), user, None, token_metas.clone()); + + let mut user_tokens = token.tokens(Key::Account(user)); + println!("{:?}", user_tokens); + println!("{:?}", user_tokens.first().unwrap().clone()); + + token.burn_many( + Sender(user), + user, + vec![ + user_tokens.first().unwrap().clone(), + user_tokens.last().unwrap().clone(), + ], + ); + assert_eq!(token.total_supply(), U256::from(2)); + assert_eq!(token.balance_of(Key::Account(user)), U256::from(2)); + + user_tokens = token.tokens(Key::Account(user)); + println!("{:?}", user_tokens); + assert_eq!(U256::from(user_tokens.len() as u64), U256::from(2)); +} + +#[test] +fn test_burn_many_from_allowance_with_approve() { + let (env, token, owner) = deploy(); + let user = env.next_user(); + let token_metas = vec![ + meta::red_dragon(), + meta::blue_dragon(), + meta::black_dragon(), + meta::gold_dragon(), + ]; + + token.mint_many(Sender(owner), user, None, token_metas.clone()); + + let mut user_tokens = token.tokens(Key::Account(user)); + println!("{:?}", user_tokens); + println!("{:?}", user_tokens.first().unwrap().clone()); + token.approve(Sender(user), owner, user_tokens.clone()); + token.burn_many( + Sender(owner), + user, + vec![ + user_tokens.first().unwrap().clone(), + user_tokens.last().unwrap().clone(), + ], + ); + assert_eq!(token.total_supply(), U256::from(2)); + assert_eq!(token.balance_of(Key::Account(user)), U256::from(2)); + + user_tokens = token.tokens(Key::Account(user)); + println!("{:?}", user_tokens); + assert_eq!(U256::from(user_tokens.len() as u64), U256::from(2)); +} + +#[test] +#[should_panic] +fn test_burn_many_from_allowance_without_approve() { + let (env, token, owner) = deploy(); + let user = env.next_user(); + let token_metas = vec![ + meta::red_dragon(), + meta::blue_dragon(), + meta::black_dragon(), + meta::gold_dragon(), + ]; + + token.mint_many(Sender(owner), user, None, token_metas.clone()); + + let user_tokens = token.tokens(Key::Account(user)); + println!("{:?}", user_tokens); + println!("{:?}", user_tokens.first().unwrap().clone()); + token.burn_many( + Sender(owner), + user, + vec![ + user_tokens.first().unwrap().clone(), + user_tokens.last().unwrap().clone(), + ], + ); +} + +#[test] +fn test_burn_one() { + // TODO: the sender should be owner of nft item or allowed party + let (env, token, owner) = deploy(); + let user = env.next_user(); + let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; + token.mint_many(Sender(owner), user, None, token_metas.clone()); + + let mut user_tokens = token.tokens(Key::Account(user)); + token.burn_one(Sender(user), user, user_tokens.first().unwrap().clone()); + assert_eq!(token.total_supply(), U256::from(1)); + assert_eq!(token.balance_of(Key::Account(user)), U256::from(1)); + + user_tokens = token.tokens(Key::Account(user)); + assert_eq!(U256::from(user_tokens.len() as u64), U256::from(1)); +} + +#[test] +fn test_transfer_token() { + let (env, token, owner) = deploy(); + let ali = env.next_user(); + let bob = env.next_user(); + let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; + + token.mint_many(Sender(owner), ali, None, token_metas.clone()); + let mut ali_tokens = token.tokens(Key::Account(ali)); + + assert_eq!(token.total_supply(), U256::from(2)); + assert_eq!(token.balance_of(Key::Account(ali)), U256::from(2)); + assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(2)); + assert_eq!( + token.owner_of(ali_tokens.get(0).unwrap().clone()).unwrap(), + Key::Account(ali) + ); + assert_eq!( + token.owner_of(ali_tokens.get(1).unwrap().clone()).unwrap(), + Key::Account(ali) + ); + + token.transfer(Sender(ali), bob, vec![ali_tokens.get(0).unwrap().clone()]); + ali_tokens = token.tokens(Key::Account(ali)); + let bob_tokens = token.tokens(Key::Account(bob)); + assert_eq!(token.total_supply(), U256::from(2)); + assert_eq!(token.balance_of(Key::Account(ali)), U256::from(1)); + assert_eq!(token.balance_of(Key::Account(bob)), U256::from(1)); + assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(1)); + assert_eq!(U256::from(bob_tokens.len() as u64), U256::from(1)); + assert_eq!( + token.owner_of(ali_tokens.get(0).unwrap().clone()).unwrap(), + Key::Account(ali) + ); + assert_eq!( + token.owner_of(bob_tokens.get(0).unwrap().clone()).unwrap(), + Key::Account(bob) + ); +} + +#[test] +fn test_transfer_from_tokens_with_approve() { + let (env, token, owner) = deploy(); + let ali = env.next_user(); + let bob = env.next_user(); + let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; + + token.mint_many(Sender(owner), ali, None, token_metas.clone()); + let mut ali_tokens = token.tokens(Key::Account(ali)); + + assert_eq!(token.total_supply(), U256::from(2)); + assert_eq!(token.balance_of(Key::Account(ali)), U256::from(2)); + assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(2)); + assert_eq!( + token.owner_of(ali_tokens.get(0).unwrap().clone()).unwrap(), + Key::Account(ali) + ); + assert_eq!( + token.owner_of(ali_tokens.get(1).unwrap().clone()).unwrap(), + Key::Account(ali) + ); + token.approve(Sender(ali), owner, vec![ali_tokens.get(0).unwrap().clone()]); + token.transfer_from( + Sender(owner), + ali, + bob, + vec![ali_tokens.get(0).unwrap().clone()], + ); + ali_tokens = token.tokens(Key::Account(ali)); + let bob_tokens = token.tokens(Key::Account(bob)); + assert_eq!(token.total_supply(), U256::from(2)); + assert_eq!(token.balance_of(Key::Account(ali)), U256::from(1)); + assert_eq!(token.balance_of(Key::Account(bob)), U256::from(1)); + assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(1)); + assert_eq!(U256::from(bob_tokens.len() as u64), U256::from(1)); + assert_eq!( + token.owner_of(ali_tokens.get(0).unwrap().clone()).unwrap(), + Key::Account(ali) + ); + assert_eq!( + token.owner_of(bob_tokens.get(0).unwrap().clone()).unwrap(), + Key::Account(bob) + ); +} + +#[test] +#[should_panic] +fn test_transfer_from_tokens_without_approve() { + let (env, token, owner) = deploy(); + let ali = env.next_user(); + let bob = env.next_user(); + let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; + + token.mint_many(Sender(owner), ali, None, token_metas.clone()); + let ali_tokens = token.tokens(Key::Account(ali)); + + assert_eq!(token.total_supply(), U256::from(2)); + assert_eq!(token.balance_of(Key::Account(ali)), U256::from(2)); + assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(2)); + assert_eq!( + token.owner_of(ali_tokens.get(0).unwrap().clone()).unwrap(), + Key::Account(ali) + ); + assert_eq!( + token.owner_of(ali_tokens.get(1).unwrap().clone()).unwrap(), + Key::Account(ali) + ); + token.transfer_from( + Sender(owner), + ali, + bob, + vec![ali_tokens.get(0).unwrap().clone()], + ); +} + +#[test] +fn test_approve() { + let (env, token, owner) = deploy(); + let user = env.next_user(); + let token_metas = vec![ + meta::red_dragon(), + meta::blue_dragon(), + meta::black_dragon(), + meta::gold_dragon(), + ]; + + token.mint_many(Sender(owner), user, None, token_metas.clone()); + + let user_tokens = token.tokens(Key::Account(user)); + println!("{:?}", user_tokens); + println!("{:?}", user_tokens.first().unwrap().clone()); + token.approve( + Sender(user), + owner, + vec![ + user_tokens.get(0).unwrap().clone(), + user_tokens.get(2).unwrap().clone(), + ], + ); + assert_eq!( + token + .get_approved(user, user_tokens.get(0).unwrap().clone()) + .unwrap(), + Key::Account(owner) + ); + assert_eq!( + token + .get_approved(user, user_tokens.get(2).unwrap().clone()) + .unwrap(), + Key::Account(owner) + ); +} + +#[test] +fn test_token_metadata_update() { + let (env, token, owner) = deploy(); + let user = env.next_user(); + let token_id = TokenId::from("123456"); + + token.mint_one( + Sender(owner), + user, + Some(token_id.clone()), + meta::red_dragon(), + ); + + token.update_token_meta(Sender(owner), token_id.clone(), meta::gold_dragon()); + assert_eq!(token.token_meta(token_id).unwrap(), meta::gold_dragon()); +} diff --git a/cep47-tests/src/contract_tests.rs b/cep47-tests/src/contract_tests.rs deleted file mode 100644 index 0471782..0000000 --- a/cep47-tests/src/contract_tests.rs +++ /dev/null @@ -1,311 +0,0 @@ -use crate::cep47::{token_cfg, CasperCEP47Contract, Meta, TokenId}; -use casper_types::U256; - -mod meta { - use super::Meta; - use maplit::btreemap; - - pub fn red_dragon() -> Meta { - btreemap! { - "color".to_string() => "red".to_string() - } - } - - pub fn blue_dragon() -> Meta { - btreemap! { - "color".to_string() => "blue".to_string() - } - } - - pub fn black_dragon() -> Meta { - btreemap! { - "color".to_string() => "black".to_string() - } - } - - pub fn gold_dragon() -> Meta { - btreemap! { - "color".to_string() => "gold".to_string() - } - } -} - -#[test] -fn test_deploy() { - let contract = CasperCEP47Contract::deploy(); - - assert_eq!(contract.name(), token_cfg::NAME); - assert_eq!(contract.symbol(), token_cfg::SYMBOL); - assert_eq!(contract.meta(), token_cfg::contract_meta()); - assert_eq!(contract.total_supply(), U256::zero()); -} - -#[test] -fn test_token_meta() { - let mut contract = CasperCEP47Contract::deploy(); - let token_id = String::from("custom_token_id"); - let token_meta = meta::red_dragon(); - - contract.mint_one( - &contract.ali.clone(), - Some(&token_id), - &token_meta, - &contract.admin.clone(), - ); - - let ali_token_meta = contract.token_meta(&token_id).unwrap(); - assert_eq!(ali_token_meta, token_meta); - - let ali_tokens: Vec = contract.tokens(&contract.ali); - assert_eq!(ali_tokens, vec![token_id]); -} - -#[test] -fn test_mint_one_with_random_token_id() { - let mut contract = CasperCEP47Contract::deploy(); - let token_meta = meta::red_dragon(); - contract.mint_one( - &contract.ali.clone(), - None, - &token_meta, - &contract.admin.clone(), - ); - - assert_eq!(contract.total_supply(), U256::one()); - assert_eq!(contract.balance_of(&contract.ali), U256::one()); - - let ali_tokens: Vec = contract.tokens(&contract.ali); - assert_eq!(U256::from(ali_tokens.len() as u64), U256::one()); - assert_eq!(contract.owner_of(&ali_tokens[0]), Some(contract.ali)); -} - -#[test] -fn test_mint_one_with_set_token_id() { - let mut contract = CasperCEP47Contract::deploy(); - let token_id = TokenId::from("123456"); - let token_meta = meta::red_dragon(); - contract.mint_one( - &contract.ali.clone(), - Some(&token_id), - &token_meta, - &contract.admin.clone(), - ); - - let ali_tokens: Vec = contract.tokens(&contract.ali); - assert_eq!(ali_tokens, vec![token_id.clone()]); - assert_eq!(contract.total_supply(), U256::one()); - assert_eq!(contract.balance_of(&contract.ali), U256::one()); - assert_eq!(U256::from(ali_tokens.len() as u64), U256::one()); - assert_eq!(contract.owner_of(&token_id), Some(contract.ali)); -} - -#[test] -#[should_panic] -fn test_mint_one_with_not_unique_token_id() { - let mut contract = CasperCEP47Contract::deploy(); - let token_id = TokenId::from("123456"); - let token_meta = meta::red_dragon(); - contract.mint_one( - &contract.ali.clone(), - Some(&token_id), - &token_meta, - &contract.admin.clone(), - ); - contract.mint_one( - &contract.ali.clone(), - Some(&token_id), - &token_meta, - &contract.admin.clone(), - ); -} - -#[test] -fn test_mint_copies() { - let mut contract = CasperCEP47Contract::deploy(); - let token_meta = meta::gold_dragon(); - contract.mint_copies( - &contract.ali.clone(), - None, - &token_meta, - 3, - &contract.admin.clone(), - ); - - let ali_tokens: Vec = contract.tokens(&contract.ali); - assert_eq!(contract.total_supply(), U256::from(3)); - assert_eq!(contract.balance_of(&contract.ali), U256::from(3)); - assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(3)); - assert_eq!(contract.owner_of(&ali_tokens[0]), Some(contract.ali)); - assert_eq!(contract.owner_of(&ali_tokens[1]), Some(contract.ali)); - assert_eq!(contract.owner_of(&ali_tokens[2]), Some(contract.ali)); -} - -#[test] -fn test_mint_many() { - let mut contract = CasperCEP47Contract::deploy(); - let token_metas: Vec = vec![meta::gold_dragon(), meta::red_dragon()]; - contract.mint_many( - &contract.ali.clone(), - None, - &token_metas, - &contract.admin.clone(), - ); - - let ali_tokens: Vec = contract.tokens(&contract.ali); - - assert_eq!(contract.total_supply(), U256::from(2)); - assert_eq!(contract.balance_of(&contract.ali), U256::from(2)); - assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(2)); - assert_eq!(contract.owner_of(&ali_tokens[0]), Some(contract.ali)); - assert_eq!(contract.owner_of(&ali_tokens[1]), Some(contract.ali)); -} - -#[test] -fn test_burn_many() { - let mut contract = CasperCEP47Contract::deploy(); - let token_metas: Vec = vec![ - meta::gold_dragon(), - meta::blue_dragon(), - meta::black_dragon(), - meta::red_dragon(), - ]; - contract.mint_many( - &contract.ali.clone(), - None, - &token_metas, - &contract.admin.clone(), - ); - - let ali_tokens: Vec = contract.tokens(&contract.ali); - println!("{:?}", ali_tokens); - println!("{:?}", ali_tokens.first().unwrap().clone()); - - contract.burn_many( - &contract.ali.clone(), - &vec![ - ali_tokens.first().unwrap().clone(), - ali_tokens.last().unwrap().clone(), - ], - &contract.admin.clone(), - ); - assert_eq!(contract.total_supply(), U256::from(2)); - assert_eq!(contract.balance_of(&contract.ali), U256::from(2)); - - let ali_tokens = contract.tokens(&contract.ali); - println!("{:?}", ali_tokens); - assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(2)); -} - -#[test] -fn test_burn_one() { - let mut contract = CasperCEP47Contract::deploy(); - let token_metas: Vec = vec![meta::gold_dragon(), meta::red_dragon()]; - contract.mint_many( - &contract.ali.clone(), - None, - &token_metas, - &contract.admin.clone(), - ); - - let ali_tokens = contract.tokens(&contract.ali); - - contract.burn_one( - &contract.ali.clone(), - ali_tokens.first().unwrap(), - &contract.admin.clone(), - ); - assert_eq!(contract.total_supply(), U256::from(1)); - assert_eq!(contract.balance_of(&contract.ali), U256::from(1)); - - let ali_tokens = contract.tokens(&contract.ali); - assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(1)); -} - -#[test] -fn test_transfer_token() { - let mut contract = CasperCEP47Contract::deploy(); - let token_metas: Vec = vec![meta::gold_dragon(), meta::blue_dragon()]; - contract.mint_many( - &contract.ali.clone(), - None, - &token_metas, - &contract.admin.clone(), - ); - - let ali_tokens: Vec = contract.tokens(&contract.ali); - - contract.transfer_token(&contract.bob.clone(), &ali_tokens[1], &contract.ali.clone()); - - assert_eq!(contract.balance_of(&contract.ali), U256::from(1)); - assert_eq!(contract.balance_of(&contract.bob), U256::from(1)); - assert_eq!(contract.total_supply(), U256::from(2)); - assert_eq!(contract.owner_of(&ali_tokens[0]), Some(contract.ali)); - assert_eq!(contract.owner_of(&ali_tokens[1]), Some(contract.bob)); -} - -#[test] -fn test_transfer_many_tokens() { - let mut contract = CasperCEP47Contract::deploy(); - let token_metas: Vec = vec![ - meta::gold_dragon(), - meta::black_dragon(), - meta::black_dragon(), - ]; - contract.mint_many( - &contract.ali.clone(), - None, - &token_metas, - &contract.admin.clone(), - ); - let ali_tokens: Vec = contract.tokens(&contract.ali); - contract.transfer_many_tokens( - &contract.bob.clone(), - &ali_tokens[..2].to_vec(), - &contract.ali.clone(), - ); - - assert_eq!(contract.balance_of(&contract.ali), U256::from(1)); - assert_eq!(contract.balance_of(&contract.bob), U256::from(2)); - assert_eq!(contract.total_supply(), U256::from(3)); - assert_eq!(contract.owner_of(&ali_tokens[0]), Some(contract.bob)); - assert_eq!(contract.owner_of(&ali_tokens[1]), Some(contract.bob)); - assert_eq!(contract.owner_of(&ali_tokens[2]), Some(contract.ali)); -} - -#[test] -fn test_transfer_all_tokens() { - let mut contract = CasperCEP47Contract::deploy(); - let token_metas: Vec = vec![meta::gold_dragon(), meta::blue_dragon()]; - contract.mint_many( - &contract.ali.clone(), - None, - &token_metas, - &contract.admin.clone(), - ); - - let ali_tokens: Vec = contract.tokens(&contract.ali); - - contract.transfer_all_tokens(&contract.bob.clone(), &contract.ali.clone()); - assert_eq!(contract.balance_of(&contract.ali), U256::from(0)); - assert_eq!(contract.balance_of(&contract.bob), U256::from(2)); - assert_eq!(contract.total_supply(), U256::from(2)); - - assert_eq!(contract.owner_of(&ali_tokens[0]), Some(contract.bob)); - assert_eq!(contract.owner_of(&ali_tokens[1]), Some(contract.bob)); -} - -#[test] -fn test_token_metadata_update() { - let mut contract = CasperCEP47Contract::deploy(); - let token_id = TokenId::from("123456"); - let token_meta = meta::red_dragon(); - contract.mint_one( - &contract.ali.clone(), - Some(&token_id), - &token_meta, - &contract.admin.clone(), - ); - - contract.update_token_metadata(&token_id, &meta::blue_dragon(), &contract.admin.clone()); - assert_eq!(contract.token_meta(&token_id).unwrap(), meta::blue_dragon()); -} diff --git a/cep47-tests/src/lib.rs b/cep47-tests/src/lib.rs index f86f3b0..058c332 100644 --- a/cep47-tests/src/lib.rs +++ b/cep47-tests/src/lib.rs @@ -1,5 +1,5 @@ #[cfg(test)] -pub mod cep47; +pub mod cep47_tests; #[cfg(test)] -pub mod contract_tests; +pub mod cep47_instance; diff --git a/cep47-tests/wasm/.gitkeep b/cep47-tests/wasm/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/cep47/Cargo.toml b/cep47/Cargo.toml index fc0a308..8e8b95f 100644 --- a/cep47/Cargo.toml +++ b/cep47/Cargo.toml @@ -5,33 +5,14 @@ authors = ["astro019 "] edition = "2018" [dependencies] -hex = "0.4.3" -casper-contract = "1.3.1" -casper-types = "1.3.1" -cep47-logic = { path = "../cep47-logic" } +hex = { version = "0.4.3", default-features = false } +casper-contract = "1.3.2" +casper-types = "1.3.2" +contract-utils = { path = "../utils/contract-utils" } -[lib] -name = "cep47" - -[features] -default = ["casper-contract/std", "casper-types/std"] -no_name = [] -no_symbol = [] -no_meta = [] -no_balance_of = [] -no_owner_of = [] -no_total_supply = [] -no_token_uri = [] -no_tokens = [] -no_is_paused = [] -no_pause = [] -no_unpause = [] -no_mint_one = [] -no_mint_many = [] -no_mint_copies = [] -no_burn_many = [] -no_burn_one = [] -no_transfer_token = [] -no_transfer_many_tokens = [] -no_transfer_all_tokens = [] -no_update_token_metadata = [] \ No newline at end of file +[[bin]] +name = "cep47-token" +path = "bin/cep47_token.rs" +bench = false +doctest = false +test = false diff --git a/cep47/bin/cep47_token.rs b/cep47/bin/cep47_token.rs new file mode 100644 index 0000000..3cbbbab --- /dev/null +++ b/cep47/bin/cep47_token.rs @@ -0,0 +1,352 @@ +#![no_main] +#![no_std] + +#[macro_use] +extern crate alloc; + +use alloc::{ + boxed::Box, + collections::BTreeSet, + format, + string::{String, ToString}, + vec::Vec, +}; +use casper_contract::{ + contract_api::{runtime, storage}, + unwrap_or_revert::UnwrapOrRevert, +}; +use casper_types::{ + contracts::NamedKeys, runtime_args, CLType, CLTyped, CLValue, EntryPoint, EntryPointAccess, + EntryPointType, EntryPoints, Group, Key, Parameter, RuntimeArgs, URef, U256, +}; +use cep47::{Meta, TokenId, CEP47}; +use contract_utils::{ContractContext, OnChainContractStorage}; + +#[derive(Default)] +struct NFTToken(OnChainContractStorage); + +impl ContractContext for NFTToken { + fn storage(&self) -> &OnChainContractStorage { + &self.0 + } +} + +impl CEP47 for NFTToken {} +impl NFTToken { + fn constructor(&mut self, name: String, symbol: String, meta: Meta) { + CEP47::init(self, name, symbol, meta); + } +} + +#[no_mangle] +fn constructor() { + let name = runtime::get_named_arg::("name"); + let symbol = runtime::get_named_arg::("symbol"); + let meta = runtime::get_named_arg::("meta"); + NFTToken::default().constructor(name, symbol, meta); +} + +#[no_mangle] +fn name() { + let ret = NFTToken::default().name(); + runtime::ret(CLValue::from_t(ret).unwrap_or_revert()); +} + +#[no_mangle] +fn symbol() { + let ret = NFTToken::default().symbol(); + runtime::ret(CLValue::from_t(ret).unwrap_or_revert()); +} + +#[no_mangle] +fn meta() { + let ret = NFTToken::default().meta(); + runtime::ret(CLValue::from_t(ret).unwrap_or_revert()); +} + +#[no_mangle] +fn total_supply() { + let ret = NFTToken::default().total_supply(); + runtime::ret(CLValue::from_t(ret).unwrap_or_revert()); +} + +#[no_mangle] +fn balance_of() { + let owner = runtime::get_named_arg::("owner"); + let ret = NFTToken::default().balance_of(owner); + runtime::ret(CLValue::from_t(ret).unwrap_or_revert()); +} + +#[no_mangle] +fn owner_of() { + let token_id = runtime::get_named_arg::("token_id"); + let ret = NFTToken::default().owner_of(token_id); + runtime::ret(CLValue::from_t(ret).unwrap_or_revert()); +} + +#[no_mangle] +fn token_meta() { + let token_id = runtime::get_named_arg::("token_id"); + let ret = NFTToken::default().token_meta(token_id); + runtime::ret(CLValue::from_t(ret).unwrap_or_revert()); +} + +#[no_mangle] +fn update_token_meta() { + let token_id = runtime::get_named_arg::("token_id"); + let token_meta = runtime::get_named_arg::("token_meta"); + NFTToken::default() + .set_token_meta(token_id, token_meta) + .unwrap_or_revert(); +} + +#[no_mangle] +fn tokens() { + let owner = runtime::get_named_arg::("owner"); + let ret = NFTToken::default().get_tokens(owner); + runtime::ret(CLValue::from_t(ret).unwrap_or_revert()); +} + +#[no_mangle] +fn mint() { + let recipient = runtime::get_named_arg::("recipient"); + let token_ids = runtime::get_named_arg::>>("token_ids"); + let token_metas = runtime::get_named_arg::>("token_metas"); + NFTToken::default() + .mint(recipient, token_ids, token_metas) + .unwrap_or_revert(); +} + +#[no_mangle] +fn mint_copies() { + let recipient = runtime::get_named_arg::("recipient"); + let token_ids = runtime::get_named_arg::>>("token_ids"); + let token_meta = runtime::get_named_arg::("token_meta"); + let count = runtime::get_named_arg::("count"); + NFTToken::default() + .mint_copies(recipient, token_ids, token_meta, count) + .unwrap_or_revert(); +} + +#[no_mangle] +fn burn() { + let owner = runtime::get_named_arg::("owner"); + let token_ids = runtime::get_named_arg::>("token_ids"); + NFTToken::default() + .burn(owner, token_ids) + .unwrap_or_revert(); +} + +#[no_mangle] +fn transfer() { + let recipient = runtime::get_named_arg::("recipient"); + let token_ids = runtime::get_named_arg::>("token_ids"); + NFTToken::default() + .transfer(recipient, token_ids) + .unwrap_or_revert(); +} + +#[no_mangle] +fn transfer_from() { + let sender = runtime::get_named_arg::("sender"); + let recipient = runtime::get_named_arg::("recipient"); + let token_ids = runtime::get_named_arg::>("token_ids"); + NFTToken::default() + .transfer_from(sender, recipient, token_ids) + .unwrap_or_revert(); +} + +#[no_mangle] +fn approve() { + let spender = runtime::get_named_arg::("spender"); + let token_ids = runtime::get_named_arg::>("token_ids"); + NFTToken::default() + .approve(spender, token_ids) + .unwrap_or_revert(); +} + +#[no_mangle] +fn get_approved() { + let owner = runtime::get_named_arg::("owner"); + let token_id = runtime::get_named_arg::("token_id"); + let ret = NFTToken::default().get_approved(owner, token_id); + runtime::ret(CLValue::from_t(ret).unwrap_or_revert()); +} + +#[no_mangle] +fn call() { + let (package_hash, access_token) = storage::create_contract_package_at_hash(); + let mut named_keys = NamedKeys::new(); + let contract_package_hash_wrapped = storage::new_uref(package_hash).into(); + named_keys.insert( + "contract_package_hash".to_string(), + contract_package_hash_wrapped, + ); + let (contract_hash, _) = + storage::add_contract_version(package_hash, get_entry_points(), named_keys); + + // Read arguments for the constructor call. + let name: String = runtime::get_named_arg("name"); + let symbol: String = runtime::get_named_arg("symbol"); + let meta: Meta = runtime::get_named_arg("meta"); + + // Prepare constructor args + let constructor_args = runtime_args! { + "name" => name, + "symbol" => symbol, + "meta" => meta + }; + + // Add the constructor group to the package hash with a single URef. + let constructor_access: URef = + storage::create_contract_user_group(package_hash, "constructor", 1, Default::default()) + .unwrap_or_revert() + .pop() + .unwrap_or_revert(); + + // Call the constructor entry point + let _: () = + runtime::call_versioned_contract(package_hash, None, "constructor", constructor_args); + + // Remove all URefs from the constructor group, so no one can call it for the second time. + let mut urefs = BTreeSet::new(); + urefs.insert(constructor_access); + storage::remove_contract_user_group_urefs(package_hash, "constructor", urefs) + .unwrap_or_revert(); + + // Store contract in the account's named keys. + let contract_name: alloc::string::String = runtime::get_named_arg("contract_name"); + runtime::put_key( + &format!("{}_package_hash", contract_name), + package_hash.into(), + ); + runtime::put_key( + &format!("{}_package_hash_wrapped", contract_name), + contract_package_hash_wrapped, + ); + runtime::put_key( + &format!("{}_contract_hash", contract_name), + contract_hash.into(), + ); + runtime::put_key( + &format!("{}_contract_hash_wrapped", contract_name), + storage::new_uref(contract_hash).into(), + ); + runtime::put_key( + &format!("{}_package_access_token", contract_name), + access_token.into(), + ); +} + +fn get_entry_points() -> EntryPoints { + let mut entry_points = EntryPoints::new(); + entry_points.add_entry_point(EntryPoint::new( + "constructor", + vec![ + Parameter::new("name", String::cl_type()), + Parameter::new("symbol", String::cl_type()), + Parameter::new("meta", Meta::cl_type()), + ], + <()>::cl_type(), + EntryPointAccess::Groups(vec![Group::new("constructor")]), + EntryPointType::Contract, + )); + entry_points.add_entry_point(EntryPoint::new( + "mint", + vec![ + Parameter::new("recipient", Key::cl_type()), + Parameter::new( + "token_ids", + CLType::Option(Box::new(CLType::List(Box::new(TokenId::cl_type())))), + ), + Parameter::new("token_metas", CLType::List(Box::new(Meta::cl_type()))), + ], + <()>::cl_type(), + EntryPointAccess::Public, + EntryPointType::Contract, + )); + entry_points.add_entry_point(EntryPoint::new( + "mint_copies", + vec![ + Parameter::new("recipient", Key::cl_type()), + Parameter::new( + "token_ids", + CLType::Option(Box::new(CLType::List(Box::new(TokenId::cl_type())))), + ), + Parameter::new("token_meta", Meta::cl_type()), + Parameter::new("count", CLType::U32), + ], + <()>::cl_type(), + EntryPointAccess::Public, + EntryPointType::Contract, + )); + entry_points.add_entry_point(EntryPoint::new( + "burn", + vec![ + Parameter::new("owner", Key::cl_type()), + Parameter::new("token_ids", CLType::List(Box::new(TokenId::cl_type()))), + ], + <()>::cl_type(), + EntryPointAccess::Public, + EntryPointType::Contract, + )); + entry_points.add_entry_point(EntryPoint::new( + "transfer", + vec![ + Parameter::new("recipient", Key::cl_type()), + Parameter::new("token_ids", CLType::List(Box::new(TokenId::cl_type()))), + ], + <()>::cl_type(), + EntryPointAccess::Public, + EntryPointType::Contract, + )); + entry_points.add_entry_point(EntryPoint::new( + "transfer_from", + vec![ + Parameter::new("sender", Key::cl_type()), + Parameter::new("recipient", Key::cl_type()), + Parameter::new("token_ids", CLType::List(Box::new(TokenId::cl_type()))), + ], + <()>::cl_type(), + EntryPointAccess::Public, + EntryPointType::Contract, + )); + entry_points.add_entry_point(EntryPoint::new( + "approve", + vec![ + Parameter::new("spender", Key::cl_type()), + Parameter::new("token_ids", CLType::List(Box::new(TokenId::cl_type()))), + ], + <()>::cl_type(), + EntryPointAccess::Public, + EntryPointType::Contract, + )); + entry_points.add_entry_point(EntryPoint::new( + "get_approved", + vec![ + Parameter::new("owner", Key::cl_type()), + Parameter::new("token_id", TokenId::cl_type()), + ], + CLType::Option(Box::new(CLType::Key)), + EntryPointAccess::Public, + EntryPointType::Contract, + )); + entry_points.add_entry_point(EntryPoint::new( + "update_token_meta", + vec![ + Parameter::new("token_id", TokenId::cl_type()), + Parameter::new("token_meta", Meta::cl_type()), + ], + <()>::cl_type(), + EntryPointAccess::Public, + EntryPointType::Contract, + )); + entry_points.add_entry_point(EntryPoint::new( + "total_supply", + vec![], + U256::cl_type(), + EntryPointAccess::Public, + EntryPointType::Contract, + )); + entry_points +} diff --git a/cep47/src/cep47.rs b/cep47/src/cep47.rs new file mode 100644 index 0000000..c1ddc9a --- /dev/null +++ b/cep47/src/cep47.rs @@ -0,0 +1,332 @@ +use crate::{ + data::{self, Allowances, Balances, Metadata, OwnedTokens, Owners}, + event::CEP47Event, + Meta, TokenId, +}; +use alloc::{string::String, vec::Vec}; +use casper_contract::{contract_api::runtime, unwrap_or_revert::UnwrapOrRevert}; +use casper_types::{bytesrepr::ToBytes, ApiError, Key, U256}; +use contract_utils::{ContractContext, ContractStorage}; + +#[repr(u16)] +pub enum Error { + PermissionDenied = 1, + ArgumentsError = 2, + TokenIdAlreadyExists = 3, + TokenIdDoesntExist = 4, +} + +impl From for ApiError { + fn from(error: Error) -> ApiError { + ApiError::User(error as u16) + } +} + +pub trait CEP47: ContractContext { + fn init(&mut self, name: String, symbol: String, meta: Meta) { + data::set_name(name); + data::set_symbol(symbol); + data::set_meta(meta); + data::set_total_supply(U256::zero()); + Owners::init(); + OwnedTokens::init(); + Metadata::init(); + Balances::init(); + Allowances::init(); + } + + fn name(&self) -> String { + data::name() + } + + fn symbol(&self) -> String { + data::symbol() + } + + fn meta(&self) -> Meta { + data::meta() + } + + fn total_supply(&self) -> U256 { + data::total_supply() + } + + fn balance_of(&self, owner: Key) -> U256 { + Balances::instance().get(&owner) + } + + fn owner_of(&self, token_id: TokenId) -> Option { + Owners::instance().get(&token_id) + } + + fn token_meta(&self, token_id: TokenId) -> Option { + Metadata::instance().get(&token_id) + } + + fn set_token_meta(&mut self, token_id: TokenId, meta: Meta) -> Result<(), Error> { + if self.owner_of(token_id.clone()).is_none() { + return Err(Error::TokenIdAlreadyExists); + }; + + let metadata_dict = Metadata::instance(); + metadata_dict.set(&token_id, meta); + + self.emit(CEP47Event::MetadataUpdate { token_id }); + Ok(()) + } + + fn get_tokens(&self, owner: Key) -> Vec { + OwnedTokens::instance().get(&owner) + } + + fn set_tokens(&mut self, owner: Key, token_ids: Vec) { + let owners_dict = Owners::instance(); + let owned_tokens_dict = OwnedTokens::instance(); + let balances_dict = Balances::instance(); + + for token_id in &token_ids { + owners_dict.set(token_id, owner); + } + + let prev_balance = balances_dict.get(&owner); + let new_balance = U256::from(token_ids.len() as u64); + balances_dict.set(&owner, new_balance); + + owned_tokens_dict.set(&owner, token_ids); + + let new_total_supply = data::total_supply() - prev_balance + new_balance; + data::set_total_supply(new_total_supply); + } + + fn generate_token_ids(&mut self, n: u32) -> Vec { + let block_time = runtime::get_blocktime(); + let mut token_ids = Vec::new(); + let nonce = data::nonce(); + for i in nonce..nonce + n { + let mut bytes: Vec = block_time.to_bytes().unwrap_or_revert(); + bytes.append(&mut i.to_bytes().unwrap_or_revert()); + let hash = runtime::blake2b(bytes); + token_ids.push(hex::encode(hash)); + } + data::set_nonce(nonce + n); + token_ids + } + + fn validate_token_ids(&self, token_ids: Vec) -> bool { + for token_id in &token_ids { + if self.owner_of(token_id.clone()).is_some() { + return false; + } + } + true + } + + fn mint( + &mut self, + recipient: Key, + token_ids: Option>, + token_metas: Vec, + ) -> Result<(), Error> { + let unique_token_ids = match token_ids { + // Validate token_ids and metas. + Some(token_ids) => { + if token_ids.len() != token_metas.len() { + return Err(Error::ArgumentsError); + }; + let valid = self.validate_token_ids(token_ids.clone()); + if !valid { + return Err(Error::TokenIdAlreadyExists); + }; + token_ids + } + None => self.generate_token_ids(token_metas.len() as u32), + }; + + let owners_dict = Owners::instance(); + let owned_tokens_dict = OwnedTokens::instance(); + let metadata_dict = Metadata::instance(); + let balances_dict = Balances::instance(); + + let mut recipient_tokens = owned_tokens_dict.get(&recipient); + for (token_id, token_meta) in unique_token_ids.iter().zip(&token_metas) { + metadata_dict.set(token_id, token_meta.clone()); + owners_dict.set(token_id, recipient); + recipient_tokens.push(token_id.clone()); + } + + owned_tokens_dict.set(&recipient, recipient_tokens); + + let minted_tokens_count = U256::from(unique_token_ids.len() as u64); + let prev_balance = balances_dict.get(&recipient); + let new_balance = prev_balance + minted_tokens_count; + balances_dict.set(&recipient, new_balance); + + let new_total_supply = data::total_supply() + minted_tokens_count; + data::set_total_supply(new_total_supply); + + self.emit(CEP47Event::Mint { + recipient, + token_ids: unique_token_ids, + }); + Ok(()) + } + + fn mint_copies( + &mut self, + recipient: Key, + token_ids: Option>, + token_meta: Meta, + count: u32, + ) -> Result<(), Error> { + if let Some(token_ids) = &token_ids { + if token_ids.len() != count as usize { + return Err(Error::ArgumentsError); + } + } + let token_metas = vec![token_meta; count as usize]; + self.mint(recipient, token_ids, token_metas) + } + + fn burn(&mut self, owner: Key, token_ids: Vec) -> Result<(), Error> { + let owners_dict = Owners::instance(); + let owned_tokens_dict = OwnedTokens::instance(); + let metadata_dict = Metadata::instance(); + let balances_dict = Balances::instance(); + let allowances_dict = Allowances::instance(); + + let mut owner_tokens = owned_tokens_dict.get(&owner); + let spender = self.get_caller(); + + for token_id in &token_ids { + if spender != owner && !self.is_approved(owner, token_id.clone(), spender) { + return Err(Error::PermissionDenied); + } + match owners_dict.get(token_id) { + Some(owner_of_key) => { + if owner_of_key != owner { + return Err(Error::PermissionDenied); + } + } + None => { + return Err(Error::TokenIdDoesntExist); + } + } + let index = owner_tokens + .iter() + .position(|x| x == token_id) + .unwrap_or_revert(); + owner_tokens.remove(index); + metadata_dict.remove(token_id); + owners_dict.remove(token_id); + allowances_dict.remove(&owner, token_id); + } + + balances_dict.set(&owner, U256::from(owner_tokens.len() as u64)); + owned_tokens_dict.set(&owner, owner_tokens); + + let burnt_tokens_count = U256::from(token_ids.len() as u64); + let new_total_supply = data::total_supply() - burnt_tokens_count; + data::set_total_supply(new_total_supply); + + self.emit(CEP47Event::Burn { owner, token_ids }); + Ok(()) + } + + fn approve(&mut self, spender: Key, token_ids: Vec) -> Result<(), Error> { + let caller = self.get_caller(); + for token_id in &token_ids { + let owner = self.owner_of(token_id.clone()); + if owner.is_none() { + return Err(Error::ArgumentsError); + } + if owner.unwrap() != caller { + return Err(Error::PermissionDenied); + } + Allowances::instance().set(&caller, token_id, spender); + } + self.emit(CEP47Event::Approve { + owner: caller, + spender, + token_ids, + }); + Ok(()) + } + + fn get_approved(&self, owner: Key, token_id: TokenId) -> Option { + Allowances::instance().get(&owner, &token_id) + } + + fn transfer(&mut self, recipient: Key, token_ids: Vec) -> Result<(), Error> { + self.transfer_from(self.get_caller(), recipient, token_ids) + } + + fn transfer_from( + &mut self, + owner: Key, + recipient: Key, + token_ids: Vec, + ) -> Result<(), Error> { + let allowances_dict = Allowances::instance(); + let spender = self.get_caller(); + if owner != spender { + for token_id in &token_ids { + if !self.is_approved(owner, token_id.clone(), spender) { + return Err(Error::PermissionDenied); + } + allowances_dict.remove(&owner, token_id); + } + } + + let owners_dict = Owners::instance(); + let owned_tokens_dict = OwnedTokens::instance(); + let balances_dict = Balances::instance(); + + let mut sender_tokens = owned_tokens_dict.get(&owner); + let mut recipient_tokens = owned_tokens_dict.get(&recipient); + for token_id in &token_ids { + match owners_dict.get(token_id) { + Some(owner_of_key) => { + if owner_of_key != owner { + return Err(Error::PermissionDenied); + } + } + None => { + return Err(Error::TokenIdDoesntExist); + } + } + let index = sender_tokens + .iter() + .position(|x| x == token_id) + .unwrap_or_revert(); + sender_tokens.remove(index); + recipient_tokens.push(token_id.clone()); + owners_dict.set(token_id, recipient); + } + + balances_dict.set(&owner, sender_tokens.len().into()); + owned_tokens_dict.set(&owner, sender_tokens); + + balances_dict.set(&recipient, recipient_tokens.len().into()); + owned_tokens_dict.set(&recipient, recipient_tokens); + self.emit(CEP47Event::Transfer { + sender: owner, + recipient, + token_ids, + }); + Ok(()) + } + + fn is_approved(&self, owner: Key, token_id: TokenId, spender: Key) -> bool { + let allowances_dict = Allowances::instance(); + if let Some(spender_of) = allowances_dict.get(&owner, &token_id) { + if spender_of == spender { + return true; + } + } + return false; + } + + fn emit(&mut self, event: CEP47Event) { + data::emit(&event); + } +} diff --git a/cep47/src/cep47_storage.rs b/cep47/src/cep47_storage.rs deleted file mode 100644 index 143c942..0000000 --- a/cep47/src/cep47_storage.rs +++ /dev/null @@ -1,198 +0,0 @@ -use casper_contract::{contract_api::runtime, unwrap_or_revert::UnwrapOrRevert}; -use casper_types::{bytesrepr::ToBytes, ApiError, Key, U256}; -use cep47_logic::{CEP47Storage, Meta, TokenId}; - -use crate::data::{self, Balances, Metadata, OwnedTokens, Owners}; - -#[derive(Default)] -pub struct CasperCEP47Storage {} -impl CasperCEP47Storage { - pub fn new() -> CasperCEP47Storage { - CasperCEP47Storage {} - } -} - -impl CEP47Storage for CasperCEP47Storage { - fn name(&self) -> String { - data::name() - } - - fn symbol(&self) -> String { - data::symbol() - } - - fn meta(&self) -> Meta { - data::meta() - } - - fn total_supply(&self) -> U256 { - data::total_supply() - } - - fn balance_of(&self, owner: &Key) -> U256 { - Balances::instance().get(owner) - } - - fn onwer_of(&self, token_id: &TokenId) -> Option { - Owners::instance().get(token_id) - } - - fn token_meta(&self, token_id: &TokenId) -> Option { - Metadata::instance().get(token_id) - } - - fn is_paused(&self) -> bool { - data::is_paused() - } - - fn pause(&mut self) { - data::pause(); - } - - fn unpause(&mut self) { - data::unpause(); - } - - fn get_tokens(&self, owner: &Key) -> Vec { - OwnedTokens::instance().get(owner) - } - - fn set_tokens(&mut self, owner: &Key, token_ids: Vec) { - // Prepare dictionaries. - let owners_dict = Owners::instance(); - let owned_tokens_dict = OwnedTokens::instance(); - let balances_dict = Balances::instance(); - - // Update the owner for each token. - for token_id in &token_ids { - owners_dict.set(token_id, *owner); - } - - // Update balance of the owner. - let prev_balance = balances_dict.get(owner); - let new_balance = U256::from(token_ids.len() as u64); - balances_dict.set(owner, new_balance); - - // Update owner's list of tokens. - owned_tokens_dict.set(owner, token_ids); - - // Update total_supply. - let new_total_supply = data::total_supply() - prev_balance + new_balance; - data::update_total_supply(new_total_supply); - } - - fn mint_many(&mut self, recipient: &Key, token_ids: &Vec, token_metas: &Vec) { - // Prepare dictionaries. - let owners_dict = Owners::instance(); - let owned_tokens_dict = OwnedTokens::instance(); - let balances_dict = Balances::instance(); - let metadata_dict = Metadata::instance(); - - // Load recipient's tokens. - let mut recipient_tokens = owned_tokens_dict.get(recipient); - - // Create new tokens. - for (token_id, token_meta) in token_ids.iter().zip(token_metas) { - // Set metadata. - metadata_dict.set(token_id, token_meta.clone()); - - // Set token owner. - owners_dict.set(token_id, *recipient); - - // Update current list of recipient's tokens. - recipient_tokens.push(token_id.clone()); - } - - // Update owned tokens. - owned_tokens_dict.set(recipient, recipient_tokens); - - // Update recipient's balance. - let new_tokens_count: U256 = token_ids.len().into(); - let prev_balance = balances_dict.get(recipient); - let new_balance = prev_balance + new_tokens_count; - balances_dict.set(recipient, new_balance); - - // Update total supply. - let new_total_supply = data::total_supply() + new_tokens_count; - data::update_total_supply(new_total_supply); - } - - fn burn_many(&mut self, owner: &Key, token_ids: &Vec) { - // Prepare dictionaries. - let owners_dict = Owners::instance(); - let owned_tokens_dict = OwnedTokens::instance(); - let balances_dict = Balances::instance(); - let metadata_dict = Metadata::instance(); - - // Load owner's tokens. - let mut owner_tokens = owned_tokens_dict.get(owner); - - // Remove tokens. - for token_id in token_ids { - // Remove token form the onwer's list. - // Make sure that token is owned by the recipient. - let index = owner_tokens - .iter() - .position(|x| x == token_id) - .unwrap_or_revert(); - owner_tokens.remove(index); - - // TODO: Remove meta. - metadata_dict.remove(token_id); - - // TODO: Remove ownership. - owners_dict.remove(token_id); - } - - // Decrement owner's balance. - balances_dict.set(owner, owner_tokens.len().into()); - - // Update owner's tokens. - owned_tokens_dict.set(owner, owner_tokens); - - // Decrement total supply. - let remove_tokens_count: U256 = token_ids.len().into(); - let new_total_supply = data::total_supply() - remove_tokens_count; - data::update_total_supply(new_total_supply); - } - - fn update_token_metadata(&mut self, token_id: &TokenId, meta: Meta) { - let metadata_dict = Metadata::instance(); - let current_meta = metadata_dict.get(token_id); - match current_meta { - None => runtime::revert(ApiError::None), - Some(_) => metadata_dict.set(token_id, meta), - }; - } - - fn gen_token_ids(&mut self, n: u32) -> Vec { - let block_time = runtime::get_blocktime(); - let mut token_ids = Vec::new(); - let nonce = data::get_nonce(); - for i in nonce..nonce + n { - let mut bytes: Vec = block_time.to_bytes().unwrap_or_revert(); - bytes.append(&mut i.to_bytes().unwrap_or_revert()); - let hash = runtime::blake2b(bytes); - token_ids.push(hex::encode(hash)); - } - data::set_nonce(nonce + n); - token_ids - } - - fn validate_token_ids(&self, token_ids: &Vec) -> bool { - for token_id in token_ids { - if self.onwer_of(token_id).is_some() { - return false; - } - } - true - } - - fn emit(&mut self, event: cep47_logic::events::CEP47Event) { - data::emit(&event) - } - - fn contact_package_hash(&self) -> casper_types::ContractPackageHash { - data::contract_package_hash() - } -} diff --git a/cep47/src/data.rs b/cep47/src/data.rs index 378b6b5..6635831 100644 --- a/cep47/src/data.rs +++ b/cep47/src/data.rs @@ -1,49 +1,26 @@ -use std::{collections::BTreeMap, convert::TryInto}; - -use casper_contract::{ - contract_api::{ - runtime, - storage::{self, new_dictionary}, - }, - unwrap_or_revert::UnwrapOrRevert, +use alloc::{ + collections::BTreeMap, + string::{String, ToString}, + vec::Vec, }; -use casper_types::{ - bytesrepr::{FromBytes, ToBytes}, - contracts::NamedKeys, - ApiError, CLTyped, ContractPackageHash, Key, URef, U256, -}; -use cep47_logic::{events::CEP47Event, Meta, TokenId}; +use casper_contract::{contract_api::storage, unwrap_or_revert::UnwrapOrRevert}; +use casper_types::{ContractPackageHash, Key, URef, U256}; +use contract_utils::{get_key, key_and_value_to_str, set_key, Dict}; + +use crate::{event::CEP47Event, Meta, TokenId}; const BALANCES_DICT: &str = "balances"; -const OWNED_TOKENS_DICT: &str = "owned_tokens"; -const TOKEN_OWNERS_DICT: &str = "owners"; +pub const ALLOWANCES_DICT: &str = "allowances"; const METADATA_DICT: &str = "metadata"; +const OWNERS_DICT: &str = "owners"; +const OWNED_TOKENS_DICT: &str = "owned_tokens"; +const CONTRACT_PACKAGE_HASH: &str = "contract_package_hash"; -struct Dict { - uref: URef, -} - -impl Dict { - pub fn at(name: &str) -> Dict { - let key: Key = runtime::get_key(name).unwrap_or_revert(); - let uref: URef = *key.as_uref().unwrap_or_revert(); - Dict { uref } - } - - pub fn get(&self, key: &str) -> Option { - storage::dictionary_get(self.uref, key) - .unwrap_or_revert() - .unwrap_or_default() - } - - pub fn set(&self, key: &str, value: T) { - storage::dictionary_put(self.uref, key, Some(value)); - } - - pub fn remove(&self, key: &str) { - storage::dictionary_put(self.uref, key, Option::::None); - } -} +pub const NAME: &str = "name"; +pub const META: &str = "meta"; +pub const SYMBOL: &str = "symbol"; +pub const TOTAL_SUPPLY: &str = "total_supply"; +pub const NONCE: &str = "nonce"; pub struct Balances { dict: Dict, @@ -52,45 +29,21 @@ pub struct Balances { impl Balances { pub fn instance() -> Balances { Balances { - dict: Dict::at(BALANCES_DICT), + dict: Dict::instance(BALANCES_DICT), } } - pub fn get(&self, key: &Key) -> U256 { - self.dict.get(&key_to_str(key)).unwrap_or_default() - } - - pub fn set(&self, key: &Key, value: U256) { - self.dict.set(&key_to_str(key), value); - } - - // pub fn remove(&self, key: &Key) { - // self.dict.remove::(&key_to_str(key)); - // } -} - -pub struct OwnedTokens { - dict: Dict, -} - -impl OwnedTokens { - pub fn instance() -> OwnedTokens { - OwnedTokens { - dict: Dict::at(OWNED_TOKENS_DICT), - } + pub fn init() { + Dict::init(BALANCES_DICT) } - pub fn get(&self, key: &Key) -> Vec { - self.dict.get(&key_to_str(key)).unwrap_or_default() + pub fn get(&self, owner: &Key) -> U256 { + self.dict.get_by_key(owner).unwrap_or_default() } - pub fn set(&self, key: &Key, value: Vec) { - self.dict.set(&key_to_str(key), value); + pub fn set(&self, owner: &Key, value: U256) { + self.dict.set_by_key(owner, value); } - - // pub fn remove(&self, key: &Key) { - // self.dict.remove::(&key_to_str(key)); - // } } pub struct Owners { @@ -100,10 +53,14 @@ pub struct Owners { impl Owners { pub fn instance() -> Owners { Owners { - dict: Dict::at(TOKEN_OWNERS_DICT), + dict: Dict::instance(OWNERS_DICT), } } + pub fn init() { + Dict::init(OWNERS_DICT) + } + pub fn get(&self, key: &TokenId) -> Option { self.dict.get(key) } @@ -124,10 +81,14 @@ pub struct Metadata { impl Metadata { pub fn instance() -> Metadata { Metadata { - dict: Dict::at(METADATA_DICT), + dict: Dict::instance(METADATA_DICT), } } + pub fn init() { + Dict::init(METADATA_DICT) + } + pub fn get(&self, key: &TokenId) -> Option { self.dict.get(key) } @@ -141,169 +102,173 @@ impl Metadata { } } -pub fn name() -> String { - get_key("name").unwrap_or_revert() +pub struct OwnedTokens { + dict: Dict, } -pub fn symbol() -> String { - get_key("symbol").unwrap_or_revert() +impl OwnedTokens { + pub fn instance() -> OwnedTokens { + OwnedTokens { + dict: Dict::instance(OWNED_TOKENS_DICT), + } + } + + pub fn init() { + Dict::init(OWNED_TOKENS_DICT) + } + + pub fn get(&self, owner: &Key) -> Vec { + self.dict.get_by_key(owner).unwrap_or_default() + } + + pub fn set(&self, owner: &Key, value: Vec) { + self.dict.set_by_key(owner, value); + } } -pub fn meta() -> Meta { - get_key("meta").unwrap_or_revert() +pub struct Allowances { + dict: Dict, } -pub fn total_supply() -> U256 { - get_key("total_supply").unwrap_or_revert() +impl Allowances { + pub fn instance() -> Allowances { + Allowances { + dict: Dict::instance(ALLOWANCES_DICT), + } + } + + pub fn init() { + Dict::init(ALLOWANCES_DICT) + } + + pub fn get(&self, owner: &Key, token_id: &TokenId) -> Option { + self.dict + .get(key_and_value_to_str::(owner, token_id).as_str()) + } + + pub fn set(&self, owner: &Key, token_id: &TokenId, value: Key) { + self.dict.set( + key_and_value_to_str::(owner, token_id).as_str(), + value, + ); + } + + pub fn remove(&self, owner: &Key, token_id: &TokenId) { + self.dict + .remove::(key_and_value_to_str::(owner, token_id).as_str()); + } } -pub fn update_total_supply(total_supply: U256) { - set_key("total_supply", total_supply); +pub fn name() -> String { + get_key(NAME).unwrap_or_revert() } -pub fn is_paused() -> bool { - get_key("paused").unwrap() +pub fn set_name(name: String) { + set_key(NAME, name); } -pub fn pause() { - set_key("paused", true); +pub fn symbol() -> String { + get_key(SYMBOL).unwrap_or_revert() } -pub fn unpause() { - set_key("paused", false); +pub fn set_symbol(symbol: String) { + set_key(SYMBOL, symbol); } -pub fn get_nonce() -> u32 { - get_key("nonce").unwrap_or_default() +pub fn meta() -> Meta { + get_key(META).unwrap_or_revert() } -pub fn set_nonce(nonce: u32) { - set_key("nonce", nonce); +pub fn set_meta(meta: Meta) { + set_key(META, meta); } -pub fn contract_package_hash() -> ContractPackageHash { - get_key("contract_package_hash").unwrap_or_revert() +pub fn total_supply() -> U256 { + get_key(TOTAL_SUPPLY).unwrap_or_default() } -pub fn initial_named_keys( - package_hash: ContractPackageHash, - token_name: &str, - token_symbol: &str, - token_meta: Meta, - paused: bool, -) -> NamedKeys { - let mut named_keys = NamedKeys::new(); - named_keys.insert("name".to_string(), storage::new_uref(token_name).into()); - named_keys.insert("symbol".to_string(), storage::new_uref(token_symbol).into()); - named_keys.insert("meta".to_string(), storage::new_uref(token_meta).into()); - named_keys.insert( - "total_supply".to_string(), - storage::new_uref(U256::zero()).into(), - ); - named_keys.insert("paused".to_string(), storage::new_uref(paused).into()); - named_keys.insert( - "contract_package_hash".to_string(), - storage::new_uref(package_hash).into(), - ); - - // Add empty dictionaries. - add_empty_dict(&mut named_keys, BALANCES_DICT); - add_empty_dict(&mut named_keys, OWNED_TOKENS_DICT); - add_empty_dict(&mut named_keys, TOKEN_OWNERS_DICT); - add_empty_dict(&mut named_keys, METADATA_DICT); - - named_keys +pub fn set_total_supply(total_supply: U256) { + set_key(TOTAL_SUPPLY, total_supply); } -fn add_empty_dict(named_keys: &mut NamedKeys, name: &str) { - let dict = new_dictionary(name).unwrap_or_revert(); - runtime::remove_key(name); - named_keys.insert(name.to_string(), dict.into()); +pub fn nonce() -> u32 { + get_key(NONCE).unwrap_or_default() } -fn key_to_str(key: &Key) -> String { - match key { - Key::Account(account) => account.to_string(), - Key::Hash(package) => hex::encode(package), - _ => runtime::revert(ApiError::UnexpectedKeyVariant), - } +pub fn set_nonce(nonce: u32) { + set_key(NONCE, nonce); +} + +pub fn contract_package_hash() -> ContractPackageHash { + get_key(CONTRACT_PACKAGE_HASH).unwrap_or_revert() } pub fn emit(event: &CEP47Event) { let mut events = Vec::new(); let package = contract_package_hash(); match event { - CEP47Event::MetadataUpdate { token_id } => { - let mut event = BTreeMap::new(); - event.insert("contract_package_hash", package.to_string()); - event.insert("event_type", "cep47_metadata_update".to_string()); - event.insert("token_id", token_id.to_string()); - events.push(event); - } - CEP47Event::Transfer { - sender, + CEP47Event::Mint { recipient, token_ids, } => { for token_id in token_ids { - let mut event = BTreeMap::new(); - event.insert("contract_package_hash", package.to_string()); - event.insert("event_type", "cep47_transfer_token".to_string()); - event.insert("sender", sender.to_string()); - event.insert("recipient", recipient.to_string()); - event.insert("token_id", token_id.to_string()); - events.push(event); + let mut param = BTreeMap::new(); + param.insert(CONTRACT_PACKAGE_HASH, package.to_string()); + param.insert("event_type", "cep47_mint_one".to_string()); + param.insert("recipient", recipient.to_string()); + param.insert("token_id", token_id.to_string()); + events.push(param); } } - CEP47Event::Mint { - recipient, + CEP47Event::Burn { owner, token_ids } => { + for token_id in token_ids { + let mut param = BTreeMap::new(); + param.insert(CONTRACT_PACKAGE_HASH, package.to_string()); + param.insert("event_type", "cep47_burn_one".to_string()); + param.insert("owner", owner.to_string()); + param.insert("token_id", token_id.to_string()); + events.push(param); + } + } + CEP47Event::Approve { + owner, + spender, token_ids, } => { for token_id in token_ids { - let mut event = BTreeMap::new(); - event.insert("contract_package_hash", package.to_string()); - event.insert("event_type", "cep47_mint_one".to_string()); - event.insert("recipient", recipient.to_string()); - event.insert("token_id", token_id.to_string()); - events.push(event); + let mut param = BTreeMap::new(); + param.insert(CONTRACT_PACKAGE_HASH, package.to_string()); + param.insert("event_type", "cep47_approve_token".to_string()); + param.insert("owner", owner.to_string()); + param.insert("spender", spender.to_string()); + param.insert("token_id", token_id.to_string()); + events.push(param); } } - CEP47Event::Burn { owner, token_ids } => { + CEP47Event::Transfer { + sender, + recipient, + token_ids, + } => { for token_id in token_ids { - let mut event = BTreeMap::new(); - event.insert("contract_package_hash", package.to_string()); - event.insert("event_type", "cep47_burn_one".to_string()); - event.insert("owner", owner.to_string()); - event.insert("token_id", token_id.to_string()); - events.push(event); + let mut param = BTreeMap::new(); + param.insert(CONTRACT_PACKAGE_HASH, package.to_string()); + param.insert("event_type", "cep47_transfer_token".to_string()); + param.insert("sender", sender.to_string()); + param.insert("recipient", recipient.to_string()); + param.insert("token_id", token_id.to_string()); + events.push(param); } } - }; - for event in events { - let _: URef = storage::new_uref(event); - } -} - -fn get_key(name: &str) -> Option { - match runtime::get_key(name) { - None => None, - Some(value) => { - let key = value.try_into().unwrap_or_revert(); - let value = storage::read(key).unwrap_or_revert().unwrap_or_revert(); - Some(value) - } - } -} - -fn set_key(name: &str, value: T) { - match runtime::get_key(name) { - Some(key) => { - let key_ref = key.try_into().unwrap_or_revert(); - storage::write(key_ref, value); - } - None => { - let key = storage::new_uref(value).into(); - runtime::put_key(name, key); + CEP47Event::MetadataUpdate { token_id } => { + let mut param = BTreeMap::new(); + param.insert(CONTRACT_PACKAGE_HASH, package.to_string()); + param.insert("event_type", "cep47_metadata_update".to_string()); + param.insert("token_id", token_id.to_string()); + events.push(param); } + }; + for param in events { + let _: URef = storage::new_uref(param); } } diff --git a/cep47/src/entrypoints.rs b/cep47/src/entrypoints.rs deleted file mode 100644 index 396bb72..0000000 --- a/cep47/src/entrypoints.rs +++ /dev/null @@ -1,188 +0,0 @@ -use std::collections::BTreeSet; - -use casper_contract::{ - contract_api::{runtime, storage}, - unwrap_or_revert::UnwrapOrRevert, -}; -use casper_types::{ - CLType, CLTyped, ContractPackageHash, EntryPoint, EntryPointAccess, EntryPointType, - EntryPoints, Key, Parameter, -}; -use cep47_logic::{Meta, TokenId}; - -pub fn get_entrypoints(package_hash: Option) -> EntryPoints { - let secure = if let Some(contract_package_hash) = package_hash { - let deployer_group = storage::create_contract_user_group( - contract_package_hash, - "deployer", - 1, - BTreeSet::default(), - ) - .unwrap_or_revert(); - runtime::put_key("deployer_group_access", Key::URef(deployer_group[0])); - true - } else { - false - }; - - let mut entry_points = EntryPoints::new(); - entry_points.add_entry_point(endpoint("name", vec![], CLType::String, None)); - entry_points.add_entry_point(endpoint("symbol", vec![], CLType::String, None)); - entry_points.add_entry_point(endpoint("meta", vec![], Meta::cl_type(), None)); - entry_points.add_entry_point(endpoint("total_supply", vec![], CLType::U256, None)); - entry_points.add_entry_point(endpoint("is_paused", vec![], CLType::Bool, None)); - entry_points.add_entry_point(endpoint( - "pause", - vec![], - CLType::Unit, - if secure { Some("deployer") } else { None }, - )); - entry_points.add_entry_point(endpoint( - "unpause", - vec![], - CLType::Unit, - if secure { Some("deployer") } else { None }, - )); - entry_points.add_entry_point(endpoint( - "balance_of", - vec![Parameter::new("account", CLType::Key)], - CLType::U256, - None, - )); - entry_points.add_entry_point(endpoint( - "owner_of", - vec![Parameter::new("token_id", TokenId::cl_type())], - CLType::Option(Box::new(CLType::Key)), - None, - )); - entry_points.add_entry_point(endpoint( - "token_meta", - vec![Parameter::new("token_id", TokenId::cl_type())], - CLType::Option(Box::new(CLType::String)), - None, - )); - entry_points.add_entry_point(endpoint( - "tokens", - vec![Parameter::new("owner", CLType::Key)], - CLType::List(Box::new(CLType::String)), - None, - )); - entry_points.add_entry_point(endpoint( - "total_supply", - vec![Parameter::new("owner", CLType::Key)], - CLType::List(Box::new(CLType::String)), - None, - )); - entry_points.add_entry_point(endpoint( - "mint_one", - vec![ - Parameter::new("recipient", CLType::Key), - Parameter::new("token_ids", CLType::Option(Box::new(TokenId::cl_type()))), - Parameter::new("token_meta", Meta::cl_type()), - ], - CLType::Unit, - if secure { Some("deployer") } else { None }, - )); - entry_points.add_entry_point(endpoint( - "mint_many", - vec![ - Parameter::new("recipient", CLType::Key), - Parameter::new( - "token_ids", - CLType::Option(Box::new(CLType::List(Box::new(TokenId::cl_type())))), - ), - Parameter::new("token_metas", CLType::List(Box::new(Meta::cl_type()))), - ], - CLType::Unit, - if secure { Some("deployer") } else { None }, - )); - entry_points.add_entry_point(endpoint( - "mint_copies", - vec![ - Parameter::new("recipient", CLType::Key), - Parameter::new( - "token_ids", - CLType::Option(Box::new(CLType::List(Box::new(TokenId::cl_type())))), - ), - Parameter::new("token_meta", Meta::cl_type()), - Parameter::new("count", CLType::U32), - ], - CLType::Unit, - if secure { Some("deployer") } else { None }, - )); - entry_points.add_entry_point(endpoint( - "update_token_metadata", - vec![ - Parameter::new("token_id", TokenId::cl_type()), - Parameter::new("meta", Meta::cl_type()), - ], - CLType::Unit, - if secure { Some("deployer") } else { None }, - )); - entry_points.add_entry_point(endpoint( - "burn_one", - vec![ - Parameter::new("owner", CLType::Key), - Parameter::new("token_id", TokenId::cl_type()), - ], - CLType::Unit, - if secure { Some("deployer") } else { None }, - )); - entry_points.add_entry_point(endpoint( - "burn_many", - vec![ - Parameter::new("owner", CLType::Key), - Parameter::new("token_ids", CLType::List(Box::new(TokenId::cl_type()))), - ], - CLType::Unit, - if secure { Some("deployer") } else { None }, - )); - entry_points.add_entry_point(endpoint( - "transfer_token", - vec![ - Parameter::new("sender", CLType::Key), - Parameter::new("recipient", CLType::Key), - Parameter::new("token_id", TokenId::cl_type()), - ], - CLType::Unit, - None, - )); - entry_points.add_entry_point(endpoint( - "transfer_many_tokens", - vec![ - Parameter::new("sender", CLType::Key), - Parameter::new("recipient", CLType::Key), - Parameter::new("token_ids", CLType::List(Box::new(TokenId::cl_type()))), - ], - CLType::Unit, - None, - )); - entry_points.add_entry_point(endpoint( - "transfer_all_tokens", - vec![ - Parameter::new("sender", CLType::Key), - Parameter::new("recipient", CLType::Key), - ], - CLType::Unit, - None, - )); - entry_points -} - -pub fn endpoint( - name: &str, - param: Vec, - ret: CLType, - access: Option<&str>, -) -> EntryPoint { - EntryPoint::new( - String::from(name), - param, - ret, - match access { - None => EntryPointAccess::Public, - Some(access_key) => EntryPointAccess::groups(&[access_key]), - }, - EntryPointType::Contract, - ) -} diff --git a/cep47-logic/src/events.rs b/cep47/src/event.rs similarity index 71% rename from cep47-logic/src/events.rs rename to cep47/src/event.rs index ec16f6e..a8cfa53 100644 --- a/cep47-logic/src/events.rs +++ b/cep47/src/event.rs @@ -1,18 +1,9 @@ -use std::collections::{BTreeMap, BTreeSet}; - -use casper_types::{account::AccountHash, ContractPackageHash, Key}; +use alloc::vec::Vec; +use casper_types::Key; use crate::TokenId; pub enum CEP47Event { - MetadataUpdate { - token_id: TokenId, - }, - Transfer { - sender: Key, - recipient: Key, - token_ids: Vec, - }, Mint { recipient: Key, token_ids: Vec, @@ -21,4 +12,17 @@ pub enum CEP47Event { owner: Key, token_ids: Vec, }, + Approve { + owner: Key, + spender: Key, + token_ids: Vec, + }, + Transfer { + sender: Key, + recipient: Key, + token_ids: Vec, + }, + MetadataUpdate { + token_id: TokenId, + }, } diff --git a/cep47/src/lib.rs b/cep47/src/lib.rs index 234dc1b..e6c0bab 100644 --- a/cep47/src/lib.rs +++ b/cep47/src/lib.rs @@ -1,297 +1,13 @@ -#![allow(unused_imports)] -#![allow(unused_parens)] -#![allow(non_snake_case)] - +#![no_std] +#[macro_use] extern crate alloc; -use alloc::{ - collections::{BTreeMap, BTreeSet}, - string::String, -}; -use casper_contract::{ - contract_api::{runtime, storage}, - unwrap_or_revert::UnwrapOrRevert, -}; -use casper_types::{ - account::AccountHash, - bytesrepr::{FromBytes, ToBytes}, - contracts::NamedKeys, - system::CallStackElement, - AccessRights, ApiError, AsymmetricType, CLType, CLTyped, CLValue, ContractPackageHash, - EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, HashAddr, Key, Parameter, URef, - U256, -}; -pub use cep47_logic::Meta; -use cep47_logic::{CEP47Contract, CEP47Storage, TokenId, WithStorage}; - -use core::convert::TryInto; -use std::{ - collections::hash_map::DefaultHasher, - hash::{Hash, Hasher}, - ops::AddAssign, -}; - -mod cep47_storage; -mod data; -mod entrypoints; - -pub use cep47_storage::CasperCEP47Storage; -pub use entrypoints::get_entrypoints; - -use data::{Balances, Metadata, OwnedTokens, Owners}; - -#[derive(Default)] -pub struct CasperCEP47Contract { - storage: CasperCEP47Storage, -} - -impl CasperCEP47Contract { - pub fn new() -> CasperCEP47Contract { - CasperCEP47Contract { - storage: CasperCEP47Storage::new(), - } - } -} - -impl WithStorage for CasperCEP47Contract { - fn storage(&self) -> &CasperCEP47Storage { - &self.storage - } - fn storage_mut(&mut self) -> &mut CasperCEP47Storage { - &mut self.storage - } -} - -impl CEP47Contract for CasperCEP47Contract {} - -#[cfg(not(feature = "no_name"))] -#[no_mangle] -pub extern "C" fn name() { - let contract = CasperCEP47Contract::new(); - ret(contract.name()) -} - -#[cfg(not(feature = "no_symbol"))] -#[no_mangle] -pub extern "C" fn symbol() { - let contract = CasperCEP47Contract::new(); - ret((contract.symbol(), 42u8)) -} - -#[cfg(not(feature = "no_meta"))] -#[no_mangle] -pub extern "C" fn meta() { - let contract = CasperCEP47Contract::new(); - ret(contract.meta()) -} - -#[cfg(not(feature = "no_balance_of"))] -#[no_mangle] -pub extern "C" fn balance_of() { - let account: Key = runtime::get_named_arg("account"); - let contract = CasperCEP47Contract::new(); - ret(contract.balance_of(&account)) -} - -#[cfg(not(feature = "no_owner_of"))] -#[no_mangle] -pub extern "C" fn owner_of() { - let token_id: TokenId = runtime::get_named_arg("token_id"); - let contract = CasperCEP47Contract::new(); - ret(contract.owner_of(&token_id)) -} - -#[cfg(not(feature = "no_total_supply"))] -#[no_mangle] -pub extern "C" fn total_supply() { - let contract = CasperCEP47Contract::new(); - ret(contract.total_supply()) -} - -#[cfg(not(feature = "no_token_meta"))] -#[no_mangle] -pub extern "C" fn token_meta() { - let token_id: TokenId = runtime::get_named_arg("token_id"); - let contract = CasperCEP47Contract::new(); - ret(contract.token_meta(&token_id)) -} - -#[cfg(not(feature = "no_tokens"))] -#[no_mangle] -pub extern "C" fn tokens() { - let owner: Key = runtime::get_named_arg("owner"); - let contract = CasperCEP47Contract::new(); - ret(contract.tokens(&owner)) -} - -#[cfg(not(feature = "no_is_paused"))] -#[no_mangle] -pub extern "C" fn is_paused() { - let contract = CasperCEP47Contract::new(); - ret(contract.is_paused()) -} - -#[cfg(not(feature = "no_pause"))] -#[no_mangle] -pub extern "C" fn pause() { - let mut contract = CasperCEP47Contract::new(); - contract.pause(); -} - -#[cfg(not(feature = "no_unpause"))] -#[no_mangle] -pub extern "C" fn unpause() { - let mut contract = CasperCEP47Contract::new(); - contract.unpause(); -} - -#[cfg(not(feature = "no_mint_one"))] -#[no_mangle] -pub extern "C" fn mint_one() { - let recipient: Key = runtime::get_named_arg("recipient"); - let token_id: Option = runtime::get_named_arg("token_id"); - let token_meta: Meta = runtime::get_named_arg("token_meta"); - let mut contract = CasperCEP47Contract::new(); - contract - .mint_one(&recipient, token_id, token_meta) - .unwrap_or_revert(); -} - -#[cfg(not(feature = "no_mint_many"))] -#[no_mangle] -pub extern "C" fn mint_many() { - let recipient: Key = runtime::get_named_arg("recipient"); - let token_ids: Option> = runtime::get_named_arg("token_ids"); - let token_metas: Vec = runtime::get_named_arg("token_metas"); - let mut contract = CasperCEP47Contract::new(); - contract - .mint_many(&recipient, token_ids, token_metas) - .unwrap_or_revert(); -} - -#[cfg(not(feature = "no_mint_copies"))] -#[no_mangle] -pub extern "C" fn mint_copies() { - let recipient: Key = runtime::get_named_arg("recipient"); - let token_ids: Option> = runtime::get_named_arg("token_ids"); - let token_meta: Meta = runtime::get_named_arg("token_meta"); - let count: u32 = runtime::get_named_arg("count"); - let mut contract = CasperCEP47Contract::new(); - contract - .mint_copies(&recipient, token_ids, token_meta, count) - .unwrap_or_revert(); -} - -#[cfg(not(feature = "no_burn_many"))] -#[no_mangle] -pub extern "C" fn burn_many() { - let owner: Key = runtime::get_named_arg("owner"); - let token_ids: Vec = runtime::get_named_arg("token_ids"); - let mut contract = CasperCEP47Contract::new(); - contract.burn_many(&owner, token_ids); -} - -#[cfg(not(feature = "no_burn_one"))] -#[no_mangle] -pub extern "C" fn burn_one() { - let owner: Key = runtime::get_named_arg("owner"); - let token_id: TokenId = runtime::get_named_arg("token_id"); - let mut contract = CasperCEP47Contract::new(); - contract.burn_one(&owner, token_id); -} - -#[cfg(not(feature = "no_transfer_token"))] -#[no_mangle] -pub extern "C" fn transfer_token() { - let sender: Key = get_caller(); - let recipient: Key = runtime::get_named_arg("recipient"); - let token_id: TokenId = runtime::get_named_arg("token_id"); - let mut contract = CasperCEP47Contract::new(); - let res = contract.transfer_token(&sender, &recipient, &token_id); - res.unwrap_or_revert(); -} - -#[cfg(not(feature = "no_transfer_many_tokens"))] -#[no_mangle] -pub extern "C" fn transfer_many_tokens() { - let sender: Key = get_caller(); - let recipient: Key = runtime::get_named_arg("recipient"); - let token_ids: Vec = runtime::get_named_arg("token_ids"); - let mut contract = CasperCEP47Contract::new(); - let res = contract.transfer_many_tokens(&sender, &recipient, &token_ids); - res.unwrap_or_revert(); -} - -#[cfg(not(feature = "no_transfer_all_tokens"))] -#[no_mangle] -pub extern "C" fn transfer_all_tokens() { - let sender: Key = get_caller(); - let recipient: Key = runtime::get_named_arg("recipient"); - let mut contract = CasperCEP47Contract::new(); - let res = contract.transfer_all_tokens(&sender, &recipient); - res.unwrap_or_revert(); -} - -#[cfg(not(feature = "no_update_token_metadata"))] -#[no_mangle] -pub extern "C" fn update_token_metadata() { - let token_id: TokenId = runtime::get_named_arg("token_id"); - let meta: Meta = runtime::get_named_arg("token_meta"); - let mut contract = CasperCEP47Contract::new(); - let res = contract.update_token_metadata(token_id, meta); - res.unwrap_or_revert(); -} - -pub fn deploy( - token_name: String, - token_symbol: String, - token_meta: Meta, - entry_points: EntryPoints, - contract_package_hash: ContractPackageHash, - paused: bool, -) { - // Get named keys for the contract. - let named_keys = data::initial_named_keys( - contract_package_hash, - &token_name, - &token_symbol, - token_meta, - paused, - ); - - // Add new version to the package. - let (contract_hash, _) = - storage::add_contract_version(contract_package_hash, entry_points, named_keys); - - // Save contracts. - runtime::put_key( - format!("{}_contract", &token_name).as_str(), - contract_hash.into(), - ); - - // Save contract hashs. - let contract_hash_pack = storage::new_uref(contract_hash); - runtime::put_key( - format!("{}_contract_hash", token_name).as_str(), - contract_hash_pack.into(), - ); -} +mod cep47; +pub mod data; +pub mod event; -pub fn ret(value: T) { - runtime::ret(CLValue::from_t(value).unwrap_or_revert()) -} +pub use cep47::CEP47; -fn get_caller() -> Key { - match runtime::get_call_stack().first().unwrap_or_revert() { - CallStackElement::Session { account_hash } => (*account_hash).into(), - CallStackElement::StoredSession { - account_hash, - contract_package_hash: _, - contract_hash: _, - } => (*account_hash).into(), - CallStackElement::StoredContract { - contract_package_hash, - contract_hash: _, - } => (*contract_package_hash).into(), - } -} +use alloc::{collections::BTreeMap, string::String}; +pub type TokenId = String; +pub type Meta = BTreeMap; diff --git a/test-contracts/Cargo.toml b/test-contracts/Cargo.toml deleted file mode 100644 index 00e1e89..0000000 --- a/test-contracts/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -[package] -name = "test-contracts" -version = "0.1.0" -authors = ["astro019 "] -edition = "2018" - -[dependencies] -casper-contract = "1.3.1" -casper-types = "1.3.1" -cep47 = { path="../cep47"} - -[[bin]] -name = "dragons-nft" -path = "src/dragons-nft.rs" -bench = false -doctest = false -test = false - -[features] -default = ["casper-contract/std", "casper-types/std"] - diff --git a/test-contracts/src/dragons-nft.rs b/test-contracts/src/dragons-nft.rs deleted file mode 100644 index be930a5..0000000 --- a/test-contracts/src/dragons-nft.rs +++ /dev/null @@ -1,18 +0,0 @@ -#![no_main] - -use casper_contract::contract_api::runtime::get_named_arg; -use casper_contract::contract_api::storage::create_contract_package_at_hash; - -#[no_mangle] -pub extern "C" fn call() { - let (contract_package_hash, _) = create_contract_package_at_hash(); - let entry_points = cep47::get_entrypoints(Some(contract_package_hash)); - cep47::deploy( - get_named_arg::("token_name"), - get_named_arg::("token_symbol"), - get_named_arg::("token_meta"), - entry_points, - contract_package_hash, - false, - ); -} diff --git a/utils/contract-utils/Cargo.toml b/utils/contract-utils/Cargo.toml new file mode 100644 index 0000000..74a65da --- /dev/null +++ b/utils/contract-utils/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "contract-utils" +version = "0.1.0" +authors = ["Maciej Zielinski "] +edition = "2018" + +[dependencies] +casper-contract = "1.3.2" +casper-types = "1.3.2" +hex = { version = "0.4.3", default-features = false } + diff --git a/utils/contract-utils/src/admin_control.rs b/utils/contract-utils/src/admin_control.rs new file mode 100644 index 0000000..2d3d5be --- /dev/null +++ b/utils/contract-utils/src/admin_control.rs @@ -0,0 +1,63 @@ +use casper_contract::{ + contract_api::{runtime, storage}, + unwrap_or_revert::UnwrapOrRevert, +}; +use casper_types::{ApiError, Key}; + +use crate::{ContractContext, ContractStorage, Dict}; + +const ADMINS_DICT: &str = "admins"; + +pub trait AdminControl: ContractContext { + fn init(&mut self) { + Admins::init(); + } + + fn add_admin(&mut self, address: Key) { + self.assert_caller_is_admin(); + self.add_admin_without_checked(address); + } + + fn disable_admin(&mut self, address: Key) { + self.assert_caller_is_admin(); + Admins::instance().disable_admin(&address); + } + + fn add_admin_without_checked(&mut self, address: Key) { + Admins::instance().add_admin(&address); + } + + fn assert_caller_is_admin(&self) { + let caller = self.get_caller(); + if !Admins::instance().is_admin(&caller) { + runtime::revert(ApiError::User(20)); + } + } +} + +struct Admins { + dict: Dict, +} + +impl Admins { + pub fn instance() -> Admins { + Admins { + dict: Dict::instance(ADMINS_DICT), + } + } + pub fn init() { + storage::new_dictionary(ADMINS_DICT).unwrap_or_revert(); + } + + pub fn is_admin(&self, key: &Key) -> bool { + self.dict.get_by_key::<()>(key).is_some() + } + + pub fn add_admin(&self, key: &Key) { + self.dict.set_by_key(key, ()); + } + + pub fn disable_admin(&self, key: &Key) { + self.dict.remove_by_key::<()>(key); + } +} diff --git a/utils/contract-utils/src/contract_context.rs b/utils/contract-utils/src/contract_context.rs new file mode 100644 index 0000000..2fc178d --- /dev/null +++ b/utils/contract-utils/src/contract_context.rs @@ -0,0 +1,34 @@ +use casper_contract::unwrap_or_revert::UnwrapOrRevert; +use casper_types::{system::CallStackElement, Key}; + +use crate::ContractStorage; + +pub trait ContractContext { + fn storage(&self) -> &Storage; + + fn get_caller(&self) -> Key { + let call_stack = self.storage().call_stack(); + let caller = call_stack.get(call_stack.len() - 2); + element_to_key(caller.unwrap_or_revert()) + } + + fn self_addr(&mut self) -> Key { + let call_stack = self.storage().call_stack(); + element_to_key(call_stack.last().unwrap_or_revert()) + } +} + +fn element_to_key(element: &CallStackElement) -> Key { + match element { + CallStackElement::Session { account_hash } => (*account_hash).into(), + CallStackElement::StoredSession { + account_hash, + contract_package_hash: _, + contract_hash: _, + } => (*account_hash).into(), + CallStackElement::StoredContract { + contract_package_hash, + contract_hash: _, + } => (*contract_package_hash).into(), + } +} diff --git a/utils/contract-utils/src/contract_storage.rs b/utils/contract-utils/src/contract_storage.rs new file mode 100644 index 0000000..6aded67 --- /dev/null +++ b/utils/contract-utils/src/contract_storage.rs @@ -0,0 +1,21 @@ +use alloc::vec::Vec; +use core::lazy::OnceCell; + +use casper_contract::contract_api::runtime; +use casper_types::system::CallStackElement; + +pub trait ContractStorage { + fn call_stack(&self) -> &[CallStackElement]; +} + +#[derive(Default)] +pub struct OnChainContractStorage { + call_stack: OnceCell>, +} + +impl ContractStorage for OnChainContractStorage { + fn call_stack(&self) -> &[CallStackElement] { + let call_stack = self.call_stack.get_or_init(runtime::get_call_stack); + call_stack.as_slice() + } +} diff --git a/utils/contract-utils/src/data.rs b/utils/contract-utils/src/data.rs new file mode 100644 index 0000000..db086ac --- /dev/null +++ b/utils/contract-utils/src/data.rs @@ -0,0 +1,121 @@ +use alloc::string::{String, ToString}; +use core::convert::TryInto; + +use casper_contract::{ + contract_api::{runtime, storage}, + unwrap_or_revert::UnwrapOrRevert, +}; +use casper_types::{ + bytesrepr::{FromBytes, ToBytes}, + ApiError, CLTyped, Key, URef, +}; + +pub struct Dict { + uref: URef, +} + +impl Dict { + pub fn instance(name: &str) -> Dict { + let key = runtime::get_key(name).unwrap_or_revert(); + let uref = *key.as_uref().unwrap_or_revert(); + Dict { uref } + } + + pub fn init(name: &str) { + storage::new_dictionary(name).unwrap_or_revert(); + } + + pub fn at(uref: URef) -> Dict { + Dict { uref } + } + + pub fn get(&self, key: &str) -> Option { + storage::dictionary_get(self.uref, key) + .unwrap_or_revert() + .unwrap_or_default() + } + + pub fn get_by_key(&self, key: &Key) -> Option { + self.get(&key_to_str(key)) + } + + pub fn get_by_keys(&self, keys: (&Key, &Key)) -> Option { + self.get(&keys_to_str(keys.0, keys.1)) + } + + pub fn set(&self, key: &str, value: T) { + storage::dictionary_put(self.uref, key, Some(value)); + } + + pub fn set_by_key(&self, key: &Key, value: T) { + self.set(&key_to_str(key), value); + } + + pub fn set_by_keys(&self, keys: (&Key, &Key), value: T) { + self.set(&keys_to_str(keys.0, keys.1), value) + } + + pub fn remove(&self, key: &str) { + storage::dictionary_put(self.uref, key, Option::::None); + } + + pub fn remove_by_key(&self, key: &Key) { + self.remove::(&key_to_str(key)); + } + + pub fn remove_by_vec_of_keys(&self, keys: (&Key, &Key)) { + self.remove::(&keys_to_str(keys.0, keys.1)) + } +} + +pub fn key_to_str(key: &Key) -> String { + match key { + Key::Account(account) => account.to_string(), + Key::Hash(package) => hex::encode(package), + _ => runtime::revert(ApiError::UnexpectedKeyVariant), + } +} + +pub fn keys_to_str(key_a: &Key, key_b: &Key) -> String { + let mut bytes_a = key_a.to_bytes().unwrap_or_revert(); + let mut bytes_b = key_b.to_bytes().unwrap_or_revert(); + + bytes_a.append(&mut bytes_b); + + let bytes = runtime::blake2b(bytes_a); + hex::encode(bytes) +} + +pub fn key_and_value_to_str(key: &Key, value: &T) -> String { + let mut bytes_a = key.to_bytes().unwrap_or_revert(); + let mut bytes_b = value.to_bytes().unwrap_or_revert(); + + bytes_a.append(&mut bytes_b); + + let bytes = runtime::blake2b(bytes_a); + hex::encode(bytes) +} + +pub fn get_key(name: &str) -> Option { + match runtime::get_key(name) { + None => None, + Some(value) => { + let key = value.try_into().unwrap_or_revert(); + let value = storage::read(key).unwrap_or_revert().unwrap_or_revert(); + Some(value) + } + } +} + +pub fn set_key(name: &str, value: T) { + match runtime::get_key(name) { + Some(key) => { + let key_ref = key.try_into().unwrap_or_revert(); + storage::write(key_ref, value); + } + None => { + let key = storage::new_uref(value).into(); + runtime::put_key(name, key); + } + } +} diff --git a/utils/contract-utils/src/lib.rs b/utils/contract-utils/src/lib.rs new file mode 100644 index 0000000..4e52e04 --- /dev/null +++ b/utils/contract-utils/src/lib.rs @@ -0,0 +1,14 @@ +#![no_std] +#![feature(once_cell)] + +extern crate alloc; + +mod admin_control; +mod contract_context; +mod contract_storage; +mod data; + +pub use admin_control::AdminControl; +pub use contract_context::ContractContext; +pub use contract_storage::{ContractStorage, OnChainContractStorage}; +pub use data::{get_key, key_and_value_to_str, set_key, Dict}; diff --git a/utils/test-env/Cargo.toml b/utils/test-env/Cargo.toml new file mode 100644 index 0000000..7256e7f --- /dev/null +++ b/utils/test-env/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "test-env" +version = "0.1.0" +authors = ["Maciej Zielinski "] +edition = "2018" + +[dependencies] +casper-contract = "1.3.0" +casper-types = "1.3.0" +casper-engine-test-support = "1.3.0" + +[features] +default = ["casper-contract/std", "casper-types/std", "casper-engine-test-support/test-support", "casper-contract/test-support"] diff --git a/utils/test-env/src/lib.rs b/utils/test-env/src/lib.rs new file mode 100644 index 0000000..f2634bf --- /dev/null +++ b/utils/test-env/src/lib.rs @@ -0,0 +1,7 @@ +mod test_contract; +mod test_env; + +use casper_engine_test_support::AccountHash; +pub use test_contract::TestContract; +pub use test_env::TestEnv; +pub struct Sender(pub AccountHash); diff --git a/utils/test-env/src/test_contract.rs b/utils/test-env/src/test_contract.rs new file mode 100644 index 0000000..c349192 --- /dev/null +++ b/utils/test-env/src/test_contract.rs @@ -0,0 +1,61 @@ +use casper_engine_test_support::{AccountHash, Code, Hash, Value}; +use casper_types::{bytesrepr::FromBytes, CLTyped, RuntimeArgs}; + +use crate::{Sender, TestEnv}; + +pub struct TestContract { + env: TestEnv, + name: String, + contract_owner: AccountHash, +} + +impl TestContract { + pub fn new( + env: &TestEnv, + wasm: &str, + name: &str, + sender: Sender, + mut args: RuntimeArgs, + ) -> TestContract { + let Sender(contract_owner) = sender; + let session_code = Code::from(wasm); + args.insert("contract_name", name).unwrap(); + env.run(sender, session_code, args); + + TestContract { + env: env.clone(), + name: String::from(name), + contract_owner, + } + } + + pub fn query_dictionary( + &self, + dict_name: &str, + key: String, + ) -> Option { + self.env + .query_dictionary(self.contract_hash(), dict_name, key) + } + + pub fn query_named_key(&self, key: String) -> T { + let contract_name = format!("{}_contract_hash", self.name); + self.env + .query_account_named_key(self.contract_owner, &[contract_name, key]) + .into_t() + .unwrap() + } + + pub fn contract_hash(&self) -> Hash { + let key = format!("{}_contract_hash_wrapped", self.name); + let value: Value = self + .env + .query_account_named_key(self.contract_owner, &[key]); + value.into_t().unwrap() + } + + pub fn call_contract(&self, sender: Sender, entry_point: &str, session_args: RuntimeArgs) { + let session_code = Code::Hash(self.contract_hash(), String::from(entry_point)); + self.env.run(sender, session_code, session_args); + } +} diff --git a/utils/test-env/src/test_env.rs b/utils/test-env/src/test_env.rs new file mode 100644 index 0000000..409df8b --- /dev/null +++ b/utils/test-env/src/test_env.rs @@ -0,0 +1,120 @@ +use std::sync::{Arc, Mutex}; + +use casper_engine_test_support::{ + AccountHash, Code, Hash, SessionBuilder, TestContext, TestContextBuilder, Value, +}; +use casper_types::{bytesrepr::FromBytes, CLTyped, Key, PublicKey, RuntimeArgs, SecretKey, U512}; + +use crate::Sender; + +#[derive(Clone)] +pub struct TestEnv { + state: Arc>, +} + +impl TestEnv { + pub fn new() -> TestEnv { + TestEnv { + state: Arc::new(Mutex::new(TestEnvState::new())), + } + } + + pub fn run(&self, sender: Sender, session_code: Code, session_args: RuntimeArgs) { + self.state + .lock() + .unwrap() + .run(sender, session_code, session_args); + } + + pub fn next_user(&self) -> AccountHash { + self.state.lock().unwrap().next_user() + } + + pub fn query_dictionary( + &self, + contract_hash: Hash, + dict_name: &str, + key: String, + ) -> Option { + self.state + .lock() + .unwrap() + .query_dictionary(contract_hash, dict_name, key) + } + + pub fn query_account_named_key(&self, account: AccountHash, path: &[String]) -> Value { + self.state + .lock() + .unwrap() + .query_account_named_key(account, path) + } +} + +impl Default for TestEnv { + fn default() -> Self { + TestEnv::new() + } +} + +struct TestEnvState { + context: TestContext, + accounts: Vec, +} + +impl TestEnvState { + pub fn new() -> TestEnvState { + let mut context_builder = TestContextBuilder::new(); + + let mut accounts = Vec::new(); + for i in 0..10u8 { + let secret_key: SecretKey = SecretKey::ed25519_from_bytes([i; 32]).unwrap(); + let public_key: PublicKey = (&secret_key).into(); + accounts.push(AccountHash::from(&public_key)); + context_builder = + context_builder.with_public_key(public_key, U512::from(500_000_000_000_000u64)); + } + + TestEnvState { + context: context_builder.build(), + accounts, + } + } + + pub fn next_user(&mut self) -> AccountHash { + self.accounts.pop().unwrap() + } + + pub fn run(&mut self, sender: Sender, session_code: Code, session_args: RuntimeArgs) { + let Sender(sender) = sender; + let session = SessionBuilder::new(session_code, session_args) + .with_address(sender) + .with_authorization_keys(&[sender]) + .build(); + self.context.run(session); + } + + pub fn query_dictionary( + &self, + contract_hash: Hash, + dict_name: &str, + key: String, + ) -> Option { + match self.context.query_dictionary_item( + Key::Hash(contract_hash), + Some(dict_name.to_string()), + key, + ) { + Err(_) => None, + Ok(maybe_value) => { + let value: Option = maybe_value + .into_t() + .unwrap_or_else(|_| panic!("is not expected type.")); + value + } + } + } + + pub fn query_account_named_key(&self, account: AccountHash, path: &[String]) -> Value { + self.context.query(account, path).unwrap() + } +} From 92153965fab3d6e18549ca159677c50bedff8fca Mon Sep 17 00:00:00 2001 From: Maciej Zielinski Date: Fri, 20 Aug 2021 14:09:01 +0200 Subject: [PATCH 68/98] PR fixes --- cep47-logic/src/events.rs | 22 ++++++++++++++++++++++ cep47-logic/src/lib.rs | 21 ++++++--------------- cep47-logic/src/tests.rs | 12 ++++++++++++ cep47/src/cep47_storage.rs | 13 +++++++++++++ cep47/src/data.rs | 18 +++++++++--------- 5 files changed, 62 insertions(+), 24 deletions(-) diff --git a/cep47-logic/src/events.rs b/cep47-logic/src/events.rs index ec16f6e..406b736 100644 --- a/cep47-logic/src/events.rs +++ b/cep47-logic/src/events.rs @@ -22,3 +22,25 @@ pub enum CEP47Event { token_ids: Vec, }, } + +impl CEP47Event { + pub fn type_name(&self) -> String { + match self { + CEP47Event::MetadataUpdate { token_id: _ } => "cep47_metadata_update", + CEP47Event::Transfer { + sender: _, + recipient: _, + token_ids: _, + } => "cep47_transfer_token", + CEP47Event::Mint { + recipient: _, + token_ids: _, + } => "cep47_mint_one", + CEP47Event::Burn { + owner: _, + token_ids: _, + } => "cep47_burn_one", + } + .to_string() + } +} diff --git a/cep47-logic/src/lib.rs b/cep47-logic/src/lib.rs index e170aba..67da492 100644 --- a/cep47-logic/src/lib.rs +++ b/cep47-logic/src/lib.rs @@ -148,13 +148,8 @@ pub trait CEP47Contract: WithStorage { } fn burn_many(&mut self, owner: &Key, token_ids: Vec) -> Result<(), Error> { - for token_id in token_ids.iter() { - let token_owner = self.storage().owner_of(token_id); - if let Some(token_owner) = token_owner { - if &token_owner != owner { - return Err(Error::NotAnOwner); - } - } + if !self.storage().are_all_owner_tokens(owner, &token_ids) { + return Err(Error::NotAnOwner); } self.storage_mut().burn_many(owner, &token_ids); @@ -188,13 +183,8 @@ pub trait CEP47Contract: WithStorage { return Err(Error::PermissionDenied); } - for token_id in token_ids.iter() { - let token_owner = self.storage().owner_of(token_id); - if let Some(token_owner) = token_owner { - if &token_owner != sender { - return Err(Error::NotAnOwner); - } - } + if !self.storage().are_all_owner_tokens(sender, token_ids) { + return Err(Error::NotAnOwner); } self.storage_mut() @@ -238,7 +228,7 @@ pub trait CEP47Storage { fn total_supply(&self) -> U256; fn token_meta(&self, token_id: &TokenId) -> Option; - // Controls + // Pause and unpause transfers. fn is_paused(&self) -> bool; fn pause(&mut self); fn unpause(&mut self); @@ -251,6 +241,7 @@ pub trait CEP47Storage { fn gen_token_ids(&mut self, n: u32) -> Vec; fn validate_token_ids(&self, token_ids: &Vec) -> bool; + fn are_all_owner_tokens(&self, owner: &Key, token_ids: &Vec) -> bool; fn emit(&mut self, event: CEP47Event); fn contact_package_hash(&self) -> ContractPackageHash; diff --git a/cep47-logic/src/tests.rs b/cep47-logic/src/tests.rs index 14df69b..ed1b87c 100644 --- a/cep47-logic/src/tests.rs +++ b/cep47-logic/src/tests.rs @@ -161,6 +161,18 @@ impl CEP47Storage for TestStorage { fn contact_package_hash(&self) -> casper_types::ContractPackageHash { [1u8; 32].into() } + + fn are_all_owner_tokens(&self, owner: &Key, token_ids: &Vec) -> bool { + for token_id in token_ids.iter() { + let token_owner = self.owner_of(token_id); + if let Some(token_owner) = token_owner { + if &token_owner != owner { + return false; + } + } + } + true + } } struct TestContract { diff --git a/cep47/src/cep47_storage.rs b/cep47/src/cep47_storage.rs index a5c1f76..39f7b9d 100644 --- a/cep47/src/cep47_storage.rs +++ b/cep47/src/cep47_storage.rs @@ -162,4 +162,17 @@ impl CEP47Storage for CasperCEP47Storage { fn contact_package_hash(&self) -> casper_types::ContractPackageHash { data::contract_package_hash() } + + fn are_all_owner_tokens(&self, owner: &Key, token_ids: &Vec) -> bool { + let owners_dict = Owners::instance(); + for token_id in token_ids.iter() { + let token_owner = owners_dict.get(token_id); + if let Some(token_owner) = token_owner { + if &token_owner != owner { + return false; + } + } + } + true + } } diff --git a/cep47/src/data.rs b/cep47/src/data.rs index 889c548..50e2509 100644 --- a/cep47/src/data.rs +++ b/cep47/src/data.rs @@ -216,18 +216,18 @@ fn key_to_str(key: &Key) -> String { } } -pub fn emit(event: &CEP47Event) { +pub fn emit(cep47_event: &CEP47Event) { let mut events = Vec::new(); let package = contract_package_hash(); let mut events_count = get_events_count(); - match event { + match cep47_event { CEP47Event::MetadataUpdate { token_id } => { let mut event = BTreeMap::new(); let event_id = events_count.to_string(); event.insert("event_id", event_id.clone()); - event.insert("contract_package_hash", package.to_formatted_string()); - event.insert("event_type", "cep47_metadata_update".to_string()); + event.insert("contract_package_hash", package.to_string()); + event.insert("event_type", cep47_event.type_name()); event.insert("token_id", token_id.to_string()); events.push((event_id, event)); events_count += 1; @@ -241,8 +241,8 @@ pub fn emit(event: &CEP47Event) { let mut event = BTreeMap::new(); let event_id = events_count.to_string(); event.insert("event_id", event_id.clone()); - event.insert("contract_package_hash", package.to_formatted_string()); - event.insert("event_type", "cep47_transfer_token".to_string()); + event.insert("contract_package_hash", package.to_string()); + event.insert("event_type", cep47_event.type_name()); event.insert("sender", sender.to_formatted_string()); event.insert("recipient", recipient.to_formatted_string()); event.insert("token_id", token_id.to_string()); @@ -258,8 +258,8 @@ pub fn emit(event: &CEP47Event) { let mut event = BTreeMap::new(); let event_id = events_count.to_string(); event.insert("event_id", event_id.clone()); - event.insert("contract_package_hash", package.to_formatted_string()); - event.insert("event_type", "cep47_mint_one".to_string()); + event.insert("contract_package_hash", package.to_string()); + event.insert("event_type", cep47_event.type_name()); event.insert("recipient", recipient.to_formatted_string()); event.insert("token_id", token_id.to_string()); events.push((event_id, event)); @@ -272,7 +272,7 @@ pub fn emit(event: &CEP47Event) { let event_id = events_count.to_string(); event.insert("event_id", event_id.clone()); event.insert("contract_package_hash", package.to_string()); - event.insert("event_type", "cep47_burn_one".to_string()); + event.insert("event_type", cep47_event.type_name()); event.insert("owner", owner.to_string()); event.insert("token_id", token_id.to_string()); events.push((event_id, event)); From 0e4e2d0f6d118bb088fd6a3658776274fecae762 Mon Sep 17 00:00:00 2001 From: Maciej Zielinski Date: Fri, 20 Aug 2021 14:22:23 +0200 Subject: [PATCH 69/98] Don't change events structure --- cep47/src/data.rs | 48 +++++++++-------------------------------------- 1 file changed, 9 insertions(+), 39 deletions(-) diff --git a/cep47/src/data.rs b/cep47/src/data.rs index 50e2509..6b14471 100644 --- a/cep47/src/data.rs +++ b/cep47/src/data.rs @@ -17,7 +17,6 @@ use cep47_logic::{events::CEP47Event, Meta, TokenId}; const BALANCES_DICT: &str = "balances"; const TOKEN_OWNERS_DICT: &str = "owners"; const METADATA_DICT: &str = "metadata"; -const EVENTS_DICT: &str = "events"; struct Dict { uref: URef, @@ -157,14 +156,6 @@ pub fn set_nonce(nonce: u32) { set_key("nonce", nonce); } -pub fn get_events_count() -> u32 { - get_key("events_count").unwrap_or_revert() -} - -pub fn set_events_count(events_count: u32) { - set_key("events_count", events_count); -} - pub fn contract_package_hash() -> ContractPackageHash { get_key("contract_package_hash").unwrap_or_revert() } @@ -194,10 +185,6 @@ pub fn initial_named_keys( add_empty_dict(&mut named_keys, BALANCES_DICT); add_empty_dict(&mut named_keys, TOKEN_OWNERS_DICT); add_empty_dict(&mut named_keys, METADATA_DICT); - add_empty_dict(&mut named_keys, EVENTS_DICT); - - // Set events count. - named_keys.insert("events_count".to_string(), storage::new_uref(0u32).into()); named_keys } @@ -219,18 +206,13 @@ fn key_to_str(key: &Key) -> String { pub fn emit(cep47_event: &CEP47Event) { let mut events = Vec::new(); let package = contract_package_hash(); - let mut events_count = get_events_count(); - match cep47_event { CEP47Event::MetadataUpdate { token_id } => { let mut event = BTreeMap::new(); - let event_id = events_count.to_string(); - event.insert("event_id", event_id.clone()); event.insert("contract_package_hash", package.to_string()); event.insert("event_type", cep47_event.type_name()); event.insert("token_id", token_id.to_string()); - events.push((event_id, event)); - events_count += 1; + events.push(event); } CEP47Event::Transfer { sender, @@ -239,15 +221,12 @@ pub fn emit(cep47_event: &CEP47Event) { } => { for token_id in token_ids { let mut event = BTreeMap::new(); - let event_id = events_count.to_string(); - event.insert("event_id", event_id.clone()); event.insert("contract_package_hash", package.to_string()); event.insert("event_type", cep47_event.type_name()); - event.insert("sender", sender.to_formatted_string()); - event.insert("recipient", recipient.to_formatted_string()); + event.insert("sender", sender.to_string()); + event.insert("recipient", recipient.to_string()); event.insert("token_id", token_id.to_string()); - events.push((event_id, event)); - events_count += 1; + events.push(event); } } CEP47Event::Mint { @@ -256,36 +235,27 @@ pub fn emit(cep47_event: &CEP47Event) { } => { for token_id in token_ids { let mut event = BTreeMap::new(); - let event_id = events_count.to_string(); - event.insert("event_id", event_id.clone()); event.insert("contract_package_hash", package.to_string()); event.insert("event_type", cep47_event.type_name()); - event.insert("recipient", recipient.to_formatted_string()); + event.insert("recipient", recipient.to_string()); event.insert("token_id", token_id.to_string()); - events.push((event_id, event)); - events_count += 1; + events.push(event); } } CEP47Event::Burn { owner, token_ids } => { for token_id in token_ids { let mut event = BTreeMap::new(); - let event_id = events_count.to_string(); - event.insert("event_id", event_id.clone()); event.insert("contract_package_hash", package.to_string()); event.insert("event_type", cep47_event.type_name()); event.insert("owner", owner.to_string()); event.insert("token_id", token_id.to_string()); - events.push((event_id, event)); - events_count += 1; + events.push(event); } } }; - - let events_dict = Dict::at(EVENTS_DICT); - for (event_id, event) in events { - events_dict.set(&event_id, event); + for event in events { + let _: URef = storage::new_uref(event); } - set_events_count(events_count); } fn get_key(name: &str) -> Option { From 6d74272214184e382b360259fd060607c1aab294 Mon Sep 17 00:00:00 2001 From: astro019 Date: Tue, 24 Aug 2021 00:29:41 +1000 Subject: [PATCH 70/98] update owned_tokens indexable --- cep47-tests/src/cep47_instance.rs | 9 +- cep47-tests/src/cep47_tests.rs | 203 ++++++++++++++++++------------ cep47/bin/cep47_token.rs | 83 ++++++++---- cep47/src/cep47.rs | 60 +++------ cep47/src/data.rs | 68 ++++++++-- utils/contract-utils/src/lib.rs | 2 +- 6 files changed, 259 insertions(+), 166 deletions(-) diff --git a/cep47-tests/src/cep47_instance.rs b/cep47-tests/src/cep47_instance.rs index cafdfc3..1a51bfa 100644 --- a/cep47-tests/src/cep47_instance.rs +++ b/cep47-tests/src/cep47_instance.rs @@ -178,10 +178,11 @@ impl CEP47Instance { ) } - pub fn tokens>(&self, account: T) -> Vec { - self.0 - .query_dictionary("owned_tokens", key_to_str(&account.into())) - .unwrap_or_default() + pub fn get_token_by_index>(&self, account: T, index: u32) -> Option { + self.0.query_dictionary( + "owned_tokens_by_index", + key_and_value_to_str(&account.into(), &index), + ) } pub fn balance_of>(&self, account: T) -> U256 { diff --git a/cep47-tests/src/cep47_tests.rs b/cep47-tests/src/cep47_tests.rs index 24f3793..29e77a3 100644 --- a/cep47-tests/src/cep47_tests.rs +++ b/cep47-tests/src/cep47_tests.rs @@ -82,8 +82,8 @@ fn test_token_meta() { let user_token_meta = token.token_meta(token_id.clone()); assert_eq!(user_token_meta.unwrap(), token_meta); - let user_tokens = token.tokens(Key::Account(user)); - assert_eq!(user_tokens, vec![token_id]); + let first_user_token = token.get_token_by_index(Key::Account(user), 0u32); + assert_eq!(first_user_token, Some(token_id)); } #[test] @@ -95,12 +95,13 @@ fn test_mint_one_with_random_token_id() { assert_eq!(token.total_supply(), U256::one()); assert_eq!(token.balance_of(user), U256::one()); - let user_tokens: Vec = token.tokens(Key::Account(user)); - assert_eq!(U256::from(user_tokens.len() as u64), U256::one()); + let first_user_token: Option = token.get_token_by_index(Key::Account(user), 0u32); + let second_user_token: Option = token.get_token_by_index(Key::Account(user), 1u32); assert_eq!( - token.owner_of(user_tokens.get(0).unwrap().clone()).unwrap(), + token.owner_of(first_user_token.unwrap()).unwrap(), Key::Account(user) ); + assert_eq!(second_user_token, None); } #[test] @@ -116,11 +117,12 @@ fn test_mint_one_with_set_token_id() { Some(token_id.clone()), token_meta.clone(), ); - let user_tokens = token.tokens(Key::Account(user)); - assert_eq!(user_tokens, vec![token_id.clone()]); + let first_user_token = token.get_token_by_index(Key::Account(user), 0u32); + let second_user_token = token.get_token_by_index(Key::Account(user), 1u32); + assert_eq!(first_user_token, Some(token_id.clone())); assert_eq!(token.total_supply(), U256::one()); assert_eq!(token.balance_of(Key::Account(user)), U256::one()); - assert_eq!(U256::from(user_tokens.len() as u64), U256::one()); + assert_eq!(second_user_token, None); assert_eq!(token.owner_of(token_id).unwrap(), Key::Account(user)); } @@ -152,23 +154,24 @@ fn test_mint_copies() { let (env, token, owner) = deploy(); let user = env.next_user(); let token_meta = meta::red_dragon(); - token.mint_copies(Sender(owner), user, None, token_meta.clone(), 3); - - let user_tokens = token.tokens(Key::Account(user)); + let first_user_token = token.get_token_by_index(Key::Account(user), 0u32); + let second_user_token = token.get_token_by_index(Key::Account(user), 1u32); + let third_user_token = token.get_token_by_index(Key::Account(user), 2u32); + let fourth_user_token = token.get_token_by_index(Key::Account(user), 3u32); assert_eq!(token.total_supply(), U256::from(3)); assert_eq!(token.balance_of(Key::Account(user)), U256::from(3)); - assert_eq!(U256::from(user_tokens.len() as u64), U256::from(3)); + assert_eq!(fourth_user_token, None); assert_eq!( - token.owner_of(user_tokens.get(0).unwrap().clone()).unwrap(), + token.owner_of(first_user_token.unwrap()).unwrap(), Key::Account(user) ); assert_eq!( - token.owner_of(user_tokens.get(1).unwrap().clone()).unwrap(), + token.owner_of(second_user_token.unwrap()).unwrap(), Key::Account(user) ); assert_eq!( - token.owner_of(user_tokens.get(2).unwrap().clone()).unwrap(), + token.owner_of(third_user_token.unwrap()).unwrap(), Key::Account(user) ); } @@ -178,25 +181,25 @@ fn test_mint_many() { let (env, token, owner) = deploy(); let user = env.next_user(); let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; - token.mint_many(Sender(owner), user, None, token_metas.clone()); - let user_tokens = token.tokens(Key::Account(user)); + let first_user_token = token.get_token_by_index(Key::Account(user), 0u32); + let second_user_token = token.get_token_by_index(Key::Account(user), 1u32); + let third_user_token = token.get_token_by_index(Key::Account(user), 2u32); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(user)), U256::from(2)); - assert_eq!(U256::from(user_tokens.len() as u64), U256::from(2)); + assert_eq!(third_user_token, None); assert_eq!( - token.owner_of(user_tokens.get(0).unwrap().clone()).unwrap(), + token.owner_of(first_user_token.unwrap()).unwrap(), Key::Account(user) ); assert_eq!( - token.owner_of(user_tokens.get(1).unwrap().clone()).unwrap(), + token.owner_of(second_user_token.unwrap()).unwrap(), Key::Account(user) ); } #[test] fn test_burn_many() { - // TODO: the sender should be owner of nft item or allowed party let (env, token, owner) = deploy(); let user = env.next_user(); let token_metas = vec![ @@ -208,24 +211,29 @@ fn test_burn_many() { token.mint_many(Sender(owner), user, None, token_metas.clone()); - let mut user_tokens = token.tokens(Key::Account(user)); - println!("{:?}", user_tokens); - println!("{:?}", user_tokens.first().unwrap().clone()); - + let first_user_token = token.get_token_by_index(Key::Account(user), 0u32); + let second_user_token = token.get_token_by_index(Key::Account(user), 1u32); + let third_user_token = token.get_token_by_index(Key::Account(user), 2u32); + let fourth_user_token = token.get_token_by_index(Key::Account(user), 3u32); token.burn_many( Sender(user), user, vec![ - user_tokens.first().unwrap().clone(), - user_tokens.last().unwrap().clone(), + first_user_token.clone().unwrap(), + fourth_user_token.clone().unwrap(), ], ); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(user)), U256::from(2)); - user_tokens = token.tokens(Key::Account(user)); - println!("{:?}", user_tokens); - assert_eq!(U256::from(user_tokens.len() as u64), U256::from(2)); + let new_first_user_token = token.get_token_by_index(Key::Account(user), 0u32); + let new_second_user_token = token.get_token_by_index(Key::Account(user), 1u32); + let new_third_user_token = token.get_token_by_index(Key::Account(user), 2u32); + let new_fourth_user_token = token.get_token_by_index(Key::Account(user), 3u32); + assert_eq!(new_first_user_token, third_user_token); + assert_eq!(new_second_user_token, second_user_token); + assert_eq!(new_third_user_token, None); + assert_eq!(new_fourth_user_token, None); } #[test] @@ -241,24 +249,37 @@ fn test_burn_many_from_allowance_with_approve() { token.mint_many(Sender(owner), user, None, token_metas.clone()); - let mut user_tokens = token.tokens(Key::Account(user)); - println!("{:?}", user_tokens); - println!("{:?}", user_tokens.first().unwrap().clone()); - token.approve(Sender(user), owner, user_tokens.clone()); + let first_user_token = token.get_token_by_index(Key::Account(user), 0u32); + let second_user_token = token.get_token_by_index(Key::Account(user), 1u32); + let third_user_token = token.get_token_by_index(Key::Account(user), 2u32); + let fourth_user_token = token.get_token_by_index(Key::Account(user), 3u32); + token.approve( + Sender(user), + owner, + vec![ + first_user_token.clone().unwrap(), + third_user_token.clone().unwrap(), + ], + ); token.burn_many( Sender(owner), user, vec![ - user_tokens.first().unwrap().clone(), - user_tokens.last().unwrap().clone(), + first_user_token.clone().unwrap(), + third_user_token.clone().unwrap(), ], ); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(user)), U256::from(2)); - user_tokens = token.tokens(Key::Account(user)); - println!("{:?}", user_tokens); - assert_eq!(U256::from(user_tokens.len() as u64), U256::from(2)); + let new_first_user_token = token.get_token_by_index(Key::Account(user), 0u32); + let new_second_user_token = token.get_token_by_index(Key::Account(user), 1u32); + let new_third_user_token = token.get_token_by_index(Key::Account(user), 2u32); + let new_fourth_user_token = token.get_token_by_index(Key::Account(user), 3u32); + assert_eq!(new_first_user_token, fourth_user_token); + assert_eq!(new_second_user_token, second_user_token); + assert_eq!(new_third_user_token, None); + assert_eq!(new_fourth_user_token, None); } #[test] @@ -275,15 +296,14 @@ fn test_burn_many_from_allowance_without_approve() { token.mint_many(Sender(owner), user, None, token_metas.clone()); - let user_tokens = token.tokens(Key::Account(user)); - println!("{:?}", user_tokens); - println!("{:?}", user_tokens.first().unwrap().clone()); + let first_user_token = token.get_token_by_index(Key::Account(user), 0u32); + let second_user_token = token.get_token_by_index(Key::Account(user), 1u32); token.burn_many( Sender(owner), user, vec![ - user_tokens.first().unwrap().clone(), - user_tokens.last().unwrap().clone(), + first_user_token.clone().unwrap(), + second_user_token.clone().unwrap(), ], ); } @@ -296,13 +316,16 @@ fn test_burn_one() { let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; token.mint_many(Sender(owner), user, None, token_metas.clone()); - let mut user_tokens = token.tokens(Key::Account(user)); - token.burn_one(Sender(user), user, user_tokens.first().unwrap().clone()); + let first_user_token = token.get_token_by_index(Key::Account(user), 0u32); + let second_user_token = token.get_token_by_index(Key::Account(user), 1u32); + token.burn_one(Sender(user), user, first_user_token.clone().unwrap()); assert_eq!(token.total_supply(), U256::from(1)); assert_eq!(token.balance_of(Key::Account(user)), U256::from(1)); - user_tokens = token.tokens(Key::Account(user)); - assert_eq!(U256::from(user_tokens.len() as u64), U256::from(1)); + let new_first_user_token = token.get_token_by_index(Key::Account(user), 0u32); + let new_second_user_token = token.get_token_by_index(Key::Account(user), 1u32); + assert_eq!(new_first_user_token, second_user_token); + assert_eq!(new_second_user_token, None); } #[test] @@ -313,36 +336,46 @@ fn test_transfer_token() { let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; token.mint_many(Sender(owner), ali, None, token_metas.clone()); - let mut ali_tokens = token.tokens(Key::Account(ali)); + let first_ali_token = token.get_token_by_index(Key::Account(ali), 0u32); + let second_ali_token = token.get_token_by_index(Key::Account(ali), 1u32); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(ali)), U256::from(2)); - assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(2)); assert_eq!( - token.owner_of(ali_tokens.get(0).unwrap().clone()).unwrap(), + token.owner_of(first_ali_token.clone().unwrap()).unwrap(), Key::Account(ali) ); assert_eq!( - token.owner_of(ali_tokens.get(1).unwrap().clone()).unwrap(), + token.owner_of(second_ali_token.clone().unwrap()).unwrap(), Key::Account(ali) ); - token.transfer(Sender(ali), bob, vec![ali_tokens.get(0).unwrap().clone()]); - ali_tokens = token.tokens(Key::Account(ali)); - let bob_tokens = token.tokens(Key::Account(bob)); + token.transfer(Sender(ali), bob, vec![first_ali_token.clone().unwrap()]); + let new_first_ali_token = token.get_token_by_index(Key::Account(ali), 0u32); + let new_second_ali_token = token.get_token_by_index(Key::Account(ali), 1u32); + let new_first_bob_token = token.get_token_by_index(Key::Account(bob), 0u32); + let new_second_bob_token = token.get_token_by_index(Key::Account(bob), 1u32); + println!("{:?}", new_first_ali_token.clone()); + println!("{:?}", new_second_ali_token.clone()); + println!("{:?}", new_first_bob_token.clone()); + println!("{:?}", new_second_bob_token.clone()); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(ali)), U256::from(1)); assert_eq!(token.balance_of(Key::Account(bob)), U256::from(1)); - assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(1)); - assert_eq!(U256::from(bob_tokens.len() as u64), U256::from(1)); assert_eq!( - token.owner_of(ali_tokens.get(0).unwrap().clone()).unwrap(), + token + .owner_of(new_first_ali_token.clone().unwrap()) + .unwrap(), Key::Account(ali) ); assert_eq!( - token.owner_of(bob_tokens.get(0).unwrap().clone()).unwrap(), + token + .owner_of(new_first_bob_token.clone().unwrap()) + .unwrap(), Key::Account(bob) ); + assert_eq!(new_second_ali_token, None); + assert_eq!(new_second_bob_token, None); } #[test] @@ -353,41 +386,47 @@ fn test_transfer_from_tokens_with_approve() { let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; token.mint_many(Sender(owner), ali, None, token_metas.clone()); - let mut ali_tokens = token.tokens(Key::Account(ali)); + let first_ali_token = token.get_token_by_index(Key::Account(ali), 0u32); + let second_ali_token = token.get_token_by_index(Key::Account(ali), 1u32); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(ali)), U256::from(2)); - assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(2)); assert_eq!( - token.owner_of(ali_tokens.get(0).unwrap().clone()).unwrap(), + token.owner_of(first_ali_token.clone().unwrap()).unwrap(), Key::Account(ali) ); assert_eq!( - token.owner_of(ali_tokens.get(1).unwrap().clone()).unwrap(), + token.owner_of(second_ali_token.clone().unwrap()).unwrap(), Key::Account(ali) ); - token.approve(Sender(ali), owner, vec![ali_tokens.get(0).unwrap().clone()]); + token.approve(Sender(ali), owner, vec![second_ali_token.clone().unwrap()]); token.transfer_from( Sender(owner), ali, bob, - vec![ali_tokens.get(0).unwrap().clone()], + vec![second_ali_token.clone().unwrap()], ); - ali_tokens = token.tokens(Key::Account(ali)); - let bob_tokens = token.tokens(Key::Account(bob)); + let new_first_ali_token = token.get_token_by_index(Key::Account(ali), 0u32); + let new_second_ali_token = token.get_token_by_index(Key::Account(ali), 1u32); + let new_first_bob_token = token.get_token_by_index(Key::Account(bob), 0u32); + let new_second_bob_token = token.get_token_by_index(Key::Account(bob), 1u32); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(ali)), U256::from(1)); assert_eq!(token.balance_of(Key::Account(bob)), U256::from(1)); - assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(1)); - assert_eq!(U256::from(bob_tokens.len() as u64), U256::from(1)); assert_eq!( - token.owner_of(ali_tokens.get(0).unwrap().clone()).unwrap(), + token + .owner_of(new_first_ali_token.clone().unwrap()) + .unwrap(), Key::Account(ali) ); assert_eq!( - token.owner_of(bob_tokens.get(0).unwrap().clone()).unwrap(), + token + .owner_of(new_first_bob_token.clone().unwrap()) + .unwrap(), Key::Account(bob) ); + assert_eq!(new_second_ali_token, None); + assert_eq!(new_second_bob_token, None); } #[test] @@ -399,24 +438,23 @@ fn test_transfer_from_tokens_without_approve() { let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; token.mint_many(Sender(owner), ali, None, token_metas.clone()); - let ali_tokens = token.tokens(Key::Account(ali)); + let first_ali_token = token.get_token_by_index(Key::Account(ali), 0u32); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(ali)), U256::from(2)); - assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(2)); assert_eq!( - token.owner_of(ali_tokens.get(0).unwrap().clone()).unwrap(), + token.owner_of(first_ali_token.clone().unwrap()).unwrap(), Key::Account(ali) ); assert_eq!( - token.owner_of(ali_tokens.get(1).unwrap().clone()).unwrap(), + token.owner_of(first_ali_token.clone().unwrap()).unwrap(), Key::Account(ali) ); token.transfer_from( Sender(owner), ali, bob, - vec![ali_tokens.get(0).unwrap().clone()], + vec![first_ali_token.clone().unwrap()], ); } @@ -433,26 +471,25 @@ fn test_approve() { token.mint_many(Sender(owner), user, None, token_metas.clone()); - let user_tokens = token.tokens(Key::Account(user)); - println!("{:?}", user_tokens); - println!("{:?}", user_tokens.first().unwrap().clone()); + let first_user_token = token.get_token_by_index(Key::Account(user), 0u32); + let fourth_user_token = token.get_token_by_index(Key::Account(user), 3u32); token.approve( Sender(user), owner, vec![ - user_tokens.get(0).unwrap().clone(), - user_tokens.get(2).unwrap().clone(), + first_user_token.clone().unwrap(), + fourth_user_token.clone().unwrap(), ], ); assert_eq!( token - .get_approved(user, user_tokens.get(0).unwrap().clone()) + .get_approved(user, first_user_token.clone().unwrap()) .unwrap(), Key::Account(owner) ); assert_eq!( token - .get_approved(user, user_tokens.get(2).unwrap().clone()) + .get_approved(user, fourth_user_token.clone().unwrap()) .unwrap(), Key::Account(owner) ); diff --git a/cep47/bin/cep47_token.rs b/cep47/bin/cep47_token.rs index 3cbbbab..0910d6f 100644 --- a/cep47/bin/cep47_token.rs +++ b/cep47/bin/cep47_token.rs @@ -100,13 +100,6 @@ fn update_token_meta() { .unwrap_or_revert(); } -#[no_mangle] -fn tokens() { - let owner = runtime::get_named_arg::("owner"); - let ret = NFTToken::default().get_tokens(owner); - runtime::ret(CLValue::from_t(ret).unwrap_or_revert()); -} - #[no_mangle] fn mint() { let recipient = runtime::get_named_arg::("recipient"); @@ -251,6 +244,65 @@ fn get_entry_points() -> EntryPoints { EntryPointAccess::Groups(vec![Group::new("constructor")]), EntryPointType::Contract, )); + entry_points.add_entry_point(EntryPoint::new( + "name", + vec![], + String::cl_type(), + EntryPointAccess::Public, + EntryPointType::Contract, + )); + entry_points.add_entry_point(EntryPoint::new( + "symbol", + vec![], + String::cl_type(), + EntryPointAccess::Public, + EntryPointType::Contract, + )); + entry_points.add_entry_point(EntryPoint::new( + "meta", + vec![], + Meta::cl_type(), + EntryPointAccess::Public, + EntryPointType::Contract, + )); + entry_points.add_entry_point(EntryPoint::new( + "total_supply", + vec![], + U256::cl_type(), + EntryPointAccess::Public, + EntryPointType::Contract, + )); + entry_points.add_entry_point(EntryPoint::new( + "balance_of", + vec![Parameter::new("owner", Key::cl_type())], + U256::cl_type(), + EntryPointAccess::Public, + EntryPointType::Contract, + )); + entry_points.add_entry_point(EntryPoint::new( + "owner_of", + vec![Parameter::new("token_id", TokenId::cl_type())], + CLType::Option(Box::new(CLType::Key)), + EntryPointAccess::Public, + EntryPointType::Contract, + )); + entry_points.add_entry_point(EntryPoint::new( + "token_meta", + vec![Parameter::new("token_id", TokenId::cl_type())], + Meta::cl_type(), + EntryPointAccess::Public, + EntryPointType::Contract, + )); + entry_points.add_entry_point(EntryPoint::new( + "update_token_meta", + vec![ + Parameter::new("token_id", TokenId::cl_type()), + Parameter::new("token_meta", Meta::cl_type()), + ], + <()>::cl_type(), + EntryPointAccess::Public, + EntryPointType::Contract, + )); entry_points.add_entry_point(EntryPoint::new( "mint", vec![ @@ -331,22 +383,5 @@ fn get_entry_points() -> EntryPoints { EntryPointAccess::Public, EntryPointType::Contract, )); - entry_points.add_entry_point(EntryPoint::new( - "update_token_meta", - vec![ - Parameter::new("token_id", TokenId::cl_type()), - Parameter::new("token_meta", Meta::cl_type()), - ], - <()>::cl_type(), - EntryPointAccess::Public, - EntryPointType::Contract, - )); - entry_points.add_entry_point(EntryPoint::new( - "total_supply", - vec![], - U256::cl_type(), - EntryPointAccess::Public, - EntryPointType::Contract, - )); entry_points } diff --git a/cep47/src/cep47.rs b/cep47/src/cep47.rs index c1ddc9a..1662b1a 100644 --- a/cep47/src/cep47.rs +++ b/cep47/src/cep47.rs @@ -75,27 +75,8 @@ pub trait CEP47: ContractContext { Ok(()) } - fn get_tokens(&self, owner: Key) -> Vec { - OwnedTokens::instance().get(&owner) - } - - fn set_tokens(&mut self, owner: Key, token_ids: Vec) { - let owners_dict = Owners::instance(); - let owned_tokens_dict = OwnedTokens::instance(); - let balances_dict = Balances::instance(); - - for token_id in &token_ids { - owners_dict.set(token_id, owner); - } - - let prev_balance = balances_dict.get(&owner); - let new_balance = U256::from(token_ids.len() as u64); - balances_dict.set(&owner, new_balance); - - owned_tokens_dict.set(&owner, token_ids); - - let new_total_supply = data::total_supply() - prev_balance + new_balance; - data::set_total_supply(new_total_supply); + fn get_token_by_index(&self, owner: Key, index: u32) -> Option { + OwnedTokens::instance().get_token_by_index(&owner, &index) } fn generate_token_ids(&mut self, n: u32) -> Vec { @@ -147,15 +128,12 @@ pub trait CEP47: ContractContext { let metadata_dict = Metadata::instance(); let balances_dict = Balances::instance(); - let mut recipient_tokens = owned_tokens_dict.get(&recipient); for (token_id, token_meta) in unique_token_ids.iter().zip(&token_metas) { metadata_dict.set(token_id, token_meta.clone()); owners_dict.set(token_id, recipient); - recipient_tokens.push(token_id.clone()); + owned_tokens_dict.set_token(&recipient, token_id.clone()); } - owned_tokens_dict.set(&recipient, recipient_tokens); - let minted_tokens_count = U256::from(unique_token_ids.len() as u64); let prev_balance = balances_dict.get(&recipient); let new_balance = prev_balance + minted_tokens_count; @@ -194,7 +172,6 @@ pub trait CEP47: ContractContext { let balances_dict = Balances::instance(); let allowances_dict = Allowances::instance(); - let mut owner_tokens = owned_tokens_dict.get(&owner); let spender = self.get_caller(); for token_id in &token_ids { @@ -211,18 +188,15 @@ pub trait CEP47: ContractContext { return Err(Error::TokenIdDoesntExist); } } - let index = owner_tokens - .iter() - .position(|x| x == token_id) - .unwrap_or_revert(); - owner_tokens.remove(index); + owned_tokens_dict.remove_token(&owner, token_id.clone()); metadata_dict.remove(token_id); owners_dict.remove(token_id); allowances_dict.remove(&owner, token_id); } - balances_dict.set(&owner, U256::from(owner_tokens.len() as u64)); - owned_tokens_dict.set(&owner, owner_tokens); + let owner_balance = balances_dict.get(&owner); + let new_owner_balance = owner_balance - U256::from(token_ids.len() as u64); + balances_dict.set(&owner, new_owner_balance); let burnt_tokens_count = U256::from(token_ids.len() as u64); let new_total_supply = data::total_supply() - burnt_tokens_count; @@ -281,8 +255,6 @@ pub trait CEP47: ContractContext { let owned_tokens_dict = OwnedTokens::instance(); let balances_dict = Balances::instance(); - let mut sender_tokens = owned_tokens_dict.get(&owner); - let mut recipient_tokens = owned_tokens_dict.get(&recipient); for token_id in &token_ids { match owners_dict.get(token_id) { Some(owner_of_key) => { @@ -294,20 +266,18 @@ pub trait CEP47: ContractContext { return Err(Error::TokenIdDoesntExist); } } - let index = sender_tokens - .iter() - .position(|x| x == token_id) - .unwrap_or_revert(); - sender_tokens.remove(index); - recipient_tokens.push(token_id.clone()); + owned_tokens_dict.remove_token(&owner, token_id.clone()); + owned_tokens_dict.set_token(&recipient, token_id.clone()); owners_dict.set(token_id, recipient); } + let owner_balance = balances_dict.get(&owner); + let new_owner_balance = owner_balance - U256::from(token_ids.len() as u64); + balances_dict.set(&owner, new_owner_balance); - balances_dict.set(&owner, sender_tokens.len().into()); - owned_tokens_dict.set(&owner, sender_tokens); + let recipient_balance = balances_dict.get(&recipient); + let new_recipient_balance = recipient_balance + U256::from(token_ids.len() as u64); + balances_dict.set(&recipient, new_recipient_balance); - balances_dict.set(&recipient, recipient_tokens.len().into()); - owned_tokens_dict.set(&recipient, recipient_tokens); self.emit(CEP47Event::Transfer { sender: owner, recipient, diff --git a/cep47/src/data.rs b/cep47/src/data.rs index 6635831..24b9850 100644 --- a/cep47/src/data.rs +++ b/cep47/src/data.rs @@ -5,7 +5,7 @@ use alloc::{ }; use casper_contract::{contract_api::storage, unwrap_or_revert::UnwrapOrRevert}; use casper_types::{ContractPackageHash, Key, URef, U256}; -use contract_utils::{get_key, key_and_value_to_str, set_key, Dict}; +use contract_utils::{get_key, key_and_value_to_str, key_to_str, set_key, Dict}; use crate::{event::CEP47Event, Meta, TokenId}; @@ -13,7 +13,9 @@ const BALANCES_DICT: &str = "balances"; pub const ALLOWANCES_DICT: &str = "allowances"; const METADATA_DICT: &str = "metadata"; const OWNERS_DICT: &str = "owners"; -const OWNED_TOKENS_DICT: &str = "owned_tokens"; +const OWNED_TOKENS_BY_INDEX_DICT: &str = "owned_tokens_by_index"; +const OWNED_INDEXES_BY_TOKEN_DICT: &str = "owned_indexes_by_token"; +const OWNED_TOKENS_LENGTH_DICT: &str = "owned_tokens_length"; const CONTRACT_PACKAGE_HASH: &str = "contract_package_hash"; pub const NAME: &str = "name"; @@ -103,26 +105,74 @@ impl Metadata { } pub struct OwnedTokens { - dict: Dict, + token_dict: Dict, + index_dict: Dict, + length_dict: Dict, } impl OwnedTokens { pub fn instance() -> OwnedTokens { OwnedTokens { - dict: Dict::instance(OWNED_TOKENS_DICT), + token_dict: Dict::instance(OWNED_TOKENS_BY_INDEX_DICT), + index_dict: Dict::instance(OWNED_INDEXES_BY_TOKEN_DICT), + length_dict: Dict::instance(OWNED_TOKENS_LENGTH_DICT), } } pub fn init() { - Dict::init(OWNED_TOKENS_DICT) + Dict::init(OWNED_TOKENS_BY_INDEX_DICT); + Dict::init(OWNED_INDEXES_BY_TOKEN_DICT); + Dict::init(OWNED_TOKENS_LENGTH_DICT); } - pub fn get(&self, owner: &Key) -> Vec { - self.dict.get_by_key(owner).unwrap_or_default() + pub fn get_token_by_index(&self, owner: &Key, index: &u32) -> Option { + self.token_dict.get(&key_and_value_to_str(owner, index)) } - pub fn set(&self, owner: &Key, value: Vec) { - self.dict.set_by_key(owner, value); + pub fn get_index_by_token(&self, owner: &Key, value: &TokenId) -> Option { + self.index_dict.get(&key_and_value_to_str(owner, value)) + } + + pub fn get_tokens_len(&self, owner: &Key) -> Option { + self.length_dict.get(&key_to_str(owner)) + } + + pub fn set_tokens_len(&self, owner: &Key, value: u32) { + self.length_dict.set(&key_to_str(owner), value); + } + + pub fn set_token(&self, owner: &Key, value: TokenId) { + let length = self.get_tokens_len(owner).unwrap_or_default(); + self.index_dict + .set(&key_and_value_to_str(owner, &value), length.clone()); + self.token_dict + .set(&key_and_value_to_str(owner, &length), value); + self.set_tokens_len(owner, length + 1); + } + + pub fn remove_token(&self, owner: &Key, value: TokenId) { + let length = self.get_tokens_len(owner).unwrap_or_revert(); + let index = self.get_index_by_token(owner, &value).unwrap_or_revert(); + if length == index + 1 { + self.token_dict + .remove::(&key_and_value_to_str(owner, &(length - 1))); + self.set_tokens_len(owner, length - 1); + } else if length > index + 1 { + let last = self.get_token_by_index(owner, &(length - 1)); + self.index_dict.set( + &key_and_value_to_str(owner, &last.clone().unwrap_or_revert()), + index, + ); + self.token_dict.set( + &key_and_value_to_str(owner, &index), + last.clone().unwrap_or_revert(), + ); + self.token_dict + .remove::(&key_and_value_to_str(owner, &(length - 1))); + self.set_tokens_len(owner, length - 1); + } + self.index_dict + .remove::(&key_and_value_to_str(owner, &value)); } } diff --git a/utils/contract-utils/src/lib.rs b/utils/contract-utils/src/lib.rs index 4e52e04..6006aa4 100644 --- a/utils/contract-utils/src/lib.rs +++ b/utils/contract-utils/src/lib.rs @@ -11,4 +11,4 @@ mod data; pub use admin_control::AdminControl; pub use contract_context::ContractContext; pub use contract_storage::{ContractStorage, OnChainContractStorage}; -pub use data::{get_key, key_and_value_to_str, set_key, Dict}; +pub use data::{get_key, key_and_value_to_str, key_to_str, set_key, Dict}; From 15409d8316e3d3fa2a8da73c27fe6bd80839213c Mon Sep 17 00:00:00 2001 From: astro019 Date: Fri, 20 Aug 2021 13:28:19 +1000 Subject: [PATCH 71/98] wip: reorganize cep47 lib --- .DS_Store | Bin 0 -> 6148 bytes Cargo.lock | 97 ++-- Cargo.toml | 5 +- Makefile | 13 +- cep47-logic/Cargo.toml | 12 - cep47-tests/Cargo.toml | 13 +- cep47-tests/src/cep47_instance.rs | 233 +++++++++ cep47-tests/src/cep47_tests.rs | 476 ++++++++++++++++++ cep47-tests/src/lib.rs | 4 +- cep47-tests/wasm/.gitkeep | 0 cep47/Cargo.toml | 36 +- cep47/bin/cep47_token.rs | 352 +++++++++++++ cep47/src/cep47.rs | 332 ++++++++++++ cep47/src/data.rs | 325 ++++++------ .../src/events.rs => cep47/src/event.rs | 26 +- cep47/src/lib.rs | 292 +---------- utils/contract-utils/Cargo.toml | 11 + utils/contract-utils/src/admin_control.rs | 63 +++ utils/contract-utils/src/contract_context.rs | 34 ++ utils/contract-utils/src/contract_storage.rs | 21 + utils/contract-utils/src/data.rs | 121 +++++ utils/contract-utils/src/lib.rs | 14 + utils/test-env/Cargo.toml | 13 + utils/test-env/src/lib.rs | 7 + utils/test-env/src/test_contract.rs | 61 +++ utils/test-env/src/test_env.rs | 120 +++++ 26 files changed, 2111 insertions(+), 570 deletions(-) create mode 100644 .DS_Store delete mode 100644 cep47-logic/Cargo.toml create mode 100644 cep47-tests/src/cep47_instance.rs create mode 100644 cep47-tests/src/cep47_tests.rs delete mode 100644 cep47-tests/wasm/.gitkeep create mode 100644 cep47/bin/cep47_token.rs create mode 100644 cep47/src/cep47.rs rename cep47-logic/src/events.rs => cep47/src/event.rs (87%) create mode 100644 utils/contract-utils/Cargo.toml create mode 100644 utils/contract-utils/src/admin_control.rs create mode 100644 utils/contract-utils/src/contract_context.rs create mode 100644 utils/contract-utils/src/contract_storage.rs create mode 100644 utils/contract-utils/src/data.rs create mode 100644 utils/contract-utils/src/lib.rs create mode 100644 utils/test-env/Cargo.toml create mode 100644 utils/test-env/src/lib.rs create mode 100644 utils/test-env/src/test_contract.rs create mode 100644 utils/test-env/src/test_env.rs diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0/dev/null | true - wasm-strip target/wasm32-unknown-unknown/release/owning-contract.wasm 2>/dev/null | true + cargo build --release -p cep47 --target wasm32-unknown-unknown + wasm-strip target/wasm32-unknown-unknown/release/cep47-token.wasm 2>/dev/null | true test-only: - cargo test -p cep47-logic cargo test -p cep47-tests copy-wasm-file-to-test: - mkdir -p cep47-tests/wasm cp target/wasm32-unknown-unknown/release/*.wasm cep47-tests/wasm test: build-contract copy-wasm-file-to-test test-only clippy: - cargo clippy --all-targets --all -- -A clippy::ptr_arg + cargo clippy --all-targets --all -- -D warnings check-lint: clippy cargo fmt --all -- --check -format: +lint: clippy cargo fmt --all -lint: clippy format - clean: cargo clean rm -rf cep47-tests/wasm/*.wasm diff --git a/cep47-logic/Cargo.toml b/cep47-logic/Cargo.toml deleted file mode 100644 index 171bd5f..0000000 --- a/cep47-logic/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "cep47-logic" -version = "0.1.0" -authors = ["Maciej Zielinski "] -edition = "2018" - -[dependencies] -casper-types = "1.3.1" - -[dev-dependencies] -rand = "0.7.3" -maplit = "1.0.2" \ No newline at end of file diff --git a/cep47-tests/Cargo.toml b/cep47-tests/Cargo.toml index 68d40e1..60dd240 100644 --- a/cep47-tests/Cargo.toml +++ b/cep47-tests/Cargo.toml @@ -1,15 +1,18 @@ [package] name = "cep47-tests" version = "0.1.0" -authors = ["astro019 "] edition = "2018" +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + [dependencies] -casper-contract = "1.3.1" -casper-types = "1.3.1" -casper-engine-test-support = "1.3.1" -maplit = "1.0.2" +casper-contract = "1.3.2" +casper-types = "1.3.2" +casper-engine-test-support = "1.3.2" +test-env = { path = "../utils/test-env" } +contract-utils = { path = "../utils/contract-utils" } hex = "0.4.3" +blake2 = "0.9.1" [features] default = ["casper-contract/std", "casper-types/std", "casper-contract/test-support"] diff --git a/cep47-tests/src/cep47_instance.rs b/cep47-tests/src/cep47_instance.rs new file mode 100644 index 0000000..cafdfc3 --- /dev/null +++ b/cep47-tests/src/cep47_instance.rs @@ -0,0 +1,233 @@ +use std::collections::BTreeMap; + +use blake2::{ + digest::{Update, VariableOutput}, + VarBlake2b, +}; +use casper_types::{bytesrepr::ToBytes, runtime_args, CLTyped, Key, RuntimeArgs, U256}; +use test_env::{Sender, TestContract, TestEnv}; + +pub type TokenId = String; +pub type Meta = BTreeMap; + +pub struct CEP47Instance(TestContract); + +impl CEP47Instance { + pub fn new( + env: &TestEnv, + contract_name: &str, + sender: Sender, + name: &str, + symbol: &str, + meta: Meta, + ) -> CEP47Instance { + CEP47Instance(TestContract::new( + env, + "cep47-token.wasm", + contract_name, + sender, + runtime_args! { + "name" => name, + "symbol" => symbol, + "meta" => meta + }, + )) + } + + pub fn constructor(&self, sender: Sender, name: &str, symbol: &str, meta: Meta) { + self.0.call_contract( + sender, + "constructor", + runtime_args! { + "name" => name, + "symbol" => symbol, + "meta" => meta}, + ); + } + + pub fn mint_one>( + &self, + sender: Sender, + recipient: T, + token_id: Option, + token_meta: Meta, + ) { + self.0.call_contract( + sender, + "mint", + runtime_args! { + "recipient" => recipient.into(), + "token_ids" => token_id.map(|x| vec![x]), + "token_metas" => vec![token_meta] + }, + ) + } + + pub fn mint_copies>( + &self, + sender: Sender, + recipient: T, + token_ids: Option>, + token_meta: Meta, + count: u32, + ) { + self.0.call_contract( + sender, + "mint_copies", + runtime_args! { + "recipient" => recipient.into(), + "token_ids" => token_ids, + "token_meta" => token_meta, + "count" => count + }, + ) + } + + pub fn mint_many>( + &self, + sender: Sender, + recipient: T, + token_ids: Option>, + token_metas: Vec, + ) { + self.0.call_contract( + sender, + "mint", + runtime_args! { + "recipient" => recipient.into(), + "token_ids" => token_ids, + "token_metas" => token_metas + }, + ) + } + + pub fn burn_one>(&self, sender: Sender, owner: T, token_id: TokenId) { + self.0.call_contract( + sender, + "burn", + runtime_args! { + "owner" => owner.into(), + "token_ids" => vec![token_id] + }, + ) + } + + pub fn burn_many>(&self, sender: Sender, owner: T, token_ids: Vec) { + self.0.call_contract( + sender, + "burn", + runtime_args! { + "owner" => owner.into(), + "token_ids" => token_ids + }, + ) + } + + pub fn transfer>(&self, sender: Sender, recipient: T, token_ids: Vec) { + self.0.call_contract( + sender, + "transfer", + runtime_args! { + "recipient" => recipient.into(), + "token_ids" => token_ids + }, + ) + } + + pub fn transfer_from>( + &self, + sender: Sender, + owner: T, + recipient: T, + token_ids: Vec, + ) { + self.0.call_contract( + sender, + "transfer_from", + runtime_args! { + "sender" => owner.into(), + "recipient" => recipient.into(), + "token_ids" => token_ids + }, + ) + } + + pub fn approve>(&self, sender: Sender, spender: T, token_ids: Vec) { + self.0.call_contract( + sender, + "approve", + runtime_args! {"spender" => spender.into(), "token_ids" => token_ids}, + ) + } + + pub fn get_approved>(&self, owner: T, token_id: TokenId) -> Option { + self.0.query_dictionary( + "allowances", + key_and_value_to_str::(&owner.into(), &token_id), + ) + } + + pub fn update_token_meta(&self, sender: Sender, token_id: TokenId, token_meta: Meta) { + self.0.call_contract( + sender, + "update_token_meta", + runtime_args! { + "token_id" => token_id, + "token_meta" => token_meta + }, + ) + } + + pub fn tokens>(&self, account: T) -> Vec { + self.0 + .query_dictionary("owned_tokens", key_to_str(&account.into())) + .unwrap_or_default() + } + + pub fn balance_of>(&self, account: T) -> U256 { + self.0 + .query_dictionary("balances", key_to_str(&account.into())) + .unwrap_or_default() + } + + pub fn owner_of(&self, token_id: TokenId) -> Option { + self.0.query_dictionary("owners", token_id) + } + + pub fn token_meta(&self, token_id: TokenId) -> Option { + self.0.query_dictionary("metadata", token_id) + } + + pub fn name(&self) -> String { + self.0.query_named_key(String::from("name")) + } + + pub fn symbol(&self) -> String { + self.0.query_named_key(String::from("symbol")) + } + + pub fn total_supply(&self) -> U256 { + self.0.query_named_key(String::from("total_supply")) + } + + pub fn meta(&self) -> Meta { + self.0.query_named_key(String::from("meta")) + } +} + +pub fn key_to_str(key: &Key) -> String { + match key { + Key::Account(account) => account.to_string(), + Key::Hash(package) => hex::encode(package), + _ => panic!("Unexpected key type"), + } +} + +pub fn key_and_value_to_str(key: &Key, value: &T) -> String { + let mut hasher = VarBlake2b::new(32).unwrap(); + hasher.update(key.to_bytes().unwrap()); + hasher.update(value.to_bytes().unwrap()); + let mut ret = [0u8; 32]; + hasher.finalize_variable(|hash| ret.clone_from_slice(hash)); + hex::encode(ret) +} diff --git a/cep47-tests/src/cep47_tests.rs b/cep47-tests/src/cep47_tests.rs new file mode 100644 index 0000000..24f3793 --- /dev/null +++ b/cep47-tests/src/cep47_tests.rs @@ -0,0 +1,476 @@ +use std::collections::BTreeMap; + +use casper_engine_test_support::AccountHash; +use casper_types::{Key, U256}; +use test_env::{Sender, TestEnv}; + +use crate::cep47_instance::{CEP47Instance, Meta, TokenId}; + +const NAME: &str = "DragonsNFT"; +const SYMBOL: &str = "DGNFT"; + +mod meta { + use super::{BTreeMap, Meta}; + pub fn contract_meta() -> Meta { + let mut meta = BTreeMap::new(); + meta.insert("origin".to_string(), "fire".to_string()); + meta + } + + pub fn red_dragon() -> Meta { + let mut meta = BTreeMap::new(); + meta.insert("color".to_string(), "red".to_string()); + meta + } + + pub fn blue_dragon() -> Meta { + let mut meta = BTreeMap::new(); + meta.insert("color".to_string(), "blue".to_string()); + meta + } + + pub fn black_dragon() -> Meta { + let mut meta = BTreeMap::new(); + meta.insert("color".to_string(), "black".to_string()); + meta + } + + pub fn gold_dragon() -> Meta { + let mut meta = BTreeMap::new(); + meta.insert("color".to_string(), "gold".to_string()); + meta + } +} + +fn deploy() -> (TestEnv, CEP47Instance, AccountHash) { + let env = TestEnv::new(); + let owner = env.next_user(); + let token = CEP47Instance::new( + &env, + NAME, + Sender(owner), + NAME, + SYMBOL, + meta::contract_meta(), + ); + (env, token, owner) +} + +#[test] +fn test_deploy() { + let (_, token, _) = deploy(); + assert_eq!(token.name(), NAME); + assert_eq!(token.symbol(), SYMBOL); + assert_eq!(token.meta(), meta::contract_meta()); + assert_eq!(token.total_supply(), U256::zero()); +} + +#[test] +fn test_token_meta() { + let (env, token, owner) = deploy(); + let user = env.next_user(); + let token_id = TokenId::from("custom_token_id"); + let token_meta = meta::red_dragon(); + + token.mint_one( + Sender(owner), + user, + Some(token_id.clone()), + token_meta.clone(), + ); + + let user_token_meta = token.token_meta(token_id.clone()); + assert_eq!(user_token_meta.unwrap(), token_meta); + + let user_tokens = token.tokens(Key::Account(user)); + assert_eq!(user_tokens, vec![token_id]); +} + +#[test] +fn test_mint_one_with_random_token_id() { + let (env, token, owner) = deploy(); + let user = env.next_user(); + token.mint_one(Sender(owner), user, None, meta::red_dragon()); + + assert_eq!(token.total_supply(), U256::one()); + assert_eq!(token.balance_of(user), U256::one()); + + let user_tokens: Vec = token.tokens(Key::Account(user)); + assert_eq!(U256::from(user_tokens.len() as u64), U256::one()); + assert_eq!( + token.owner_of(user_tokens.get(0).unwrap().clone()).unwrap(), + Key::Account(user) + ); +} + +#[test] +fn test_mint_one_with_set_token_id() { + let (env, token, owner) = deploy(); + let user = env.next_user(); + let token_id = TokenId::from("123456"); + let token_meta = meta::red_dragon(); + + token.mint_one( + Sender(owner), + user, + Some(token_id.clone()), + token_meta.clone(), + ); + let user_tokens = token.tokens(Key::Account(user)); + assert_eq!(user_tokens, vec![token_id.clone()]); + assert_eq!(token.total_supply(), U256::one()); + assert_eq!(token.balance_of(Key::Account(user)), U256::one()); + assert_eq!(U256::from(user_tokens.len() as u64), U256::one()); + assert_eq!(token.owner_of(token_id).unwrap(), Key::Account(user)); +} + +#[test] +#[should_panic] +fn test_mint_one_with_not_unique_token_id() { + let (env, token, owner) = deploy(); + let user = env.next_user(); + let token_id = TokenId::from("123456"); + let token_meta = meta::red_dragon(); + + token.mint_one( + Sender(owner), + user, + Some(token_id.clone()), + token_meta.clone(), + ); + + token.mint_one( + Sender(owner), + user, + Some(token_id.clone()), + token_meta.clone(), + ); +} + +#[test] +fn test_mint_copies() { + let (env, token, owner) = deploy(); + let user = env.next_user(); + let token_meta = meta::red_dragon(); + + token.mint_copies(Sender(owner), user, None, token_meta.clone(), 3); + + let user_tokens = token.tokens(Key::Account(user)); + assert_eq!(token.total_supply(), U256::from(3)); + assert_eq!(token.balance_of(Key::Account(user)), U256::from(3)); + assert_eq!(U256::from(user_tokens.len() as u64), U256::from(3)); + assert_eq!( + token.owner_of(user_tokens.get(0).unwrap().clone()).unwrap(), + Key::Account(user) + ); + assert_eq!( + token.owner_of(user_tokens.get(1).unwrap().clone()).unwrap(), + Key::Account(user) + ); + assert_eq!( + token.owner_of(user_tokens.get(2).unwrap().clone()).unwrap(), + Key::Account(user) + ); +} + +#[test] +fn test_mint_many() { + let (env, token, owner) = deploy(); + let user = env.next_user(); + let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; + + token.mint_many(Sender(owner), user, None, token_metas.clone()); + let user_tokens = token.tokens(Key::Account(user)); + assert_eq!(token.total_supply(), U256::from(2)); + assert_eq!(token.balance_of(Key::Account(user)), U256::from(2)); + assert_eq!(U256::from(user_tokens.len() as u64), U256::from(2)); + assert_eq!( + token.owner_of(user_tokens.get(0).unwrap().clone()).unwrap(), + Key::Account(user) + ); + assert_eq!( + token.owner_of(user_tokens.get(1).unwrap().clone()).unwrap(), + Key::Account(user) + ); +} + +#[test] +fn test_burn_many() { + // TODO: the sender should be owner of nft item or allowed party + let (env, token, owner) = deploy(); + let user = env.next_user(); + let token_metas = vec![ + meta::red_dragon(), + meta::blue_dragon(), + meta::black_dragon(), + meta::gold_dragon(), + ]; + + token.mint_many(Sender(owner), user, None, token_metas.clone()); + + let mut user_tokens = token.tokens(Key::Account(user)); + println!("{:?}", user_tokens); + println!("{:?}", user_tokens.first().unwrap().clone()); + + token.burn_many( + Sender(user), + user, + vec![ + user_tokens.first().unwrap().clone(), + user_tokens.last().unwrap().clone(), + ], + ); + assert_eq!(token.total_supply(), U256::from(2)); + assert_eq!(token.balance_of(Key::Account(user)), U256::from(2)); + + user_tokens = token.tokens(Key::Account(user)); + println!("{:?}", user_tokens); + assert_eq!(U256::from(user_tokens.len() as u64), U256::from(2)); +} + +#[test] +fn test_burn_many_from_allowance_with_approve() { + let (env, token, owner) = deploy(); + let user = env.next_user(); + let token_metas = vec![ + meta::red_dragon(), + meta::blue_dragon(), + meta::black_dragon(), + meta::gold_dragon(), + ]; + + token.mint_many(Sender(owner), user, None, token_metas.clone()); + + let mut user_tokens = token.tokens(Key::Account(user)); + println!("{:?}", user_tokens); + println!("{:?}", user_tokens.first().unwrap().clone()); + token.approve(Sender(user), owner, user_tokens.clone()); + token.burn_many( + Sender(owner), + user, + vec![ + user_tokens.first().unwrap().clone(), + user_tokens.last().unwrap().clone(), + ], + ); + assert_eq!(token.total_supply(), U256::from(2)); + assert_eq!(token.balance_of(Key::Account(user)), U256::from(2)); + + user_tokens = token.tokens(Key::Account(user)); + println!("{:?}", user_tokens); + assert_eq!(U256::from(user_tokens.len() as u64), U256::from(2)); +} + +#[test] +#[should_panic] +fn test_burn_many_from_allowance_without_approve() { + let (env, token, owner) = deploy(); + let user = env.next_user(); + let token_metas = vec![ + meta::red_dragon(), + meta::blue_dragon(), + meta::black_dragon(), + meta::gold_dragon(), + ]; + + token.mint_many(Sender(owner), user, None, token_metas.clone()); + + let user_tokens = token.tokens(Key::Account(user)); + println!("{:?}", user_tokens); + println!("{:?}", user_tokens.first().unwrap().clone()); + token.burn_many( + Sender(owner), + user, + vec![ + user_tokens.first().unwrap().clone(), + user_tokens.last().unwrap().clone(), + ], + ); +} + +#[test] +fn test_burn_one() { + // TODO: the sender should be owner of nft item or allowed party + let (env, token, owner) = deploy(); + let user = env.next_user(); + let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; + token.mint_many(Sender(owner), user, None, token_metas.clone()); + + let mut user_tokens = token.tokens(Key::Account(user)); + token.burn_one(Sender(user), user, user_tokens.first().unwrap().clone()); + assert_eq!(token.total_supply(), U256::from(1)); + assert_eq!(token.balance_of(Key::Account(user)), U256::from(1)); + + user_tokens = token.tokens(Key::Account(user)); + assert_eq!(U256::from(user_tokens.len() as u64), U256::from(1)); +} + +#[test] +fn test_transfer_token() { + let (env, token, owner) = deploy(); + let ali = env.next_user(); + let bob = env.next_user(); + let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; + + token.mint_many(Sender(owner), ali, None, token_metas.clone()); + let mut ali_tokens = token.tokens(Key::Account(ali)); + + assert_eq!(token.total_supply(), U256::from(2)); + assert_eq!(token.balance_of(Key::Account(ali)), U256::from(2)); + assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(2)); + assert_eq!( + token.owner_of(ali_tokens.get(0).unwrap().clone()).unwrap(), + Key::Account(ali) + ); + assert_eq!( + token.owner_of(ali_tokens.get(1).unwrap().clone()).unwrap(), + Key::Account(ali) + ); + + token.transfer(Sender(ali), bob, vec![ali_tokens.get(0).unwrap().clone()]); + ali_tokens = token.tokens(Key::Account(ali)); + let bob_tokens = token.tokens(Key::Account(bob)); + assert_eq!(token.total_supply(), U256::from(2)); + assert_eq!(token.balance_of(Key::Account(ali)), U256::from(1)); + assert_eq!(token.balance_of(Key::Account(bob)), U256::from(1)); + assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(1)); + assert_eq!(U256::from(bob_tokens.len() as u64), U256::from(1)); + assert_eq!( + token.owner_of(ali_tokens.get(0).unwrap().clone()).unwrap(), + Key::Account(ali) + ); + assert_eq!( + token.owner_of(bob_tokens.get(0).unwrap().clone()).unwrap(), + Key::Account(bob) + ); +} + +#[test] +fn test_transfer_from_tokens_with_approve() { + let (env, token, owner) = deploy(); + let ali = env.next_user(); + let bob = env.next_user(); + let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; + + token.mint_many(Sender(owner), ali, None, token_metas.clone()); + let mut ali_tokens = token.tokens(Key::Account(ali)); + + assert_eq!(token.total_supply(), U256::from(2)); + assert_eq!(token.balance_of(Key::Account(ali)), U256::from(2)); + assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(2)); + assert_eq!( + token.owner_of(ali_tokens.get(0).unwrap().clone()).unwrap(), + Key::Account(ali) + ); + assert_eq!( + token.owner_of(ali_tokens.get(1).unwrap().clone()).unwrap(), + Key::Account(ali) + ); + token.approve(Sender(ali), owner, vec![ali_tokens.get(0).unwrap().clone()]); + token.transfer_from( + Sender(owner), + ali, + bob, + vec![ali_tokens.get(0).unwrap().clone()], + ); + ali_tokens = token.tokens(Key::Account(ali)); + let bob_tokens = token.tokens(Key::Account(bob)); + assert_eq!(token.total_supply(), U256::from(2)); + assert_eq!(token.balance_of(Key::Account(ali)), U256::from(1)); + assert_eq!(token.balance_of(Key::Account(bob)), U256::from(1)); + assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(1)); + assert_eq!(U256::from(bob_tokens.len() as u64), U256::from(1)); + assert_eq!( + token.owner_of(ali_tokens.get(0).unwrap().clone()).unwrap(), + Key::Account(ali) + ); + assert_eq!( + token.owner_of(bob_tokens.get(0).unwrap().clone()).unwrap(), + Key::Account(bob) + ); +} + +#[test] +#[should_panic] +fn test_transfer_from_tokens_without_approve() { + let (env, token, owner) = deploy(); + let ali = env.next_user(); + let bob = env.next_user(); + let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; + + token.mint_many(Sender(owner), ali, None, token_metas.clone()); + let ali_tokens = token.tokens(Key::Account(ali)); + + assert_eq!(token.total_supply(), U256::from(2)); + assert_eq!(token.balance_of(Key::Account(ali)), U256::from(2)); + assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(2)); + assert_eq!( + token.owner_of(ali_tokens.get(0).unwrap().clone()).unwrap(), + Key::Account(ali) + ); + assert_eq!( + token.owner_of(ali_tokens.get(1).unwrap().clone()).unwrap(), + Key::Account(ali) + ); + token.transfer_from( + Sender(owner), + ali, + bob, + vec![ali_tokens.get(0).unwrap().clone()], + ); +} + +#[test] +fn test_approve() { + let (env, token, owner) = deploy(); + let user = env.next_user(); + let token_metas = vec![ + meta::red_dragon(), + meta::blue_dragon(), + meta::black_dragon(), + meta::gold_dragon(), + ]; + + token.mint_many(Sender(owner), user, None, token_metas.clone()); + + let user_tokens = token.tokens(Key::Account(user)); + println!("{:?}", user_tokens); + println!("{:?}", user_tokens.first().unwrap().clone()); + token.approve( + Sender(user), + owner, + vec![ + user_tokens.get(0).unwrap().clone(), + user_tokens.get(2).unwrap().clone(), + ], + ); + assert_eq!( + token + .get_approved(user, user_tokens.get(0).unwrap().clone()) + .unwrap(), + Key::Account(owner) + ); + assert_eq!( + token + .get_approved(user, user_tokens.get(2).unwrap().clone()) + .unwrap(), + Key::Account(owner) + ); +} + +#[test] +fn test_token_metadata_update() { + let (env, token, owner) = deploy(); + let user = env.next_user(); + let token_id = TokenId::from("123456"); + + token.mint_one( + Sender(owner), + user, + Some(token_id.clone()), + meta::red_dragon(), + ); + + token.update_token_meta(Sender(owner), token_id.clone(), meta::gold_dragon()); + assert_eq!(token.token_meta(token_id).unwrap(), meta::gold_dragon()); +} diff --git a/cep47-tests/src/lib.rs b/cep47-tests/src/lib.rs index f86f3b0..058c332 100644 --- a/cep47-tests/src/lib.rs +++ b/cep47-tests/src/lib.rs @@ -1,5 +1,5 @@ #[cfg(test)] -pub mod cep47; +pub mod cep47_tests; #[cfg(test)] -pub mod contract_tests; +pub mod cep47_instance; diff --git a/cep47-tests/wasm/.gitkeep b/cep47-tests/wasm/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/cep47/Cargo.toml b/cep47/Cargo.toml index c5fe8dd..8e8b95f 100644 --- a/cep47/Cargo.toml +++ b/cep47/Cargo.toml @@ -5,30 +5,14 @@ authors = ["astro019 "] edition = "2018" [dependencies] -hex = "0.4.3" -casper-contract = "1.3.1" -casper-types = "1.3.1" -cep47-logic = { path = "../cep47-logic" } +hex = { version = "0.4.3", default-features = false } +casper-contract = "1.3.2" +casper-types = "1.3.2" +contract-utils = { path = "../utils/contract-utils" } -[lib] -name = "cep47" - -[features] -default = ["casper-contract/std", "casper-types/std"] -no_name = [] -no_symbol = [] -no_meta = [] -no_balance_of = [] -no_owner_of = [] -no_total_supply = [] -no_is_paused = [] -no_pause = [] -no_unpause = [] -no_mint_one = [] -no_mint_many = [] -no_mint_copies = [] -no_burn_many = [] -no_burn_one = [] -no_transfer_token = [] -no_transfer_many_tokens = [] -no_update_token_metadata = [] \ No newline at end of file +[[bin]] +name = "cep47-token" +path = "bin/cep47_token.rs" +bench = false +doctest = false +test = false diff --git a/cep47/bin/cep47_token.rs b/cep47/bin/cep47_token.rs new file mode 100644 index 0000000..3cbbbab --- /dev/null +++ b/cep47/bin/cep47_token.rs @@ -0,0 +1,352 @@ +#![no_main] +#![no_std] + +#[macro_use] +extern crate alloc; + +use alloc::{ + boxed::Box, + collections::BTreeSet, + format, + string::{String, ToString}, + vec::Vec, +}; +use casper_contract::{ + contract_api::{runtime, storage}, + unwrap_or_revert::UnwrapOrRevert, +}; +use casper_types::{ + contracts::NamedKeys, runtime_args, CLType, CLTyped, CLValue, EntryPoint, EntryPointAccess, + EntryPointType, EntryPoints, Group, Key, Parameter, RuntimeArgs, URef, U256, +}; +use cep47::{Meta, TokenId, CEP47}; +use contract_utils::{ContractContext, OnChainContractStorage}; + +#[derive(Default)] +struct NFTToken(OnChainContractStorage); + +impl ContractContext for NFTToken { + fn storage(&self) -> &OnChainContractStorage { + &self.0 + } +} + +impl CEP47 for NFTToken {} +impl NFTToken { + fn constructor(&mut self, name: String, symbol: String, meta: Meta) { + CEP47::init(self, name, symbol, meta); + } +} + +#[no_mangle] +fn constructor() { + let name = runtime::get_named_arg::("name"); + let symbol = runtime::get_named_arg::("symbol"); + let meta = runtime::get_named_arg::("meta"); + NFTToken::default().constructor(name, symbol, meta); +} + +#[no_mangle] +fn name() { + let ret = NFTToken::default().name(); + runtime::ret(CLValue::from_t(ret).unwrap_or_revert()); +} + +#[no_mangle] +fn symbol() { + let ret = NFTToken::default().symbol(); + runtime::ret(CLValue::from_t(ret).unwrap_or_revert()); +} + +#[no_mangle] +fn meta() { + let ret = NFTToken::default().meta(); + runtime::ret(CLValue::from_t(ret).unwrap_or_revert()); +} + +#[no_mangle] +fn total_supply() { + let ret = NFTToken::default().total_supply(); + runtime::ret(CLValue::from_t(ret).unwrap_or_revert()); +} + +#[no_mangle] +fn balance_of() { + let owner = runtime::get_named_arg::("owner"); + let ret = NFTToken::default().balance_of(owner); + runtime::ret(CLValue::from_t(ret).unwrap_or_revert()); +} + +#[no_mangle] +fn owner_of() { + let token_id = runtime::get_named_arg::("token_id"); + let ret = NFTToken::default().owner_of(token_id); + runtime::ret(CLValue::from_t(ret).unwrap_or_revert()); +} + +#[no_mangle] +fn token_meta() { + let token_id = runtime::get_named_arg::("token_id"); + let ret = NFTToken::default().token_meta(token_id); + runtime::ret(CLValue::from_t(ret).unwrap_or_revert()); +} + +#[no_mangle] +fn update_token_meta() { + let token_id = runtime::get_named_arg::("token_id"); + let token_meta = runtime::get_named_arg::("token_meta"); + NFTToken::default() + .set_token_meta(token_id, token_meta) + .unwrap_or_revert(); +} + +#[no_mangle] +fn tokens() { + let owner = runtime::get_named_arg::("owner"); + let ret = NFTToken::default().get_tokens(owner); + runtime::ret(CLValue::from_t(ret).unwrap_or_revert()); +} + +#[no_mangle] +fn mint() { + let recipient = runtime::get_named_arg::("recipient"); + let token_ids = runtime::get_named_arg::>>("token_ids"); + let token_metas = runtime::get_named_arg::>("token_metas"); + NFTToken::default() + .mint(recipient, token_ids, token_metas) + .unwrap_or_revert(); +} + +#[no_mangle] +fn mint_copies() { + let recipient = runtime::get_named_arg::("recipient"); + let token_ids = runtime::get_named_arg::>>("token_ids"); + let token_meta = runtime::get_named_arg::("token_meta"); + let count = runtime::get_named_arg::("count"); + NFTToken::default() + .mint_copies(recipient, token_ids, token_meta, count) + .unwrap_or_revert(); +} + +#[no_mangle] +fn burn() { + let owner = runtime::get_named_arg::("owner"); + let token_ids = runtime::get_named_arg::>("token_ids"); + NFTToken::default() + .burn(owner, token_ids) + .unwrap_or_revert(); +} + +#[no_mangle] +fn transfer() { + let recipient = runtime::get_named_arg::("recipient"); + let token_ids = runtime::get_named_arg::>("token_ids"); + NFTToken::default() + .transfer(recipient, token_ids) + .unwrap_or_revert(); +} + +#[no_mangle] +fn transfer_from() { + let sender = runtime::get_named_arg::("sender"); + let recipient = runtime::get_named_arg::("recipient"); + let token_ids = runtime::get_named_arg::>("token_ids"); + NFTToken::default() + .transfer_from(sender, recipient, token_ids) + .unwrap_or_revert(); +} + +#[no_mangle] +fn approve() { + let spender = runtime::get_named_arg::("spender"); + let token_ids = runtime::get_named_arg::>("token_ids"); + NFTToken::default() + .approve(spender, token_ids) + .unwrap_or_revert(); +} + +#[no_mangle] +fn get_approved() { + let owner = runtime::get_named_arg::("owner"); + let token_id = runtime::get_named_arg::("token_id"); + let ret = NFTToken::default().get_approved(owner, token_id); + runtime::ret(CLValue::from_t(ret).unwrap_or_revert()); +} + +#[no_mangle] +fn call() { + let (package_hash, access_token) = storage::create_contract_package_at_hash(); + let mut named_keys = NamedKeys::new(); + let contract_package_hash_wrapped = storage::new_uref(package_hash).into(); + named_keys.insert( + "contract_package_hash".to_string(), + contract_package_hash_wrapped, + ); + let (contract_hash, _) = + storage::add_contract_version(package_hash, get_entry_points(), named_keys); + + // Read arguments for the constructor call. + let name: String = runtime::get_named_arg("name"); + let symbol: String = runtime::get_named_arg("symbol"); + let meta: Meta = runtime::get_named_arg("meta"); + + // Prepare constructor args + let constructor_args = runtime_args! { + "name" => name, + "symbol" => symbol, + "meta" => meta + }; + + // Add the constructor group to the package hash with a single URef. + let constructor_access: URef = + storage::create_contract_user_group(package_hash, "constructor", 1, Default::default()) + .unwrap_or_revert() + .pop() + .unwrap_or_revert(); + + // Call the constructor entry point + let _: () = + runtime::call_versioned_contract(package_hash, None, "constructor", constructor_args); + + // Remove all URefs from the constructor group, so no one can call it for the second time. + let mut urefs = BTreeSet::new(); + urefs.insert(constructor_access); + storage::remove_contract_user_group_urefs(package_hash, "constructor", urefs) + .unwrap_or_revert(); + + // Store contract in the account's named keys. + let contract_name: alloc::string::String = runtime::get_named_arg("contract_name"); + runtime::put_key( + &format!("{}_package_hash", contract_name), + package_hash.into(), + ); + runtime::put_key( + &format!("{}_package_hash_wrapped", contract_name), + contract_package_hash_wrapped, + ); + runtime::put_key( + &format!("{}_contract_hash", contract_name), + contract_hash.into(), + ); + runtime::put_key( + &format!("{}_contract_hash_wrapped", contract_name), + storage::new_uref(contract_hash).into(), + ); + runtime::put_key( + &format!("{}_package_access_token", contract_name), + access_token.into(), + ); +} + +fn get_entry_points() -> EntryPoints { + let mut entry_points = EntryPoints::new(); + entry_points.add_entry_point(EntryPoint::new( + "constructor", + vec![ + Parameter::new("name", String::cl_type()), + Parameter::new("symbol", String::cl_type()), + Parameter::new("meta", Meta::cl_type()), + ], + <()>::cl_type(), + EntryPointAccess::Groups(vec![Group::new("constructor")]), + EntryPointType::Contract, + )); + entry_points.add_entry_point(EntryPoint::new( + "mint", + vec![ + Parameter::new("recipient", Key::cl_type()), + Parameter::new( + "token_ids", + CLType::Option(Box::new(CLType::List(Box::new(TokenId::cl_type())))), + ), + Parameter::new("token_metas", CLType::List(Box::new(Meta::cl_type()))), + ], + <()>::cl_type(), + EntryPointAccess::Public, + EntryPointType::Contract, + )); + entry_points.add_entry_point(EntryPoint::new( + "mint_copies", + vec![ + Parameter::new("recipient", Key::cl_type()), + Parameter::new( + "token_ids", + CLType::Option(Box::new(CLType::List(Box::new(TokenId::cl_type())))), + ), + Parameter::new("token_meta", Meta::cl_type()), + Parameter::new("count", CLType::U32), + ], + <()>::cl_type(), + EntryPointAccess::Public, + EntryPointType::Contract, + )); + entry_points.add_entry_point(EntryPoint::new( + "burn", + vec![ + Parameter::new("owner", Key::cl_type()), + Parameter::new("token_ids", CLType::List(Box::new(TokenId::cl_type()))), + ], + <()>::cl_type(), + EntryPointAccess::Public, + EntryPointType::Contract, + )); + entry_points.add_entry_point(EntryPoint::new( + "transfer", + vec![ + Parameter::new("recipient", Key::cl_type()), + Parameter::new("token_ids", CLType::List(Box::new(TokenId::cl_type()))), + ], + <()>::cl_type(), + EntryPointAccess::Public, + EntryPointType::Contract, + )); + entry_points.add_entry_point(EntryPoint::new( + "transfer_from", + vec![ + Parameter::new("sender", Key::cl_type()), + Parameter::new("recipient", Key::cl_type()), + Parameter::new("token_ids", CLType::List(Box::new(TokenId::cl_type()))), + ], + <()>::cl_type(), + EntryPointAccess::Public, + EntryPointType::Contract, + )); + entry_points.add_entry_point(EntryPoint::new( + "approve", + vec![ + Parameter::new("spender", Key::cl_type()), + Parameter::new("token_ids", CLType::List(Box::new(TokenId::cl_type()))), + ], + <()>::cl_type(), + EntryPointAccess::Public, + EntryPointType::Contract, + )); + entry_points.add_entry_point(EntryPoint::new( + "get_approved", + vec![ + Parameter::new("owner", Key::cl_type()), + Parameter::new("token_id", TokenId::cl_type()), + ], + CLType::Option(Box::new(CLType::Key)), + EntryPointAccess::Public, + EntryPointType::Contract, + )); + entry_points.add_entry_point(EntryPoint::new( + "update_token_meta", + vec![ + Parameter::new("token_id", TokenId::cl_type()), + Parameter::new("token_meta", Meta::cl_type()), + ], + <()>::cl_type(), + EntryPointAccess::Public, + EntryPointType::Contract, + )); + entry_points.add_entry_point(EntryPoint::new( + "total_supply", + vec![], + U256::cl_type(), + EntryPointAccess::Public, + EntryPointType::Contract, + )); + entry_points +} diff --git a/cep47/src/cep47.rs b/cep47/src/cep47.rs new file mode 100644 index 0000000..c1ddc9a --- /dev/null +++ b/cep47/src/cep47.rs @@ -0,0 +1,332 @@ +use crate::{ + data::{self, Allowances, Balances, Metadata, OwnedTokens, Owners}, + event::CEP47Event, + Meta, TokenId, +}; +use alloc::{string::String, vec::Vec}; +use casper_contract::{contract_api::runtime, unwrap_or_revert::UnwrapOrRevert}; +use casper_types::{bytesrepr::ToBytes, ApiError, Key, U256}; +use contract_utils::{ContractContext, ContractStorage}; + +#[repr(u16)] +pub enum Error { + PermissionDenied = 1, + ArgumentsError = 2, + TokenIdAlreadyExists = 3, + TokenIdDoesntExist = 4, +} + +impl From for ApiError { + fn from(error: Error) -> ApiError { + ApiError::User(error as u16) + } +} + +pub trait CEP47: ContractContext { + fn init(&mut self, name: String, symbol: String, meta: Meta) { + data::set_name(name); + data::set_symbol(symbol); + data::set_meta(meta); + data::set_total_supply(U256::zero()); + Owners::init(); + OwnedTokens::init(); + Metadata::init(); + Balances::init(); + Allowances::init(); + } + + fn name(&self) -> String { + data::name() + } + + fn symbol(&self) -> String { + data::symbol() + } + + fn meta(&self) -> Meta { + data::meta() + } + + fn total_supply(&self) -> U256 { + data::total_supply() + } + + fn balance_of(&self, owner: Key) -> U256 { + Balances::instance().get(&owner) + } + + fn owner_of(&self, token_id: TokenId) -> Option { + Owners::instance().get(&token_id) + } + + fn token_meta(&self, token_id: TokenId) -> Option { + Metadata::instance().get(&token_id) + } + + fn set_token_meta(&mut self, token_id: TokenId, meta: Meta) -> Result<(), Error> { + if self.owner_of(token_id.clone()).is_none() { + return Err(Error::TokenIdAlreadyExists); + }; + + let metadata_dict = Metadata::instance(); + metadata_dict.set(&token_id, meta); + + self.emit(CEP47Event::MetadataUpdate { token_id }); + Ok(()) + } + + fn get_tokens(&self, owner: Key) -> Vec { + OwnedTokens::instance().get(&owner) + } + + fn set_tokens(&mut self, owner: Key, token_ids: Vec) { + let owners_dict = Owners::instance(); + let owned_tokens_dict = OwnedTokens::instance(); + let balances_dict = Balances::instance(); + + for token_id in &token_ids { + owners_dict.set(token_id, owner); + } + + let prev_balance = balances_dict.get(&owner); + let new_balance = U256::from(token_ids.len() as u64); + balances_dict.set(&owner, new_balance); + + owned_tokens_dict.set(&owner, token_ids); + + let new_total_supply = data::total_supply() - prev_balance + new_balance; + data::set_total_supply(new_total_supply); + } + + fn generate_token_ids(&mut self, n: u32) -> Vec { + let block_time = runtime::get_blocktime(); + let mut token_ids = Vec::new(); + let nonce = data::nonce(); + for i in nonce..nonce + n { + let mut bytes: Vec = block_time.to_bytes().unwrap_or_revert(); + bytes.append(&mut i.to_bytes().unwrap_or_revert()); + let hash = runtime::blake2b(bytes); + token_ids.push(hex::encode(hash)); + } + data::set_nonce(nonce + n); + token_ids + } + + fn validate_token_ids(&self, token_ids: Vec) -> bool { + for token_id in &token_ids { + if self.owner_of(token_id.clone()).is_some() { + return false; + } + } + true + } + + fn mint( + &mut self, + recipient: Key, + token_ids: Option>, + token_metas: Vec, + ) -> Result<(), Error> { + let unique_token_ids = match token_ids { + // Validate token_ids and metas. + Some(token_ids) => { + if token_ids.len() != token_metas.len() { + return Err(Error::ArgumentsError); + }; + let valid = self.validate_token_ids(token_ids.clone()); + if !valid { + return Err(Error::TokenIdAlreadyExists); + }; + token_ids + } + None => self.generate_token_ids(token_metas.len() as u32), + }; + + let owners_dict = Owners::instance(); + let owned_tokens_dict = OwnedTokens::instance(); + let metadata_dict = Metadata::instance(); + let balances_dict = Balances::instance(); + + let mut recipient_tokens = owned_tokens_dict.get(&recipient); + for (token_id, token_meta) in unique_token_ids.iter().zip(&token_metas) { + metadata_dict.set(token_id, token_meta.clone()); + owners_dict.set(token_id, recipient); + recipient_tokens.push(token_id.clone()); + } + + owned_tokens_dict.set(&recipient, recipient_tokens); + + let minted_tokens_count = U256::from(unique_token_ids.len() as u64); + let prev_balance = balances_dict.get(&recipient); + let new_balance = prev_balance + minted_tokens_count; + balances_dict.set(&recipient, new_balance); + + let new_total_supply = data::total_supply() + minted_tokens_count; + data::set_total_supply(new_total_supply); + + self.emit(CEP47Event::Mint { + recipient, + token_ids: unique_token_ids, + }); + Ok(()) + } + + fn mint_copies( + &mut self, + recipient: Key, + token_ids: Option>, + token_meta: Meta, + count: u32, + ) -> Result<(), Error> { + if let Some(token_ids) = &token_ids { + if token_ids.len() != count as usize { + return Err(Error::ArgumentsError); + } + } + let token_metas = vec![token_meta; count as usize]; + self.mint(recipient, token_ids, token_metas) + } + + fn burn(&mut self, owner: Key, token_ids: Vec) -> Result<(), Error> { + let owners_dict = Owners::instance(); + let owned_tokens_dict = OwnedTokens::instance(); + let metadata_dict = Metadata::instance(); + let balances_dict = Balances::instance(); + let allowances_dict = Allowances::instance(); + + let mut owner_tokens = owned_tokens_dict.get(&owner); + let spender = self.get_caller(); + + for token_id in &token_ids { + if spender != owner && !self.is_approved(owner, token_id.clone(), spender) { + return Err(Error::PermissionDenied); + } + match owners_dict.get(token_id) { + Some(owner_of_key) => { + if owner_of_key != owner { + return Err(Error::PermissionDenied); + } + } + None => { + return Err(Error::TokenIdDoesntExist); + } + } + let index = owner_tokens + .iter() + .position(|x| x == token_id) + .unwrap_or_revert(); + owner_tokens.remove(index); + metadata_dict.remove(token_id); + owners_dict.remove(token_id); + allowances_dict.remove(&owner, token_id); + } + + balances_dict.set(&owner, U256::from(owner_tokens.len() as u64)); + owned_tokens_dict.set(&owner, owner_tokens); + + let burnt_tokens_count = U256::from(token_ids.len() as u64); + let new_total_supply = data::total_supply() - burnt_tokens_count; + data::set_total_supply(new_total_supply); + + self.emit(CEP47Event::Burn { owner, token_ids }); + Ok(()) + } + + fn approve(&mut self, spender: Key, token_ids: Vec) -> Result<(), Error> { + let caller = self.get_caller(); + for token_id in &token_ids { + let owner = self.owner_of(token_id.clone()); + if owner.is_none() { + return Err(Error::ArgumentsError); + } + if owner.unwrap() != caller { + return Err(Error::PermissionDenied); + } + Allowances::instance().set(&caller, token_id, spender); + } + self.emit(CEP47Event::Approve { + owner: caller, + spender, + token_ids, + }); + Ok(()) + } + + fn get_approved(&self, owner: Key, token_id: TokenId) -> Option { + Allowances::instance().get(&owner, &token_id) + } + + fn transfer(&mut self, recipient: Key, token_ids: Vec) -> Result<(), Error> { + self.transfer_from(self.get_caller(), recipient, token_ids) + } + + fn transfer_from( + &mut self, + owner: Key, + recipient: Key, + token_ids: Vec, + ) -> Result<(), Error> { + let allowances_dict = Allowances::instance(); + let spender = self.get_caller(); + if owner != spender { + for token_id in &token_ids { + if !self.is_approved(owner, token_id.clone(), spender) { + return Err(Error::PermissionDenied); + } + allowances_dict.remove(&owner, token_id); + } + } + + let owners_dict = Owners::instance(); + let owned_tokens_dict = OwnedTokens::instance(); + let balances_dict = Balances::instance(); + + let mut sender_tokens = owned_tokens_dict.get(&owner); + let mut recipient_tokens = owned_tokens_dict.get(&recipient); + for token_id in &token_ids { + match owners_dict.get(token_id) { + Some(owner_of_key) => { + if owner_of_key != owner { + return Err(Error::PermissionDenied); + } + } + None => { + return Err(Error::TokenIdDoesntExist); + } + } + let index = sender_tokens + .iter() + .position(|x| x == token_id) + .unwrap_or_revert(); + sender_tokens.remove(index); + recipient_tokens.push(token_id.clone()); + owners_dict.set(token_id, recipient); + } + + balances_dict.set(&owner, sender_tokens.len().into()); + owned_tokens_dict.set(&owner, sender_tokens); + + balances_dict.set(&recipient, recipient_tokens.len().into()); + owned_tokens_dict.set(&recipient, recipient_tokens); + self.emit(CEP47Event::Transfer { + sender: owner, + recipient, + token_ids, + }); + Ok(()) + } + + fn is_approved(&self, owner: Key, token_id: TokenId, spender: Key) -> bool { + let allowances_dict = Allowances::instance(); + if let Some(spender_of) = allowances_dict.get(&owner, &token_id) { + if spender_of == spender { + return true; + } + } + return false; + } + + fn emit(&mut self, event: CEP47Event) { + data::emit(&event); + } +} diff --git a/cep47/src/data.rs b/cep47/src/data.rs index 6b14471..d9bb369 100644 --- a/cep47/src/data.rs +++ b/cep47/src/data.rs @@ -1,48 +1,26 @@ -use std::{collections::BTreeMap, convert::TryInto}; - -use casper_contract::{ - contract_api::{ - runtime, - storage::{self, new_dictionary}, - }, - unwrap_or_revert::UnwrapOrRevert, +use alloc::{ + collections::BTreeMap, + string::{String, ToString}, + vec::Vec, }; -use casper_types::{ - bytesrepr::{FromBytes, ToBytes}, - contracts::NamedKeys, - ApiError, CLTyped, ContractPackageHash, Key, URef, U256, -}; -use cep47_logic::{events::CEP47Event, Meta, TokenId}; +use casper_contract::{contract_api::storage, unwrap_or_revert::UnwrapOrRevert}; +use casper_types::{ContractPackageHash, Key, URef, U256}; +use contract_utils::{get_key, key_and_value_to_str, set_key, Dict}; + +use crate::{event::CEP47Event, Meta, TokenId}; const BALANCES_DICT: &str = "balances"; -const TOKEN_OWNERS_DICT: &str = "owners"; +pub const ALLOWANCES_DICT: &str = "allowances"; const METADATA_DICT: &str = "metadata"; +const OWNERS_DICT: &str = "owners"; +const OWNED_TOKENS_DICT: &str = "owned_tokens"; +const CONTRACT_PACKAGE_HASH: &str = "contract_package_hash"; -struct Dict { - uref: URef, -} - -impl Dict { - pub fn at(name: &str) -> Dict { - let key: Key = runtime::get_key(name).unwrap_or_revert(); - let uref: URef = *key.as_uref().unwrap_or_revert(); - Dict { uref } - } - - pub fn get(&self, key: &str) -> Option { - storage::dictionary_get(self.uref, key) - .unwrap_or_revert() - .unwrap_or_default() - } - - pub fn set(&self, key: &str, value: T) { - storage::dictionary_put(self.uref, key, Some(value)); - } - - pub fn remove(&self, key: &str) { - storage::dictionary_put(self.uref, key, Option::::None); - } -} +pub const NAME: &str = "name"; +pub const META: &str = "meta"; +pub const SYMBOL: &str = "symbol"; +pub const TOTAL_SUPPLY: &str = "total_supply"; +pub const NONCE: &str = "nonce"; pub struct Balances { dict: Dict, @@ -51,21 +29,21 @@ pub struct Balances { impl Balances { pub fn instance() -> Balances { Balances { - dict: Dict::at(BALANCES_DICT), + dict: Dict::instance(BALANCES_DICT), } } - pub fn get(&self, key: &Key) -> U256 { - self.dict.get(&key_to_str(key)).unwrap_or_default() + pub fn init() { + Dict::init(BALANCES_DICT) } - pub fn set(&self, key: &Key, value: U256) { - self.dict.set(&key_to_str(key), value); + pub fn get(&self, owner: &Key) -> U256 { + self.dict.get_by_key(owner).unwrap_or_default() } - // pub fn remove(&self, key: &Key) { - // self.dict.remove::(&key_to_str(key)); - // } + pub fn set(&self, owner: &Key, value: U256) { + self.dict.set_by_key(owner, value); + } } pub struct Owners { @@ -75,10 +53,14 @@ pub struct Owners { impl Owners { pub fn instance() -> Owners { Owners { - dict: Dict::at(TOKEN_OWNERS_DICT), + dict: Dict::instance(OWNERS_DICT), } } + pub fn init() { + Dict::init(OWNERS_DICT) + } + pub fn get(&self, key: &TokenId) -> Option { self.dict.get(key) } @@ -99,10 +81,14 @@ pub struct Metadata { impl Metadata { pub fn instance() -> Metadata { Metadata { - dict: Dict::at(METADATA_DICT), + dict: Dict::instance(METADATA_DICT), } } + pub fn init() { + Dict::init(METADATA_DICT) + } + pub fn get(&self, key: &TokenId) -> Option { self.dict.get(key) } @@ -116,168 +102,173 @@ impl Metadata { } } -pub fn name() -> String { - get_key("name").unwrap_or_revert() +pub struct OwnedTokens { + dict: Dict, } -pub fn symbol() -> String { - get_key("symbol").unwrap_or_revert() +impl OwnedTokens { + pub fn instance() -> OwnedTokens { + OwnedTokens { + dict: Dict::instance(OWNED_TOKENS_DICT), + } + } + + pub fn init() { + Dict::init(OWNED_TOKENS_DICT) + } + + pub fn get(&self, owner: &Key) -> Vec { + self.dict.get_by_key(owner).unwrap_or_default() + } + + pub fn set(&self, owner: &Key, value: Vec) { + self.dict.set_by_key(owner, value); + } } -pub fn meta() -> Meta { - get_key("meta").unwrap_or_revert() +pub struct Allowances { + dict: Dict, } -pub fn total_supply() -> U256 { - get_key("total_supply").unwrap_or_revert() +impl Allowances { + pub fn instance() -> Allowances { + Allowances { + dict: Dict::instance(ALLOWANCES_DICT), + } + } + + pub fn init() { + Dict::init(ALLOWANCES_DICT) + } + + pub fn get(&self, owner: &Key, token_id: &TokenId) -> Option { + self.dict + .get(key_and_value_to_str::(owner, token_id).as_str()) + } + + pub fn set(&self, owner: &Key, token_id: &TokenId, value: Key) { + self.dict.set( + key_and_value_to_str::(owner, token_id).as_str(), + value, + ); + } + + pub fn remove(&self, owner: &Key, token_id: &TokenId) { + self.dict + .remove::(key_and_value_to_str::(owner, token_id).as_str()); + } } -pub fn update_total_supply(total_supply: U256) { - set_key("total_supply", total_supply); +pub fn name() -> String { + get_key(NAME).unwrap_or_revert() } -pub fn is_paused() -> bool { - get_key("paused").unwrap() +pub fn set_name(name: String) { + set_key(NAME, name); } -pub fn pause() { - set_key("paused", true); +pub fn symbol() -> String { + get_key(SYMBOL).unwrap_or_revert() } -pub fn unpause() { - set_key("paused", false); +pub fn set_symbol(symbol: String) { + set_key(SYMBOL, symbol); } -pub fn get_nonce() -> u32 { - get_key("nonce").unwrap_or_default() +pub fn meta() -> Meta { + get_key(META).unwrap_or_revert() } -pub fn set_nonce(nonce: u32) { - set_key("nonce", nonce); +pub fn set_meta(meta: Meta) { + set_key(META, meta); } -pub fn contract_package_hash() -> ContractPackageHash { - get_key("contract_package_hash").unwrap_or_revert() +pub fn total_supply() -> U256 { + get_key(TOTAL_SUPPLY).unwrap_or_default() } -pub fn initial_named_keys( - package_hash: ContractPackageHash, - token_name: &str, - token_symbol: &str, - token_meta: Meta, - paused: bool, -) -> NamedKeys { - let mut named_keys = NamedKeys::new(); - named_keys.insert("name".to_string(), storage::new_uref(token_name).into()); - named_keys.insert("symbol".to_string(), storage::new_uref(token_symbol).into()); - named_keys.insert("meta".to_string(), storage::new_uref(token_meta).into()); - named_keys.insert( - "total_supply".to_string(), - storage::new_uref(U256::zero()).into(), - ); - named_keys.insert("paused".to_string(), storage::new_uref(paused).into()); - named_keys.insert( - "contract_package_hash".to_string(), - storage::new_uref(package_hash).into(), - ); - - // Add empty dictionaries. - add_empty_dict(&mut named_keys, BALANCES_DICT); - add_empty_dict(&mut named_keys, TOKEN_OWNERS_DICT); - add_empty_dict(&mut named_keys, METADATA_DICT); - - named_keys +pub fn set_total_supply(total_supply: U256) { + set_key(TOTAL_SUPPLY, total_supply); } -fn add_empty_dict(named_keys: &mut NamedKeys, name: &str) { - let dict = new_dictionary(name).unwrap_or_revert(); - runtime::remove_key(name); - named_keys.insert(name.to_string(), dict.into()); +pub fn nonce() -> u32 { + get_key(NONCE).unwrap_or_default() } -fn key_to_str(key: &Key) -> String { - match key { - Key::Account(account) => account.to_string(), - Key::Hash(package) => hex::encode(package), - _ => runtime::revert(ApiError::UnexpectedKeyVariant), - } +pub fn set_nonce(nonce: u32) { + set_key(NONCE, nonce); +} + +pub fn contract_package_hash() -> ContractPackageHash { + get_key(CONTRACT_PACKAGE_HASH).unwrap_or_revert() } pub fn emit(cep47_event: &CEP47Event) { let mut events = Vec::new(); let package = contract_package_hash(); - match cep47_event { - CEP47Event::MetadataUpdate { token_id } => { - let mut event = BTreeMap::new(); - event.insert("contract_package_hash", package.to_string()); - event.insert("event_type", cep47_event.type_name()); - event.insert("token_id", token_id.to_string()); - events.push(event); - } - CEP47Event::Transfer { - sender, + match event { + CEP47Event::Mint { recipient, token_ids, } => { for token_id in token_ids { - let mut event = BTreeMap::new(); - event.insert("contract_package_hash", package.to_string()); - event.insert("event_type", cep47_event.type_name()); - event.insert("sender", sender.to_string()); - event.insert("recipient", recipient.to_string()); - event.insert("token_id", token_id.to_string()); - events.push(event); + let mut param = BTreeMap::new(); + param.insert(CONTRACT_PACKAGE_HASH, package.to_string()); + param.insert("event_type", "cep47_mint_one".to_string()); + param.insert("recipient", recipient.to_string()); + param.insert("token_id", token_id.to_string()); + events.push(param); } } - CEP47Event::Mint { - recipient, + CEP47Event::Burn { owner, token_ids } => { + for token_id in token_ids { + let mut param = BTreeMap::new(); + param.insert(CONTRACT_PACKAGE_HASH, package.to_string()); + param.insert("event_type", "cep47_burn_one".to_string()); + param.insert("owner", owner.to_string()); + param.insert("token_id", token_id.to_string()); + events.push(param); + } + } + CEP47Event::Approve { + owner, + spender, token_ids, } => { for token_id in token_ids { - let mut event = BTreeMap::new(); - event.insert("contract_package_hash", package.to_string()); - event.insert("event_type", cep47_event.type_name()); - event.insert("recipient", recipient.to_string()); - event.insert("token_id", token_id.to_string()); - events.push(event); + let mut param = BTreeMap::new(); + param.insert(CONTRACT_PACKAGE_HASH, package.to_string()); + param.insert("event_type", "cep47_approve_token".to_string()); + param.insert("owner", owner.to_string()); + param.insert("spender", spender.to_string()); + param.insert("token_id", token_id.to_string()); + events.push(param); } } - CEP47Event::Burn { owner, token_ids } => { + CEP47Event::Transfer { + sender, + recipient, + token_ids, + } => { for token_id in token_ids { - let mut event = BTreeMap::new(); - event.insert("contract_package_hash", package.to_string()); - event.insert("event_type", cep47_event.type_name()); - event.insert("owner", owner.to_string()); - event.insert("token_id", token_id.to_string()); - events.push(event); + let mut param = BTreeMap::new(); + param.insert(CONTRACT_PACKAGE_HASH, package.to_string()); + param.insert("event_type", "cep47_transfer_token".to_string()); + param.insert("sender", sender.to_string()); + param.insert("recipient", recipient.to_string()); + param.insert("token_id", token_id.to_string()); + events.push(param); } } - }; - for event in events { - let _: URef = storage::new_uref(event); - } -} - -fn get_key(name: &str) -> Option { - match runtime::get_key(name) { - None => None, - Some(value) => { - let key = value.try_into().unwrap_or_revert(); - let value = storage::read(key).unwrap_or_revert().unwrap_or_revert(); - Some(value) - } - } -} - -fn set_key(name: &str, value: T) { - match runtime::get_key(name) { - Some(key) => { - let key_ref = key.try_into().unwrap_or_revert(); - storage::write(key_ref, value); - } - None => { - let key = storage::new_uref(value).into(); - runtime::put_key(name, key); + CEP47Event::MetadataUpdate { token_id } => { + let mut param = BTreeMap::new(); + param.insert(CONTRACT_PACKAGE_HASH, package.to_string()); + param.insert("event_type", "cep47_metadata_update".to_string()); + param.insert("token_id", token_id.to_string()); + events.push(param); } + }; + for param in events { + let _: URef = storage::new_uref(param); } } diff --git a/cep47-logic/src/events.rs b/cep47/src/event.rs similarity index 87% rename from cep47-logic/src/events.rs rename to cep47/src/event.rs index 406b736..aaf64cd 100644 --- a/cep47-logic/src/events.rs +++ b/cep47/src/event.rs @@ -1,18 +1,9 @@ -use std::collections::{BTreeMap, BTreeSet}; - -use casper_types::{account::AccountHash, ContractPackageHash, Key}; +use alloc::vec::Vec; +use casper_types::Key; use crate::TokenId; pub enum CEP47Event { - MetadataUpdate { - token_id: TokenId, - }, - Transfer { - sender: Key, - recipient: Key, - token_ids: Vec, - }, Mint { recipient: Key, token_ids: Vec, @@ -21,6 +12,19 @@ pub enum CEP47Event { owner: Key, token_ids: Vec, }, + Approve { + owner: Key, + spender: Key, + token_ids: Vec, + }, + Transfer { + sender: Key, + recipient: Key, + token_ids: Vec, + }, + MetadataUpdate { + token_id: TokenId, + }, } impl CEP47Event { diff --git a/cep47/src/lib.rs b/cep47/src/lib.rs index 6b37cd2..e6c0bab 100644 --- a/cep47/src/lib.rs +++ b/cep47/src/lib.rs @@ -1,287 +1,13 @@ -#![allow(unused_imports)] -#![allow(unused_parens)] -#![allow(non_snake_case)] - +#![no_std] +#[macro_use] extern crate alloc; -use alloc::{ - collections::{BTreeMap, BTreeSet}, - string::String, -}; -use casper_contract::{ - contract_api::{ - runtime::{self, revert}, - storage, - }, - unwrap_or_revert::UnwrapOrRevert, -}; -use casper_types::{ - account::AccountHash, - bytesrepr::{FromBytes, ToBytes}, - contracts::NamedKeys, - system::CallStackElement, - AccessRights, ApiError, AsymmetricType, CLType, CLTyped, CLValue, ContractPackageHash, - EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, HashAddr, Key, Parameter, URef, - U256, -}; -pub use cep47_logic::Meta; -use cep47_logic::{CEP47Contract, CEP47Storage, TokenId, WithStorage}; - -use core::convert::TryInto; -use std::{ - collections::hash_map::DefaultHasher, - hash::{Hash, Hasher}, - ops::AddAssign, -}; - -mod cep47_storage; -mod data; -mod entrypoints; - -pub use cep47_storage::CasperCEP47Storage; -pub use entrypoints::get_entrypoints; - -use data::{Balances, Metadata, Owners}; - -#[derive(Default)] -pub struct CasperCEP47Contract { - storage: CasperCEP47Storage, -} - -impl CasperCEP47Contract { - pub fn new() -> CasperCEP47Contract { - CasperCEP47Contract { - storage: CasperCEP47Storage::new(), - } - } -} - -impl WithStorage for CasperCEP47Contract { - fn storage(&self) -> &CasperCEP47Storage { - &self.storage - } - fn storage_mut(&mut self) -> &mut CasperCEP47Storage { - &mut self.storage - } -} - -impl CEP47Contract for CasperCEP47Contract {} - -#[cfg(not(feature = "no_name"))] -#[no_mangle] -pub extern "C" fn name() { - let contract = CasperCEP47Contract::new(); - ret(contract.name()) -} - -#[cfg(not(feature = "no_symbol"))] -#[no_mangle] -pub extern "C" fn symbol() { - let contract = CasperCEP47Contract::new(); - ret((contract.symbol(), 42u8)) -} - -#[cfg(not(feature = "no_meta"))] -#[no_mangle] -pub extern "C" fn meta() { - let contract = CasperCEP47Contract::new(); - ret(contract.meta()) -} - -#[cfg(not(feature = "no_balance_of"))] -#[no_mangle] -pub extern "C" fn balance_of() { - let account: Key = runtime::get_named_arg("account"); - let contract = CasperCEP47Contract::new(); - ret(contract.balance_of(&account)) -} - -#[cfg(not(feature = "no_owner_of"))] -#[no_mangle] -pub extern "C" fn owner_of() { - let token_id: TokenId = runtime::get_named_arg("token_id"); - let contract = CasperCEP47Contract::new(); - ret(contract.owner_of(&token_id)) -} - -#[cfg(not(feature = "no_total_supply"))] -#[no_mangle] -pub extern "C" fn total_supply() { - let contract = CasperCEP47Contract::new(); - ret(contract.total_supply()) -} - -#[cfg(not(feature = "no_token_meta"))] -#[no_mangle] -pub extern "C" fn token_meta() { - let token_id: TokenId = runtime::get_named_arg("token_id"); - let contract = CasperCEP47Contract::new(); - ret(contract.token_meta(&token_id)) -} - -#[cfg(not(feature = "no_is_paused"))] -#[no_mangle] -pub extern "C" fn is_paused() { - let contract = CasperCEP47Contract::new(); - ret(contract.is_paused()) -} - -#[cfg(not(feature = "no_pause"))] -#[no_mangle] -pub extern "C" fn pause() { - let mut contract = CasperCEP47Contract::new(); - contract.pause(); -} - -#[cfg(not(feature = "no_unpause"))] -#[no_mangle] -pub extern "C" fn unpause() { - let mut contract = CasperCEP47Contract::new(); - contract.unpause(); -} - -#[cfg(not(feature = "no_mint_one"))] -#[no_mangle] -pub extern "C" fn mint_one() { - let recipient: Key = runtime::get_named_arg("recipient"); - let token_id: Option = runtime::get_named_arg("token_id"); - let token_meta: Meta = runtime::get_named_arg("token_meta"); - let mut contract = CasperCEP47Contract::new(); - contract - .mint_one(&recipient, token_id, token_meta) - .unwrap_or_revert(); -} - -#[cfg(not(feature = "no_mint_many"))] -#[no_mangle] -pub extern "C" fn mint_many() { - let recipient: Key = runtime::get_named_arg("recipient"); - let token_ids: Option> = runtime::get_named_arg("token_ids"); - let token_metas: Vec = runtime::get_named_arg("token_metas"); - let mut contract = CasperCEP47Contract::new(); - contract - .mint_many(&recipient, token_ids, token_metas) - .unwrap_or_revert(); -} - -#[cfg(not(feature = "no_mint_copies"))] -#[no_mangle] -pub extern "C" fn mint_copies() { - let recipient: Key = runtime::get_named_arg("recipient"); - let token_ids: Option> = runtime::get_named_arg("token_ids"); - let token_meta: Meta = runtime::get_named_arg("token_meta"); - let count: u32 = runtime::get_named_arg("count"); - let mut contract = CasperCEP47Contract::new(); - contract - .mint_copies(&recipient, token_ids, token_meta, count) - .unwrap_or_revert(); -} - -#[cfg(not(feature = "no_burn_many"))] -#[no_mangle] -pub extern "C" fn burn_many() { - let owner: Key = runtime::get_named_arg("owner"); - let token_ids: Vec = runtime::get_named_arg("token_ids"); - let mut contract = CasperCEP47Contract::new(); - contract.burn_many(&owner, token_ids).unwrap_or_revert(); -} - -#[cfg(not(feature = "no_burn_one"))] -#[no_mangle] -pub extern "C" fn burn_one() { - let owner: Key = runtime::get_named_arg("owner"); - let token_id: TokenId = runtime::get_named_arg("token_id"); - let mut contract = CasperCEP47Contract::new(); - contract.burn_one(&owner, token_id).unwrap_or_revert(); -} - -#[cfg(not(feature = "no_transfer_token"))] -#[no_mangle] -pub extern "C" fn transfer_token() { - let sender: Key = get_caller(); - let recipient: Key = runtime::get_named_arg("recipient"); - let token_id: TokenId = runtime::get_named_arg("token_id"); - let mut contract = CasperCEP47Contract::new(); - contract - .transfer_token(&sender, &recipient, &token_id) - .unwrap_or_revert(); -} - -#[cfg(not(feature = "no_transfer_many_tokens"))] -#[no_mangle] -pub extern "C" fn transfer_many_tokens() { - let sender: Key = get_caller(); - let recipient: Key = runtime::get_named_arg("recipient"); - let token_ids: Vec = runtime::get_named_arg("token_ids"); - let mut contract = CasperCEP47Contract::new(); - contract - .transfer_many_tokens(&sender, &recipient, &token_ids) - .unwrap_or_revert(); -} - -#[cfg(not(feature = "no_update_token_metadata"))] -#[no_mangle] -pub extern "C" fn update_token_metadata() { - let token_id: TokenId = runtime::get_named_arg("token_id"); - let meta: Meta = runtime::get_named_arg("token_meta"); - let mut contract = CasperCEP47Contract::new(); - contract - .update_token_metadata(token_id, meta) - .unwrap_or_revert(); -} - -pub fn deploy( - token_name: String, - token_symbol: String, - token_meta: Meta, - entry_points: EntryPoints, - contract_package_hash: ContractPackageHash, - paused: bool, -) { - // Get named keys for the contract. - let named_keys = data::initial_named_keys( - contract_package_hash, - &token_name, - &token_symbol, - token_meta, - paused, - ); - - // Add new version to the package. - let (contract_hash, _) = - storage::add_contract_version(contract_package_hash, entry_points, named_keys); - - // Save contracts. - runtime::put_key( - format!("{}_contract", &token_name).as_str(), - contract_hash.into(), - ); - - // Save contract hashs. - let contract_hash_pack = storage::new_uref(contract_hash); - runtime::put_key( - format!("{}_contract_hash", token_name).as_str(), - contract_hash_pack.into(), - ); -} +mod cep47; +pub mod data; +pub mod event; -pub fn ret(value: T) { - runtime::ret(CLValue::from_t(value).unwrap_or_revert()) -} +pub use cep47::CEP47; -fn get_caller() -> Key { - let mut callstack = runtime::get_call_stack(); - callstack.pop(); - match callstack.last().unwrap_or_revert() { - CallStackElement::Session { account_hash } => (*account_hash).into(), - CallStackElement::StoredSession { - account_hash, - contract_package_hash: _, - contract_hash: _, - } => (*account_hash).into(), - CallStackElement::StoredContract { - contract_package_hash, - contract_hash: _, - } => (*contract_package_hash).into(), - } -} +use alloc::{collections::BTreeMap, string::String}; +pub type TokenId = String; +pub type Meta = BTreeMap; diff --git a/utils/contract-utils/Cargo.toml b/utils/contract-utils/Cargo.toml new file mode 100644 index 0000000..74a65da --- /dev/null +++ b/utils/contract-utils/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "contract-utils" +version = "0.1.0" +authors = ["Maciej Zielinski "] +edition = "2018" + +[dependencies] +casper-contract = "1.3.2" +casper-types = "1.3.2" +hex = { version = "0.4.3", default-features = false } + diff --git a/utils/contract-utils/src/admin_control.rs b/utils/contract-utils/src/admin_control.rs new file mode 100644 index 0000000..2d3d5be --- /dev/null +++ b/utils/contract-utils/src/admin_control.rs @@ -0,0 +1,63 @@ +use casper_contract::{ + contract_api::{runtime, storage}, + unwrap_or_revert::UnwrapOrRevert, +}; +use casper_types::{ApiError, Key}; + +use crate::{ContractContext, ContractStorage, Dict}; + +const ADMINS_DICT: &str = "admins"; + +pub trait AdminControl: ContractContext { + fn init(&mut self) { + Admins::init(); + } + + fn add_admin(&mut self, address: Key) { + self.assert_caller_is_admin(); + self.add_admin_without_checked(address); + } + + fn disable_admin(&mut self, address: Key) { + self.assert_caller_is_admin(); + Admins::instance().disable_admin(&address); + } + + fn add_admin_without_checked(&mut self, address: Key) { + Admins::instance().add_admin(&address); + } + + fn assert_caller_is_admin(&self) { + let caller = self.get_caller(); + if !Admins::instance().is_admin(&caller) { + runtime::revert(ApiError::User(20)); + } + } +} + +struct Admins { + dict: Dict, +} + +impl Admins { + pub fn instance() -> Admins { + Admins { + dict: Dict::instance(ADMINS_DICT), + } + } + pub fn init() { + storage::new_dictionary(ADMINS_DICT).unwrap_or_revert(); + } + + pub fn is_admin(&self, key: &Key) -> bool { + self.dict.get_by_key::<()>(key).is_some() + } + + pub fn add_admin(&self, key: &Key) { + self.dict.set_by_key(key, ()); + } + + pub fn disable_admin(&self, key: &Key) { + self.dict.remove_by_key::<()>(key); + } +} diff --git a/utils/contract-utils/src/contract_context.rs b/utils/contract-utils/src/contract_context.rs new file mode 100644 index 0000000..2fc178d --- /dev/null +++ b/utils/contract-utils/src/contract_context.rs @@ -0,0 +1,34 @@ +use casper_contract::unwrap_or_revert::UnwrapOrRevert; +use casper_types::{system::CallStackElement, Key}; + +use crate::ContractStorage; + +pub trait ContractContext { + fn storage(&self) -> &Storage; + + fn get_caller(&self) -> Key { + let call_stack = self.storage().call_stack(); + let caller = call_stack.get(call_stack.len() - 2); + element_to_key(caller.unwrap_or_revert()) + } + + fn self_addr(&mut self) -> Key { + let call_stack = self.storage().call_stack(); + element_to_key(call_stack.last().unwrap_or_revert()) + } +} + +fn element_to_key(element: &CallStackElement) -> Key { + match element { + CallStackElement::Session { account_hash } => (*account_hash).into(), + CallStackElement::StoredSession { + account_hash, + contract_package_hash: _, + contract_hash: _, + } => (*account_hash).into(), + CallStackElement::StoredContract { + contract_package_hash, + contract_hash: _, + } => (*contract_package_hash).into(), + } +} diff --git a/utils/contract-utils/src/contract_storage.rs b/utils/contract-utils/src/contract_storage.rs new file mode 100644 index 0000000..6aded67 --- /dev/null +++ b/utils/contract-utils/src/contract_storage.rs @@ -0,0 +1,21 @@ +use alloc::vec::Vec; +use core::lazy::OnceCell; + +use casper_contract::contract_api::runtime; +use casper_types::system::CallStackElement; + +pub trait ContractStorage { + fn call_stack(&self) -> &[CallStackElement]; +} + +#[derive(Default)] +pub struct OnChainContractStorage { + call_stack: OnceCell>, +} + +impl ContractStorage for OnChainContractStorage { + fn call_stack(&self) -> &[CallStackElement] { + let call_stack = self.call_stack.get_or_init(runtime::get_call_stack); + call_stack.as_slice() + } +} diff --git a/utils/contract-utils/src/data.rs b/utils/contract-utils/src/data.rs new file mode 100644 index 0000000..db086ac --- /dev/null +++ b/utils/contract-utils/src/data.rs @@ -0,0 +1,121 @@ +use alloc::string::{String, ToString}; +use core::convert::TryInto; + +use casper_contract::{ + contract_api::{runtime, storage}, + unwrap_or_revert::UnwrapOrRevert, +}; +use casper_types::{ + bytesrepr::{FromBytes, ToBytes}, + ApiError, CLTyped, Key, URef, +}; + +pub struct Dict { + uref: URef, +} + +impl Dict { + pub fn instance(name: &str) -> Dict { + let key = runtime::get_key(name).unwrap_or_revert(); + let uref = *key.as_uref().unwrap_or_revert(); + Dict { uref } + } + + pub fn init(name: &str) { + storage::new_dictionary(name).unwrap_or_revert(); + } + + pub fn at(uref: URef) -> Dict { + Dict { uref } + } + + pub fn get(&self, key: &str) -> Option { + storage::dictionary_get(self.uref, key) + .unwrap_or_revert() + .unwrap_or_default() + } + + pub fn get_by_key(&self, key: &Key) -> Option { + self.get(&key_to_str(key)) + } + + pub fn get_by_keys(&self, keys: (&Key, &Key)) -> Option { + self.get(&keys_to_str(keys.0, keys.1)) + } + + pub fn set(&self, key: &str, value: T) { + storage::dictionary_put(self.uref, key, Some(value)); + } + + pub fn set_by_key(&self, key: &Key, value: T) { + self.set(&key_to_str(key), value); + } + + pub fn set_by_keys(&self, keys: (&Key, &Key), value: T) { + self.set(&keys_to_str(keys.0, keys.1), value) + } + + pub fn remove(&self, key: &str) { + storage::dictionary_put(self.uref, key, Option::::None); + } + + pub fn remove_by_key(&self, key: &Key) { + self.remove::(&key_to_str(key)); + } + + pub fn remove_by_vec_of_keys(&self, keys: (&Key, &Key)) { + self.remove::(&keys_to_str(keys.0, keys.1)) + } +} + +pub fn key_to_str(key: &Key) -> String { + match key { + Key::Account(account) => account.to_string(), + Key::Hash(package) => hex::encode(package), + _ => runtime::revert(ApiError::UnexpectedKeyVariant), + } +} + +pub fn keys_to_str(key_a: &Key, key_b: &Key) -> String { + let mut bytes_a = key_a.to_bytes().unwrap_or_revert(); + let mut bytes_b = key_b.to_bytes().unwrap_or_revert(); + + bytes_a.append(&mut bytes_b); + + let bytes = runtime::blake2b(bytes_a); + hex::encode(bytes) +} + +pub fn key_and_value_to_str(key: &Key, value: &T) -> String { + let mut bytes_a = key.to_bytes().unwrap_or_revert(); + let mut bytes_b = value.to_bytes().unwrap_or_revert(); + + bytes_a.append(&mut bytes_b); + + let bytes = runtime::blake2b(bytes_a); + hex::encode(bytes) +} + +pub fn get_key(name: &str) -> Option { + match runtime::get_key(name) { + None => None, + Some(value) => { + let key = value.try_into().unwrap_or_revert(); + let value = storage::read(key).unwrap_or_revert().unwrap_or_revert(); + Some(value) + } + } +} + +pub fn set_key(name: &str, value: T) { + match runtime::get_key(name) { + Some(key) => { + let key_ref = key.try_into().unwrap_or_revert(); + storage::write(key_ref, value); + } + None => { + let key = storage::new_uref(value).into(); + runtime::put_key(name, key); + } + } +} diff --git a/utils/contract-utils/src/lib.rs b/utils/contract-utils/src/lib.rs new file mode 100644 index 0000000..4e52e04 --- /dev/null +++ b/utils/contract-utils/src/lib.rs @@ -0,0 +1,14 @@ +#![no_std] +#![feature(once_cell)] + +extern crate alloc; + +mod admin_control; +mod contract_context; +mod contract_storage; +mod data; + +pub use admin_control::AdminControl; +pub use contract_context::ContractContext; +pub use contract_storage::{ContractStorage, OnChainContractStorage}; +pub use data::{get_key, key_and_value_to_str, set_key, Dict}; diff --git a/utils/test-env/Cargo.toml b/utils/test-env/Cargo.toml new file mode 100644 index 0000000..7256e7f --- /dev/null +++ b/utils/test-env/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "test-env" +version = "0.1.0" +authors = ["Maciej Zielinski "] +edition = "2018" + +[dependencies] +casper-contract = "1.3.0" +casper-types = "1.3.0" +casper-engine-test-support = "1.3.0" + +[features] +default = ["casper-contract/std", "casper-types/std", "casper-engine-test-support/test-support", "casper-contract/test-support"] diff --git a/utils/test-env/src/lib.rs b/utils/test-env/src/lib.rs new file mode 100644 index 0000000..f2634bf --- /dev/null +++ b/utils/test-env/src/lib.rs @@ -0,0 +1,7 @@ +mod test_contract; +mod test_env; + +use casper_engine_test_support::AccountHash; +pub use test_contract::TestContract; +pub use test_env::TestEnv; +pub struct Sender(pub AccountHash); diff --git a/utils/test-env/src/test_contract.rs b/utils/test-env/src/test_contract.rs new file mode 100644 index 0000000..c349192 --- /dev/null +++ b/utils/test-env/src/test_contract.rs @@ -0,0 +1,61 @@ +use casper_engine_test_support::{AccountHash, Code, Hash, Value}; +use casper_types::{bytesrepr::FromBytes, CLTyped, RuntimeArgs}; + +use crate::{Sender, TestEnv}; + +pub struct TestContract { + env: TestEnv, + name: String, + contract_owner: AccountHash, +} + +impl TestContract { + pub fn new( + env: &TestEnv, + wasm: &str, + name: &str, + sender: Sender, + mut args: RuntimeArgs, + ) -> TestContract { + let Sender(contract_owner) = sender; + let session_code = Code::from(wasm); + args.insert("contract_name", name).unwrap(); + env.run(sender, session_code, args); + + TestContract { + env: env.clone(), + name: String::from(name), + contract_owner, + } + } + + pub fn query_dictionary( + &self, + dict_name: &str, + key: String, + ) -> Option { + self.env + .query_dictionary(self.contract_hash(), dict_name, key) + } + + pub fn query_named_key(&self, key: String) -> T { + let contract_name = format!("{}_contract_hash", self.name); + self.env + .query_account_named_key(self.contract_owner, &[contract_name, key]) + .into_t() + .unwrap() + } + + pub fn contract_hash(&self) -> Hash { + let key = format!("{}_contract_hash_wrapped", self.name); + let value: Value = self + .env + .query_account_named_key(self.contract_owner, &[key]); + value.into_t().unwrap() + } + + pub fn call_contract(&self, sender: Sender, entry_point: &str, session_args: RuntimeArgs) { + let session_code = Code::Hash(self.contract_hash(), String::from(entry_point)); + self.env.run(sender, session_code, session_args); + } +} diff --git a/utils/test-env/src/test_env.rs b/utils/test-env/src/test_env.rs new file mode 100644 index 0000000..409df8b --- /dev/null +++ b/utils/test-env/src/test_env.rs @@ -0,0 +1,120 @@ +use std::sync::{Arc, Mutex}; + +use casper_engine_test_support::{ + AccountHash, Code, Hash, SessionBuilder, TestContext, TestContextBuilder, Value, +}; +use casper_types::{bytesrepr::FromBytes, CLTyped, Key, PublicKey, RuntimeArgs, SecretKey, U512}; + +use crate::Sender; + +#[derive(Clone)] +pub struct TestEnv { + state: Arc>, +} + +impl TestEnv { + pub fn new() -> TestEnv { + TestEnv { + state: Arc::new(Mutex::new(TestEnvState::new())), + } + } + + pub fn run(&self, sender: Sender, session_code: Code, session_args: RuntimeArgs) { + self.state + .lock() + .unwrap() + .run(sender, session_code, session_args); + } + + pub fn next_user(&self) -> AccountHash { + self.state.lock().unwrap().next_user() + } + + pub fn query_dictionary( + &self, + contract_hash: Hash, + dict_name: &str, + key: String, + ) -> Option { + self.state + .lock() + .unwrap() + .query_dictionary(contract_hash, dict_name, key) + } + + pub fn query_account_named_key(&self, account: AccountHash, path: &[String]) -> Value { + self.state + .lock() + .unwrap() + .query_account_named_key(account, path) + } +} + +impl Default for TestEnv { + fn default() -> Self { + TestEnv::new() + } +} + +struct TestEnvState { + context: TestContext, + accounts: Vec, +} + +impl TestEnvState { + pub fn new() -> TestEnvState { + let mut context_builder = TestContextBuilder::new(); + + let mut accounts = Vec::new(); + for i in 0..10u8 { + let secret_key: SecretKey = SecretKey::ed25519_from_bytes([i; 32]).unwrap(); + let public_key: PublicKey = (&secret_key).into(); + accounts.push(AccountHash::from(&public_key)); + context_builder = + context_builder.with_public_key(public_key, U512::from(500_000_000_000_000u64)); + } + + TestEnvState { + context: context_builder.build(), + accounts, + } + } + + pub fn next_user(&mut self) -> AccountHash { + self.accounts.pop().unwrap() + } + + pub fn run(&mut self, sender: Sender, session_code: Code, session_args: RuntimeArgs) { + let Sender(sender) = sender; + let session = SessionBuilder::new(session_code, session_args) + .with_address(sender) + .with_authorization_keys(&[sender]) + .build(); + self.context.run(session); + } + + pub fn query_dictionary( + &self, + contract_hash: Hash, + dict_name: &str, + key: String, + ) -> Option { + match self.context.query_dictionary_item( + Key::Hash(contract_hash), + Some(dict_name.to_string()), + key, + ) { + Err(_) => None, + Ok(maybe_value) => { + let value: Option = maybe_value + .into_t() + .unwrap_or_else(|_| panic!("is not expected type.")); + value + } + } + } + + pub fn query_account_named_key(&self, account: AccountHash, path: &[String]) -> Value { + self.context.query(account, path).unwrap() + } +} From 9e32bcc8ab840ec0958cdaf3805d63f2314c1cbc Mon Sep 17 00:00:00 2001 From: astro019 Date: Tue, 24 Aug 2021 00:29:41 +1000 Subject: [PATCH 72/98] update owned_tokens indexable --- cep47-tests/src/cep47_instance.rs | 9 +- cep47-tests/src/cep47_tests.rs | 203 ++++++++++++++++++------------ cep47/bin/cep47_token.rs | 83 ++++++++---- cep47/src/cep47.rs | 60 +++------ cep47/src/data.rs | 68 ++++++++-- utils/contract-utils/src/lib.rs | 2 +- 6 files changed, 259 insertions(+), 166 deletions(-) diff --git a/cep47-tests/src/cep47_instance.rs b/cep47-tests/src/cep47_instance.rs index cafdfc3..1a51bfa 100644 --- a/cep47-tests/src/cep47_instance.rs +++ b/cep47-tests/src/cep47_instance.rs @@ -178,10 +178,11 @@ impl CEP47Instance { ) } - pub fn tokens>(&self, account: T) -> Vec { - self.0 - .query_dictionary("owned_tokens", key_to_str(&account.into())) - .unwrap_or_default() + pub fn get_token_by_index>(&self, account: T, index: u32) -> Option { + self.0.query_dictionary( + "owned_tokens_by_index", + key_and_value_to_str(&account.into(), &index), + ) } pub fn balance_of>(&self, account: T) -> U256 { diff --git a/cep47-tests/src/cep47_tests.rs b/cep47-tests/src/cep47_tests.rs index 24f3793..29e77a3 100644 --- a/cep47-tests/src/cep47_tests.rs +++ b/cep47-tests/src/cep47_tests.rs @@ -82,8 +82,8 @@ fn test_token_meta() { let user_token_meta = token.token_meta(token_id.clone()); assert_eq!(user_token_meta.unwrap(), token_meta); - let user_tokens = token.tokens(Key::Account(user)); - assert_eq!(user_tokens, vec![token_id]); + let first_user_token = token.get_token_by_index(Key::Account(user), 0u32); + assert_eq!(first_user_token, Some(token_id)); } #[test] @@ -95,12 +95,13 @@ fn test_mint_one_with_random_token_id() { assert_eq!(token.total_supply(), U256::one()); assert_eq!(token.balance_of(user), U256::one()); - let user_tokens: Vec = token.tokens(Key::Account(user)); - assert_eq!(U256::from(user_tokens.len() as u64), U256::one()); + let first_user_token: Option = token.get_token_by_index(Key::Account(user), 0u32); + let second_user_token: Option = token.get_token_by_index(Key::Account(user), 1u32); assert_eq!( - token.owner_of(user_tokens.get(0).unwrap().clone()).unwrap(), + token.owner_of(first_user_token.unwrap()).unwrap(), Key::Account(user) ); + assert_eq!(second_user_token, None); } #[test] @@ -116,11 +117,12 @@ fn test_mint_one_with_set_token_id() { Some(token_id.clone()), token_meta.clone(), ); - let user_tokens = token.tokens(Key::Account(user)); - assert_eq!(user_tokens, vec![token_id.clone()]); + let first_user_token = token.get_token_by_index(Key::Account(user), 0u32); + let second_user_token = token.get_token_by_index(Key::Account(user), 1u32); + assert_eq!(first_user_token, Some(token_id.clone())); assert_eq!(token.total_supply(), U256::one()); assert_eq!(token.balance_of(Key::Account(user)), U256::one()); - assert_eq!(U256::from(user_tokens.len() as u64), U256::one()); + assert_eq!(second_user_token, None); assert_eq!(token.owner_of(token_id).unwrap(), Key::Account(user)); } @@ -152,23 +154,24 @@ fn test_mint_copies() { let (env, token, owner) = deploy(); let user = env.next_user(); let token_meta = meta::red_dragon(); - token.mint_copies(Sender(owner), user, None, token_meta.clone(), 3); - - let user_tokens = token.tokens(Key::Account(user)); + let first_user_token = token.get_token_by_index(Key::Account(user), 0u32); + let second_user_token = token.get_token_by_index(Key::Account(user), 1u32); + let third_user_token = token.get_token_by_index(Key::Account(user), 2u32); + let fourth_user_token = token.get_token_by_index(Key::Account(user), 3u32); assert_eq!(token.total_supply(), U256::from(3)); assert_eq!(token.balance_of(Key::Account(user)), U256::from(3)); - assert_eq!(U256::from(user_tokens.len() as u64), U256::from(3)); + assert_eq!(fourth_user_token, None); assert_eq!( - token.owner_of(user_tokens.get(0).unwrap().clone()).unwrap(), + token.owner_of(first_user_token.unwrap()).unwrap(), Key::Account(user) ); assert_eq!( - token.owner_of(user_tokens.get(1).unwrap().clone()).unwrap(), + token.owner_of(second_user_token.unwrap()).unwrap(), Key::Account(user) ); assert_eq!( - token.owner_of(user_tokens.get(2).unwrap().clone()).unwrap(), + token.owner_of(third_user_token.unwrap()).unwrap(), Key::Account(user) ); } @@ -178,25 +181,25 @@ fn test_mint_many() { let (env, token, owner) = deploy(); let user = env.next_user(); let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; - token.mint_many(Sender(owner), user, None, token_metas.clone()); - let user_tokens = token.tokens(Key::Account(user)); + let first_user_token = token.get_token_by_index(Key::Account(user), 0u32); + let second_user_token = token.get_token_by_index(Key::Account(user), 1u32); + let third_user_token = token.get_token_by_index(Key::Account(user), 2u32); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(user)), U256::from(2)); - assert_eq!(U256::from(user_tokens.len() as u64), U256::from(2)); + assert_eq!(third_user_token, None); assert_eq!( - token.owner_of(user_tokens.get(0).unwrap().clone()).unwrap(), + token.owner_of(first_user_token.unwrap()).unwrap(), Key::Account(user) ); assert_eq!( - token.owner_of(user_tokens.get(1).unwrap().clone()).unwrap(), + token.owner_of(second_user_token.unwrap()).unwrap(), Key::Account(user) ); } #[test] fn test_burn_many() { - // TODO: the sender should be owner of nft item or allowed party let (env, token, owner) = deploy(); let user = env.next_user(); let token_metas = vec![ @@ -208,24 +211,29 @@ fn test_burn_many() { token.mint_many(Sender(owner), user, None, token_metas.clone()); - let mut user_tokens = token.tokens(Key::Account(user)); - println!("{:?}", user_tokens); - println!("{:?}", user_tokens.first().unwrap().clone()); - + let first_user_token = token.get_token_by_index(Key::Account(user), 0u32); + let second_user_token = token.get_token_by_index(Key::Account(user), 1u32); + let third_user_token = token.get_token_by_index(Key::Account(user), 2u32); + let fourth_user_token = token.get_token_by_index(Key::Account(user), 3u32); token.burn_many( Sender(user), user, vec![ - user_tokens.first().unwrap().clone(), - user_tokens.last().unwrap().clone(), + first_user_token.clone().unwrap(), + fourth_user_token.clone().unwrap(), ], ); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(user)), U256::from(2)); - user_tokens = token.tokens(Key::Account(user)); - println!("{:?}", user_tokens); - assert_eq!(U256::from(user_tokens.len() as u64), U256::from(2)); + let new_first_user_token = token.get_token_by_index(Key::Account(user), 0u32); + let new_second_user_token = token.get_token_by_index(Key::Account(user), 1u32); + let new_third_user_token = token.get_token_by_index(Key::Account(user), 2u32); + let new_fourth_user_token = token.get_token_by_index(Key::Account(user), 3u32); + assert_eq!(new_first_user_token, third_user_token); + assert_eq!(new_second_user_token, second_user_token); + assert_eq!(new_third_user_token, None); + assert_eq!(new_fourth_user_token, None); } #[test] @@ -241,24 +249,37 @@ fn test_burn_many_from_allowance_with_approve() { token.mint_many(Sender(owner), user, None, token_metas.clone()); - let mut user_tokens = token.tokens(Key::Account(user)); - println!("{:?}", user_tokens); - println!("{:?}", user_tokens.first().unwrap().clone()); - token.approve(Sender(user), owner, user_tokens.clone()); + let first_user_token = token.get_token_by_index(Key::Account(user), 0u32); + let second_user_token = token.get_token_by_index(Key::Account(user), 1u32); + let third_user_token = token.get_token_by_index(Key::Account(user), 2u32); + let fourth_user_token = token.get_token_by_index(Key::Account(user), 3u32); + token.approve( + Sender(user), + owner, + vec![ + first_user_token.clone().unwrap(), + third_user_token.clone().unwrap(), + ], + ); token.burn_many( Sender(owner), user, vec![ - user_tokens.first().unwrap().clone(), - user_tokens.last().unwrap().clone(), + first_user_token.clone().unwrap(), + third_user_token.clone().unwrap(), ], ); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(user)), U256::from(2)); - user_tokens = token.tokens(Key::Account(user)); - println!("{:?}", user_tokens); - assert_eq!(U256::from(user_tokens.len() as u64), U256::from(2)); + let new_first_user_token = token.get_token_by_index(Key::Account(user), 0u32); + let new_second_user_token = token.get_token_by_index(Key::Account(user), 1u32); + let new_third_user_token = token.get_token_by_index(Key::Account(user), 2u32); + let new_fourth_user_token = token.get_token_by_index(Key::Account(user), 3u32); + assert_eq!(new_first_user_token, fourth_user_token); + assert_eq!(new_second_user_token, second_user_token); + assert_eq!(new_third_user_token, None); + assert_eq!(new_fourth_user_token, None); } #[test] @@ -275,15 +296,14 @@ fn test_burn_many_from_allowance_without_approve() { token.mint_many(Sender(owner), user, None, token_metas.clone()); - let user_tokens = token.tokens(Key::Account(user)); - println!("{:?}", user_tokens); - println!("{:?}", user_tokens.first().unwrap().clone()); + let first_user_token = token.get_token_by_index(Key::Account(user), 0u32); + let second_user_token = token.get_token_by_index(Key::Account(user), 1u32); token.burn_many( Sender(owner), user, vec![ - user_tokens.first().unwrap().clone(), - user_tokens.last().unwrap().clone(), + first_user_token.clone().unwrap(), + second_user_token.clone().unwrap(), ], ); } @@ -296,13 +316,16 @@ fn test_burn_one() { let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; token.mint_many(Sender(owner), user, None, token_metas.clone()); - let mut user_tokens = token.tokens(Key::Account(user)); - token.burn_one(Sender(user), user, user_tokens.first().unwrap().clone()); + let first_user_token = token.get_token_by_index(Key::Account(user), 0u32); + let second_user_token = token.get_token_by_index(Key::Account(user), 1u32); + token.burn_one(Sender(user), user, first_user_token.clone().unwrap()); assert_eq!(token.total_supply(), U256::from(1)); assert_eq!(token.balance_of(Key::Account(user)), U256::from(1)); - user_tokens = token.tokens(Key::Account(user)); - assert_eq!(U256::from(user_tokens.len() as u64), U256::from(1)); + let new_first_user_token = token.get_token_by_index(Key::Account(user), 0u32); + let new_second_user_token = token.get_token_by_index(Key::Account(user), 1u32); + assert_eq!(new_first_user_token, second_user_token); + assert_eq!(new_second_user_token, None); } #[test] @@ -313,36 +336,46 @@ fn test_transfer_token() { let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; token.mint_many(Sender(owner), ali, None, token_metas.clone()); - let mut ali_tokens = token.tokens(Key::Account(ali)); + let first_ali_token = token.get_token_by_index(Key::Account(ali), 0u32); + let second_ali_token = token.get_token_by_index(Key::Account(ali), 1u32); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(ali)), U256::from(2)); - assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(2)); assert_eq!( - token.owner_of(ali_tokens.get(0).unwrap().clone()).unwrap(), + token.owner_of(first_ali_token.clone().unwrap()).unwrap(), Key::Account(ali) ); assert_eq!( - token.owner_of(ali_tokens.get(1).unwrap().clone()).unwrap(), + token.owner_of(second_ali_token.clone().unwrap()).unwrap(), Key::Account(ali) ); - token.transfer(Sender(ali), bob, vec![ali_tokens.get(0).unwrap().clone()]); - ali_tokens = token.tokens(Key::Account(ali)); - let bob_tokens = token.tokens(Key::Account(bob)); + token.transfer(Sender(ali), bob, vec![first_ali_token.clone().unwrap()]); + let new_first_ali_token = token.get_token_by_index(Key::Account(ali), 0u32); + let new_second_ali_token = token.get_token_by_index(Key::Account(ali), 1u32); + let new_first_bob_token = token.get_token_by_index(Key::Account(bob), 0u32); + let new_second_bob_token = token.get_token_by_index(Key::Account(bob), 1u32); + println!("{:?}", new_first_ali_token.clone()); + println!("{:?}", new_second_ali_token.clone()); + println!("{:?}", new_first_bob_token.clone()); + println!("{:?}", new_second_bob_token.clone()); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(ali)), U256::from(1)); assert_eq!(token.balance_of(Key::Account(bob)), U256::from(1)); - assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(1)); - assert_eq!(U256::from(bob_tokens.len() as u64), U256::from(1)); assert_eq!( - token.owner_of(ali_tokens.get(0).unwrap().clone()).unwrap(), + token + .owner_of(new_first_ali_token.clone().unwrap()) + .unwrap(), Key::Account(ali) ); assert_eq!( - token.owner_of(bob_tokens.get(0).unwrap().clone()).unwrap(), + token + .owner_of(new_first_bob_token.clone().unwrap()) + .unwrap(), Key::Account(bob) ); + assert_eq!(new_second_ali_token, None); + assert_eq!(new_second_bob_token, None); } #[test] @@ -353,41 +386,47 @@ fn test_transfer_from_tokens_with_approve() { let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; token.mint_many(Sender(owner), ali, None, token_metas.clone()); - let mut ali_tokens = token.tokens(Key::Account(ali)); + let first_ali_token = token.get_token_by_index(Key::Account(ali), 0u32); + let second_ali_token = token.get_token_by_index(Key::Account(ali), 1u32); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(ali)), U256::from(2)); - assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(2)); assert_eq!( - token.owner_of(ali_tokens.get(0).unwrap().clone()).unwrap(), + token.owner_of(first_ali_token.clone().unwrap()).unwrap(), Key::Account(ali) ); assert_eq!( - token.owner_of(ali_tokens.get(1).unwrap().clone()).unwrap(), + token.owner_of(second_ali_token.clone().unwrap()).unwrap(), Key::Account(ali) ); - token.approve(Sender(ali), owner, vec![ali_tokens.get(0).unwrap().clone()]); + token.approve(Sender(ali), owner, vec![second_ali_token.clone().unwrap()]); token.transfer_from( Sender(owner), ali, bob, - vec![ali_tokens.get(0).unwrap().clone()], + vec![second_ali_token.clone().unwrap()], ); - ali_tokens = token.tokens(Key::Account(ali)); - let bob_tokens = token.tokens(Key::Account(bob)); + let new_first_ali_token = token.get_token_by_index(Key::Account(ali), 0u32); + let new_second_ali_token = token.get_token_by_index(Key::Account(ali), 1u32); + let new_first_bob_token = token.get_token_by_index(Key::Account(bob), 0u32); + let new_second_bob_token = token.get_token_by_index(Key::Account(bob), 1u32); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(ali)), U256::from(1)); assert_eq!(token.balance_of(Key::Account(bob)), U256::from(1)); - assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(1)); - assert_eq!(U256::from(bob_tokens.len() as u64), U256::from(1)); assert_eq!( - token.owner_of(ali_tokens.get(0).unwrap().clone()).unwrap(), + token + .owner_of(new_first_ali_token.clone().unwrap()) + .unwrap(), Key::Account(ali) ); assert_eq!( - token.owner_of(bob_tokens.get(0).unwrap().clone()).unwrap(), + token + .owner_of(new_first_bob_token.clone().unwrap()) + .unwrap(), Key::Account(bob) ); + assert_eq!(new_second_ali_token, None); + assert_eq!(new_second_bob_token, None); } #[test] @@ -399,24 +438,23 @@ fn test_transfer_from_tokens_without_approve() { let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; token.mint_many(Sender(owner), ali, None, token_metas.clone()); - let ali_tokens = token.tokens(Key::Account(ali)); + let first_ali_token = token.get_token_by_index(Key::Account(ali), 0u32); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(ali)), U256::from(2)); - assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(2)); assert_eq!( - token.owner_of(ali_tokens.get(0).unwrap().clone()).unwrap(), + token.owner_of(first_ali_token.clone().unwrap()).unwrap(), Key::Account(ali) ); assert_eq!( - token.owner_of(ali_tokens.get(1).unwrap().clone()).unwrap(), + token.owner_of(first_ali_token.clone().unwrap()).unwrap(), Key::Account(ali) ); token.transfer_from( Sender(owner), ali, bob, - vec![ali_tokens.get(0).unwrap().clone()], + vec![first_ali_token.clone().unwrap()], ); } @@ -433,26 +471,25 @@ fn test_approve() { token.mint_many(Sender(owner), user, None, token_metas.clone()); - let user_tokens = token.tokens(Key::Account(user)); - println!("{:?}", user_tokens); - println!("{:?}", user_tokens.first().unwrap().clone()); + let first_user_token = token.get_token_by_index(Key::Account(user), 0u32); + let fourth_user_token = token.get_token_by_index(Key::Account(user), 3u32); token.approve( Sender(user), owner, vec![ - user_tokens.get(0).unwrap().clone(), - user_tokens.get(2).unwrap().clone(), + first_user_token.clone().unwrap(), + fourth_user_token.clone().unwrap(), ], ); assert_eq!( token - .get_approved(user, user_tokens.get(0).unwrap().clone()) + .get_approved(user, first_user_token.clone().unwrap()) .unwrap(), Key::Account(owner) ); assert_eq!( token - .get_approved(user, user_tokens.get(2).unwrap().clone()) + .get_approved(user, fourth_user_token.clone().unwrap()) .unwrap(), Key::Account(owner) ); diff --git a/cep47/bin/cep47_token.rs b/cep47/bin/cep47_token.rs index 3cbbbab..0910d6f 100644 --- a/cep47/bin/cep47_token.rs +++ b/cep47/bin/cep47_token.rs @@ -100,13 +100,6 @@ fn update_token_meta() { .unwrap_or_revert(); } -#[no_mangle] -fn tokens() { - let owner = runtime::get_named_arg::("owner"); - let ret = NFTToken::default().get_tokens(owner); - runtime::ret(CLValue::from_t(ret).unwrap_or_revert()); -} - #[no_mangle] fn mint() { let recipient = runtime::get_named_arg::("recipient"); @@ -251,6 +244,65 @@ fn get_entry_points() -> EntryPoints { EntryPointAccess::Groups(vec![Group::new("constructor")]), EntryPointType::Contract, )); + entry_points.add_entry_point(EntryPoint::new( + "name", + vec![], + String::cl_type(), + EntryPointAccess::Public, + EntryPointType::Contract, + )); + entry_points.add_entry_point(EntryPoint::new( + "symbol", + vec![], + String::cl_type(), + EntryPointAccess::Public, + EntryPointType::Contract, + )); + entry_points.add_entry_point(EntryPoint::new( + "meta", + vec![], + Meta::cl_type(), + EntryPointAccess::Public, + EntryPointType::Contract, + )); + entry_points.add_entry_point(EntryPoint::new( + "total_supply", + vec![], + U256::cl_type(), + EntryPointAccess::Public, + EntryPointType::Contract, + )); + entry_points.add_entry_point(EntryPoint::new( + "balance_of", + vec![Parameter::new("owner", Key::cl_type())], + U256::cl_type(), + EntryPointAccess::Public, + EntryPointType::Contract, + )); + entry_points.add_entry_point(EntryPoint::new( + "owner_of", + vec![Parameter::new("token_id", TokenId::cl_type())], + CLType::Option(Box::new(CLType::Key)), + EntryPointAccess::Public, + EntryPointType::Contract, + )); + entry_points.add_entry_point(EntryPoint::new( + "token_meta", + vec![Parameter::new("token_id", TokenId::cl_type())], + Meta::cl_type(), + EntryPointAccess::Public, + EntryPointType::Contract, + )); + entry_points.add_entry_point(EntryPoint::new( + "update_token_meta", + vec![ + Parameter::new("token_id", TokenId::cl_type()), + Parameter::new("token_meta", Meta::cl_type()), + ], + <()>::cl_type(), + EntryPointAccess::Public, + EntryPointType::Contract, + )); entry_points.add_entry_point(EntryPoint::new( "mint", vec![ @@ -331,22 +383,5 @@ fn get_entry_points() -> EntryPoints { EntryPointAccess::Public, EntryPointType::Contract, )); - entry_points.add_entry_point(EntryPoint::new( - "update_token_meta", - vec![ - Parameter::new("token_id", TokenId::cl_type()), - Parameter::new("token_meta", Meta::cl_type()), - ], - <()>::cl_type(), - EntryPointAccess::Public, - EntryPointType::Contract, - )); - entry_points.add_entry_point(EntryPoint::new( - "total_supply", - vec![], - U256::cl_type(), - EntryPointAccess::Public, - EntryPointType::Contract, - )); entry_points } diff --git a/cep47/src/cep47.rs b/cep47/src/cep47.rs index c1ddc9a..1662b1a 100644 --- a/cep47/src/cep47.rs +++ b/cep47/src/cep47.rs @@ -75,27 +75,8 @@ pub trait CEP47: ContractContext { Ok(()) } - fn get_tokens(&self, owner: Key) -> Vec { - OwnedTokens::instance().get(&owner) - } - - fn set_tokens(&mut self, owner: Key, token_ids: Vec) { - let owners_dict = Owners::instance(); - let owned_tokens_dict = OwnedTokens::instance(); - let balances_dict = Balances::instance(); - - for token_id in &token_ids { - owners_dict.set(token_id, owner); - } - - let prev_balance = balances_dict.get(&owner); - let new_balance = U256::from(token_ids.len() as u64); - balances_dict.set(&owner, new_balance); - - owned_tokens_dict.set(&owner, token_ids); - - let new_total_supply = data::total_supply() - prev_balance + new_balance; - data::set_total_supply(new_total_supply); + fn get_token_by_index(&self, owner: Key, index: u32) -> Option { + OwnedTokens::instance().get_token_by_index(&owner, &index) } fn generate_token_ids(&mut self, n: u32) -> Vec { @@ -147,15 +128,12 @@ pub trait CEP47: ContractContext { let metadata_dict = Metadata::instance(); let balances_dict = Balances::instance(); - let mut recipient_tokens = owned_tokens_dict.get(&recipient); for (token_id, token_meta) in unique_token_ids.iter().zip(&token_metas) { metadata_dict.set(token_id, token_meta.clone()); owners_dict.set(token_id, recipient); - recipient_tokens.push(token_id.clone()); + owned_tokens_dict.set_token(&recipient, token_id.clone()); } - owned_tokens_dict.set(&recipient, recipient_tokens); - let minted_tokens_count = U256::from(unique_token_ids.len() as u64); let prev_balance = balances_dict.get(&recipient); let new_balance = prev_balance + minted_tokens_count; @@ -194,7 +172,6 @@ pub trait CEP47: ContractContext { let balances_dict = Balances::instance(); let allowances_dict = Allowances::instance(); - let mut owner_tokens = owned_tokens_dict.get(&owner); let spender = self.get_caller(); for token_id in &token_ids { @@ -211,18 +188,15 @@ pub trait CEP47: ContractContext { return Err(Error::TokenIdDoesntExist); } } - let index = owner_tokens - .iter() - .position(|x| x == token_id) - .unwrap_or_revert(); - owner_tokens.remove(index); + owned_tokens_dict.remove_token(&owner, token_id.clone()); metadata_dict.remove(token_id); owners_dict.remove(token_id); allowances_dict.remove(&owner, token_id); } - balances_dict.set(&owner, U256::from(owner_tokens.len() as u64)); - owned_tokens_dict.set(&owner, owner_tokens); + let owner_balance = balances_dict.get(&owner); + let new_owner_balance = owner_balance - U256::from(token_ids.len() as u64); + balances_dict.set(&owner, new_owner_balance); let burnt_tokens_count = U256::from(token_ids.len() as u64); let new_total_supply = data::total_supply() - burnt_tokens_count; @@ -281,8 +255,6 @@ pub trait CEP47: ContractContext { let owned_tokens_dict = OwnedTokens::instance(); let balances_dict = Balances::instance(); - let mut sender_tokens = owned_tokens_dict.get(&owner); - let mut recipient_tokens = owned_tokens_dict.get(&recipient); for token_id in &token_ids { match owners_dict.get(token_id) { Some(owner_of_key) => { @@ -294,20 +266,18 @@ pub trait CEP47: ContractContext { return Err(Error::TokenIdDoesntExist); } } - let index = sender_tokens - .iter() - .position(|x| x == token_id) - .unwrap_or_revert(); - sender_tokens.remove(index); - recipient_tokens.push(token_id.clone()); + owned_tokens_dict.remove_token(&owner, token_id.clone()); + owned_tokens_dict.set_token(&recipient, token_id.clone()); owners_dict.set(token_id, recipient); } + let owner_balance = balances_dict.get(&owner); + let new_owner_balance = owner_balance - U256::from(token_ids.len() as u64); + balances_dict.set(&owner, new_owner_balance); - balances_dict.set(&owner, sender_tokens.len().into()); - owned_tokens_dict.set(&owner, sender_tokens); + let recipient_balance = balances_dict.get(&recipient); + let new_recipient_balance = recipient_balance + U256::from(token_ids.len() as u64); + balances_dict.set(&recipient, new_recipient_balance); - balances_dict.set(&recipient, recipient_tokens.len().into()); - owned_tokens_dict.set(&recipient, recipient_tokens); self.emit(CEP47Event::Transfer { sender: owner, recipient, diff --git a/cep47/src/data.rs b/cep47/src/data.rs index d9bb369..2e27cbb 100644 --- a/cep47/src/data.rs +++ b/cep47/src/data.rs @@ -5,7 +5,7 @@ use alloc::{ }; use casper_contract::{contract_api::storage, unwrap_or_revert::UnwrapOrRevert}; use casper_types::{ContractPackageHash, Key, URef, U256}; -use contract_utils::{get_key, key_and_value_to_str, set_key, Dict}; +use contract_utils::{get_key, key_and_value_to_str, key_to_str, set_key, Dict}; use crate::{event::CEP47Event, Meta, TokenId}; @@ -13,7 +13,9 @@ const BALANCES_DICT: &str = "balances"; pub const ALLOWANCES_DICT: &str = "allowances"; const METADATA_DICT: &str = "metadata"; const OWNERS_DICT: &str = "owners"; -const OWNED_TOKENS_DICT: &str = "owned_tokens"; +const OWNED_TOKENS_BY_INDEX_DICT: &str = "owned_tokens_by_index"; +const OWNED_INDEXES_BY_TOKEN_DICT: &str = "owned_indexes_by_token"; +const OWNED_TOKENS_LENGTH_DICT: &str = "owned_tokens_length"; const CONTRACT_PACKAGE_HASH: &str = "contract_package_hash"; pub const NAME: &str = "name"; @@ -103,26 +105,74 @@ impl Metadata { } pub struct OwnedTokens { - dict: Dict, + token_dict: Dict, + index_dict: Dict, + length_dict: Dict, } impl OwnedTokens { pub fn instance() -> OwnedTokens { OwnedTokens { - dict: Dict::instance(OWNED_TOKENS_DICT), + token_dict: Dict::instance(OWNED_TOKENS_BY_INDEX_DICT), + index_dict: Dict::instance(OWNED_INDEXES_BY_TOKEN_DICT), + length_dict: Dict::instance(OWNED_TOKENS_LENGTH_DICT), } } pub fn init() { - Dict::init(OWNED_TOKENS_DICT) + Dict::init(OWNED_TOKENS_BY_INDEX_DICT); + Dict::init(OWNED_INDEXES_BY_TOKEN_DICT); + Dict::init(OWNED_TOKENS_LENGTH_DICT); } - pub fn get(&self, owner: &Key) -> Vec { - self.dict.get_by_key(owner).unwrap_or_default() + pub fn get_token_by_index(&self, owner: &Key, index: &u32) -> Option { + self.token_dict.get(&key_and_value_to_str(owner, index)) } - pub fn set(&self, owner: &Key, value: Vec) { - self.dict.set_by_key(owner, value); + pub fn get_index_by_token(&self, owner: &Key, value: &TokenId) -> Option { + self.index_dict.get(&key_and_value_to_str(owner, value)) + } + + pub fn get_tokens_len(&self, owner: &Key) -> Option { + self.length_dict.get(&key_to_str(owner)) + } + + pub fn set_tokens_len(&self, owner: &Key, value: u32) { + self.length_dict.set(&key_to_str(owner), value); + } + + pub fn set_token(&self, owner: &Key, value: TokenId) { + let length = self.get_tokens_len(owner).unwrap_or_default(); + self.index_dict + .set(&key_and_value_to_str(owner, &value), length.clone()); + self.token_dict + .set(&key_and_value_to_str(owner, &length), value); + self.set_tokens_len(owner, length + 1); + } + + pub fn remove_token(&self, owner: &Key, value: TokenId) { + let length = self.get_tokens_len(owner).unwrap_or_revert(); + let index = self.get_index_by_token(owner, &value).unwrap_or_revert(); + if length == index + 1 { + self.token_dict + .remove::(&key_and_value_to_str(owner, &(length - 1))); + self.set_tokens_len(owner, length - 1); + } else if length > index + 1 { + let last = self.get_token_by_index(owner, &(length - 1)); + self.index_dict.set( + &key_and_value_to_str(owner, &last.clone().unwrap_or_revert()), + index, + ); + self.token_dict.set( + &key_and_value_to_str(owner, &index), + last.clone().unwrap_or_revert(), + ); + self.token_dict + .remove::(&key_and_value_to_str(owner, &(length - 1))); + self.set_tokens_len(owner, length - 1); + } + self.index_dict + .remove::(&key_and_value_to_str(owner, &value)); } } diff --git a/utils/contract-utils/src/lib.rs b/utils/contract-utils/src/lib.rs index 4e52e04..6006aa4 100644 --- a/utils/contract-utils/src/lib.rs +++ b/utils/contract-utils/src/lib.rs @@ -11,4 +11,4 @@ mod data; pub use admin_control::AdminControl; pub use contract_context::ContractContext; pub use contract_storage::{ContractStorage, OnChainContractStorage}; -pub use data::{get_key, key_and_value_to_str, set_key, Dict}; +pub use data::{get_key, key_and_value_to_str, key_to_str, set_key, Dict}; From 2c6a6fcb511191c275aa315b3ccb20a02a702fb8 Mon Sep 17 00:00:00 2001 From: astro019 Date: Tue, 24 Aug 2021 00:58:13 +1000 Subject: [PATCH 73/98] rebase against master and resolved conflict --- .DS_Store | Bin 6148 -> 6148 bytes Cargo.toml | 1 - cep47-logic/src/lib.rs | 248 -------------- cep47-logic/src/tests.rs | 472 -------------------------- cep47-tests/src/cep47.rs | 338 ------------------ cep47-tests/src/contract_tests.rs | 400 ---------------------- cep47/src/cep47_storage.rs | 178 ---------- cep47/src/data.rs | 2 +- cep47/src/entrypoints.rs | 173 ---------- cep47/src/event.rs | 22 -- test-contracts/Cargo.toml | 28 -- test-contracts/src/dragons-nft.rs | 29 -- test-contracts/src/owning_contract.rs | 53 --- 13 files changed, 1 insertion(+), 1943 deletions(-) delete mode 100644 cep47-logic/src/lib.rs delete mode 100644 cep47-logic/src/tests.rs delete mode 100644 cep47-tests/src/cep47.rs delete mode 100644 cep47-tests/src/contract_tests.rs delete mode 100644 cep47/src/cep47_storage.rs delete mode 100644 cep47/src/entrypoints.rs delete mode 100644 test-contracts/Cargo.toml delete mode 100644 test-contracts/src/dragons-nft.rs delete mode 100644 test-contracts/src/owning_contract.rs diff --git a/.DS_Store b/.DS_Store index 5008ddfcf53c02e82d7eee2e57c38e5672ef89f6..02a084fae7da1800d91dc5a2838daf55ef606003 100644 GIT binary patch literal 6148 zcmeHKOHRWu5FJAb72R~nG8bS`gv2&f=?S_EUE!=eSH3gYh&= z^IEKSr~<0M?^A%k-40D@PB~qW_x(N|S4YzAK7^co=>7;~uxI zXjYlSW7HT^<`KNw4YorYFj-RKYjqxgMQPOIuzzp6e2+mxM0tIp7c8Lm#}z=$X6yDG zs#gV60aak90PhbW8e=3_IJ8>_oIL^nx!_pCHUCm@PAC`&77j52GcFbAQjHujj7vv< zC~=Ws;n1a%k;8|Pm5rQGj9ne`hc=u{AjHu~2NHo+1YW5HK<@2y7PQ5M$Y_z%h$?Gdl-A2T%b}u84%9H(hI5x+KtY8KJ$3PAT diff --git a/Cargo.toml b/Cargo.toml index 435dc02..b635878 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,4 +8,3 @@ members = [ [profile.release] codegen-units = 1 lto = true -codegen-units = 1 \ No newline at end of file diff --git a/cep47-logic/src/lib.rs b/cep47-logic/src/lib.rs deleted file mode 100644 index 67da492..0000000 --- a/cep47-logic/src/lib.rs +++ /dev/null @@ -1,248 +0,0 @@ -#![allow(dead_code)] -#![allow(unused_imports)] - -use std::collections::BTreeMap; - -use casper_types::{ApiError, AsymmetricType, ContractPackageHash, Key, URef, U256}; - -#[cfg(test)] -#[macro_use] -extern crate maplit; - -pub mod events; -#[cfg(test)] -pub mod tests; - -use events::CEP47Event; - -pub type TokenId = String; -pub type Meta = BTreeMap; - -#[derive(Debug)] -#[repr(u16)] -pub enum Error { - PermissionDenied = 1, - ArgumentsError = 2, - TokenIdAlreadyExists = 3, - TokenIdDoesntExist = 4, - NotAnOwner = 5, -} - -impl From for ApiError { - fn from(error: Error) -> ApiError { - ApiError::User(error as u16) - } -} - -pub trait WithStorage { - fn storage(&self) -> &Storage; - fn storage_mut(&mut self) -> &mut Storage; -} - -pub trait CEP47Contract: WithStorage { - // Metadata - fn name(&self) -> String { - self.storage().name() - } - - fn symbol(&self) -> String { - self.storage().symbol() - } - - fn meta(&self) -> Meta { - self.storage().meta() - } - - // Getters - fn balance_of(&self, owner: &Key) -> U256 { - self.storage().balance_of(owner) - } - - fn owner_of(&self, token_id: &TokenId) -> Option { - self.storage().owner_of(token_id) - } - - fn total_supply(&self) -> U256 { - self.storage().total_supply() - } - - fn token_meta(&self, token_id: &TokenId) -> Option { - self.storage().token_meta(token_id) - } - - fn is_paused(&self) -> bool { - self.storage().is_paused() - } - - fn pause(&mut self) { - self.storage_mut().pause(); - } - - fn unpause(&mut self) { - self.storage_mut().unpause(); - } - - // Minter function. - // Guarded by the entrypoint group. - fn mint_one( - &mut self, - recipient: &Key, - token_id: Option, - token_meta: Meta, - ) -> Result<(), Error> { - self.mint_many(recipient, token_id.map(|id| vec![id]), vec![token_meta]) - } - - fn mint_many( - &mut self, - recipient: &Key, - token_ids: Option>, - token_metas: Vec, - ) -> Result<(), Error> { - let unique_token_ids = match token_ids { - // Validate token_ids and metas. - Some(token_ids) => { - if token_ids.len() != token_metas.len() { - return Err(Error::ArgumentsError); - }; - let valid = self.storage().validate_token_ids(&token_ids); - if !valid { - return Err(Error::TokenIdAlreadyExists); - }; - Ok(token_ids) - } - None => Ok(self.storage_mut().gen_token_ids(token_metas.len() as u32)), - }; - - unique_token_ids.map(|token_ids| { - // Mint tokens. - self.storage_mut() - .mint_many(recipient, &token_ids, &token_metas); - - // Emit event. - self.storage_mut().emit(CEP47Event::Mint { - recipient: *recipient, - token_ids, - }); - }) - } - - fn mint_copies( - &mut self, - recipient: &Key, - token_ids: Option>, - token_meta: Meta, - count: u32, - ) -> Result<(), Error> { - if let Some(token_ids) = &token_ids { - if token_ids.len() != count as usize { - return Err(Error::ArgumentsError); - }; - }; - let token_metas = vec![token_meta; count as usize]; - self.mint_many(recipient, token_ids, token_metas) - } - - fn burn_one(&mut self, owner: &Key, token_id: TokenId) -> Result<(), Error> { - self.burn_many(owner, vec![token_id]) - } - - fn burn_many(&mut self, owner: &Key, token_ids: Vec) -> Result<(), Error> { - if !self.storage().are_all_owner_tokens(owner, &token_ids) { - return Err(Error::NotAnOwner); - } - - self.storage_mut().burn_many(owner, &token_ids); - - // Emit burn event. - self.storage_mut().emit(CEP47Event::Burn { - owner: *owner, - token_ids, - }); - - Ok(()) - } - - // Transfer functions. - fn transfer_token( - &mut self, - sender: &Key, - recipient: &Key, - token_id: &TokenId, - ) -> Result<(), Error> { - self.transfer_many_tokens(sender, recipient, &vec![token_id.clone()]) - } - - fn transfer_many_tokens( - &mut self, - sender: &Key, - recipient: &Key, - token_ids: &Vec, - ) -> Result<(), Error> { - if self.is_paused() { - return Err(Error::PermissionDenied); - } - - if !self.storage().are_all_owner_tokens(sender, token_ids) { - return Err(Error::NotAnOwner); - } - - self.storage_mut() - .transfer_many(sender, recipient, token_ids); - - // Emit transfer event. - self.storage_mut().emit(CEP47Event::Transfer { - sender: *sender, - recipient: *recipient, - token_ids: token_ids.clone(), - }); - Ok(()) - } - - fn update_token_metadata(&mut self, token_id: TokenId, meta: Meta) -> Result<(), Error> { - // Assert token exists. - if self.owner_of(&token_id).is_none() { - return Err(Error::TokenIdDoesntExist); - }; - - // Update the storage. - self.storage_mut().update_token_metadata(&token_id, meta); - - // Emit token update event. - self.storage_mut() - .emit(CEP47Event::MetadataUpdate { token_id }); - - Ok(()) - } -} - -pub trait CEP47Storage { - // Metadata. - fn name(&self) -> String; - fn symbol(&self) -> String; - fn meta(&self) -> Meta; - - // Getters - fn balance_of(&self, owner: &Key) -> U256; - fn owner_of(&self, token_id: &TokenId) -> Option; - fn total_supply(&self) -> U256; - fn token_meta(&self, token_id: &TokenId) -> Option; - - // Pause and unpause transfers. - fn is_paused(&self) -> bool; - fn pause(&mut self); - fn unpause(&mut self); - - // Setters - fn mint_many(&mut self, recipient: &Key, token_ids: &Vec, token_metas: &Vec); - fn transfer_many(&mut self, sender: &Key, recipient: &Key, token_ids: &Vec); - fn burn_many(&mut self, owner: &Key, token_ids: &Vec); - fn update_token_metadata(&mut self, token_id: &TokenId, meta: Meta); - - fn gen_token_ids(&mut self, n: u32) -> Vec; - fn validate_token_ids(&self, token_ids: &Vec) -> bool; - fn are_all_owner_tokens(&self, owner: &Key, token_ids: &Vec) -> bool; - - fn emit(&mut self, event: CEP47Event); - fn contact_package_hash(&self) -> ContractPackageHash; -} diff --git a/cep47-logic/src/tests.rs b/cep47-logic/src/tests.rs deleted file mode 100644 index ed1b87c..0000000 --- a/cep47-logic/src/tests.rs +++ /dev/null @@ -1,472 +0,0 @@ -use casper_types::{AccessRights, ContractPackageHash}; -use rand::Rng; - -use crate::{ - AsymmetricType, CEP47Contract, CEP47Storage, Error, Key, Meta, TokenId, URef, WithStorage, U256, -}; -use casper_types::PublicKey; -use std::{ - collections::{hash_map::DefaultHasher, BTreeMap}, - hash::{Hash, Hasher}, - sync::Mutex, -}; - -struct TestStorage { - name: String, - symbol: String, - meta: Meta, - paused: bool, - total_supply: U256, - tokens: BTreeMap>, - token_metas: BTreeMap, - balances: BTreeMap, - belongs_to: BTreeMap, - urefs: BTreeMap, - token_id_generator: u32, -} - -impl TestStorage { - pub fn new() -> TestStorage { - TestStorage { - name: String::from("Casper Enhancement Proposal 47"), - symbol: String::from("CEP47"), - meta: meta::contract_info(), - paused: false, - total_supply: U256::from(0), - tokens: BTreeMap::new(), - balances: BTreeMap::new(), - belongs_to: BTreeMap::new(), - token_metas: BTreeMap::new(), - urefs: BTreeMap::new(), - token_id_generator: 1, - } - } -} - -impl CEP47Storage for TestStorage { - fn name(&self) -> String { - self.name.clone() - } - - fn symbol(&self) -> String { - self.symbol.clone() - } - - fn meta(&self) -> Meta { - self.meta.clone() - } - - fn balance_of(&self, owner: &Key) -> U256 { - let owner_balance = self.balances.get(owner); - owner_balance.cloned().unwrap_or_default() - } - - fn owner_of(&self, token_id: &TokenId) -> Option { - let owner = self.belongs_to.get(token_id); - owner.cloned() - } - - fn total_supply(&self) -> U256 { - self.total_supply - } - - fn token_meta(&self, token_id: &TokenId) -> Option { - let meta = self.token_metas.get(token_id); - meta.cloned() - } - - fn is_paused(&self) -> bool { - self.paused - } - - fn pause(&mut self) { - self.paused = true; - } - - fn unpause(&mut self) { - self.paused = false; - } - - fn mint_many(&mut self, recipient: &Key, token_ids: &Vec, token_metas: &Vec) { - let amount = token_ids.len(); - - // Update balance. - let recipient_balance = self.balances.get(recipient).copied().unwrap_or_default(); - let recipient_new_balance = recipient_balance + amount; - self.balances.insert(*recipient, recipient_new_balance); - - self.total_supply = self.total_supply + amount; - - // Mint tokens. - for (token_id, token_meta) in token_ids.iter().zip(token_metas) { - self.token_metas - .insert(token_id.clone(), token_meta.clone()); - self.belongs_to.insert(token_id.clone(), *recipient); - } - } - - fn transfer_many(&mut self, sender: &Key, recipient: &Key, token_ids: &Vec) { - let amount = token_ids.len(); - let sender_balance = self.balances.get(sender).copied().unwrap_or_default(); - let recipient_balance = self.balances.get(recipient).copied().unwrap_or_default(); - self.balances.insert(*sender, sender_balance - amount); - self.balances.insert(*recipient, recipient_balance + amount); - - for token_id in token_ids.iter() { - self.belongs_to.insert(token_id.clone(), *recipient); - } - } - - fn burn_many(&mut self, owner: &Key, token_ids: &Vec) { - let amount = token_ids.len(); - - // Update balance. - let recipient_balance = self.balances.get(owner).copied().unwrap_or_default(); - let recipient_new_balance = recipient_balance - amount; - self.balances.insert(*owner, recipient_new_balance); - - self.total_supply = self.total_supply - amount; - - for token_id in token_ids.iter() { - self.belongs_to.remove(token_id); - self.token_metas.remove(token_id); - } - } - - fn update_token_metadata(&mut self, token_id: &TokenId, meta: Meta) { - self.token_metas.insert(token_id.clone(), meta).unwrap(); - } - - fn gen_token_ids(&mut self, n: u32) -> Vec { - let mut tokens = Vec::new(); - for _ in 0..n { - let id = format!("token_{}", &self.token_id_generator); - tokens.push(id); - self.token_id_generator += 1; - } - tokens - } - - fn validate_token_ids(&self, token_ids: &Vec) -> bool { - for token_id in token_ids { - if self.owner_of(token_id).is_some() { - return false; - } - } - true - } - - fn emit(&mut self, _event: crate::events::CEP47Event) {} - - fn contact_package_hash(&self) -> casper_types::ContractPackageHash { - [1u8; 32].into() - } - - fn are_all_owner_tokens(&self, owner: &Key, token_ids: &Vec) -> bool { - for token_id in token_ids.iter() { - let token_owner = self.owner_of(token_id); - if let Some(token_owner) = token_owner { - if &token_owner != owner { - return false; - } - } - } - true - } -} - -struct TestContract { - storage: TestStorage, -} - -impl TestContract { - pub fn new() -> TestContract { - TestContract { - storage: TestStorage::new(), - } - } -} - -impl WithStorage for TestContract { - fn storage(&self) -> &TestStorage { - &self.storage - } - - fn storage_mut(&mut self) -> &mut TestStorage { - &mut self.storage - } -} - -impl CEP47Contract for TestContract {} - -mod meta { - use super::BTreeMap; - - pub fn contract_info() -> BTreeMap { - btreemap! { - "github".to_string() => "https://github.com/casper-ecosystem/casper-nft-cep47".to_string() - } - } - - pub fn apple() -> BTreeMap { - btreemap! { - "fruit".to_string() => "Apple".to_string(), - "size".to_string() => "A".to_string() - } - } - - pub fn orange() -> BTreeMap { - btreemap! { - "fruit".to_string() => "Orange".to_string(), - "size".to_string() => "B".to_string() - } - } - - pub fn banana() -> BTreeMap { - btreemap! { - "fruit".to_string() => "Banana".to_string(), - "size".to_string() => "B".to_string() - } - } -} - -#[test] -fn test_metadata() { - let contract = TestContract::new(); - assert_eq!( - contract.name(), - String::from("Casper Enhancement Proposal 47") - ); - assert_eq!(contract.symbol(), String::from("CEP47")); - assert_eq!(contract.meta(), meta::contract_info()); -} - -#[test] -fn test_mint_many() { - let mut contract = TestContract::new(); - let ali_pk = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); - let bob_pk = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); - let ali: Key = ali_pk.to_account_hash().into(); - let ali_first_token_id = "banana_01".to_string(); - let ali_second_token_id = "orange_01".to_string(); - let ali_token_ids = vec![ali_first_token_id.clone(), ali_second_token_id.clone()]; - - let bob: Key = bob_pk.to_account_hash().into(); - let bob_first_token_id = "banana_02".to_string(); - let bob_second_token_id = "apple_02".to_string(); - let bob_token_ids = vec![bob_first_token_id.clone(), bob_second_token_id.clone()]; - - assert_eq!(contract.total_supply(), U256::from(0)); - contract - .mint_many( - &ali, - Some(ali_token_ids), - vec![meta::banana(), meta::orange()], - ) - .unwrap(); - contract - .mint_many( - &bob, - Some(bob_token_ids), - vec![meta::banana(), meta::apple()], - ) - .unwrap(); - - // Check total balance. - assert_eq!(contract.total_supply(), U256::from(4)); - - // Check balances - assert_eq!(contract.balance_of(&ali), U256::from(2)); - assert_eq!(contract.balance_of(&bob), U256::from(2)); - - // Check ownership - assert_eq!(&contract.owner_of(&ali_first_token_id).unwrap(), &ali); - assert_eq!(&contract.owner_of(&ali_second_token_id).unwrap(), &ali); - assert_eq!(&contract.owner_of(&bob_first_token_id).unwrap(), &bob); - assert_eq!(&contract.owner_of(&bob_second_token_id).unwrap(), &bob); - - // Check metas. - assert_eq!( - contract.token_meta(&ali_first_token_id).unwrap(), - meta::banana() - ); - assert_eq!( - contract.token_meta(&ali_second_token_id).unwrap(), - meta::orange() - ); - assert_eq!( - contract.token_meta(&bob_first_token_id).unwrap(), - meta::banana() - ); - assert_eq!( - contract.token_meta(&bob_second_token_id).unwrap(), - meta::apple() - ); -} - -#[test] -fn test_mint_copies() { - let mut contract = TestContract::new(); - let ali_pk = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); - let ali: Key = ali_pk.to_account_hash().into(); - let token_ids: Vec = vec!["a", "b", "c", "d", "e", "f", "g"] - .into_iter() - .map(String::from) - .collect(); - - contract - .mint_copies(&ali, Some(token_ids.clone()), meta::apple(), 7) - .unwrap(); - - assert_eq!(contract.total_supply(), U256::from(7)); - assert_eq!(contract.balance_of(&ali), U256::from(7)); - - for token_id in &token_ids { - assert_eq!(contract.owner_of(token_id).unwrap(), ali); - assert_eq!(contract.token_meta(token_id).unwrap(), meta::apple()); - } -} - -#[test] -fn test_burn_many() { - let mut contract = TestContract::new(); - let ali_pk = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); - let ali: Key = ali_pk.to_account_hash().into(); - let tokens_to_burn = vec!["a".to_string(), "b".to_string()]; - let tokens_to_remain = vec!["c".to_string(), "d".to_string(), "e".to_string()]; - let token_ids: Vec = tokens_to_burn - .iter() - .cloned() - .chain(tokens_to_remain.iter().cloned()) - .collect(); - - contract - .mint_copies(&ali, Some(token_ids), meta::banana(), 5) - .unwrap(); - - contract.burn_many(&ali, tokens_to_burn.clone()).unwrap(); - - // Check balances - assert_eq!(contract.total_supply(), U256::from(3)); - assert_eq!(contract.balance_of(&ali), U256::from(3)); - - // Check burned tokens - for token_id in &tokens_to_burn { - assert!(contract.owner_of(token_id).is_none()); - assert!(contract.token_meta(token_id).is_none()); - } - - // Check rest of tokens. - for token_id in &tokens_to_remain { - assert_eq!(&contract.owner_of(token_id).unwrap(), &ali); - assert_eq!(&contract.token_meta(token_id).unwrap(), &meta::banana()); - } -} - -#[test] -fn test_burn_one() { - let mut contract = TestContract::new(); - let ali_pk = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); - let ali: Key = ali_pk.to_account_hash().into(); - let token_to_burn = "a".to_string(); - let tokens_to_remain = vec!["c".to_string(), "d".to_string(), "e".to_string()]; - let token_ids: Vec = vec![token_to_burn.clone()] - .iter() - .cloned() - .chain(tokens_to_remain.iter().cloned()) - .collect(); - - contract - .mint_copies(&ali, Some(token_ids), meta::banana(), 4) - .unwrap(); - - contract.burn_one(&ali, token_to_burn.clone()).unwrap(); - - // Check balances - assert_eq!(contract.total_supply(), U256::from(3)); - assert_eq!(contract.balance_of(&ali), U256::from(3)); - - // Check burned tokens - assert!(contract.owner_of(&token_to_burn).is_none()); - assert!(contract.token_meta(&token_to_burn).is_none()); - - // Check rest of tokens. - for token_id in &tokens_to_remain { - assert_eq!(&contract.owner_of(token_id).unwrap(), &ali); - assert_eq!(&contract.token_meta(token_id).unwrap(), &meta::banana()); - } -} -#[test] -fn test_transfer_token() { - let mut contract = TestContract::new(); - let ali_pk = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); - let bob_pk = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); - let ali: Key = ali_pk.to_account_hash().into(); - let bob: Key = bob_pk.to_account_hash().into(); - let token_id: TokenId = "apple".to_string(); - - contract - .mint_one(&ali, Some(token_id.clone()), meta::apple()) - .unwrap(); - - assert_eq!(contract.total_supply(), U256::from(1)); - assert_eq!(contract.balance_of(&ali), U256::from(1)); - assert_eq!(contract.balance_of(&bob), U256::from(0)); - - contract.transfer_token(&ali, &bob, &token_id).unwrap(); - - assert_eq!(contract.balance_of(&ali), U256::from(0)); - assert_eq!(contract.balance_of(&bob), U256::from(1)); - assert_eq!(contract.owner_of(&token_id).unwrap(), bob); -} - -#[test] -fn test_transfer_many_tokens() { - let mut contract = TestContract::new(); - let ali_pk = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); - let bob_pk = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); - let ali: Key = ali_pk.to_account_hash().into(); - let bob: Key = bob_pk.to_account_hash().into(); - let tokens_to_transfer = vec!["a".to_string(), "b".to_string()]; - let tokens_to_remain = vec!["c".to_string(), "d".to_string(), "e".to_string()]; - let token_ids: Vec = tokens_to_transfer - .iter() - .cloned() - .chain(tokens_to_remain.iter().cloned()) - .collect(); - - contract - .mint_copies(&ali, Some(token_ids), meta::banana(), 5) - .unwrap(); - - contract - .transfer_many_tokens(&ali, &bob, &tokens_to_transfer) - .unwrap(); - - assert_eq!(contract.balance_of(&ali), U256::from(3)); - assert_eq!(contract.balance_of(&bob), U256::from(2)); - assert_eq!(contract.total_supply(), U256::from(5)); - - // Check ali tokens. - for token_id in &tokens_to_remain { - assert_eq!(&contract.owner_of(token_id).unwrap(), &ali); - } - - // Check bob tokens. - for token_id in &tokens_to_transfer { - assert_eq!(&contract.owner_of(token_id).unwrap(), &bob); - } -} - -#[test] -fn test_update_metadata() { - let mut contract = TestContract::new(); - let ali_pk = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); - let ali: Key = ali_pk.to_account_hash().into(); - - let token_id = TokenId::from("new_token"); - let _: Result<(), Error> = contract.mint_one(&ali, Some(token_id.clone()), meta::apple()); - assert_eq!(meta::apple(), contract.token_meta(&token_id).unwrap()); - let _: Result<(), Error> = contract.update_token_metadata(token_id.clone(), meta::banana()); - assert_eq!(meta::banana(), contract.token_meta(&token_id).unwrap()); -} diff --git a/cep47-tests/src/cep47.rs b/cep47-tests/src/cep47.rs deleted file mode 100644 index 37fd06e..0000000 --- a/cep47-tests/src/cep47.rs +++ /dev/null @@ -1,338 +0,0 @@ -use std::collections::BTreeMap; - -use casper_engine_test_support::{Code, Hash, SessionBuilder, TestContext, TestContextBuilder}; -use casper_types::{ - account::AccountHash, bytesrepr::FromBytes, runtime_args, CLTyped, ContractPackageHash, - HashAddr, Key, PublicKey, RuntimeArgs, SecretKey, U256, U512, -}; - -pub mod token_cfg { - use super::Meta; - use maplit::btreemap; - - pub const NAME: &str = "DragonsNFT"; - pub const SYMBOL: &str = "DRAG"; - - pub fn contract_meta() -> Meta { - btreemap! { - "origin".to_string() => "fire".to_string() - } - } -} - -pub const CONTRACT_KEY: &str = "DragonsNFT_contract"; -pub const CONTRACT_HASH_KEY: &str = "DragonsNFT_contract_hash"; - -const BALANCES_DICT: &str = "balances"; -const TOKEN_OWNERS_DICT: &str = "owners"; -const METADATA_DICT: &str = "metadata"; - -pub struct CasperCEP47Contract { - pub context: TestContext, - pub hash: Hash, - pub admin: AccountHash, - pub ali: AccountHash, - pub bob: AccountHash, -} - -pub type TokenId = String; -pub type Meta = BTreeMap; - -impl CasperCEP47Contract { - pub fn deploy() -> Self { - let admin_secret = SecretKey::ed25519_from_bytes([1u8; 32]).unwrap(); - let ali_secret = SecretKey::ed25519_from_bytes([3u8; 32]).unwrap(); - let bob_secret = SecretKey::ed25519_from_bytes([5u8; 32]).unwrap(); - - let admin: PublicKey = (&admin_secret).into(); - let ali: PublicKey = (&ali_secret).into(); - let bob: PublicKey = (&bob_secret).into(); - let mut context = TestContextBuilder::new() - .with_public_key(admin.clone(), U512::from(500_000_000_000_000_000u64)) - .with_public_key(ali.clone(), U512::from(500_000_000_000_000_000u64)) - .with_public_key(bob.clone(), U512::from(500_000_000_000_000_000u64)) - .build(); - let session_code = Code::from("dragons-nft.wasm"); - let session_args = runtime_args! { - "token_name" => token_cfg::NAME, - "token_symbol" => token_cfg::SYMBOL, - "token_meta" => token_cfg::contract_meta() - }; - let session = SessionBuilder::new(session_code, session_args) - .with_address(admin.to_account_hash()) - .with_authorization_keys(&[admin.to_account_hash()]) - .build(); - context.run(session); - let hash = context - .query(admin.to_account_hash(), &[CONTRACT_HASH_KEY.to_string()]) - .unwrap() - .into_t() - .unwrap(); - - Self { - context, - hash, - admin: admin.to_account_hash(), - ali: ali.to_account_hash(), - bob: bob.to_account_hash(), - } - } - - pub fn deploy_secondary_contract(&mut self, wasm: &str, args: RuntimeArgs) -> (Hash, HashAddr) { - let session_code = Code::from(wasm); - let session = SessionBuilder::new(session_code, args) - .with_address(self.admin) - .with_authorization_keys(&[self.admin]) - .build(); - self.context.run(session); - let hash = self - .context - .query(self.admin, &["owning_contract_hash".to_string()]) - .unwrap() - .into_t() - .unwrap(); - let package = self - .context - .query(self.admin, &["owning_contract_pack".to_string()]) - .unwrap() - .into_t() - .unwrap(); - (hash, package) - } - - fn call(&mut self, sender: &AccountHash, method: &str, args: RuntimeArgs) { - let account = *sender; - let code = Code::Hash(self.hash, method.to_string()); - let session = SessionBuilder::new(code, args) - .with_address(account) - .with_authorization_keys(&[account]) - .build(); - self.context.run(session); - } - - fn query_contract(&self, name: &str) -> Option { - match self - .context - .query(self.admin, &[CONTRACT_KEY.to_string(), name.to_string()]) - { - Err(_) => None, - Ok(maybe_value) => { - let value = maybe_value - .into_t() - .unwrap_or_else(|_| panic!("{} is not expected type.", name)); - Some(value) - } - } - } - - fn query_dictionary_value( - &self, - dict_name: &str, - key: String, - ) -> Option { - match self.context.query_dictionary_item( - Key::Hash(self.hash), - Some(dict_name.to_string()), - key, - ) { - Err(_) => None, - Ok(maybe_value) => { - let value: Option = maybe_value - .into_t() - .unwrap_or_else(|_| panic!("is not expected type.")); - value - } - } - } - - pub fn name(&self) -> String { - self.query_contract("name").unwrap() - } - - pub fn symbol(&self) -> String { - self.query_contract("symbol").unwrap() - } - - pub fn meta(&self) -> Meta { - self.query_contract("meta").unwrap() - } - - pub fn total_supply(&self) -> U256 { - self.query_contract("total_supply").unwrap() - } - - pub fn owner_of(&self, token_id: &TokenId) -> Option { - self.query_dictionary_value::(TOKEN_OWNERS_DICT, token_id.clone()) - } - - pub fn balance_of(&self, owner: &Key) -> U256 { - let value: Option = - self.query_dictionary_value(BALANCES_DICT, Self::key_to_str(owner)); - value.unwrap_or_default() - } - - pub fn token_meta(&self, token_id: &TokenId) -> Option { - self.query_dictionary_value(METADATA_DICT, token_id.clone()) - } - - pub fn mint_one( - &mut self, - recipient: &Key, - token_id: Option<&TokenId>, - token_meta: &Meta, - sender: &AccountHash, - ) { - self.call( - sender, - "mint_one", - runtime_args! { - "recipient" => *recipient, - "token_id" => token_id.cloned(), - "token_meta" => token_meta.clone() - }, - ); - } - - pub fn mint_copies( - &mut self, - recipient: &Key, - token_ids: Option<&Vec>, - token_meta: &Meta, - count: u32, - sender: &AccountHash, - ) { - self.call( - sender, - "mint_copies", - runtime_args! { - "recipient" => *recipient, - "token_ids" => token_ids.cloned(), - "token_meta" => token_meta.clone(), - "count" => count - }, - ); - } - - pub fn mint_many( - &mut self, - recipient: &Key, - token_ids: Option<&Vec>, - token_metas: &Vec, - sender: &AccountHash, - ) { - self.call( - sender, - "mint_many", - runtime_args! { - "recipient" => *recipient, - "token_ids" => token_ids.cloned(), - "token_metas" => token_metas.clone(), - }, - ); - } - - pub fn burn_many(&mut self, owner: &Key, token_ids: &Vec, sender: &AccountHash) { - self.call( - sender, - "burn_many", - runtime_args! { - "owner" => *owner, - "token_ids" => token_ids.clone() - }, - ); - } - - pub fn burn_one(&mut self, owner: &Key, token_id: &TokenId, sender: &AccountHash) { - self.call( - sender, - "burn_one", - runtime_args! { - "owner" => *owner, - "token_id" => token_id.clone() - }, - ); - } - - pub fn transfer_token(&mut self, recipient: &Key, token_id: &TokenId, sender: &AccountHash) { - self.call( - sender, - "transfer_token", - runtime_args! { - "recipient" => *recipient, - "token_id" => token_id.clone() - }, - ); - } - - pub fn transfer_token_from_contract( - &mut self, - contract_manager: &AccountHash, - contract_hash: &Hash, - recipient: &Key, - token_id: &TokenId, - ) { - let code = Code::Hash(*contract_hash, "transfer_token".to_string()); - let nft_package: ContractPackageHash = - self.query_contract("contract_package_hash").unwrap(); - let session = SessionBuilder::new( - code, - runtime_args! { - "nft" => nft_package, - "sender" => Key::Hash(*contract_hash), - "recipient" => *recipient, - "token_id" => token_id.clone() - }, - ) - .with_address(*contract_manager) - .with_authorization_keys(&[*contract_manager]) - .build(); - self.context.run(session); - } - - pub fn transfer_many_tokens( - &mut self, - recipient: &Key, - token_ids: &Vec, - sender: &AccountHash, - ) { - self.call( - sender, - "transfer_many_tokens", - runtime_args! { - "recipient" => *recipient, - "token_ids" => token_ids.clone() - }, - ); - } - - pub fn update_token_metadata(&mut self, token_id: &TokenId, meta: &Meta, sender: &AccountHash) { - self.call( - sender, - "update_token_metadata", - runtime_args! { - "token_id" => token_id.clone(), - "token_meta" => meta.clone() - }, - ); - } - - pub fn pause(&mut self, sender: &AccountHash) { - self.call(sender, "pause", runtime_args! {}); - } - - pub fn unpause(&mut self, sender: &AccountHash) { - self.call(sender, "unpause", runtime_args! {}); - } - - pub fn is_paused(&mut self) -> bool { - self.query_contract("paused").unwrap() - } - - fn key_to_str(key: &Key) -> String { - match key { - Key::Account(account) => account.to_string(), - Key::Hash(package) => hex::encode(package), - _ => panic!(), - } - } -} diff --git a/cep47-tests/src/contract_tests.rs b/cep47-tests/src/contract_tests.rs deleted file mode 100644 index ba2cd88..0000000 --- a/cep47-tests/src/contract_tests.rs +++ /dev/null @@ -1,400 +0,0 @@ -use crate::cep47::{token_cfg, CasperCEP47Contract, Meta, TokenId}; -use casper_types::{runtime_args, Key, RuntimeArgs, U256}; - -mod meta { - use super::Meta; - use maplit::btreemap; - - pub fn red_dragon() -> Meta { - btreemap! { - "color".to_string() => "red".to_string() - } - } - - pub fn blue_dragon() -> Meta { - btreemap! { - "color".to_string() => "blue".to_string() - } - } - - pub fn black_dragon() -> Meta { - btreemap! { - "color".to_string() => "black".to_string() - } - } - - pub fn gold_dragon() -> Meta { - btreemap! { - "color".to_string() => "gold".to_string() - } - } -} - -#[test] -fn test_deploy() { - let contract = CasperCEP47Contract::deploy(); - - assert_eq!(contract.name(), token_cfg::NAME); - assert_eq!(contract.symbol(), token_cfg::SYMBOL); - assert_eq!(contract.meta(), token_cfg::contract_meta()); - assert_eq!(contract.total_supply(), U256::zero()); -} - -#[test] -fn test_token_meta() { - let mut contract = CasperCEP47Contract::deploy(); - let token_id = String::from("custom_token_id"); - let token_meta = meta::red_dragon(); - let ali = Key::Account(contract.ali); - - contract.mint_one(&ali, Some(&token_id), &token_meta, &contract.admin.clone()); - - assert_eq!(contract.token_meta(&token_id).unwrap(), token_meta); - assert_eq!(contract.owner_of(&token_id).unwrap(), ali); -} - -#[test] -fn test_mint_one_with_random_token_id() { - let mut contract = CasperCEP47Contract::deploy(); - let token_meta = meta::red_dragon(); - let ali = Key::Account(contract.ali); - - contract.mint_one(&ali, None, &token_meta, &contract.admin.clone()); - - assert_eq!(contract.total_supply(), U256::one()); - assert_eq!(contract.balance_of(&ali), U256::one()); -} - -#[test] -fn test_mint_one_with_set_token_id() { - let mut contract = CasperCEP47Contract::deploy(); - let token_id = TokenId::from("123456"); - let token_meta = meta::red_dragon(); - let ali = Key::Account(contract.ali); - - contract.mint_one(&ali, Some(&token_id), &token_meta, &contract.admin.clone()); - - assert_eq!(contract.total_supply(), U256::one()); - assert_eq!(contract.balance_of(&ali), U256::one()); - assert_eq!(contract.owner_of(&token_id).unwrap(), ali); -} - -#[test] -#[should_panic] -fn test_mint_one_with_not_unique_token_id() { - let mut contract = CasperCEP47Contract::deploy(); - let token_id = TokenId::from("123456"); - let token_meta = meta::red_dragon(); - contract.mint_one( - &Key::Account(contract.ali), - Some(&token_id), - &token_meta, - &contract.admin.clone(), - ); - contract.mint_one( - &Key::Account(contract.ali), - Some(&token_id), - &token_meta, - &contract.admin.clone(), - ); -} - -#[test] -fn test_mint_copies() { - let mut contract = CasperCEP47Contract::deploy(); - let token_meta = meta::gold_dragon(); - let token_ids = vec![TokenId::from("a"), TokenId::from("b")]; - let ali = Key::Account(contract.ali); - contract.mint_copies( - &ali, - Some(&token_ids), - &token_meta, - 2, - &contract.admin.clone(), - ); - - assert_eq!(contract.total_supply(), U256::from(2)); - assert_eq!(contract.balance_of(&ali), U256::from(2)); - - for token_id in token_ids { - assert_eq!(&contract.owner_of(&token_id).unwrap(), &ali); - assert_eq!(&contract.token_meta(&token_id).unwrap(), &token_meta); - } -} - -#[test] -fn test_mint_many() { - let mut contract = CasperCEP47Contract::deploy(); - let token_metas = vec![meta::gold_dragon(), meta::black_dragon()]; - let token_ids = vec![TokenId::from("a"), TokenId::from("b")]; - let ali = Key::Account(contract.ali); - contract.mint_many( - &ali, - Some(&token_ids), - &token_metas, - &contract.admin.clone(), - ); - - assert_eq!(contract.total_supply(), U256::from(2)); - assert_eq!(contract.balance_of(&ali), U256::from(2)); - - for (token_id, token_meta) in token_ids.iter().zip(token_metas) { - assert_eq!(&contract.owner_of(token_id).unwrap(), &ali); - assert_eq!(&contract.token_meta(token_id).unwrap(), &token_meta); - } -} -#[test] -fn test_burn_many() { - let mut contract = CasperCEP47Contract::deploy(); - let tokens_to_burn = vec![TokenId::from("a"), TokenId::from("b")]; - let tokens_to_keep = vec![TokenId::from("c"), TokenId::from("d"), TokenId::from("e")]; - let token_ids = tokens_to_burn - .iter() - .cloned() - .chain(tokens_to_keep.iter().cloned()) - .collect(); - let token_meta = meta::black_dragon(); - let ali = Key::Account(contract.ali); - - contract.mint_copies( - &ali, - Some(&token_ids), - &token_meta, - 5, - &contract.admin.clone(), - ); - - contract.burn_many(&ali, &tokens_to_burn, &contract.admin.clone()); - - assert_eq!(contract.total_supply(), U256::from(3)); - assert_eq!(contract.balance_of(&ali), U256::from(3)); - - for token_id in tokens_to_burn { - assert!(&contract.owner_of(&token_id).is_none()); - assert!(&contract.token_meta(&token_id).is_none()); - } - - for token_id in tokens_to_keep { - assert_eq!(&contract.owner_of(&token_id).unwrap(), &ali); - assert_eq!(&contract.token_meta(&token_id).unwrap(), &token_meta); - } -} - -#[test] -fn test_burn_one() { - let mut contract = CasperCEP47Contract::deploy(); - let token_to_burn = TokenId::from("a"); - let tokens_to_keep = vec![TokenId::from("c"), TokenId::from("d"), TokenId::from("e")]; - let token_ids = vec![token_to_burn.clone()] - .into_iter() - .chain(tokens_to_keep.iter().cloned()) - .collect(); - let token_meta = meta::black_dragon(); - let ali = Key::Account(contract.ali); - - contract.mint_copies( - &ali, - Some(&token_ids), - &token_meta, - 4, - &contract.admin.clone(), - ); - - contract.burn_one(&ali, &token_to_burn, &contract.admin.clone()); - - assert_eq!(contract.total_supply(), U256::from(3)); - assert_eq!(contract.balance_of(&ali), U256::from(3)); - - assert!(&contract.owner_of(&token_to_burn).is_none()); - assert!(&contract.token_meta(&token_to_burn).is_none()); - - for token_id in tokens_to_keep { - assert_eq!(&contract.owner_of(&token_id).unwrap(), &ali); - assert_eq!(&contract.token_meta(&token_id).unwrap(), &token_meta); - } -} - -#[test] -fn test_transfer_token() { - let mut contract = CasperCEP47Contract::deploy(); - let token_to_transfer = TokenId::from("a"); - let tokens_to_keep = vec![TokenId::from("c"), TokenId::from("d"), TokenId::from("e")]; - let token_ids = vec![token_to_transfer.clone()] - .into_iter() - .chain(tokens_to_keep.iter().cloned()) - .collect(); - let token_meta = meta::black_dragon(); - let ali = Key::Account(contract.ali); - let bob = Key::Account(contract.bob); - - contract.mint_copies( - &ali, - Some(&token_ids), - &token_meta, - 4, - &contract.admin.clone(), - ); - - contract.transfer_token(&bob, &token_to_transfer, &contract.ali.clone()); - - assert_eq!(contract.total_supply(), U256::from(4)); - assert_eq!(contract.balance_of(&ali), U256::from(3)); - assert_eq!(contract.balance_of(&bob), U256::from(1)); - assert_eq!(&contract.owner_of(&token_to_transfer).unwrap(), &bob); - - for token_id in tokens_to_keep { - assert_eq!(&contract.owner_of(&token_id).unwrap(), &ali); - } -} - -#[test] -fn test_transfer_many_tokens() { - let mut contract = CasperCEP47Contract::deploy(); - let tokens_to_transfer = vec![TokenId::from("a"), TokenId::from("b")]; - let tokens_to_keep = vec![TokenId::from("c"), TokenId::from("d"), TokenId::from("e")]; - let token_ids = tokens_to_transfer - .iter() - .cloned() - .chain(tokens_to_keep.iter().cloned()) - .collect(); - let token_meta = meta::black_dragon(); - let ali = Key::Account(contract.ali); - let bob = Key::Account(contract.bob); - - contract.mint_copies( - &ali, - Some(&token_ids), - &token_meta, - 5, - &contract.admin.clone(), - ); - - contract.transfer_many_tokens(&bob, &tokens_to_transfer, &contract.ali.clone()); - - assert_eq!(contract.total_supply(), U256::from(5)); - assert_eq!(contract.balance_of(&ali), U256::from(3)); - assert_eq!(contract.balance_of(&bob), U256::from(2)); - - for token_id in tokens_to_keep { - assert_eq!(&contract.owner_of(&token_id).unwrap(), &ali); - } - - for token_id in tokens_to_transfer { - assert_eq!(&contract.owner_of(&token_id).unwrap(), &bob); - } -} - -#[test] -fn test_token_metadata_update() { - let mut contract = CasperCEP47Contract::deploy(); - let token_id = TokenId::from("123456"); - let token_meta = meta::red_dragon(); - contract.mint_one( - &Key::Account(contract.ali), - Some(&token_id), - &token_meta, - &contract.admin.clone(), - ); - - contract.update_token_metadata(&token_id, &meta::blue_dragon(), &contract.admin.clone()); - assert_eq!(contract.token_meta(&token_id).unwrap(), meta::blue_dragon()); -} - -#[test] -fn test_contract_owning_token() { - let mut contract = CasperCEP47Contract::deploy(); - let (contract_hash, package) = - contract.deploy_secondary_contract("owning-contract.wasm", runtime_args! {}); - let token_id = TokenId::from("123456"); - let token_meta = meta::red_dragon(); - let contract_address = Key::Hash(package); - let ali = Key::Account(contract.ali); - - contract.mint_one( - &contract_address, - Some(&token_id), - &token_meta, - &contract.admin.clone(), - ); - - assert_eq!(contract.total_supply(), U256::from(1)); - assert_eq!(contract.balance_of(&contract_address), U256::from(1)); - assert_eq!(&contract.owner_of(&token_id).unwrap(), &contract_address); - - contract.transfer_token_from_contract(&contract.admin.clone(), &contract_hash, &ali, &token_id); - - assert_eq!(contract.balance_of(&contract_address), U256::from(0)); - assert_eq!(contract.balance_of(&ali), U256::from(1)); - assert_eq!(&contract.owner_of(&token_id).unwrap(), &ali); -} - -#[test] -#[should_panic = "ApiError::User(1)"] -fn test_transfer_when_paused() { - let mut contract = CasperCEP47Contract::deploy(); - let token_id = TokenId::from("123456"); - let ali = Key::Account(contract.ali); - let bob = Key::Account(contract.bob); - - contract.mint_one( - &ali, - Some(&token_id), - &meta::black_dragon(), - &contract.admin.clone(), - ); - contract.pause(&contract.admin.clone()); - - // Test panics here, since contract is paused and a generic user is trying to call a non-admin function - contract.transfer_token(&bob, &token_id, &contract.ali.clone()); -} -#[test] -fn test_pausing_and_unpausing_contract() { - let mut contract = CasperCEP47Contract::deploy(); - let token_id = TokenId::from("123456"); - let ali = Key::Account(contract.ali); - let bob = Key::Account(contract.bob); - let admin = contract.admin; - - contract.pause(&admin); - contract.mint_one(&ali, Some(&token_id), &meta::black_dragon(), &admin); - - assert_eq!(contract.balance_of(&ali), U256::from(1)); - - // admin functions still work even while paused - contract.burn_one(&ali, &token_id, &admin); - contract.mint_one(&bob, Some(&token_id), &meta::black_dragon(), &admin); - - assert_eq!(contract.balance_of(&ali), U256::from(0)); - assert_eq!(contract.balance_of(&bob), U256::from(1)); - - // Transfer works after unpausing. - contract.unpause(&admin); - contract.transfer_token(&ali, &token_id, &contract.bob.clone()); -} - -#[test] -#[should_panic = "InvalidContext"] -fn test_pausing_contract_unauthorized() { - // generic user cannot pause the contract - let mut contract = CasperCEP47Contract::deploy(); - contract.pause(&contract.ali.clone()); -} - -#[test] -#[should_panic = "InvalidContext"] -fn test_unpausing_contract_unauthorized() { - // admin can pause the contract, but generic user cannot unpause - let mut contract = CasperCEP47Contract::deploy(); - contract.pause(&contract.admin.clone()); - contract.unpause(&contract.ali.clone()); -} - -#[test] -fn test_paused_field() { - let mut contract = CasperCEP47Contract::deploy(); - assert!(!contract.is_paused()); - contract.pause(&contract.admin.clone()); - assert!(contract.is_paused()); - contract.unpause(&contract.admin.clone()); - assert!(!contract.is_paused()); -} diff --git a/cep47/src/cep47_storage.rs b/cep47/src/cep47_storage.rs deleted file mode 100644 index 39f7b9d..0000000 --- a/cep47/src/cep47_storage.rs +++ /dev/null @@ -1,178 +0,0 @@ -use casper_contract::{contract_api::runtime, unwrap_or_revert::UnwrapOrRevert}; -use casper_types::{bytesrepr::ToBytes, ApiError, Key, U256}; -use cep47_logic::{CEP47Storage, Meta, TokenId}; - -use crate::data::{self, Balances, Metadata, Owners}; - -#[derive(Default)] -pub struct CasperCEP47Storage {} -impl CasperCEP47Storage { - pub fn new() -> CasperCEP47Storage { - CasperCEP47Storage {} - } -} - -impl CEP47Storage for CasperCEP47Storage { - fn name(&self) -> String { - data::name() - } - - fn symbol(&self) -> String { - data::symbol() - } - - fn meta(&self) -> Meta { - data::meta() - } - - fn total_supply(&self) -> U256 { - data::total_supply() - } - - fn balance_of(&self, owner: &Key) -> U256 { - Balances::instance().get(owner) - } - - fn owner_of(&self, token_id: &TokenId) -> Option { - Owners::instance().get(token_id) - } - - fn token_meta(&self, token_id: &TokenId) -> Option { - Metadata::instance().get(token_id) - } - - fn is_paused(&self) -> bool { - data::is_paused() - } - - fn pause(&mut self) { - data::pause(); - } - - fn unpause(&mut self) { - data::unpause(); - } - - fn mint_many(&mut self, recipient: &Key, token_ids: &Vec, token_metas: &Vec) { - // Prepare dictionaries. - let owners_dict = Owners::instance(); - let balances_dict = Balances::instance(); - let metadata_dict = Metadata::instance(); - - // Create new tokens. - for (token_id, token_meta) in token_ids.iter().zip(token_metas) { - // Set metadata. - metadata_dict.set(token_id, token_meta.clone()); - - // Set token owner. - owners_dict.set(token_id, *recipient); - } - - // Update recipient's balance. - let new_tokens_count: U256 = token_ids.len().into(); - let prev_balance = balances_dict.get(recipient); - let new_balance = prev_balance + new_tokens_count; - balances_dict.set(recipient, new_balance); - - // Update total supply. - let new_total_supply = data::total_supply() + new_tokens_count; - data::update_total_supply(new_total_supply); - } - - fn transfer_many(&mut self, sender: &Key, recipient: &Key, token_ids: &Vec) { - // Prepare dictionaries. - let owners_dict = Owners::instance(); - let balances_dict = Balances::instance(); - - // Update ownerships. - for token_id in token_ids { - owners_dict.set(token_id, *recipient); - } - - // Update balances. - let amount = token_ids.len(); - let sender_balance = balances_dict.get(sender); - let recipient_balance = balances_dict.get(recipient); - balances_dict.set(sender, sender_balance - amount); - balances_dict.set(recipient, recipient_balance + amount); - } - - fn burn_many(&mut self, owner: &Key, token_ids: &Vec) { - // Prepare dictionaries. - let owners_dict = Owners::instance(); - let balances_dict = Balances::instance(); - let metadata_dict = Metadata::instance(); - - // Remove tokens. - for token_id in token_ids { - // Remove meta. - metadata_dict.remove(token_id); - - // Remove ownership. - owners_dict.remove(token_id); - } - - // Decrement owner's balance. - let amount: U256 = token_ids.len().into(); - let prev_balance = balances_dict.get(owner); - let new_balance = prev_balance - amount; - balances_dict.set(owner, new_balance); - - // Decrement total supply. - let new_total_supply = data::total_supply() - amount; - data::update_total_supply(new_total_supply); - } - - fn update_token_metadata(&mut self, token_id: &TokenId, meta: Meta) { - let metadata_dict = Metadata::instance(); - let current_meta = metadata_dict.get(token_id); - match current_meta { - None => runtime::revert(ApiError::None), - Some(_) => metadata_dict.set(token_id, meta), - }; - } - - fn gen_token_ids(&mut self, n: u32) -> Vec { - let block_time = runtime::get_blocktime(); - let mut token_ids = Vec::new(); - let nonce = data::get_nonce(); - for i in nonce..nonce + n { - let mut bytes: Vec = block_time.to_bytes().unwrap_or_revert(); - bytes.append(&mut i.to_bytes().unwrap_or_revert()); - let hash = runtime::blake2b(bytes); - token_ids.push(hex::encode(hash)); - } - data::set_nonce(nonce + n); - token_ids - } - - fn validate_token_ids(&self, token_ids: &Vec) -> bool { - for token_id in token_ids { - if self.owner_of(token_id).is_some() { - return false; - } - } - true - } - - fn emit(&mut self, event: cep47_logic::events::CEP47Event) { - data::emit(&event) - } - - fn contact_package_hash(&self) -> casper_types::ContractPackageHash { - data::contract_package_hash() - } - - fn are_all_owner_tokens(&self, owner: &Key, token_ids: &Vec) -> bool { - let owners_dict = Owners::instance(); - for token_id in token_ids.iter() { - let token_owner = owners_dict.get(token_id); - if let Some(token_owner) = token_owner { - if &token_owner != owner { - return false; - } - } - } - true - } -} diff --git a/cep47/src/data.rs b/cep47/src/data.rs index 2e27cbb..24b9850 100644 --- a/cep47/src/data.rs +++ b/cep47/src/data.rs @@ -253,7 +253,7 @@ pub fn contract_package_hash() -> ContractPackageHash { get_key(CONTRACT_PACKAGE_HASH).unwrap_or_revert() } -pub fn emit(cep47_event: &CEP47Event) { +pub fn emit(event: &CEP47Event) { let mut events = Vec::new(); let package = contract_package_hash(); match event { diff --git a/cep47/src/entrypoints.rs b/cep47/src/entrypoints.rs deleted file mode 100644 index d427821..0000000 --- a/cep47/src/entrypoints.rs +++ /dev/null @@ -1,173 +0,0 @@ -use std::collections::BTreeSet; - -use casper_contract::{ - contract_api::{runtime, storage}, - unwrap_or_revert::UnwrapOrRevert, -}; -use casper_types::{ - CLType, CLTyped, ContractPackageHash, EntryPoint, EntryPointAccess, EntryPointType, - EntryPoints, Key, Parameter, -}; -use cep47_logic::{Meta, TokenId}; - -pub fn get_entrypoints(package_hash: Option) -> EntryPoints { - let secure = if let Some(contract_package_hash) = package_hash { - let deployer_group = storage::create_contract_user_group( - contract_package_hash, - "deployer", - 1, - BTreeSet::default(), - ) - .unwrap_or_revert(); - runtime::put_key("deployer_group_access", Key::URef(deployer_group[0])); - true - } else { - false - }; - - let mut entry_points = EntryPoints::new(); - entry_points.add_entry_point(endpoint("name", vec![], CLType::String, None)); - entry_points.add_entry_point(endpoint("symbol", vec![], CLType::String, None)); - entry_points.add_entry_point(endpoint("meta", vec![], Meta::cl_type(), None)); - entry_points.add_entry_point(endpoint("total_supply", vec![], CLType::U256, None)); - entry_points.add_entry_point(endpoint("is_paused", vec![], CLType::Bool, None)); - entry_points.add_entry_point(endpoint( - "pause", - vec![], - CLType::Unit, - if secure { Some("deployer") } else { None }, - )); - entry_points.add_entry_point(endpoint( - "unpause", - vec![], - CLType::Unit, - if secure { Some("deployer") } else { None }, - )); - entry_points.add_entry_point(endpoint( - "balance_of", - vec![Parameter::new("account", CLType::Key)], - CLType::U256, - None, - )); - entry_points.add_entry_point(endpoint( - "owner_of", - vec![Parameter::new("token_id", TokenId::cl_type())], - CLType::Option(Box::new(CLType::Key)), - None, - )); - entry_points.add_entry_point(endpoint( - "token_meta", - vec![Parameter::new("token_id", TokenId::cl_type())], - CLType::Option(Box::new(CLType::String)), - None, - )); - entry_points.add_entry_point(endpoint( - "total_supply", - vec![Parameter::new("owner", CLType::Key)], - CLType::List(Box::new(CLType::String)), - None, - )); - entry_points.add_entry_point(endpoint( - "mint_one", - vec![ - Parameter::new("recipient", CLType::Key), - Parameter::new("token_ids", CLType::Option(Box::new(TokenId::cl_type()))), - Parameter::new("token_meta", Meta::cl_type()), - ], - CLType::Unit, - if secure { Some("deployer") } else { None }, - )); - entry_points.add_entry_point(endpoint( - "mint_many", - vec![ - Parameter::new("recipient", CLType::Key), - Parameter::new( - "token_ids", - CLType::Option(Box::new(CLType::List(Box::new(TokenId::cl_type())))), - ), - Parameter::new("token_metas", CLType::List(Box::new(Meta::cl_type()))), - ], - CLType::Unit, - if secure { Some("deployer") } else { None }, - )); - entry_points.add_entry_point(endpoint( - "mint_copies", - vec![ - Parameter::new("recipient", CLType::Key), - Parameter::new( - "token_ids", - CLType::Option(Box::new(CLType::List(Box::new(TokenId::cl_type())))), - ), - Parameter::new("token_meta", Meta::cl_type()), - Parameter::new("count", CLType::U32), - ], - CLType::Unit, - if secure { Some("deployer") } else { None }, - )); - entry_points.add_entry_point(endpoint( - "update_token_metadata", - vec![ - Parameter::new("token_id", TokenId::cl_type()), - Parameter::new("meta", Meta::cl_type()), - ], - CLType::Unit, - if secure { Some("deployer") } else { None }, - )); - entry_points.add_entry_point(endpoint( - "burn_one", - vec![ - Parameter::new("owner", CLType::Key), - Parameter::new("token_id", TokenId::cl_type()), - ], - CLType::Unit, - if secure { Some("deployer") } else { None }, - )); - entry_points.add_entry_point(endpoint( - "burn_many", - vec![ - Parameter::new("owner", CLType::Key), - Parameter::new("token_ids", CLType::List(Box::new(TokenId::cl_type()))), - ], - CLType::Unit, - if secure { Some("deployer") } else { None }, - )); - entry_points.add_entry_point(endpoint( - "transfer_token", - vec![ - Parameter::new("sender", CLType::Key), - Parameter::new("recipient", CLType::Key), - Parameter::new("token_id", TokenId::cl_type()), - ], - CLType::Unit, - None, - )); - entry_points.add_entry_point(endpoint( - "transfer_many_tokens", - vec![ - Parameter::new("sender", CLType::Key), - Parameter::new("recipient", CLType::Key), - Parameter::new("token_ids", CLType::List(Box::new(TokenId::cl_type()))), - ], - CLType::Unit, - None, - )); - entry_points -} - -pub fn endpoint( - name: &str, - param: Vec, - ret: CLType, - access: Option<&str>, -) -> EntryPoint { - EntryPoint::new( - String::from(name), - param, - ret, - match access { - None => EntryPointAccess::Public, - Some(access_key) => EntryPointAccess::groups(&[access_key]), - }, - EntryPointType::Contract, - ) -} diff --git a/cep47/src/event.rs b/cep47/src/event.rs index aaf64cd..a8cfa53 100644 --- a/cep47/src/event.rs +++ b/cep47/src/event.rs @@ -26,25 +26,3 @@ pub enum CEP47Event { token_id: TokenId, }, } - -impl CEP47Event { - pub fn type_name(&self) -> String { - match self { - CEP47Event::MetadataUpdate { token_id: _ } => "cep47_metadata_update", - CEP47Event::Transfer { - sender: _, - recipient: _, - token_ids: _, - } => "cep47_transfer_token", - CEP47Event::Mint { - recipient: _, - token_ids: _, - } => "cep47_mint_one", - CEP47Event::Burn { - owner: _, - token_ids: _, - } => "cep47_burn_one", - } - .to_string() - } -} diff --git a/test-contracts/Cargo.toml b/test-contracts/Cargo.toml deleted file mode 100644 index e7bcd67..0000000 --- a/test-contracts/Cargo.toml +++ /dev/null @@ -1,28 +0,0 @@ -[package] -name = "test-contracts" -version = "0.1.0" -authors = ["astro019 "] -edition = "2018" - -[dependencies] -casper-contract = "1.3.1" -casper-types = "1.3.1" -cep47 = { path="../cep47"} - -[[bin]] -name = "dragons-nft" -path = "src/dragons-nft.rs" -bench = false -doctest = false -test = false - -[[bin]] -name = "owning-contract" -path = "src/owning_contract.rs" -bench = false -doctest = false -test = false - -[features] -default = ["casper-contract/std", "casper-types/std"] - diff --git a/test-contracts/src/dragons-nft.rs b/test-contracts/src/dragons-nft.rs deleted file mode 100644 index 07eb5ba..0000000 --- a/test-contracts/src/dragons-nft.rs +++ /dev/null @@ -1,29 +0,0 @@ -#![no_main] - -use casper_contract::contract_api::runtime::{self, get_named_arg}; -use casper_contract::contract_api::storage::create_contract_package_at_hash; - -#[no_mangle] -pub extern "C" fn call() { - let token_name: String = get_named_arg("token_name"); - let token_symbol: String = get_named_arg("token_symbol"); - let token_meta: cep47::Meta = get_named_arg("token_meta"); - - let (contract_package_hash, access_token) = create_contract_package_at_hash(); - let entry_points = cep47::get_entrypoints(Some(contract_package_hash)); - - cep47::deploy( - token_name.clone(), - token_symbol, - token_meta, - entry_points, - contract_package_hash, - false, - ); - - runtime::put_key( - &format!("{}_package_hash", token_name), - contract_package_hash.into(), - ); - runtime::put_key(&format!("{}_access_token", token_name), access_token.into()); -} diff --git a/test-contracts/src/owning_contract.rs b/test-contracts/src/owning_contract.rs deleted file mode 100644 index f2a48e7..0000000 --- a/test-contracts/src/owning_contract.rs +++ /dev/null @@ -1,53 +0,0 @@ -#![no_main] - -use casper_contract::contract_api::{ - runtime::{self, call_versioned_contract}, - storage, -}; -use casper_types::{ - contracts::NamedKeys, runtime_args, CLType, EntryPoint, EntryPointAccess, EntryPoints, Key, - RuntimeArgs, -}; - -#[no_mangle] -pub extern "C" fn transfer_token() { - call_versioned_contract( - runtime::get_named_arg("nft"), - None, - "transfer_token", - runtime_args! { - "sender" => runtime::get_named_arg::("sender"), - "recipient"=>runtime::get_named_arg::("recipient"), - "token_id"=>runtime::get_named_arg::("token_id") - }, - ) -} - -#[no_mangle] -pub extern "C" fn call() { - let (contract_package_hash, _access) = storage::create_contract_package_at_hash(); - let entry_points = { - let mut eps = EntryPoints::new(); - eps.add_entry_point(EntryPoint::new( - "transfer_token", - vec![], - CLType::Unit, - EntryPointAccess::Public, - casper_types::EntryPointType::Contract, - )); - eps - }; - let named_keys = NamedKeys::new(); - - let (contract_hash, _) = - storage::add_contract_version(contract_package_hash, entry_points, named_keys); - // wrap the contract hash so that it can be reached from the test environment - runtime::put_key( - "owning_contract_hash", - storage::new_uref(contract_hash).into(), - ); - runtime::put_key( - "owning_contract_pack", - storage::new_uref(contract_package_hash).into(), - ); -} From 5c7e08a1c3617519b5386a57e1187c8946a1bf59 Mon Sep 17 00:00:00 2001 From: astro019 Date: Tue, 24 Aug 2021 02:00:55 +1000 Subject: [PATCH 74/98] resolved lint issues --- cep47-tests/src/cep47_tests.rs | 101 ++++++++++----------------------- cep47/src/cep47.rs | 10 ++-- cep47/src/data.rs | 69 +++++++++++----------- 3 files changed, 73 insertions(+), 107 deletions(-) diff --git a/cep47-tests/src/cep47_tests.rs b/cep47-tests/src/cep47_tests.rs index 29e77a3..a8cb99b 100644 --- a/cep47-tests/src/cep47_tests.rs +++ b/cep47-tests/src/cep47_tests.rs @@ -111,12 +111,7 @@ fn test_mint_one_with_set_token_id() { let token_id = TokenId::from("123456"); let token_meta = meta::red_dragon(); - token.mint_one( - Sender(owner), - user, - Some(token_id.clone()), - token_meta.clone(), - ); + token.mint_one(Sender(owner), user, Some(token_id.clone()), token_meta); let first_user_token = token.get_token_by_index(Key::Account(user), 0u32); let second_user_token = token.get_token_by_index(Key::Account(user), 1u32); assert_eq!(first_user_token, Some(token_id.clone())); @@ -141,12 +136,7 @@ fn test_mint_one_with_not_unique_token_id() { token_meta.clone(), ); - token.mint_one( - Sender(owner), - user, - Some(token_id.clone()), - token_meta.clone(), - ); + token.mint_one(Sender(owner), user, Some(token_id), token_meta); } #[test] @@ -154,7 +144,7 @@ fn test_mint_copies() { let (env, token, owner) = deploy(); let user = env.next_user(); let token_meta = meta::red_dragon(); - token.mint_copies(Sender(owner), user, None, token_meta.clone(), 3); + token.mint_copies(Sender(owner), user, None, token_meta, 3); let first_user_token = token.get_token_by_index(Key::Account(user), 0u32); let second_user_token = token.get_token_by_index(Key::Account(user), 1u32); let third_user_token = token.get_token_by_index(Key::Account(user), 2u32); @@ -181,7 +171,7 @@ fn test_mint_many() { let (env, token, owner) = deploy(); let user = env.next_user(); let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; - token.mint_many(Sender(owner), user, None, token_metas.clone()); + token.mint_many(Sender(owner), user, None, token_metas); let first_user_token = token.get_token_by_index(Key::Account(user), 0u32); let second_user_token = token.get_token_by_index(Key::Account(user), 1u32); let third_user_token = token.get_token_by_index(Key::Account(user), 2u32); @@ -209,7 +199,7 @@ fn test_burn_many() { meta::gold_dragon(), ]; - token.mint_many(Sender(owner), user, None, token_metas.clone()); + token.mint_many(Sender(owner), user, None, token_metas); let first_user_token = token.get_token_by_index(Key::Account(user), 0u32); let second_user_token = token.get_token_by_index(Key::Account(user), 1u32); @@ -218,10 +208,7 @@ fn test_burn_many() { token.burn_many( Sender(user), user, - vec![ - first_user_token.clone().unwrap(), - fourth_user_token.clone().unwrap(), - ], + vec![first_user_token.unwrap(), fourth_user_token.unwrap()], ); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(user)), U256::from(2)); @@ -247,7 +234,7 @@ fn test_burn_many_from_allowance_with_approve() { meta::gold_dragon(), ]; - token.mint_many(Sender(owner), user, None, token_metas.clone()); + token.mint_many(Sender(owner), user, None, token_metas); let first_user_token = token.get_token_by_index(Key::Account(user), 0u32); let second_user_token = token.get_token_by_index(Key::Account(user), 1u32); @@ -264,10 +251,7 @@ fn test_burn_many_from_allowance_with_approve() { token.burn_many( Sender(owner), user, - vec![ - first_user_token.clone().unwrap(), - third_user_token.clone().unwrap(), - ], + vec![first_user_token.unwrap(), third_user_token.unwrap()], ); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(user)), U256::from(2)); @@ -294,17 +278,14 @@ fn test_burn_many_from_allowance_without_approve() { meta::gold_dragon(), ]; - token.mint_many(Sender(owner), user, None, token_metas.clone()); + token.mint_many(Sender(owner), user, None, token_metas); let first_user_token = token.get_token_by_index(Key::Account(user), 0u32); let second_user_token = token.get_token_by_index(Key::Account(user), 1u32); token.burn_many( Sender(owner), user, - vec![ - first_user_token.clone().unwrap(), - second_user_token.clone().unwrap(), - ], + vec![first_user_token.unwrap(), second_user_token.unwrap()], ); } @@ -314,11 +295,11 @@ fn test_burn_one() { let (env, token, owner) = deploy(); let user = env.next_user(); let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; - token.mint_many(Sender(owner), user, None, token_metas.clone()); + token.mint_many(Sender(owner), user, None, token_metas); let first_user_token = token.get_token_by_index(Key::Account(user), 0u32); let second_user_token = token.get_token_by_index(Key::Account(user), 1u32); - token.burn_one(Sender(user), user, first_user_token.clone().unwrap()); + token.burn_one(Sender(user), user, first_user_token.unwrap()); assert_eq!(token.total_supply(), U256::from(1)); assert_eq!(token.balance_of(Key::Account(user)), U256::from(1)); @@ -335,7 +316,7 @@ fn test_transfer_token() { let bob = env.next_user(); let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; - token.mint_many(Sender(owner), ali, None, token_metas.clone()); + token.mint_many(Sender(owner), ali, None, token_metas); let first_ali_token = token.get_token_by_index(Key::Account(ali), 0u32); let second_ali_token = token.get_token_by_index(Key::Account(ali), 1u32); @@ -346,32 +327,28 @@ fn test_transfer_token() { Key::Account(ali) ); assert_eq!( - token.owner_of(second_ali_token.clone().unwrap()).unwrap(), + token.owner_of(second_ali_token.unwrap()).unwrap(), Key::Account(ali) ); - token.transfer(Sender(ali), bob, vec![first_ali_token.clone().unwrap()]); + token.transfer(Sender(ali), bob, vec![first_ali_token.unwrap()]); let new_first_ali_token = token.get_token_by_index(Key::Account(ali), 0u32); let new_second_ali_token = token.get_token_by_index(Key::Account(ali), 1u32); let new_first_bob_token = token.get_token_by_index(Key::Account(bob), 0u32); let new_second_bob_token = token.get_token_by_index(Key::Account(bob), 1u32); - println!("{:?}", new_first_ali_token.clone()); - println!("{:?}", new_second_ali_token.clone()); - println!("{:?}", new_first_bob_token.clone()); - println!("{:?}", new_second_bob_token.clone()); + println!("{:?}", new_first_ali_token); + println!("{:?}", new_second_ali_token); + println!("{:?}", new_first_bob_token); + println!("{:?}", new_second_bob_token); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(ali)), U256::from(1)); assert_eq!(token.balance_of(Key::Account(bob)), U256::from(1)); assert_eq!( - token - .owner_of(new_first_ali_token.clone().unwrap()) - .unwrap(), + token.owner_of(new_first_ali_token.unwrap()).unwrap(), Key::Account(ali) ); assert_eq!( - token - .owner_of(new_first_bob_token.clone().unwrap()) - .unwrap(), + token.owner_of(new_first_bob_token.unwrap()).unwrap(), Key::Account(bob) ); assert_eq!(new_second_ali_token, None); @@ -385,14 +362,14 @@ fn test_transfer_from_tokens_with_approve() { let bob = env.next_user(); let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; - token.mint_many(Sender(owner), ali, None, token_metas.clone()); + token.mint_many(Sender(owner), ali, None, token_metas); let first_ali_token = token.get_token_by_index(Key::Account(ali), 0u32); let second_ali_token = token.get_token_by_index(Key::Account(ali), 1u32); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(ali)), U256::from(2)); assert_eq!( - token.owner_of(first_ali_token.clone().unwrap()).unwrap(), + token.owner_of(first_ali_token.unwrap()).unwrap(), Key::Account(ali) ); assert_eq!( @@ -400,12 +377,7 @@ fn test_transfer_from_tokens_with_approve() { Key::Account(ali) ); token.approve(Sender(ali), owner, vec![second_ali_token.clone().unwrap()]); - token.transfer_from( - Sender(owner), - ali, - bob, - vec![second_ali_token.clone().unwrap()], - ); + token.transfer_from(Sender(owner), ali, bob, vec![second_ali_token.unwrap()]); let new_first_ali_token = token.get_token_by_index(Key::Account(ali), 0u32); let new_second_ali_token = token.get_token_by_index(Key::Account(ali), 1u32); let new_first_bob_token = token.get_token_by_index(Key::Account(bob), 0u32); @@ -414,15 +386,11 @@ fn test_transfer_from_tokens_with_approve() { assert_eq!(token.balance_of(Key::Account(ali)), U256::from(1)); assert_eq!(token.balance_of(Key::Account(bob)), U256::from(1)); assert_eq!( - token - .owner_of(new_first_ali_token.clone().unwrap()) - .unwrap(), + token.owner_of(new_first_ali_token.unwrap()).unwrap(), Key::Account(ali) ); assert_eq!( - token - .owner_of(new_first_bob_token.clone().unwrap()) - .unwrap(), + token.owner_of(new_first_bob_token.unwrap()).unwrap(), Key::Account(bob) ); assert_eq!(new_second_ali_token, None); @@ -437,7 +405,7 @@ fn test_transfer_from_tokens_without_approve() { let bob = env.next_user(); let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; - token.mint_many(Sender(owner), ali, None, token_metas.clone()); + token.mint_many(Sender(owner), ali, None, token_metas); let first_ali_token = token.get_token_by_index(Key::Account(ali), 0u32); assert_eq!(token.total_supply(), U256::from(2)); @@ -450,12 +418,7 @@ fn test_transfer_from_tokens_without_approve() { token.owner_of(first_ali_token.clone().unwrap()).unwrap(), Key::Account(ali) ); - token.transfer_from( - Sender(owner), - ali, - bob, - vec![first_ali_token.clone().unwrap()], - ); + token.transfer_from(Sender(owner), ali, bob, vec![first_ali_token.unwrap()]); } #[test] @@ -469,7 +432,7 @@ fn test_approve() { meta::gold_dragon(), ]; - token.mint_many(Sender(owner), user, None, token_metas.clone()); + token.mint_many(Sender(owner), user, None, token_metas); let first_user_token = token.get_token_by_index(Key::Account(user), 0u32); let fourth_user_token = token.get_token_by_index(Key::Account(user), 3u32); @@ -482,14 +445,12 @@ fn test_approve() { ], ); assert_eq!( - token - .get_approved(user, first_user_token.clone().unwrap()) - .unwrap(), + token.get_approved(user, first_user_token.unwrap()).unwrap(), Key::Account(owner) ); assert_eq!( token - .get_approved(user, fourth_user_token.clone().unwrap()) + .get_approved(user, fourth_user_token.unwrap()) .unwrap(), Key::Account(owner) ); diff --git a/cep47/src/cep47.rs b/cep47/src/cep47.rs index 1662b1a..76f566b 100644 --- a/cep47/src/cep47.rs +++ b/cep47/src/cep47.rs @@ -11,7 +11,7 @@ use contract_utils::{ContractContext, ContractStorage}; #[repr(u16)] pub enum Error { PermissionDenied = 1, - ArgumentsError = 2, + WrongArguments = 2, TokenIdAlreadyExists = 3, TokenIdDoesntExist = 4, } @@ -112,7 +112,7 @@ pub trait CEP47: ContractContext { // Validate token_ids and metas. Some(token_ids) => { if token_ids.len() != token_metas.len() { - return Err(Error::ArgumentsError); + return Err(Error::WrongArguments); }; let valid = self.validate_token_ids(token_ids.clone()); if !valid { @@ -158,7 +158,7 @@ pub trait CEP47: ContractContext { ) -> Result<(), Error> { if let Some(token_ids) = &token_ids { if token_ids.len() != count as usize { - return Err(Error::ArgumentsError); + return Err(Error::WrongArguments); } } let token_metas = vec![token_meta; count as usize]; @@ -211,7 +211,7 @@ pub trait CEP47: ContractContext { for token_id in &token_ids { let owner = self.owner_of(token_id.clone()); if owner.is_none() { - return Err(Error::ArgumentsError); + return Err(Error::WrongArguments); } if owner.unwrap() != caller { return Err(Error::PermissionDenied); @@ -293,7 +293,7 @@ pub trait CEP47: ContractContext { return true; } } - return false; + false } fn emit(&mut self, event: CEP47Event) { diff --git a/cep47/src/data.rs b/cep47/src/data.rs index 24b9850..b0e867f 100644 --- a/cep47/src/data.rs +++ b/cep47/src/data.rs @@ -63,15 +63,15 @@ impl Owners { Dict::init(OWNERS_DICT) } - pub fn get(&self, key: &TokenId) -> Option { + pub fn get(&self, key: &str) -> Option { self.dict.get(key) } - pub fn set(&self, key: &TokenId, value: Key) { + pub fn set(&self, key: &str, value: Key) { self.dict.set(key, value); } - pub fn remove(&self, key: &TokenId) { + pub fn remove(&self, key: &str) { self.dict.remove::(key); } } @@ -91,15 +91,15 @@ impl Metadata { Dict::init(METADATA_DICT) } - pub fn get(&self, key: &TokenId) -> Option { + pub fn get(&self, key: &str) -> Option { self.dict.get(key) } - pub fn set(&self, key: &TokenId, value: Meta) { + pub fn set(&self, key: &str, value: Meta) { self.dict.set(key, value); } - pub fn remove(&self, key: &TokenId) { + pub fn remove(&self, key: &str) { self.dict.remove::(key); } } @@ -129,8 +129,9 @@ impl OwnedTokens { self.token_dict.get(&key_and_value_to_str(owner, index)) } - pub fn get_index_by_token(&self, owner: &Key, value: &TokenId) -> Option { - self.index_dict.get(&key_and_value_to_str(owner, value)) + pub fn get_index_by_token(&self, owner: &Key, value: &str) -> Option { + self.index_dict + .get(&key_and_value_to_str(owner, &value.to_string())) } pub fn get_tokens_len(&self, owner: &Key) -> Option { @@ -144,7 +145,7 @@ impl OwnedTokens { pub fn set_token(&self, owner: &Key, value: TokenId) { let length = self.get_tokens_len(owner).unwrap_or_default(); self.index_dict - .set(&key_and_value_to_str(owner, &value), length.clone()); + .set(&key_and_value_to_str(owner, &value), length); self.token_dict .set(&key_and_value_to_str(owner, &length), value); self.set_tokens_len(owner, length + 1); @@ -153,23 +154,27 @@ impl OwnedTokens { pub fn remove_token(&self, owner: &Key, value: TokenId) { let length = self.get_tokens_len(owner).unwrap_or_revert(); let index = self.get_index_by_token(owner, &value).unwrap_or_revert(); - if length == index + 1 { - self.token_dict - .remove::(&key_and_value_to_str(owner, &(length - 1))); - self.set_tokens_len(owner, length - 1); - } else if length > index + 1 { - let last = self.get_token_by_index(owner, &(length - 1)); - self.index_dict.set( - &key_and_value_to_str(owner, &last.clone().unwrap_or_revert()), - index, - ); - self.token_dict.set( - &key_and_value_to_str(owner, &index), - last.clone().unwrap_or_revert(), - ); - self.token_dict - .remove::(&key_and_value_to_str(owner, &(length - 1))); - self.set_tokens_len(owner, length - 1); + match length.cmp(&(index + 1)) { + core::cmp::Ordering::Equal => { + self.token_dict + .remove::(&key_and_value_to_str(owner, &(length - 1))); + self.set_tokens_len(owner, length - 1); + } + core::cmp::Ordering::Greater => { + let last = self.get_token_by_index(owner, &(length - 1)); + self.index_dict.set( + &key_and_value_to_str(owner, &last.clone().unwrap_or_revert()), + index, + ); + self.token_dict.set( + &key_and_value_to_str(owner, &index), + last.unwrap_or_revert(), + ); + self.token_dict + .remove::(&key_and_value_to_str(owner, &(length - 1))); + self.set_tokens_len(owner, length - 1); + } + core::cmp::Ordering::Less => {} } self.index_dict .remove::(&key_and_value_to_str(owner, &value)); @@ -191,21 +196,21 @@ impl Allowances { Dict::init(ALLOWANCES_DICT) } - pub fn get(&self, owner: &Key, token_id: &TokenId) -> Option { + pub fn get(&self, owner: &Key, token_id: &str) -> Option { self.dict - .get(key_and_value_to_str::(owner, token_id).as_str()) + .get(key_and_value_to_str::(owner, &token_id.to_string()).as_str()) } - pub fn set(&self, owner: &Key, token_id: &TokenId, value: Key) { + pub fn set(&self, owner: &Key, token_id: &str, value: Key) { self.dict.set( - key_and_value_to_str::(owner, token_id).as_str(), + key_and_value_to_str::(owner, &token_id.to_string()).as_str(), value, ); } - pub fn remove(&self, owner: &Key, token_id: &TokenId) { + pub fn remove(&self, owner: &Key, token_id: &str) { self.dict - .remove::(key_and_value_to_str::(owner, token_id).as_str()); + .remove::(key_and_value_to_str::(owner, &token_id.to_string()).as_str()); } } From 5df8194aca4d2b680aac7432e134aa3c6687ccd1 Mon Sep 17 00:00:00 2001 From: astro019 Date: Tue, 24 Aug 2021 02:25:03 +1000 Subject: [PATCH 75/98] add gitkeep for cep47-tests/wasm --- cep47-tests/wasm/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 cep47-tests/wasm/.gitkeep diff --git a/cep47-tests/wasm/.gitkeep b/cep47-tests/wasm/.gitkeep new file mode 100644 index 0000000..e69de29 From 25540f9e1c715a8885c3983008a8988452c48633 Mon Sep 17 00:00:00 2001 From: astro019 Date: Wed, 25 Aug 2021 13:15:52 +1000 Subject: [PATCH 76/98] remove duplicated balances, change token index type from u32 to uint256 --- cep47-tests/src/cep47_instance.rs | 2 +- cep47-tests/src/cep47_tests.rs | 100 +++++++++++++++--------------- cep47/src/cep47.rs | 25 +------- cep47/src/data.rs | 83 +++++++++---------------- 4 files changed, 85 insertions(+), 125 deletions(-) diff --git a/cep47-tests/src/cep47_instance.rs b/cep47-tests/src/cep47_instance.rs index 1a51bfa..0f13acb 100644 --- a/cep47-tests/src/cep47_instance.rs +++ b/cep47-tests/src/cep47_instance.rs @@ -178,7 +178,7 @@ impl CEP47Instance { ) } - pub fn get_token_by_index>(&self, account: T, index: u32) -> Option { + pub fn get_token_by_index>(&self, account: T, index: U256) -> Option { self.0.query_dictionary( "owned_tokens_by_index", key_and_value_to_str(&account.into(), &index), diff --git a/cep47-tests/src/cep47_tests.rs b/cep47-tests/src/cep47_tests.rs index a8cb99b..8976d24 100644 --- a/cep47-tests/src/cep47_tests.rs +++ b/cep47-tests/src/cep47_tests.rs @@ -82,7 +82,7 @@ fn test_token_meta() { let user_token_meta = token.token_meta(token_id.clone()); assert_eq!(user_token_meta.unwrap(), token_meta); - let first_user_token = token.get_token_by_index(Key::Account(user), 0u32); + let first_user_token = token.get_token_by_index(Key::Account(user), U256::zero()); assert_eq!(first_user_token, Some(token_id)); } @@ -95,8 +95,10 @@ fn test_mint_one_with_random_token_id() { assert_eq!(token.total_supply(), U256::one()); assert_eq!(token.balance_of(user), U256::one()); - let first_user_token: Option = token.get_token_by_index(Key::Account(user), 0u32); - let second_user_token: Option = token.get_token_by_index(Key::Account(user), 1u32); + let first_user_token: Option = + token.get_token_by_index(Key::Account(user), U256::from(0)); + let second_user_token: Option = + token.get_token_by_index(Key::Account(user), U256::from(1)); assert_eq!( token.owner_of(first_user_token.unwrap()).unwrap(), Key::Account(user) @@ -112,8 +114,8 @@ fn test_mint_one_with_set_token_id() { let token_meta = meta::red_dragon(); token.mint_one(Sender(owner), user, Some(token_id.clone()), token_meta); - let first_user_token = token.get_token_by_index(Key::Account(user), 0u32); - let second_user_token = token.get_token_by_index(Key::Account(user), 1u32); + let first_user_token = token.get_token_by_index(Key::Account(user), U256::from(0)); + let second_user_token = token.get_token_by_index(Key::Account(user), U256::from(1)); assert_eq!(first_user_token, Some(token_id.clone())); assert_eq!(token.total_supply(), U256::one()); assert_eq!(token.balance_of(Key::Account(user)), U256::one()); @@ -145,10 +147,10 @@ fn test_mint_copies() { let user = env.next_user(); let token_meta = meta::red_dragon(); token.mint_copies(Sender(owner), user, None, token_meta, 3); - let first_user_token = token.get_token_by_index(Key::Account(user), 0u32); - let second_user_token = token.get_token_by_index(Key::Account(user), 1u32); - let third_user_token = token.get_token_by_index(Key::Account(user), 2u32); - let fourth_user_token = token.get_token_by_index(Key::Account(user), 3u32); + let first_user_token = token.get_token_by_index(Key::Account(user), U256::from(0)); + let second_user_token = token.get_token_by_index(Key::Account(user), U256::from(1)); + let third_user_token = token.get_token_by_index(Key::Account(user), U256::from(2)); + let fourth_user_token = token.get_token_by_index(Key::Account(user), U256::from(3)); assert_eq!(token.total_supply(), U256::from(3)); assert_eq!(token.balance_of(Key::Account(user)), U256::from(3)); assert_eq!(fourth_user_token, None); @@ -172,9 +174,9 @@ fn test_mint_many() { let user = env.next_user(); let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; token.mint_many(Sender(owner), user, None, token_metas); - let first_user_token = token.get_token_by_index(Key::Account(user), 0u32); - let second_user_token = token.get_token_by_index(Key::Account(user), 1u32); - let third_user_token = token.get_token_by_index(Key::Account(user), 2u32); + let first_user_token = token.get_token_by_index(Key::Account(user), U256::from(0)); + let second_user_token = token.get_token_by_index(Key::Account(user), U256::from(1)); + let third_user_token = token.get_token_by_index(Key::Account(user), U256::from(2)); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(user)), U256::from(2)); assert_eq!(third_user_token, None); @@ -201,10 +203,10 @@ fn test_burn_many() { token.mint_many(Sender(owner), user, None, token_metas); - let first_user_token = token.get_token_by_index(Key::Account(user), 0u32); - let second_user_token = token.get_token_by_index(Key::Account(user), 1u32); - let third_user_token = token.get_token_by_index(Key::Account(user), 2u32); - let fourth_user_token = token.get_token_by_index(Key::Account(user), 3u32); + let first_user_token = token.get_token_by_index(Key::Account(user), U256::from(0)); + let second_user_token = token.get_token_by_index(Key::Account(user), U256::from(1)); + let third_user_token = token.get_token_by_index(Key::Account(user), U256::from(2)); + let fourth_user_token = token.get_token_by_index(Key::Account(user), U256::from(3)); token.burn_many( Sender(user), user, @@ -213,10 +215,10 @@ fn test_burn_many() { assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(user)), U256::from(2)); - let new_first_user_token = token.get_token_by_index(Key::Account(user), 0u32); - let new_second_user_token = token.get_token_by_index(Key::Account(user), 1u32); - let new_third_user_token = token.get_token_by_index(Key::Account(user), 2u32); - let new_fourth_user_token = token.get_token_by_index(Key::Account(user), 3u32); + let new_first_user_token = token.get_token_by_index(Key::Account(user), U256::from(0)); + let new_second_user_token = token.get_token_by_index(Key::Account(user), U256::from(1)); + let new_third_user_token = token.get_token_by_index(Key::Account(user), U256::from(2)); + let new_fourth_user_token = token.get_token_by_index(Key::Account(user), U256::from(3)); assert_eq!(new_first_user_token, third_user_token); assert_eq!(new_second_user_token, second_user_token); assert_eq!(new_third_user_token, None); @@ -236,10 +238,10 @@ fn test_burn_many_from_allowance_with_approve() { token.mint_many(Sender(owner), user, None, token_metas); - let first_user_token = token.get_token_by_index(Key::Account(user), 0u32); - let second_user_token = token.get_token_by_index(Key::Account(user), 1u32); - let third_user_token = token.get_token_by_index(Key::Account(user), 2u32); - let fourth_user_token = token.get_token_by_index(Key::Account(user), 3u32); + let first_user_token = token.get_token_by_index(Key::Account(user), U256::from(0)); + let second_user_token = token.get_token_by_index(Key::Account(user), U256::from(1)); + let third_user_token = token.get_token_by_index(Key::Account(user), U256::from(2)); + let fourth_user_token = token.get_token_by_index(Key::Account(user), U256::from(3)); token.approve( Sender(user), owner, @@ -256,10 +258,10 @@ fn test_burn_many_from_allowance_with_approve() { assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(user)), U256::from(2)); - let new_first_user_token = token.get_token_by_index(Key::Account(user), 0u32); - let new_second_user_token = token.get_token_by_index(Key::Account(user), 1u32); - let new_third_user_token = token.get_token_by_index(Key::Account(user), 2u32); - let new_fourth_user_token = token.get_token_by_index(Key::Account(user), 3u32); + let new_first_user_token = token.get_token_by_index(Key::Account(user), U256::from(0)); + let new_second_user_token = token.get_token_by_index(Key::Account(user), U256::from(1)); + let new_third_user_token = token.get_token_by_index(Key::Account(user), U256::from(2)); + let new_fourth_user_token = token.get_token_by_index(Key::Account(user), U256::from(3)); assert_eq!(new_first_user_token, fourth_user_token); assert_eq!(new_second_user_token, second_user_token); assert_eq!(new_third_user_token, None); @@ -280,8 +282,8 @@ fn test_burn_many_from_allowance_without_approve() { token.mint_many(Sender(owner), user, None, token_metas); - let first_user_token = token.get_token_by_index(Key::Account(user), 0u32); - let second_user_token = token.get_token_by_index(Key::Account(user), 1u32); + let first_user_token = token.get_token_by_index(Key::Account(user), U256::from(0)); + let second_user_token = token.get_token_by_index(Key::Account(user), U256::from(1)); token.burn_many( Sender(owner), user, @@ -297,14 +299,14 @@ fn test_burn_one() { let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; token.mint_many(Sender(owner), user, None, token_metas); - let first_user_token = token.get_token_by_index(Key::Account(user), 0u32); - let second_user_token = token.get_token_by_index(Key::Account(user), 1u32); + let first_user_token = token.get_token_by_index(Key::Account(user), U256::from(0)); + let second_user_token = token.get_token_by_index(Key::Account(user), U256::from(1)); token.burn_one(Sender(user), user, first_user_token.unwrap()); assert_eq!(token.total_supply(), U256::from(1)); assert_eq!(token.balance_of(Key::Account(user)), U256::from(1)); - let new_first_user_token = token.get_token_by_index(Key::Account(user), 0u32); - let new_second_user_token = token.get_token_by_index(Key::Account(user), 1u32); + let new_first_user_token = token.get_token_by_index(Key::Account(user), U256::from(0)); + let new_second_user_token = token.get_token_by_index(Key::Account(user), U256::from(1)); assert_eq!(new_first_user_token, second_user_token); assert_eq!(new_second_user_token, None); } @@ -317,8 +319,8 @@ fn test_transfer_token() { let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; token.mint_many(Sender(owner), ali, None, token_metas); - let first_ali_token = token.get_token_by_index(Key::Account(ali), 0u32); - let second_ali_token = token.get_token_by_index(Key::Account(ali), 1u32); + let first_ali_token = token.get_token_by_index(Key::Account(ali), U256::from(0)); + let second_ali_token = token.get_token_by_index(Key::Account(ali), U256::from(1)); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(ali)), U256::from(2)); @@ -332,10 +334,10 @@ fn test_transfer_token() { ); token.transfer(Sender(ali), bob, vec![first_ali_token.unwrap()]); - let new_first_ali_token = token.get_token_by_index(Key::Account(ali), 0u32); - let new_second_ali_token = token.get_token_by_index(Key::Account(ali), 1u32); - let new_first_bob_token = token.get_token_by_index(Key::Account(bob), 0u32); - let new_second_bob_token = token.get_token_by_index(Key::Account(bob), 1u32); + let new_first_ali_token = token.get_token_by_index(Key::Account(ali), U256::from(0)); + let new_second_ali_token = token.get_token_by_index(Key::Account(ali), U256::from(1)); + let new_first_bob_token = token.get_token_by_index(Key::Account(bob), U256::from(0)); + let new_second_bob_token = token.get_token_by_index(Key::Account(bob), U256::from(1)); println!("{:?}", new_first_ali_token); println!("{:?}", new_second_ali_token); println!("{:?}", new_first_bob_token); @@ -363,8 +365,8 @@ fn test_transfer_from_tokens_with_approve() { let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; token.mint_many(Sender(owner), ali, None, token_metas); - let first_ali_token = token.get_token_by_index(Key::Account(ali), 0u32); - let second_ali_token = token.get_token_by_index(Key::Account(ali), 1u32); + let first_ali_token = token.get_token_by_index(Key::Account(ali), U256::from(0)); + let second_ali_token = token.get_token_by_index(Key::Account(ali), U256::from(1)); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(ali)), U256::from(2)); @@ -378,10 +380,10 @@ fn test_transfer_from_tokens_with_approve() { ); token.approve(Sender(ali), owner, vec![second_ali_token.clone().unwrap()]); token.transfer_from(Sender(owner), ali, bob, vec![second_ali_token.unwrap()]); - let new_first_ali_token = token.get_token_by_index(Key::Account(ali), 0u32); - let new_second_ali_token = token.get_token_by_index(Key::Account(ali), 1u32); - let new_first_bob_token = token.get_token_by_index(Key::Account(bob), 0u32); - let new_second_bob_token = token.get_token_by_index(Key::Account(bob), 1u32); + let new_first_ali_token = token.get_token_by_index(Key::Account(ali), U256::from(0)); + let new_second_ali_token = token.get_token_by_index(Key::Account(ali), U256::from(1)); + let new_first_bob_token = token.get_token_by_index(Key::Account(bob), U256::from(0)); + let new_second_bob_token = token.get_token_by_index(Key::Account(bob), U256::from(1)); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(ali)), U256::from(1)); assert_eq!(token.balance_of(Key::Account(bob)), U256::from(1)); @@ -406,7 +408,7 @@ fn test_transfer_from_tokens_without_approve() { let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; token.mint_many(Sender(owner), ali, None, token_metas); - let first_ali_token = token.get_token_by_index(Key::Account(ali), 0u32); + let first_ali_token = token.get_token_by_index(Key::Account(ali), U256::from(0)); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(ali)), U256::from(2)); @@ -434,8 +436,8 @@ fn test_approve() { token.mint_many(Sender(owner), user, None, token_metas); - let first_user_token = token.get_token_by_index(Key::Account(user), 0u32); - let fourth_user_token = token.get_token_by_index(Key::Account(user), 3u32); + let first_user_token = token.get_token_by_index(Key::Account(user), U256::from(0)); + let fourth_user_token = token.get_token_by_index(Key::Account(user), U256::from(3)); token.approve( Sender(user), owner, diff --git a/cep47/src/cep47.rs b/cep47/src/cep47.rs index 76f566b..e310876 100644 --- a/cep47/src/cep47.rs +++ b/cep47/src/cep47.rs @@ -1,5 +1,5 @@ use crate::{ - data::{self, Allowances, Balances, Metadata, OwnedTokens, Owners}, + data::{self, Allowances, Metadata, OwnedTokens, Owners}, event::CEP47Event, Meta, TokenId, }; @@ -31,7 +31,6 @@ pub trait CEP47: ContractContext { Owners::init(); OwnedTokens::init(); Metadata::init(); - Balances::init(); Allowances::init(); } @@ -52,7 +51,7 @@ pub trait CEP47: ContractContext { } fn balance_of(&self, owner: Key) -> U256 { - Balances::instance().get(&owner) + OwnedTokens::instance().get_balances(&owner) } fn owner_of(&self, token_id: TokenId) -> Option { @@ -75,7 +74,7 @@ pub trait CEP47: ContractContext { Ok(()) } - fn get_token_by_index(&self, owner: Key, index: u32) -> Option { + fn get_token_by_index(&self, owner: Key, index: U256) -> Option { OwnedTokens::instance().get_token_by_index(&owner, &index) } @@ -126,7 +125,6 @@ pub trait CEP47: ContractContext { let owners_dict = Owners::instance(); let owned_tokens_dict = OwnedTokens::instance(); let metadata_dict = Metadata::instance(); - let balances_dict = Balances::instance(); for (token_id, token_meta) in unique_token_ids.iter().zip(&token_metas) { metadata_dict.set(token_id, token_meta.clone()); @@ -135,10 +133,6 @@ pub trait CEP47: ContractContext { } let minted_tokens_count = U256::from(unique_token_ids.len() as u64); - let prev_balance = balances_dict.get(&recipient); - let new_balance = prev_balance + minted_tokens_count; - balances_dict.set(&recipient, new_balance); - let new_total_supply = data::total_supply() + minted_tokens_count; data::set_total_supply(new_total_supply); @@ -169,7 +163,6 @@ pub trait CEP47: ContractContext { let owners_dict = Owners::instance(); let owned_tokens_dict = OwnedTokens::instance(); let metadata_dict = Metadata::instance(); - let balances_dict = Balances::instance(); let allowances_dict = Allowances::instance(); let spender = self.get_caller(); @@ -194,10 +187,6 @@ pub trait CEP47: ContractContext { allowances_dict.remove(&owner, token_id); } - let owner_balance = balances_dict.get(&owner); - let new_owner_balance = owner_balance - U256::from(token_ids.len() as u64); - balances_dict.set(&owner, new_owner_balance); - let burnt_tokens_count = U256::from(token_ids.len() as u64); let new_total_supply = data::total_supply() - burnt_tokens_count; data::set_total_supply(new_total_supply); @@ -253,7 +242,6 @@ pub trait CEP47: ContractContext { let owners_dict = Owners::instance(); let owned_tokens_dict = OwnedTokens::instance(); - let balances_dict = Balances::instance(); for token_id in &token_ids { match owners_dict.get(token_id) { @@ -270,13 +258,6 @@ pub trait CEP47: ContractContext { owned_tokens_dict.set_token(&recipient, token_id.clone()); owners_dict.set(token_id, recipient); } - let owner_balance = balances_dict.get(&owner); - let new_owner_balance = owner_balance - U256::from(token_ids.len() as u64); - balances_dict.set(&owner, new_owner_balance); - - let recipient_balance = balances_dict.get(&recipient); - let new_recipient_balance = recipient_balance + U256::from(token_ids.len() as u64); - balances_dict.set(&recipient, new_recipient_balance); self.emit(CEP47Event::Transfer { sender: owner, diff --git a/cep47/src/data.rs b/cep47/src/data.rs index b0e867f..5205f7f 100644 --- a/cep47/src/data.rs +++ b/cep47/src/data.rs @@ -15,7 +15,6 @@ const METADATA_DICT: &str = "metadata"; const OWNERS_DICT: &str = "owners"; const OWNED_TOKENS_BY_INDEX_DICT: &str = "owned_tokens_by_index"; const OWNED_INDEXES_BY_TOKEN_DICT: &str = "owned_indexes_by_token"; -const OWNED_TOKENS_LENGTH_DICT: &str = "owned_tokens_length"; const CONTRACT_PACKAGE_HASH: &str = "contract_package_hash"; pub const NAME: &str = "name"; @@ -24,30 +23,6 @@ pub const SYMBOL: &str = "symbol"; pub const TOTAL_SUPPLY: &str = "total_supply"; pub const NONCE: &str = "nonce"; -pub struct Balances { - dict: Dict, -} - -impl Balances { - pub fn instance() -> Balances { - Balances { - dict: Dict::instance(BALANCES_DICT), - } - } - - pub fn init() { - Dict::init(BALANCES_DICT) - } - - pub fn get(&self, owner: &Key) -> U256 { - self.dict.get_by_key(owner).unwrap_or_default() - } - - pub fn set(&self, owner: &Key, value: U256) { - self.dict.set_by_key(owner, value); - } -} - pub struct Owners { dict: Dict, } @@ -105,79 +80,81 @@ impl Metadata { } pub struct OwnedTokens { - token_dict: Dict, - index_dict: Dict, - length_dict: Dict, + tokens_dict: Dict, + indexes_dict: Dict, + balances_dict: Dict, } impl OwnedTokens { pub fn instance() -> OwnedTokens { OwnedTokens { - token_dict: Dict::instance(OWNED_TOKENS_BY_INDEX_DICT), - index_dict: Dict::instance(OWNED_INDEXES_BY_TOKEN_DICT), - length_dict: Dict::instance(OWNED_TOKENS_LENGTH_DICT), + tokens_dict: Dict::instance(OWNED_TOKENS_BY_INDEX_DICT), + indexes_dict: Dict::instance(OWNED_INDEXES_BY_TOKEN_DICT), + balances_dict: Dict::instance(BALANCES_DICT), } } pub fn init() { Dict::init(OWNED_TOKENS_BY_INDEX_DICT); Dict::init(OWNED_INDEXES_BY_TOKEN_DICT); - Dict::init(OWNED_TOKENS_LENGTH_DICT); + Dict::init(BALANCES_DICT); } - pub fn get_token_by_index(&self, owner: &Key, index: &u32) -> Option { - self.token_dict.get(&key_and_value_to_str(owner, index)) + pub fn get_token_by_index(&self, owner: &Key, index: &U256) -> Option { + self.tokens_dict.get(&key_and_value_to_str(owner, index)) } - pub fn get_index_by_token(&self, owner: &Key, value: &str) -> Option { - self.index_dict + pub fn get_index_by_token(&self, owner: &Key, value: &str) -> Option { + self.indexes_dict .get(&key_and_value_to_str(owner, &value.to_string())) } - pub fn get_tokens_len(&self, owner: &Key) -> Option { - self.length_dict.get(&key_to_str(owner)) + pub fn get_balances(&self, owner: &Key) -> U256 { + self.balances_dict + .get(&key_to_str(owner)) + .unwrap_or_default() } - pub fn set_tokens_len(&self, owner: &Key, value: u32) { - self.length_dict.set(&key_to_str(owner), value); + pub fn set_balances(&self, owner: &Key, value: U256) { + self.balances_dict.set(&key_to_str(owner), value); } pub fn set_token(&self, owner: &Key, value: TokenId) { - let length = self.get_tokens_len(owner).unwrap_or_default(); - self.index_dict + let length = self.get_balances(owner); + self.indexes_dict .set(&key_and_value_to_str(owner, &value), length); - self.token_dict + self.tokens_dict .set(&key_and_value_to_str(owner, &length), value); - self.set_tokens_len(owner, length + 1); + self.set_balances(owner, length + 1); } pub fn remove_token(&self, owner: &Key, value: TokenId) { - let length = self.get_tokens_len(owner).unwrap_or_revert(); + let length = self.get_balances(owner); let index = self.get_index_by_token(owner, &value).unwrap_or_revert(); match length.cmp(&(index + 1)) { core::cmp::Ordering::Equal => { - self.token_dict + self.tokens_dict .remove::(&key_and_value_to_str(owner, &(length - 1))); - self.set_tokens_len(owner, length - 1); + self.set_balances(owner, length - 1); } core::cmp::Ordering::Greater => { let last = self.get_token_by_index(owner, &(length - 1)); - self.index_dict.set( + self.indexes_dict.set( &key_and_value_to_str(owner, &last.clone().unwrap_or_revert()), index, ); - self.token_dict.set( + self.tokens_dict.set( &key_and_value_to_str(owner, &index), last.unwrap_or_revert(), ); - self.token_dict + self.tokens_dict .remove::(&key_and_value_to_str(owner, &(length - 1))); - self.set_tokens_len(owner, length - 1); + self.set_balances(owner, length - 1); } core::cmp::Ordering::Less => {} } - self.index_dict - .remove::(&key_and_value_to_str(owner, &value)); + self.indexes_dict + .remove::(&key_and_value_to_str(owner, &value)); } } From a3cb0e7c639bf4ed62aaa4193d8d530692ab4f14 Mon Sep 17 00:00:00 2001 From: astro019 Date: Wed, 25 Aug 2021 13:18:35 +1000 Subject: [PATCH 77/98] fixed set_token_meta error msg --- cep47/src/cep47.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cep47/src/cep47.rs b/cep47/src/cep47.rs index e310876..cc3deb9 100644 --- a/cep47/src/cep47.rs +++ b/cep47/src/cep47.rs @@ -64,7 +64,7 @@ pub trait CEP47: ContractContext { fn set_token_meta(&mut self, token_id: TokenId, meta: Meta) -> Result<(), Error> { if self.owner_of(token_id.clone()).is_none() { - return Err(Error::TokenIdAlreadyExists); + return Err(Error::TokenIdDoesntExist); }; let metadata_dict = Metadata::instance(); From bbc6509640c1dfb1c10ccc793c7954445f2a34fa Mon Sep 17 00:00:00 2001 From: astro019 Date: Wed, 25 Aug 2021 20:09:45 +1000 Subject: [PATCH 78/98] add get_token_by_index endpoint --- cep47/bin/cep47_token.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/cep47/bin/cep47_token.rs b/cep47/bin/cep47_token.rs index 0910d6f..088bff4 100644 --- a/cep47/bin/cep47_token.rs +++ b/cep47/bin/cep47_token.rs @@ -77,6 +77,14 @@ fn balance_of() { runtime::ret(CLValue::from_t(ret).unwrap_or_revert()); } +#[no_mangle] +fn get_token_by_index() { + let owner = runtime::get_named_arg::("owner"); + let index = runtime::get_named_arg::("index"); + let ret = NFTToken::default().get_token_by_index(owner, index); + runtime::ret(CLValue::from_t(ret).unwrap_or_revert()); +} + #[no_mangle] fn owner_of() { let token_id = runtime::get_named_arg::("token_id"); @@ -383,5 +391,15 @@ fn get_entry_points() -> EntryPoints { EntryPointAccess::Public, EntryPointType::Contract, )); + entry_points.add_entry_point(EntryPoint::new( + "get_token_by_index", + vec![ + Parameter::new("owner", Key::cl_type()), + Parameter::new("index", U256::cl_type()), + ], + CLType::Option(Box::new(TokenId::cl_type())), + EntryPointAccess::Public, + EntryPointType::Contract, + )); entry_points } From a24554e5cfc73e98000bb7ef8f43b2920f2e951c Mon Sep 17 00:00:00 2001 From: astro019 Date: Thu, 26 Aug 2021 20:00:00 +1000 Subject: [PATCH 79/98] make contract_utils lib public --- cep47/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/cep47/src/lib.rs b/cep47/src/lib.rs index e6c0bab..09564a0 100644 --- a/cep47/src/lib.rs +++ b/cep47/src/lib.rs @@ -7,6 +7,7 @@ pub mod data; pub mod event; pub use cep47::CEP47; +pub use contract_utils; use alloc::{collections::BTreeMap, string::String}; pub type TokenId = String; From 300b62155f1a8502c22de9f84943e6c0436a3a11 Mon Sep 17 00:00:00 2001 From: astro019 Date: Mon, 30 Aug 2021 23:29:15 +1000 Subject: [PATCH 80/98] smade transfer_from_internal and burn_internal function --- cep47/src/cep47.rs | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/cep47/src/cep47.rs b/cep47/src/cep47.rs index cc3deb9..4dac648 100644 --- a/cep47/src/cep47.rs +++ b/cep47/src/cep47.rs @@ -161,12 +161,7 @@ pub trait CEP47: ContractContext { fn burn(&mut self, owner: Key, token_ids: Vec) -> Result<(), Error> { let owners_dict = Owners::instance(); - let owned_tokens_dict = OwnedTokens::instance(); - let metadata_dict = Metadata::instance(); - let allowances_dict = Allowances::instance(); - let spender = self.get_caller(); - for token_id in &token_ids { if spender != owner && !self.is_approved(owner, token_id.clone(), spender) { return Err(Error::PermissionDenied); @@ -181,6 +176,18 @@ pub trait CEP47: ContractContext { return Err(Error::TokenIdDoesntExist); } } + } + self.burn_internal(owner, token_ids); + Ok(()) + } + + fn burn_internal(&mut self, owner: Key, token_ids: Vec) { + let owners_dict = Owners::instance(); + let owned_tokens_dict = OwnedTokens::instance(); + let metadata_dict = Metadata::instance(); + let allowances_dict = Allowances::instance(); + + for token_id in &token_ids { owned_tokens_dict.remove_token(&owner, token_id.clone()); metadata_dict.remove(token_id); owners_dict.remove(token_id); @@ -192,7 +199,6 @@ pub trait CEP47: ContractContext { data::set_total_supply(new_total_supply); self.emit(CEP47Event::Burn { owner, token_ids }); - Ok(()) } fn approve(&mut self, spender: Key, token_ids: Vec) -> Result<(), Error> { @@ -231,6 +237,8 @@ pub trait CEP47: ContractContext { ) -> Result<(), Error> { let allowances_dict = Allowances::instance(); let spender = self.get_caller(); + let owners_dict = Owners::instance(); + if owner != spender { for token_id in &token_ids { if !self.is_approved(owner, token_id.clone(), spender) { @@ -240,9 +248,6 @@ pub trait CEP47: ContractContext { } } - let owners_dict = Owners::instance(); - let owned_tokens_dict = OwnedTokens::instance(); - for token_id in &token_ids { match owners_dict.get(token_id) { Some(owner_of_key) => { @@ -254,6 +259,16 @@ pub trait CEP47: ContractContext { return Err(Error::TokenIdDoesntExist); } } + } + self.transfer_from_internal(owner, recipient, token_ids); + Ok(()) + } + + fn transfer_from_internal(&mut self, owner: Key, recipient: Key, token_ids: Vec) { + let owners_dict = Owners::instance(); + let owned_tokens_dict = OwnedTokens::instance(); + + for token_id in &token_ids { owned_tokens_dict.remove_token(&owner, token_id.clone()); owned_tokens_dict.set_token(&recipient, token_id.clone()); owners_dict.set(token_id, recipient); @@ -264,7 +279,6 @@ pub trait CEP47: ContractContext { recipient, token_ids, }); - Ok(()) } fn is_approved(&self, owner: Key, token_id: TokenId, spender: Key) -> bool { From 7d7263ca6ec331e55730c7c19a94c4ecf1dba984 Mon Sep 17 00:00:00 2001 From: astro019 Date: Thu, 2 Sep 2021 12:29:20 -0400 Subject: [PATCH 81/98] add metadata length check for token_id generation --- cep47/src/cep47.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cep47/src/cep47.rs b/cep47/src/cep47.rs index 4dac648..65c817c 100644 --- a/cep47/src/cep47.rs +++ b/cep47/src/cep47.rs @@ -119,7 +119,12 @@ pub trait CEP47: ContractContext { }; token_ids } - None => self.generate_token_ids(token_metas.len() as u32), + None => { + if token_metas.is_empty() { + return Err(Error::WrongArguments); + } + self.generate_token_ids(token_metas.len() as u32) + } }; let owners_dict = Owners::instance(); From 3ccbbf8603777683b84cb8e48b2d47301ff66166 Mon Sep 17 00:00:00 2001 From: astro019 Date: Thu, 2 Sep 2021 12:50:35 -0400 Subject: [PATCH 82/98] fixed mint supporting nft token generation with random id and empty metadata --- cep47/src/cep47.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/cep47/src/cep47.rs b/cep47/src/cep47.rs index 65c817c..53b9ce2 100644 --- a/cep47/src/cep47.rs +++ b/cep47/src/cep47.rs @@ -107,10 +107,11 @@ pub trait CEP47: ContractContext { token_ids: Option>, token_metas: Vec, ) -> Result<(), Error> { + let mut valid_token_metas = token_metas; let unique_token_ids = match token_ids { // Validate token_ids and metas. Some(token_ids) => { - if token_ids.len() != token_metas.len() { + if token_ids.len() != valid_token_metas.len() { return Err(Error::WrongArguments); }; let valid = self.validate_token_ids(token_ids.clone()); @@ -120,10 +121,10 @@ pub trait CEP47: ContractContext { token_ids } None => { - if token_metas.is_empty() { - return Err(Error::WrongArguments); + if valid_token_metas.is_empty() { + valid_token_metas = vec![Meta::new()]; } - self.generate_token_ids(token_metas.len() as u32) + self.generate_token_ids(valid_token_metas.len() as u32) } }; @@ -131,7 +132,7 @@ pub trait CEP47: ContractContext { let owned_tokens_dict = OwnedTokens::instance(); let metadata_dict = Metadata::instance(); - for (token_id, token_meta) in unique_token_ids.iter().zip(&token_metas) { + for (token_id, token_meta) in unique_token_ids.iter().zip(&valid_token_metas) { metadata_dict.set(token_id, token_meta.clone()); owners_dict.set(token_id, recipient); owned_tokens_dict.set_token(&recipient, token_id.clone()); From c9f955cdaab811ff4034da9a7a50a57fb39a9bd9 Mon Sep 17 00:00:00 2001 From: astro019 Date: Fri, 10 Sep 2021 23:59:04 +1000 Subject: [PATCH 83/98] added is_admin to admin_control --- utils/contract-utils/src/admin_control.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/utils/contract-utils/src/admin_control.rs b/utils/contract-utils/src/admin_control.rs index 2d3d5be..f759e25 100644 --- a/utils/contract-utils/src/admin_control.rs +++ b/utils/contract-utils/src/admin_control.rs @@ -33,6 +33,10 @@ pub trait AdminControl: ContractContext { runtime::revert(ApiError::User(20)); } } + + fn is_admin(&self, address: Key) -> bool { + Admins::instance().is_admin(&address) + } } struct Admins { From 7b30a5101b7aca35a284e84f0bbe2ef715dee318 Mon Sep 17 00:00:00 2001 From: astro019 Date: Mon, 13 Sep 2021 12:00:24 +1000 Subject: [PATCH 84/98] moved owner check to internal burn & transfer function --- cep47/src/cep47.rs | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/cep47/src/cep47.rs b/cep47/src/cep47.rs index 53b9ce2..fede46b 100644 --- a/cep47/src/cep47.rs +++ b/cep47/src/cep47.rs @@ -166,12 +166,22 @@ pub trait CEP47: ContractContext { } fn burn(&mut self, owner: Key, token_ids: Vec) -> Result<(), Error> { - let owners_dict = Owners::instance(); let spender = self.get_caller(); for token_id in &token_ids { if spender != owner && !self.is_approved(owner, token_id.clone(), spender) { return Err(Error::PermissionDenied); } + } + self.burn_internal(owner, token_ids) + } + + fn burn_internal(&mut self, owner: Key, token_ids: Vec) -> Result<(), Error> { + let owners_dict = Owners::instance(); + let owned_tokens_dict = OwnedTokens::instance(); + let metadata_dict = Metadata::instance(); + let allowances_dict = Allowances::instance(); + + for token_id in &token_ids { match owners_dict.get(token_id) { Some(owner_of_key) => { if owner_of_key != owner { @@ -183,15 +193,6 @@ pub trait CEP47: ContractContext { } } } - self.burn_internal(owner, token_ids); - Ok(()) - } - - fn burn_internal(&mut self, owner: Key, token_ids: Vec) { - let owners_dict = Owners::instance(); - let owned_tokens_dict = OwnedTokens::instance(); - let metadata_dict = Metadata::instance(); - let allowances_dict = Allowances::instance(); for token_id in &token_ids { owned_tokens_dict.remove_token(&owner, token_id.clone()); @@ -205,6 +206,7 @@ pub trait CEP47: ContractContext { data::set_total_supply(new_total_supply); self.emit(CEP47Event::Burn { owner, token_ids }); + Ok(()) } fn approve(&mut self, spender: Key, token_ids: Vec) -> Result<(), Error> { @@ -243,7 +245,6 @@ pub trait CEP47: ContractContext { ) -> Result<(), Error> { let allowances_dict = Allowances::instance(); let spender = self.get_caller(); - let owners_dict = Owners::instance(); if owner != spender { for token_id in &token_ids { @@ -253,6 +254,17 @@ pub trait CEP47: ContractContext { allowances_dict.remove(&owner, token_id); } } + self.transfer_from_internal(owner, recipient, token_ids) + } + + fn transfer_from_internal( + &mut self, + owner: Key, + recipient: Key, + token_ids: Vec, + ) -> Result<(), Error> { + let owners_dict = Owners::instance(); + let owned_tokens_dict = OwnedTokens::instance(); for token_id in &token_ids { match owners_dict.get(token_id) { @@ -266,13 +278,6 @@ pub trait CEP47: ContractContext { } } } - self.transfer_from_internal(owner, recipient, token_ids); - Ok(()) - } - - fn transfer_from_internal(&mut self, owner: Key, recipient: Key, token_ids: Vec) { - let owners_dict = Owners::instance(); - let owned_tokens_dict = OwnedTokens::instance(); for token_id in &token_ids { owned_tokens_dict.remove_token(&owner, token_id.clone()); @@ -285,6 +290,7 @@ pub trait CEP47: ContractContext { recipient, token_ids, }); + Ok(()) } fn is_approved(&self, owner: Key, token_id: TokenId, spender: Key) -> bool { From b029848df02f344b9a91e8f5458586c9b497ce1e Mon Sep 17 00:00:00 2001 From: astro019 Date: Mon, 13 Sep 2021 19:41:54 +1000 Subject: [PATCH 85/98] export Error of cep47 --- cep47/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cep47/src/lib.rs b/cep47/src/lib.rs index 09564a0..95a0e3c 100644 --- a/cep47/src/lib.rs +++ b/cep47/src/lib.rs @@ -6,7 +6,7 @@ mod cep47; pub mod data; pub mod event; -pub use cep47::CEP47; +pub use cep47::{CEP47, Error}; pub use contract_utils; use alloc::{collections::BTreeMap, string::String}; From c66878bd6868c2006edf7288e15b7c30aeb25b1f Mon Sep 17 00:00:00 2001 From: astro019 Date: Mon, 13 Sep 2021 19:42:40 +1000 Subject: [PATCH 86/98] export Error of cep47 --- cep47/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cep47/src/lib.rs b/cep47/src/lib.rs index 95a0e3c..bc17bb3 100644 --- a/cep47/src/lib.rs +++ b/cep47/src/lib.rs @@ -6,7 +6,7 @@ mod cep47; pub mod data; pub mod event; -pub use cep47::{CEP47, Error}; +pub use cep47::{Error, CEP47}; pub use contract_utils; use alloc::{collections::BTreeMap, string::String}; From ea96ec451417bb8307eae22613b37ec83fe62eb2 Mon Sep 17 00:00:00 2001 From: astro019 Date: Mon, 13 Sep 2021 20:01:21 +1000 Subject: [PATCH 87/98] return token_ids in mint, mint_copies --- cep47/src/cep47.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cep47/src/cep47.rs b/cep47/src/cep47.rs index fede46b..a73fd32 100644 --- a/cep47/src/cep47.rs +++ b/cep47/src/cep47.rs @@ -106,7 +106,7 @@ pub trait CEP47: ContractContext { recipient: Key, token_ids: Option>, token_metas: Vec, - ) -> Result<(), Error> { + ) -> Result, Error> { let mut valid_token_metas = token_metas; let unique_token_ids = match token_ids { // Validate token_ids and metas. @@ -144,9 +144,9 @@ pub trait CEP47: ContractContext { self.emit(CEP47Event::Mint { recipient, - token_ids: unique_token_ids, + token_ids: unique_token_ids.clone(), }); - Ok(()) + Ok(unique_token_ids) } fn mint_copies( @@ -155,7 +155,7 @@ pub trait CEP47: ContractContext { token_ids: Option>, token_meta: Meta, count: u32, - ) -> Result<(), Error> { + ) -> Result, Error> { if let Some(token_ids) = &token_ids { if token_ids.len() != count as usize { return Err(Error::WrongArguments); From a5d34d97efab4f5a29182f3ac5c95be779ab8732 Mon Sep 17 00:00:00 2001 From: astro019 Date: Wed, 17 Nov 2021 11:50:44 +1000 Subject: [PATCH 88/98] upgrade 1.3.2 to 1.4.1 --- Cargo.lock | 263 +++++++------------------------- cep47-tests/Cargo.toml | 7 +- cep47/Cargo.toml | 4 +- utils/contract-utils/Cargo.toml | 4 +- utils/test-env/Cargo.toml | 7 +- 5 files changed, 70 insertions(+), 215 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f56fb16..801a44f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -95,25 +95,24 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "casper-contract" -version = "1.3.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43c0e5d5699d804babbb360b051ebf864cc46dbd95c45b7705e06eba8b3c9bbe" +checksum = "d268cab5c7ec026f596abbb3bde5afa72e4dbca5d870f0e8f55fd456dc39239d" dependencies = [ "casper-types", "hex_fmt", - "thiserror", - "version-sync", "wee_alloc", ] [[package]] name = "casper-engine-test-support" -version = "1.3.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44af6d2e19d743ed85e5f7e63836dbc3d3e5d0ce3aab92346df5d057e4b0baba" +checksum = "e52f2b4a1c979eb65abc87d284fb8f09dd764201c051246464da90a53037948c" dependencies = [ "casper-contract", "casper-execution-engine", + "casper-hashing", "casper-types", "lmdb", "log", @@ -125,19 +124,19 @@ dependencies = [ [[package]] name = "casper-execution-engine" -version = "1.3.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "835acc287eec782dea4d55890da5c1343025417842e1ac06a8c9beda2226f2cc" +checksum = "1f71e7d10ca7cdec6a150cb9e2c87c0dcda757fd067fbee1e345bda7eceae540" dependencies = [ "anyhow", "base16", "bincode", - "blake2", + "casper-hashing", "casper-types", "chrono", "datasize", "hex", - "hex-buffer-serde", + "hex-buffer-serde 0.2.2", "hex_fmt", "hostname", "itertools", @@ -166,22 +165,39 @@ dependencies = [ "wasmi", ] +[[package]] +name = "casper-hashing" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5001fe4a9ca2fbebf62152ed1227cca215be1d912fef526a3fcaa9a21f9d7498" +dependencies = [ + "base16", + "blake2", + "casper-types", + "datasize", + "hex", + "hex-buffer-serde 0.3.0", + "itertools", + "schemars", + "serde", +] + [[package]] name = "casper-types" -version = "1.3.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e59b710b0390285d63401ba32298aa81cdbc31104a654136bf1e5f55980e97b2" +checksum = "12b42e0c175b4c593a4c10db210a0a95fe2a7ddcb99a8e82c97d7d45c08e01ed" dependencies = [ "base16", "base64", "bitflags", "blake2", "datasize", - "displaydoc", "ed25519-dalek", "hex", "hex_fmt", "k256", + "num", "num-derive", "num-integer", "num-rational 0.4.0", @@ -191,8 +207,8 @@ dependencies = [ "rand 0.8.4", "schemars", "serde", + "serde_bytes", "serde_json", - "thiserror", "uint", ] @@ -219,6 +235,7 @@ dependencies = [ "blake2", "casper-contract", "casper-engine-test-support", + "casper-hashing", "casper-types", "contract-utils", "hex", @@ -346,17 +363,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "displaydoc" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc2ab4d5a16117f9029e9a6b5e4e79f4c67f6519bc134210d4d4a04ba31f41b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "downcast-rs" version = "1.2.0" @@ -386,7 +392,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4620d40f6d2601794401d6dd95a5cf69b6c157852539470eeda433a99b3c0efc" dependencies = [ - "serde", "signature", ] @@ -399,8 +404,6 @@ dependencies = [ "curve25519-dalek", "ed25519", "rand 0.7.3", - "serde", - "serde_bytes", "sha2", "zeroize", ] @@ -445,16 +448,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "form_urlencoded" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" -dependencies = [ - "matches", - "percent-encoding", -] - [[package]] name = "funty" version = "1.1.0" @@ -471,17 +464,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - [[package]] name = "getrandom" version = "0.2.3" @@ -490,7 +472,7 @@ checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" dependencies = [ "cfg-if 1.0.0", "libc", - "wasi 0.10.2+wasi-snapshot-preview1", + "wasi", ] [[package]] @@ -529,6 +511,16 @@ dependencies = [ "serde", ] +[[package]] +name = "hex-buffer-serde" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f52012c160668b4494727f3588045aa00429849fcae51de70d68fa98228039" +dependencies = [ + "hex", + "serde", +] + [[package]] name = "hex_fmt" version = "0.3.0" @@ -556,17 +548,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "idna" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" -dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", -] - [[package]] name = "indexmap" version = "1.7.0" @@ -661,18 +642,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" -[[package]] -name = "matches" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" - -[[package]] -name = "memchr" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" - [[package]] name = "memory_units" version = "0.3.0" @@ -691,6 +660,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43db66d1170d347f9a065114077f7dccb00c1b9478c89384490a3425279a4606" dependencies = [ + "num-bigint 0.4.0", "num-complex", "num-integer", "num-iter", @@ -813,12 +783,6 @@ version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ddfc878dac00da22f8f61e7af3157988424567ab01d9920b962ef7dcbd7cd865" -[[package]] -name = "percent-encoding" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" - [[package]] name = "pin-project-lite" version = "0.2.7" @@ -866,17 +830,6 @@ dependencies = [ "tempfile", ] -[[package]] -name = "pulldown-cmark" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffade02495f22453cd593159ea2f59827aae7f53fa8323f756799b670881dcf8" -dependencies = [ - "bitflags", - "memchr", - "unicase", -] - [[package]] name = "pwasm-utils" version = "0.16.0" @@ -921,8 +874,6 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ - "getrandom 0.1.16", - "libc", "rand_chacha 0.2.2", "rand_core 0.5.1", "rand_hc 0.2.0", @@ -965,9 +916,6 @@ name = "rand_core" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", -] [[package]] name = "rand_core" @@ -975,7 +923,7 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" dependencies = [ - "getrandom 0.2.3", + "getrandom", ] [[package]] @@ -1014,15 +962,6 @@ dependencies = [ "bitflags", ] -[[package]] -name = "regex" -version = "1.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" -dependencies = [ - "regex-syntax", -] - [[package]] name = "regex-syntax" version = "0.6.25" @@ -1058,9 +997,9 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "schemars" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc6ab463ae35acccb5cba66c0084c985257b797d288b6050cc2f6ac1b266cb78" +checksum = "b82485a532ef0af18878ad4281f73e58161cdba1db7918176e9294f0ca5498a5" dependencies = [ "dyn-clone", "indexmap", @@ -1071,9 +1010,9 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "902fdfbcf871ae8f653bddf4b2c05905ddaabc08f69d32a915787e3be0d31356" +checksum = "791c2c848cff1abaeae34fef7e70da5f93171d9eea81ce0fe969a1df627a61a8" dependencies = [ "proc-macro2", "quote", @@ -1081,17 +1020,11 @@ dependencies = [ "syn", ] -[[package]] -name = "semver-parser" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b46e1121e8180c12ff69a742aabc4f310542b6ccb69f1691689ac17fdf8618aa" - [[package]] name = "serde" -version = "1.0.127" +version = "1.0.130" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8" +checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" dependencies = [ "serde_derive", ] @@ -1107,9 +1040,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.127" +version = "1.0.130" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a024926d3432516606328597e0f224a51355a493b49fdd67e9209187cbe55ecc" +checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" dependencies = [ "proc-macro2", "quote", @@ -1216,23 +1149,24 @@ version = "0.1.0" dependencies = [ "casper-contract", "casper-engine-test-support", + "casper-hashing", "casper-types", ] [[package]] name = "thiserror" -version = "1.0.26" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.26" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" dependencies = [ "proc-macro2", "quote", @@ -1249,30 +1183,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "tinyvec" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "848a1e1181b9f6753b5e96a092749e29b11d19ede67dfbbd6c7dc7e0f49b5338" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" - -[[package]] -name = "toml" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" -dependencies = [ - "serde", -] - [[package]] name = "tracing" version = "0.1.26" @@ -1323,55 +1233,19 @@ dependencies = [ "static_assertions", ] -[[package]] -name = "unicase" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" -dependencies = [ - "version_check", -] - -[[package]] -name = "unicode-bidi" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "246f4c42e67e7a4e3c6106ff716a5d067d4132a642840b242e357e468a2a0085" - -[[package]] -name = "unicode-normalization" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" -dependencies = [ - "tinyvec", -] - [[package]] name = "unicode-xid" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" -[[package]] -name = "url" -version = "2.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" -dependencies = [ - "form_urlencoded", - "idna", - "matches", - "percent-encoding", -] - [[package]] name = "uuid" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" dependencies = [ - "getrandom 0.2.3", + "getrandom", "serde", ] @@ -1385,21 +1259,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "version-sync" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cb94ca10ca0cf44f5d926ac977f0cac2d13e9789aa4bbe9d9388de445e61028" -dependencies = [ - "proc-macro2", - "pulldown-cmark", - "regex", - "semver-parser", - "syn", - "toml", - "url", -] - [[package]] name = "version_check" version = "0.9.3" @@ -1415,12 +1274,6 @@ dependencies = [ "libc", ] -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - [[package]] name = "wasi" version = "0.10.2+wasi-snapshot-preview1" diff --git a/cep47-tests/Cargo.toml b/cep47-tests/Cargo.toml index 60dd240..b363d82 100644 --- a/cep47-tests/Cargo.toml +++ b/cep47-tests/Cargo.toml @@ -6,9 +6,10 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -casper-contract = "1.3.2" -casper-types = "1.3.2" -casper-engine-test-support = "1.3.2" +casper-contract = "=1.4.1" +casper-types = "=1.4.1" +casper-hashing = "=1.4.1" +casper-engine-test-support = "=1.4.1" test-env = { path = "../utils/test-env" } contract-utils = { path = "../utils/contract-utils" } hex = "0.4.3" diff --git a/cep47/Cargo.toml b/cep47/Cargo.toml index 8e8b95f..f8f9a4e 100644 --- a/cep47/Cargo.toml +++ b/cep47/Cargo.toml @@ -6,8 +6,8 @@ edition = "2018" [dependencies] hex = { version = "0.4.3", default-features = false } -casper-contract = "1.3.2" -casper-types = "1.3.2" +casper-contract = "=1.4.1" +casper-types = "=1.4.1" contract-utils = { path = "../utils/contract-utils" } [[bin]] diff --git a/utils/contract-utils/Cargo.toml b/utils/contract-utils/Cargo.toml index 74a65da..7dcfd08 100644 --- a/utils/contract-utils/Cargo.toml +++ b/utils/contract-utils/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Maciej Zielinski "] edition = "2018" [dependencies] -casper-contract = "1.3.2" -casper-types = "1.3.2" +casper-contract = "=1.4.1" +casper-types = "=1.4.1" hex = { version = "0.4.3", default-features = false } diff --git a/utils/test-env/Cargo.toml b/utils/test-env/Cargo.toml index 7256e7f..fc8e86f 100644 --- a/utils/test-env/Cargo.toml +++ b/utils/test-env/Cargo.toml @@ -5,9 +5,10 @@ authors = ["Maciej Zielinski "] edition = "2018" [dependencies] -casper-contract = "1.3.0" -casper-types = "1.3.0" -casper-engine-test-support = "1.3.0" +casper-contract = "=1.4.1" +casper-types = "=1.4.1" +casper-hashing = "=1.4.1" +casper-engine-test-support = "=1.4.1" [features] default = ["casper-contract/std", "casper-types/std", "casper-engine-test-support/test-support", "casper-contract/test-support"] From be03402a99ac476d75f40c4f688122a0c211d2f6 Mon Sep 17 00:00:00 2001 From: astro019 Date: Wed, 17 Nov 2021 23:29:44 +1000 Subject: [PATCH 89/98] remove custom id for mint, add unique incremental id --- cep47-tests/src/cep47_instance.rs | 20 +-- cep47-tests/src/cep47_tests.rs | 201 ++++++++++++------------------ cep47/bin/cep47_token.rs | 14 +-- cep47/src/cep47.rs | 75 +++-------- cep47/src/data.rs | 4 +- 5 files changed, 100 insertions(+), 214 deletions(-) diff --git a/cep47-tests/src/cep47_instance.rs b/cep47-tests/src/cep47_instance.rs index 0f13acb..6529486 100644 --- a/cep47-tests/src/cep47_instance.rs +++ b/cep47-tests/src/cep47_instance.rs @@ -45,19 +45,12 @@ impl CEP47Instance { ); } - pub fn mint_one>( - &self, - sender: Sender, - recipient: T, - token_id: Option, - token_meta: Meta, - ) { + pub fn mint_one>(&self, sender: Sender, recipient: T, token_meta: Meta) { self.0.call_contract( sender, "mint", runtime_args! { "recipient" => recipient.into(), - "token_ids" => token_id.map(|x| vec![x]), "token_metas" => vec![token_meta] }, ) @@ -67,7 +60,6 @@ impl CEP47Instance { &self, sender: Sender, recipient: T, - token_ids: Option>, token_meta: Meta, count: u32, ) { @@ -76,26 +68,18 @@ impl CEP47Instance { "mint_copies", runtime_args! { "recipient" => recipient.into(), - "token_ids" => token_ids, "token_meta" => token_meta, "count" => count }, ) } - pub fn mint_many>( - &self, - sender: Sender, - recipient: T, - token_ids: Option>, - token_metas: Vec, - ) { + pub fn mint_many>(&self, sender: Sender, recipient: T, token_metas: Vec) { self.0.call_contract( sender, "mint", runtime_args! { "recipient" => recipient.into(), - "token_ids" => token_ids, "token_metas" => token_metas }, ) diff --git a/cep47-tests/src/cep47_tests.rs b/cep47-tests/src/cep47_tests.rs index 8976d24..38186c5 100644 --- a/cep47-tests/src/cep47_tests.rs +++ b/cep47-tests/src/cep47_tests.rs @@ -69,15 +69,10 @@ fn test_deploy() { fn test_token_meta() { let (env, token, owner) = deploy(); let user = env.next_user(); - let token_id = TokenId::from("custom_token_id"); + let token_id = TokenId::from("0"); let token_meta = meta::red_dragon(); - token.mint_one( - Sender(owner), - user, - Some(token_id.clone()), - token_meta.clone(), - ); + token.mint_one(Sender(owner), user, token_meta.clone()); let user_token_meta = token.token_meta(token_id.clone()); assert_eq!(user_token_meta.unwrap(), token_meta); @@ -87,33 +82,13 @@ fn test_token_meta() { } #[test] -fn test_mint_one_with_random_token_id() { +fn test_mint_one() { let (env, token, owner) = deploy(); let user = env.next_user(); - token.mint_one(Sender(owner), user, None, meta::red_dragon()); - - assert_eq!(token.total_supply(), U256::one()); - assert_eq!(token.balance_of(user), U256::one()); - - let first_user_token: Option = - token.get_token_by_index(Key::Account(user), U256::from(0)); - let second_user_token: Option = - token.get_token_by_index(Key::Account(user), U256::from(1)); - assert_eq!( - token.owner_of(first_user_token.unwrap()).unwrap(), - Key::Account(user) - ); - assert_eq!(second_user_token, None); -} - -#[test] -fn test_mint_one_with_set_token_id() { - let (env, token, owner) = deploy(); - let user = env.next_user(); - let token_id = TokenId::from("123456"); + let token_id = TokenId::from("0"); let token_meta = meta::red_dragon(); - token.mint_one(Sender(owner), user, Some(token_id.clone()), token_meta); + token.mint_one(Sender(owner), user, token_meta); let first_user_token = token.get_token_by_index(Key::Account(user), U256::from(0)); let second_user_token = token.get_token_by_index(Key::Account(user), U256::from(1)); assert_eq!(first_user_token, Some(token_id.clone())); @@ -123,49 +98,34 @@ fn test_mint_one_with_set_token_id() { assert_eq!(token.owner_of(token_id).unwrap(), Key::Account(user)); } -#[test] -#[should_panic] -fn test_mint_one_with_not_unique_token_id() { - let (env, token, owner) = deploy(); - let user = env.next_user(); - let token_id = TokenId::from("123456"); - let token_meta = meta::red_dragon(); - - token.mint_one( - Sender(owner), - user, - Some(token_id.clone()), - token_meta.clone(), - ); - - token.mint_one(Sender(owner), user, Some(token_id), token_meta); -} - #[test] fn test_mint_copies() { let (env, token, owner) = deploy(); let user = env.next_user(); let token_meta = meta::red_dragon(); - token.mint_copies(Sender(owner), user, None, token_meta, 3); + token.mint_copies(Sender(owner), user, token_meta, 3); let first_user_token = token.get_token_by_index(Key::Account(user), U256::from(0)); let second_user_token = token.get_token_by_index(Key::Account(user), U256::from(1)); let third_user_token = token.get_token_by_index(Key::Account(user), U256::from(2)); let fourth_user_token = token.get_token_by_index(Key::Account(user), U256::from(3)); assert_eq!(token.total_supply(), U256::from(3)); assert_eq!(token.balance_of(Key::Account(user)), U256::from(3)); - assert_eq!(fourth_user_token, None); assert_eq!( - token.owner_of(first_user_token.unwrap()).unwrap(), + token.owner_of(first_user_token.clone().unwrap()).unwrap(), Key::Account(user) ); assert_eq!( - token.owner_of(second_user_token.unwrap()).unwrap(), + token.owner_of(second_user_token.clone().unwrap()).unwrap(), Key::Account(user) ); assert_eq!( - token.owner_of(third_user_token.unwrap()).unwrap(), + token.owner_of(third_user_token.clone().unwrap()).unwrap(), Key::Account(user) ); + assert_eq!(first_user_token, Some(TokenId::from("0"))); + assert_eq!(second_user_token, Some(TokenId::from("1"))); + assert_eq!(third_user_token, Some(TokenId::from("2"))); + assert_eq!(fourth_user_token, None); } #[test] @@ -173,21 +133,23 @@ fn test_mint_many() { let (env, token, owner) = deploy(); let user = env.next_user(); let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; - token.mint_many(Sender(owner), user, None, token_metas); + token.mint_many(Sender(owner), user, token_metas); let first_user_token = token.get_token_by_index(Key::Account(user), U256::from(0)); let second_user_token = token.get_token_by_index(Key::Account(user), U256::from(1)); let third_user_token = token.get_token_by_index(Key::Account(user), U256::from(2)); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(user)), U256::from(2)); - assert_eq!(third_user_token, None); assert_eq!( - token.owner_of(first_user_token.unwrap()).unwrap(), + token.owner_of(first_user_token.clone().unwrap()).unwrap(), Key::Account(user) ); assert_eq!( - token.owner_of(second_user_token.unwrap()).unwrap(), + token.owner_of(second_user_token.clone().unwrap()).unwrap(), Key::Account(user) ); + assert_eq!(first_user_token, Some(TokenId::from("0"))); + assert_eq!(second_user_token, Some(TokenId::from("1"))); + assert_eq!(third_user_token, None); } #[test] @@ -201,16 +163,12 @@ fn test_burn_many() { meta::gold_dragon(), ]; - token.mint_many(Sender(owner), user, None, token_metas); + token.mint_many(Sender(owner), user, token_metas); - let first_user_token = token.get_token_by_index(Key::Account(user), U256::from(0)); - let second_user_token = token.get_token_by_index(Key::Account(user), U256::from(1)); - let third_user_token = token.get_token_by_index(Key::Account(user), U256::from(2)); - let fourth_user_token = token.get_token_by_index(Key::Account(user), U256::from(3)); token.burn_many( Sender(user), user, - vec![first_user_token.unwrap(), fourth_user_token.unwrap()], + vec![TokenId::from("0"), TokenId::from("3")], ); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(user)), U256::from(2)); @@ -219,8 +177,8 @@ fn test_burn_many() { let new_second_user_token = token.get_token_by_index(Key::Account(user), U256::from(1)); let new_third_user_token = token.get_token_by_index(Key::Account(user), U256::from(2)); let new_fourth_user_token = token.get_token_by_index(Key::Account(user), U256::from(3)); - assert_eq!(new_first_user_token, third_user_token); - assert_eq!(new_second_user_token, second_user_token); + assert_eq!(new_first_user_token, Some(TokenId::from("2"))); + assert_eq!(new_second_user_token, Some(TokenId::from("1"))); assert_eq!(new_third_user_token, None); assert_eq!(new_fourth_user_token, None); } @@ -236,24 +194,17 @@ fn test_burn_many_from_allowance_with_approve() { meta::gold_dragon(), ]; - token.mint_many(Sender(owner), user, None, token_metas); + token.mint_many(Sender(owner), user, token_metas); - let first_user_token = token.get_token_by_index(Key::Account(user), U256::from(0)); - let second_user_token = token.get_token_by_index(Key::Account(user), U256::from(1)); - let third_user_token = token.get_token_by_index(Key::Account(user), U256::from(2)); - let fourth_user_token = token.get_token_by_index(Key::Account(user), U256::from(3)); token.approve( Sender(user), owner, - vec![ - first_user_token.clone().unwrap(), - third_user_token.clone().unwrap(), - ], + vec![TokenId::from("0"), TokenId::from("2")], ); token.burn_many( Sender(owner), user, - vec![first_user_token.unwrap(), third_user_token.unwrap()], + vec![TokenId::from("0"), TokenId::from("2")], ); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(user)), U256::from(2)); @@ -262,8 +213,8 @@ fn test_burn_many_from_allowance_with_approve() { let new_second_user_token = token.get_token_by_index(Key::Account(user), U256::from(1)); let new_third_user_token = token.get_token_by_index(Key::Account(user), U256::from(2)); let new_fourth_user_token = token.get_token_by_index(Key::Account(user), U256::from(3)); - assert_eq!(new_first_user_token, fourth_user_token); - assert_eq!(new_second_user_token, second_user_token); + assert_eq!(new_first_user_token, Some(TokenId::from("3"))); + assert_eq!(new_second_user_token, Some(TokenId::from("1"))); assert_eq!(new_third_user_token, None); assert_eq!(new_fourth_user_token, None); } @@ -280,37 +231,57 @@ fn test_burn_many_from_allowance_without_approve() { meta::gold_dragon(), ]; - token.mint_many(Sender(owner), user, None, token_metas); + token.mint_many(Sender(owner), user, token_metas); - let first_user_token = token.get_token_by_index(Key::Account(user), U256::from(0)); - let second_user_token = token.get_token_by_index(Key::Account(user), U256::from(1)); token.burn_many( Sender(owner), user, - vec![first_user_token.unwrap(), second_user_token.unwrap()], + vec![TokenId::from("0"), TokenId::from("1")], ); } #[test] fn test_burn_one() { - // TODO: the sender should be owner of nft item or allowed party let (env, token, owner) = deploy(); let user = env.next_user(); let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; - token.mint_many(Sender(owner), user, None, token_metas); + token.mint_many(Sender(owner), user, token_metas); - let first_user_token = token.get_token_by_index(Key::Account(user), U256::from(0)); - let second_user_token = token.get_token_by_index(Key::Account(user), U256::from(1)); - token.burn_one(Sender(user), user, first_user_token.unwrap()); + token.burn_one(Sender(user), user, TokenId::from("0")); assert_eq!(token.total_supply(), U256::from(1)); assert_eq!(token.balance_of(Key::Account(user)), U256::from(1)); let new_first_user_token = token.get_token_by_index(Key::Account(user), U256::from(0)); let new_second_user_token = token.get_token_by_index(Key::Account(user), U256::from(1)); - assert_eq!(new_first_user_token, second_user_token); + assert_eq!(new_first_user_token, Some(TokenId::from("1"))); assert_eq!(new_second_user_token, None); } +#[test] +fn test_unique_id_after_burn_and_mint() { + let (env, token, owner) = deploy(); + let user = env.next_user(); + let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; + token.mint_many(Sender(owner), user, token_metas.clone()); + + assert_eq!(token.total_supply(), U256::from(2)); + token.burn_one(Sender(user), user, TokenId::from("1")); + assert_eq!(token.total_supply(), U256::from(1)); + assert_eq!(token.balance_of(Key::Account(user)), U256::from(1)); + token.mint_many(Sender(owner), user, token_metas); + + let new_first_user_token = token.get_token_by_index(Key::Account(user), U256::from(0)); + let new_second_user_token = token.get_token_by_index(Key::Account(user), U256::from(1)); + let new_third_user_token = token.get_token_by_index(Key::Account(user), U256::from(2)); + let new_fourth_user_token = token.get_token_by_index(Key::Account(user), U256::from(3)); + assert_eq!(token.balance_of(Key::Account(user)), U256::from(3)); + assert_eq!(token.total_supply(), U256::from(3)); + assert_eq!(new_first_user_token, Some(TokenId::from("0"))); + assert_eq!(new_second_user_token, Some(TokenId::from("2"))); + assert_eq!(new_third_user_token, Some(TokenId::from("3"))); + assert_eq!(new_fourth_user_token, None); +} + #[test] fn test_transfer_token() { let (env, token, owner) = deploy(); @@ -318,22 +289,20 @@ fn test_transfer_token() { let bob = env.next_user(); let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; - token.mint_many(Sender(owner), ali, None, token_metas); - let first_ali_token = token.get_token_by_index(Key::Account(ali), U256::from(0)); - let second_ali_token = token.get_token_by_index(Key::Account(ali), U256::from(1)); + token.mint_many(Sender(owner), ali, token_metas); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(ali)), U256::from(2)); assert_eq!( - token.owner_of(first_ali_token.clone().unwrap()).unwrap(), + token.owner_of(TokenId::from("0")).unwrap(), Key::Account(ali) ); assert_eq!( - token.owner_of(second_ali_token.unwrap()).unwrap(), + token.owner_of(TokenId::from("1")).unwrap(), Key::Account(ali) ); - token.transfer(Sender(ali), bob, vec![first_ali_token.unwrap()]); + token.transfer(Sender(ali), bob, vec![TokenId::from("0")]); let new_first_ali_token = token.get_token_by_index(Key::Account(ali), U256::from(0)); let new_second_ali_token = token.get_token_by_index(Key::Account(ali), U256::from(1)); let new_first_bob_token = token.get_token_by_index(Key::Account(bob), U256::from(0)); @@ -364,22 +333,19 @@ fn test_transfer_from_tokens_with_approve() { let bob = env.next_user(); let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; - token.mint_many(Sender(owner), ali, None, token_metas); - let first_ali_token = token.get_token_by_index(Key::Account(ali), U256::from(0)); - let second_ali_token = token.get_token_by_index(Key::Account(ali), U256::from(1)); - + token.mint_many(Sender(owner), ali, token_metas); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(ali)), U256::from(2)); assert_eq!( - token.owner_of(first_ali_token.unwrap()).unwrap(), + token.owner_of(TokenId::from("0")).unwrap(), Key::Account(ali) ); assert_eq!( - token.owner_of(second_ali_token.clone().unwrap()).unwrap(), + token.owner_of(TokenId::from("1")).unwrap(), Key::Account(ali) ); - token.approve(Sender(ali), owner, vec![second_ali_token.clone().unwrap()]); - token.transfer_from(Sender(owner), ali, bob, vec![second_ali_token.unwrap()]); + token.approve(Sender(ali), owner, vec![TokenId::from("1")]); + token.transfer_from(Sender(owner), ali, bob, vec![TokenId::from("1")]); let new_first_ali_token = token.get_token_by_index(Key::Account(ali), U256::from(0)); let new_second_ali_token = token.get_token_by_index(Key::Account(ali), U256::from(1)); let new_first_bob_token = token.get_token_by_index(Key::Account(bob), U256::from(0)); @@ -407,20 +373,19 @@ fn test_transfer_from_tokens_without_approve() { let bob = env.next_user(); let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; - token.mint_many(Sender(owner), ali, None, token_metas); - let first_ali_token = token.get_token_by_index(Key::Account(ali), U256::from(0)); + token.mint_many(Sender(owner), ali, token_metas); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(ali)), U256::from(2)); assert_eq!( - token.owner_of(first_ali_token.clone().unwrap()).unwrap(), + token.owner_of(TokenId::from("0")).unwrap(), Key::Account(ali) ); assert_eq!( - token.owner_of(first_ali_token.clone().unwrap()).unwrap(), + token.owner_of(TokenId::from("0")).unwrap(), Key::Account(ali) ); - token.transfer_from(Sender(owner), ali, bob, vec![first_ali_token.unwrap()]); + token.transfer_from(Sender(owner), ali, bob, vec![TokenId::from("0")]); } #[test] @@ -434,26 +399,19 @@ fn test_approve() { meta::gold_dragon(), ]; - token.mint_many(Sender(owner), user, None, token_metas); + token.mint_many(Sender(owner), user, token_metas); - let first_user_token = token.get_token_by_index(Key::Account(user), U256::from(0)); - let fourth_user_token = token.get_token_by_index(Key::Account(user), U256::from(3)); token.approve( Sender(user), owner, - vec![ - first_user_token.clone().unwrap(), - fourth_user_token.clone().unwrap(), - ], + vec![TokenId::from("0"), TokenId::from("3")], ); assert_eq!( - token.get_approved(user, first_user_token.unwrap()).unwrap(), + token.get_approved(user, TokenId::from("0")).unwrap(), Key::Account(owner) ); assert_eq!( - token - .get_approved(user, fourth_user_token.unwrap()) - .unwrap(), + token.get_approved(user, TokenId::from("3")).unwrap(), Key::Account(owner) ); } @@ -462,14 +420,9 @@ fn test_approve() { fn test_token_metadata_update() { let (env, token, owner) = deploy(); let user = env.next_user(); - let token_id = TokenId::from("123456"); + let token_id = TokenId::from("0"); - token.mint_one( - Sender(owner), - user, - Some(token_id.clone()), - meta::red_dragon(), - ); + token.mint_one(Sender(owner), user, meta::red_dragon()); token.update_token_meta(Sender(owner), token_id.clone(), meta::gold_dragon()); assert_eq!(token.token_meta(token_id).unwrap(), meta::gold_dragon()); diff --git a/cep47/bin/cep47_token.rs b/cep47/bin/cep47_token.rs index 088bff4..d59daaf 100644 --- a/cep47/bin/cep47_token.rs +++ b/cep47/bin/cep47_token.rs @@ -111,21 +111,19 @@ fn update_token_meta() { #[no_mangle] fn mint() { let recipient = runtime::get_named_arg::("recipient"); - let token_ids = runtime::get_named_arg::>>("token_ids"); let token_metas = runtime::get_named_arg::>("token_metas"); NFTToken::default() - .mint(recipient, token_ids, token_metas) + .mint(recipient, token_metas) .unwrap_or_revert(); } #[no_mangle] fn mint_copies() { let recipient = runtime::get_named_arg::("recipient"); - let token_ids = runtime::get_named_arg::>>("token_ids"); let token_meta = runtime::get_named_arg::("token_meta"); let count = runtime::get_named_arg::("count"); NFTToken::default() - .mint_copies(recipient, token_ids, token_meta, count) + .mint_copies(recipient, token_meta, count) .unwrap_or_revert(); } @@ -315,10 +313,6 @@ fn get_entry_points() -> EntryPoints { "mint", vec![ Parameter::new("recipient", Key::cl_type()), - Parameter::new( - "token_ids", - CLType::Option(Box::new(CLType::List(Box::new(TokenId::cl_type())))), - ), Parameter::new("token_metas", CLType::List(Box::new(Meta::cl_type()))), ], <()>::cl_type(), @@ -329,10 +323,6 @@ fn get_entry_points() -> EntryPoints { "mint_copies", vec![ Parameter::new("recipient", Key::cl_type()), - Parameter::new( - "token_ids", - CLType::Option(Box::new(CLType::List(Box::new(TokenId::cl_type())))), - ), Parameter::new("token_meta", Meta::cl_type()), Parameter::new("count", CLType::U32), ], diff --git a/cep47/src/cep47.rs b/cep47/src/cep47.rs index a73fd32..f03e834 100644 --- a/cep47/src/cep47.rs +++ b/cep47/src/cep47.rs @@ -1,11 +1,11 @@ use crate::{ + alloc::string::ToString, data::{self, Allowances, Metadata, OwnedTokens, Owners}, event::CEP47Event, Meta, TokenId, }; use alloc::{string::String, vec::Vec}; -use casper_contract::{contract_api::runtime, unwrap_or_revert::UnwrapOrRevert}; -use casper_types::{bytesrepr::ToBytes, ApiError, Key, U256}; +use casper_types::{ApiError, Key, U256}; use contract_utils::{ContractContext, ContractStorage}; #[repr(u16)] @@ -78,20 +78,6 @@ pub trait CEP47: ContractContext { OwnedTokens::instance().get_token_by_index(&owner, &index) } - fn generate_token_ids(&mut self, n: u32) -> Vec { - let block_time = runtime::get_blocktime(); - let mut token_ids = Vec::new(); - let nonce = data::nonce(); - for i in nonce..nonce + n { - let mut bytes: Vec = block_time.to_bytes().unwrap_or_revert(); - bytes.append(&mut i.to_bytes().unwrap_or_revert()); - let hash = runtime::blake2b(bytes); - token_ids.push(hex::encode(hash)); - } - data::set_nonce(nonce + n); - token_ids - } - fn validate_token_ids(&self, token_ids: Vec) -> bool { for token_id in &token_ids { if self.owner_of(token_id.clone()).is_some() { @@ -101,68 +87,41 @@ pub trait CEP47: ContractContext { true } - fn mint( - &mut self, - recipient: Key, - token_ids: Option>, - token_metas: Vec, - ) -> Result, Error> { - let mut valid_token_metas = token_metas; - let unique_token_ids = match token_ids { - // Validate token_ids and metas. - Some(token_ids) => { - if token_ids.len() != valid_token_metas.len() { - return Err(Error::WrongArguments); - }; - let valid = self.validate_token_ids(token_ids.clone()); - if !valid { - return Err(Error::TokenIdAlreadyExists); - }; - token_ids - } - None => { - if valid_token_metas.is_empty() { - valid_token_metas = vec![Meta::new()]; - } - self.generate_token_ids(valid_token_metas.len() as u32) - } - }; - + fn mint(&mut self, recipient: Key, token_metas: Vec) -> Result, Error> { + let mut token_id = data::nonce(); + let mut token_ids = vec![]; let owners_dict = Owners::instance(); let owned_tokens_dict = OwnedTokens::instance(); let metadata_dict = Metadata::instance(); - - for (token_id, token_meta) in unique_token_ids.iter().zip(&valid_token_metas) { - metadata_dict.set(token_id, token_meta.clone()); - owners_dict.set(token_id, recipient); - owned_tokens_dict.set_token(&recipient, token_id.clone()); + for token_meta in token_metas { + let str_token_id = token_id.to_string(); + token_ids.push(str_token_id.clone()); + metadata_dict.set(&str_token_id, token_meta.clone()); + owners_dict.set(&str_token_id, recipient); + owned_tokens_dict.set_token(&recipient, str_token_id); + token_id += U256::one(); } + data::set_nonce(token_id); - let minted_tokens_count = U256::from(unique_token_ids.len() as u64); + let minted_tokens_count = U256::from(token_ids.len() as u64); let new_total_supply = data::total_supply() + minted_tokens_count; data::set_total_supply(new_total_supply); self.emit(CEP47Event::Mint { recipient, - token_ids: unique_token_ids.clone(), + token_ids: token_ids.clone(), }); - Ok(unique_token_ids) + Ok(token_ids) } fn mint_copies( &mut self, recipient: Key, - token_ids: Option>, token_meta: Meta, count: u32, ) -> Result, Error> { - if let Some(token_ids) = &token_ids { - if token_ids.len() != count as usize { - return Err(Error::WrongArguments); - } - } let token_metas = vec![token_meta; count as usize]; - self.mint(recipient, token_ids, token_metas) + self.mint(recipient, token_metas) } fn burn(&mut self, owner: Key, token_ids: Vec) -> Result<(), Error> { diff --git a/cep47/src/data.rs b/cep47/src/data.rs index 5205f7f..dc2bfed 100644 --- a/cep47/src/data.rs +++ b/cep47/src/data.rs @@ -223,11 +223,11 @@ pub fn set_total_supply(total_supply: U256) { set_key(TOTAL_SUPPLY, total_supply); } -pub fn nonce() -> u32 { +pub fn nonce() -> U256 { get_key(NONCE).unwrap_or_default() } -pub fn set_nonce(nonce: u32) { +pub fn set_nonce(nonce: U256) { set_key(NONCE, nonce); } From 87b80a3689674141ffc1a068df138725cba50813 Mon Sep 17 00:00:00 2001 From: astro019 Date: Tue, 23 Nov 2021 11:50:56 +1000 Subject: [PATCH 90/98] remove token_id generation, accept only U256 token_id --- cep47-tests/src/cep47_instance.rs | 28 ++++- cep47-tests/src/cep47_tests.rs | 197 +++++++++++++----------------- cep47/bin/cep47_token.rs | 8 +- cep47/src/cep47.rs | 46 +++---- cep47/src/data.rs | 72 +++++------ cep47/src/lib.rs | 3 +- 6 files changed, 170 insertions(+), 184 deletions(-) diff --git a/cep47-tests/src/cep47_instance.rs b/cep47-tests/src/cep47_instance.rs index 6529486..494622e 100644 --- a/cep47-tests/src/cep47_instance.rs +++ b/cep47-tests/src/cep47_instance.rs @@ -7,7 +7,7 @@ use blake2::{ use casper_types::{bytesrepr::ToBytes, runtime_args, CLTyped, Key, RuntimeArgs, U256}; use test_env::{Sender, TestContract, TestEnv}; -pub type TokenId = String; +pub type TokenId = U256; pub type Meta = BTreeMap; pub struct CEP47Instance(TestContract); @@ -45,12 +45,19 @@ impl CEP47Instance { ); } - pub fn mint_one>(&self, sender: Sender, recipient: T, token_meta: Meta) { + pub fn mint_one>( + &self, + sender: Sender, + recipient: T, + token_id: TokenId, + token_meta: Meta, + ) { self.0.call_contract( sender, "mint", runtime_args! { "recipient" => recipient.into(), + "token_ids" => vec![token_id], "token_metas" => vec![token_meta] }, ) @@ -60,6 +67,7 @@ impl CEP47Instance { &self, sender: Sender, recipient: T, + token_ids: Vec, token_meta: Meta, count: u32, ) { @@ -68,18 +76,26 @@ impl CEP47Instance { "mint_copies", runtime_args! { "recipient" => recipient.into(), + "token_ids" => token_ids, "token_meta" => token_meta, "count" => count }, ) } - pub fn mint_many>(&self, sender: Sender, recipient: T, token_metas: Vec) { + pub fn mint_many>( + &self, + sender: Sender, + recipient: T, + token_ids: Vec, + token_metas: Vec, + ) { self.0.call_contract( sender, "mint", runtime_args! { "recipient" => recipient.into(), + "token_ids" => token_ids, "token_metas" => token_metas }, ) @@ -147,7 +163,7 @@ impl CEP47Instance { pub fn get_approved>(&self, owner: T, token_id: TokenId) -> Option { self.0.query_dictionary( "allowances", - key_and_value_to_str::(&owner.into(), &token_id), + key_and_value_to_str::(&owner.into(), &token_id.to_string()), ) } @@ -176,11 +192,11 @@ impl CEP47Instance { } pub fn owner_of(&self, token_id: TokenId) -> Option { - self.0.query_dictionary("owners", token_id) + self.0.query_dictionary("owners", token_id.to_string()) } pub fn token_meta(&self, token_id: TokenId) -> Option { - self.0.query_dictionary("metadata", token_id) + self.0.query_dictionary("metadata", token_id.to_string()) } pub fn name(&self) -> String { diff --git a/cep47-tests/src/cep47_tests.rs b/cep47-tests/src/cep47_tests.rs index 38186c5..9512c1a 100644 --- a/cep47-tests/src/cep47_tests.rs +++ b/cep47-tests/src/cep47_tests.rs @@ -69,12 +69,12 @@ fn test_deploy() { fn test_token_meta() { let (env, token, owner) = deploy(); let user = env.next_user(); - let token_id = TokenId::from("0"); + let token_id = TokenId::zero(); let token_meta = meta::red_dragon(); - token.mint_one(Sender(owner), user, token_meta.clone()); + token.mint_one(Sender(owner), user, token_id, token_meta.clone()); - let user_token_meta = token.token_meta(token_id.clone()); + let user_token_meta = token.token_meta(token_id); assert_eq!(user_token_meta.unwrap(), token_meta); let first_user_token = token.get_token_by_index(Key::Account(user), U256::zero()); @@ -85,13 +85,13 @@ fn test_token_meta() { fn test_mint_one() { let (env, token, owner) = deploy(); let user = env.next_user(); - let token_id = TokenId::from("0"); + let token_id = TokenId::zero(); let token_meta = meta::red_dragon(); - token.mint_one(Sender(owner), user, token_meta); + token.mint_one(Sender(owner), user, token_id, token_meta); let first_user_token = token.get_token_by_index(Key::Account(user), U256::from(0)); let second_user_token = token.get_token_by_index(Key::Account(user), U256::from(1)); - assert_eq!(first_user_token, Some(token_id.clone())); + assert_eq!(first_user_token, Some(token_id)); assert_eq!(token.total_supply(), U256::one()); assert_eq!(token.balance_of(Key::Account(user)), U256::one()); assert_eq!(second_user_token, None); @@ -103,7 +103,8 @@ fn test_mint_copies() { let (env, token, owner) = deploy(); let user = env.next_user(); let token_meta = meta::red_dragon(); - token.mint_copies(Sender(owner), user, token_meta, 3); + let token_ids = vec![TokenId::zero(), TokenId::one(), TokenId::from(2)]; + token.mint_copies(Sender(owner), user, token_ids.clone(), token_meta, 3); let first_user_token = token.get_token_by_index(Key::Account(user), U256::from(0)); let second_user_token = token.get_token_by_index(Key::Account(user), U256::from(1)); let third_user_token = token.get_token_by_index(Key::Account(user), U256::from(2)); @@ -111,20 +112,20 @@ fn test_mint_copies() { assert_eq!(token.total_supply(), U256::from(3)); assert_eq!(token.balance_of(Key::Account(user)), U256::from(3)); assert_eq!( - token.owner_of(first_user_token.clone().unwrap()).unwrap(), + token.owner_of(first_user_token.unwrap()).unwrap(), Key::Account(user) ); assert_eq!( - token.owner_of(second_user_token.clone().unwrap()).unwrap(), + token.owner_of(second_user_token.unwrap()).unwrap(), Key::Account(user) ); assert_eq!( - token.owner_of(third_user_token.clone().unwrap()).unwrap(), + token.owner_of(third_user_token.unwrap()).unwrap(), Key::Account(user) ); - assert_eq!(first_user_token, Some(TokenId::from("0"))); - assert_eq!(second_user_token, Some(TokenId::from("1"))); - assert_eq!(third_user_token, Some(TokenId::from("2"))); + assert_eq!(first_user_token, Some(token_ids[0])); + assert_eq!(second_user_token, Some(token_ids[1])); + assert_eq!(third_user_token, Some(token_ids[2])); assert_eq!(fourth_user_token, None); } @@ -133,22 +134,23 @@ fn test_mint_many() { let (env, token, owner) = deploy(); let user = env.next_user(); let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; - token.mint_many(Sender(owner), user, token_metas); + let token_ids = vec![TokenId::zero(), TokenId::one()]; + token.mint_many(Sender(owner), user, token_ids.clone(), token_metas); let first_user_token = token.get_token_by_index(Key::Account(user), U256::from(0)); let second_user_token = token.get_token_by_index(Key::Account(user), U256::from(1)); let third_user_token = token.get_token_by_index(Key::Account(user), U256::from(2)); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(user)), U256::from(2)); assert_eq!( - token.owner_of(first_user_token.clone().unwrap()).unwrap(), + token.owner_of(first_user_token.unwrap()).unwrap(), Key::Account(user) ); assert_eq!( - token.owner_of(second_user_token.clone().unwrap()).unwrap(), + token.owner_of(second_user_token.unwrap()).unwrap(), Key::Account(user) ); - assert_eq!(first_user_token, Some(TokenId::from("0"))); - assert_eq!(second_user_token, Some(TokenId::from("1"))); + assert_eq!(first_user_token, Some(token_ids[0])); + assert_eq!(second_user_token, Some(token_ids[1])); assert_eq!(third_user_token, None); } @@ -162,14 +164,16 @@ fn test_burn_many() { meta::black_dragon(), meta::gold_dragon(), ]; + let token_ids = vec![ + TokenId::zero(), + TokenId::one(), + TokenId::from(2), + TokenId::from(3), + ]; - token.mint_many(Sender(owner), user, token_metas); + token.mint_many(Sender(owner), user, token_ids.clone(), token_metas); - token.burn_many( - Sender(user), - user, - vec![TokenId::from("0"), TokenId::from("3")], - ); + token.burn_many(Sender(user), user, vec![token_ids[0], token_ids[3]]); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(user)), U256::from(2)); @@ -177,8 +181,8 @@ fn test_burn_many() { let new_second_user_token = token.get_token_by_index(Key::Account(user), U256::from(1)); let new_third_user_token = token.get_token_by_index(Key::Account(user), U256::from(2)); let new_fourth_user_token = token.get_token_by_index(Key::Account(user), U256::from(3)); - assert_eq!(new_first_user_token, Some(TokenId::from("2"))); - assert_eq!(new_second_user_token, Some(TokenId::from("1"))); + assert_eq!(new_first_user_token, Some(token_ids[2])); + assert_eq!(new_second_user_token, Some(token_ids[1])); assert_eq!(new_third_user_token, None); assert_eq!(new_fourth_user_token, None); } @@ -193,19 +197,17 @@ fn test_burn_many_from_allowance_with_approve() { meta::black_dragon(), meta::gold_dragon(), ]; + let token_ids = vec![ + TokenId::zero(), + TokenId::one(), + TokenId::from(2), + TokenId::from(3), + ]; - token.mint_many(Sender(owner), user, token_metas); + token.mint_many(Sender(owner), user, token_ids.clone(), token_metas); - token.approve( - Sender(user), - owner, - vec![TokenId::from("0"), TokenId::from("2")], - ); - token.burn_many( - Sender(owner), - user, - vec![TokenId::from("0"), TokenId::from("2")], - ); + token.approve(Sender(user), owner, vec![token_ids[0], token_ids[2]]); + token.burn_many(Sender(owner), user, vec![token_ids[0], token_ids[2]]); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(user)), U256::from(2)); @@ -213,8 +215,8 @@ fn test_burn_many_from_allowance_with_approve() { let new_second_user_token = token.get_token_by_index(Key::Account(user), U256::from(1)); let new_third_user_token = token.get_token_by_index(Key::Account(user), U256::from(2)); let new_fourth_user_token = token.get_token_by_index(Key::Account(user), U256::from(3)); - assert_eq!(new_first_user_token, Some(TokenId::from("3"))); - assert_eq!(new_second_user_token, Some(TokenId::from("1"))); + assert_eq!(new_first_user_token, Some(token_ids[3])); + assert_eq!(new_second_user_token, Some(token_ids[1])); assert_eq!(new_third_user_token, None); assert_eq!(new_fourth_user_token, None); } @@ -230,14 +232,16 @@ fn test_burn_many_from_allowance_without_approve() { meta::black_dragon(), meta::gold_dragon(), ]; + let token_ids = vec![ + TokenId::zero(), + TokenId::one(), + TokenId::from(2), + TokenId::from(3), + ]; - token.mint_many(Sender(owner), user, token_metas); + token.mint_many(Sender(owner), user, token_ids.clone(), token_metas); - token.burn_many( - Sender(owner), - user, - vec![TokenId::from("0"), TokenId::from("1")], - ); + token.burn_many(Sender(owner), user, vec![token_ids[0], token_ids[1]]); } #[test] @@ -245,64 +249,35 @@ fn test_burn_one() { let (env, token, owner) = deploy(); let user = env.next_user(); let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; - token.mint_many(Sender(owner), user, token_metas); + let token_ids = vec![TokenId::zero(), TokenId::one()]; + token.mint_many(Sender(owner), user, token_ids.clone(), token_metas); - token.burn_one(Sender(user), user, TokenId::from("0")); + token.burn_one(Sender(user), user, token_ids[0]); assert_eq!(token.total_supply(), U256::from(1)); assert_eq!(token.balance_of(Key::Account(user)), U256::from(1)); let new_first_user_token = token.get_token_by_index(Key::Account(user), U256::from(0)); let new_second_user_token = token.get_token_by_index(Key::Account(user), U256::from(1)); - assert_eq!(new_first_user_token, Some(TokenId::from("1"))); + assert_eq!(new_first_user_token, Some(token_ids[1])); assert_eq!(new_second_user_token, None); } -#[test] -fn test_unique_id_after_burn_and_mint() { - let (env, token, owner) = deploy(); - let user = env.next_user(); - let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; - token.mint_many(Sender(owner), user, token_metas.clone()); - - assert_eq!(token.total_supply(), U256::from(2)); - token.burn_one(Sender(user), user, TokenId::from("1")); - assert_eq!(token.total_supply(), U256::from(1)); - assert_eq!(token.balance_of(Key::Account(user)), U256::from(1)); - token.mint_many(Sender(owner), user, token_metas); - - let new_first_user_token = token.get_token_by_index(Key::Account(user), U256::from(0)); - let new_second_user_token = token.get_token_by_index(Key::Account(user), U256::from(1)); - let new_third_user_token = token.get_token_by_index(Key::Account(user), U256::from(2)); - let new_fourth_user_token = token.get_token_by_index(Key::Account(user), U256::from(3)); - assert_eq!(token.balance_of(Key::Account(user)), U256::from(3)); - assert_eq!(token.total_supply(), U256::from(3)); - assert_eq!(new_first_user_token, Some(TokenId::from("0"))); - assert_eq!(new_second_user_token, Some(TokenId::from("2"))); - assert_eq!(new_third_user_token, Some(TokenId::from("3"))); - assert_eq!(new_fourth_user_token, None); -} - #[test] fn test_transfer_token() { let (env, token, owner) = deploy(); let ali = env.next_user(); let bob = env.next_user(); let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; + let token_ids = vec![TokenId::zero(), TokenId::one()]; - token.mint_many(Sender(owner), ali, token_metas); + token.mint_many(Sender(owner), ali, token_ids.clone(), token_metas); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(ali)), U256::from(2)); - assert_eq!( - token.owner_of(TokenId::from("0")).unwrap(), - Key::Account(ali) - ); - assert_eq!( - token.owner_of(TokenId::from("1")).unwrap(), - Key::Account(ali) - ); + assert_eq!(token.owner_of(token_ids[0]).unwrap(), Key::Account(ali)); + assert_eq!(token.owner_of(token_ids[1]).unwrap(), Key::Account(ali)); - token.transfer(Sender(ali), bob, vec![TokenId::from("0")]); + token.transfer(Sender(ali), bob, vec![token_ids[0]]); let new_first_ali_token = token.get_token_by_index(Key::Account(ali), U256::from(0)); let new_second_ali_token = token.get_token_by_index(Key::Account(ali), U256::from(1)); let new_first_bob_token = token.get_token_by_index(Key::Account(bob), U256::from(0)); @@ -332,20 +307,15 @@ fn test_transfer_from_tokens_with_approve() { let ali = env.next_user(); let bob = env.next_user(); let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; + let token_ids = vec![TokenId::zero(), TokenId::one()]; - token.mint_many(Sender(owner), ali, token_metas); + token.mint_many(Sender(owner), ali, token_ids.clone(), token_metas); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(ali)), U256::from(2)); - assert_eq!( - token.owner_of(TokenId::from("0")).unwrap(), - Key::Account(ali) - ); - assert_eq!( - token.owner_of(TokenId::from("1")).unwrap(), - Key::Account(ali) - ); - token.approve(Sender(ali), owner, vec![TokenId::from("1")]); - token.transfer_from(Sender(owner), ali, bob, vec![TokenId::from("1")]); + assert_eq!(token.owner_of(token_ids[0]).unwrap(), Key::Account(ali)); + assert_eq!(token.owner_of(token_ids[1]).unwrap(), Key::Account(ali)); + token.approve(Sender(ali), owner, vec![TokenId::one()]); + token.transfer_from(Sender(owner), ali, bob, vec![TokenId::one()]); let new_first_ali_token = token.get_token_by_index(Key::Account(ali), U256::from(0)); let new_second_ali_token = token.get_token_by_index(Key::Account(ali), U256::from(1)); let new_first_bob_token = token.get_token_by_index(Key::Account(bob), U256::from(0)); @@ -372,20 +342,15 @@ fn test_transfer_from_tokens_without_approve() { let ali = env.next_user(); let bob = env.next_user(); let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; + let token_ids = vec![TokenId::zero(), TokenId::one()]; - token.mint_many(Sender(owner), ali, token_metas); + token.mint_many(Sender(owner), ali, token_ids.clone(), token_metas); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(ali)), U256::from(2)); - assert_eq!( - token.owner_of(TokenId::from("0")).unwrap(), - Key::Account(ali) - ); - assert_eq!( - token.owner_of(TokenId::from("0")).unwrap(), - Key::Account(ali) - ); - token.transfer_from(Sender(owner), ali, bob, vec![TokenId::from("0")]); + assert_eq!(token.owner_of(token_ids[0]).unwrap(), Key::Account(ali)); + assert_eq!(token.owner_of(token_ids[1]).unwrap(), Key::Account(ali)); + token.transfer_from(Sender(owner), ali, bob, vec![token_ids[0]]); } #[test] @@ -398,20 +363,22 @@ fn test_approve() { meta::black_dragon(), meta::gold_dragon(), ]; + let token_ids = vec![ + TokenId::zero(), + TokenId::one(), + TokenId::from(1), + TokenId::from(2), + ]; - token.mint_many(Sender(owner), user, token_metas); + token.mint_many(Sender(owner), user, token_ids.clone(), token_metas); - token.approve( - Sender(user), - owner, - vec![TokenId::from("0"), TokenId::from("3")], - ); + token.approve(Sender(user), owner, vec![token_ids[0], token_ids[3]]); assert_eq!( - token.get_approved(user, TokenId::from("0")).unwrap(), + token.get_approved(user, token_ids[0]).unwrap(), Key::Account(owner) ); assert_eq!( - token.get_approved(user, TokenId::from("3")).unwrap(), + token.get_approved(user, token_ids[3]).unwrap(), Key::Account(owner) ); } @@ -420,10 +387,10 @@ fn test_approve() { fn test_token_metadata_update() { let (env, token, owner) = deploy(); let user = env.next_user(); - let token_id = TokenId::from("0"); + let token_id = TokenId::zero(); - token.mint_one(Sender(owner), user, meta::red_dragon()); + token.mint_one(Sender(owner), user, token_id, meta::red_dragon()); - token.update_token_meta(Sender(owner), token_id.clone(), meta::gold_dragon()); + token.update_token_meta(Sender(owner), token_id, meta::gold_dragon()); assert_eq!(token.token_meta(token_id).unwrap(), meta::gold_dragon()); } diff --git a/cep47/bin/cep47_token.rs b/cep47/bin/cep47_token.rs index d59daaf..f90a5ee 100644 --- a/cep47/bin/cep47_token.rs +++ b/cep47/bin/cep47_token.rs @@ -111,19 +111,21 @@ fn update_token_meta() { #[no_mangle] fn mint() { let recipient = runtime::get_named_arg::("recipient"); + let token_ids = runtime::get_named_arg::>("token_ids"); let token_metas = runtime::get_named_arg::>("token_metas"); NFTToken::default() - .mint(recipient, token_metas) + .mint(recipient, token_ids, token_metas) .unwrap_or_revert(); } #[no_mangle] fn mint_copies() { let recipient = runtime::get_named_arg::("recipient"); + let token_ids = runtime::get_named_arg::>("token_ids"); let token_meta = runtime::get_named_arg::("token_meta"); let count = runtime::get_named_arg::("count"); NFTToken::default() - .mint_copies(recipient, token_meta, count) + .mint_copies(recipient, token_ids, token_meta, count) .unwrap_or_revert(); } @@ -313,6 +315,7 @@ fn get_entry_points() -> EntryPoints { "mint", vec![ Parameter::new("recipient", Key::cl_type()), + Parameter::new("token_ids", CLType::List(Box::new(TokenId::cl_type()))), Parameter::new("token_metas", CLType::List(Box::new(Meta::cl_type()))), ], <()>::cl_type(), @@ -323,6 +326,7 @@ fn get_entry_points() -> EntryPoints { "mint_copies", vec![ Parameter::new("recipient", Key::cl_type()), + Parameter::new("token_ids", CLType::List(Box::new(TokenId::cl_type()))), Parameter::new("token_meta", Meta::cl_type()), Parameter::new("count", CLType::U32), ], diff --git a/cep47/src/cep47.rs b/cep47/src/cep47.rs index f03e834..1aa1757 100644 --- a/cep47/src/cep47.rs +++ b/cep47/src/cep47.rs @@ -1,5 +1,4 @@ use crate::{ - alloc::string::ToString, data::{self, Allowances, Metadata, OwnedTokens, Owners}, event::CEP47Event, Meta, TokenId, @@ -63,7 +62,7 @@ pub trait CEP47: ContractContext { } fn set_token_meta(&mut self, token_id: TokenId, meta: Meta) -> Result<(), Error> { - if self.owner_of(token_id.clone()).is_none() { + if self.owner_of(token_id).is_none() { return Err(Error::TokenIdDoesntExist); }; @@ -80,28 +79,32 @@ pub trait CEP47: ContractContext { fn validate_token_ids(&self, token_ids: Vec) -> bool { for token_id in &token_ids { - if self.owner_of(token_id.clone()).is_some() { + if self.owner_of(*token_id).is_some() { return false; } } true } - fn mint(&mut self, recipient: Key, token_metas: Vec) -> Result, Error> { - let mut token_id = data::nonce(); - let mut token_ids = vec![]; + fn mint( + &mut self, + recipient: Key, + token_ids: Vec, + token_metas: Vec, + ) -> Result, Error> { + if token_ids.len() != token_metas.len() { + return Err(Error::WrongArguments); + }; + let owners_dict = Owners::instance(); let owned_tokens_dict = OwnedTokens::instance(); let metadata_dict = Metadata::instance(); - for token_meta in token_metas { - let str_token_id = token_id.to_string(); - token_ids.push(str_token_id.clone()); - metadata_dict.set(&str_token_id, token_meta.clone()); - owners_dict.set(&str_token_id, recipient); - owned_tokens_dict.set_token(&recipient, str_token_id); - token_id += U256::one(); + + for (token_id, token_meta) in token_ids.iter().zip(&token_metas) { + metadata_dict.set(token_id, token_meta.clone()); + owners_dict.set(token_id, recipient); + owned_tokens_dict.set_token(&recipient, token_id); } - data::set_nonce(token_id); let minted_tokens_count = U256::from(token_ids.len() as u64); let new_total_supply = data::total_supply() + minted_tokens_count; @@ -117,17 +120,18 @@ pub trait CEP47: ContractContext { fn mint_copies( &mut self, recipient: Key, + token_ids: Vec, token_meta: Meta, count: u32, ) -> Result, Error> { let token_metas = vec![token_meta; count as usize]; - self.mint(recipient, token_metas) + self.mint(recipient, token_ids, token_metas) } fn burn(&mut self, owner: Key, token_ids: Vec) -> Result<(), Error> { let spender = self.get_caller(); for token_id in &token_ids { - if spender != owner && !self.is_approved(owner, token_id.clone(), spender) { + if spender != owner && !self.is_approved(owner, *token_id, spender) { return Err(Error::PermissionDenied); } } @@ -154,7 +158,7 @@ pub trait CEP47: ContractContext { } for token_id in &token_ids { - owned_tokens_dict.remove_token(&owner, token_id.clone()); + owned_tokens_dict.remove_token(&owner, token_id); metadata_dict.remove(token_id); owners_dict.remove(token_id); allowances_dict.remove(&owner, token_id); @@ -171,7 +175,7 @@ pub trait CEP47: ContractContext { fn approve(&mut self, spender: Key, token_ids: Vec) -> Result<(), Error> { let caller = self.get_caller(); for token_id in &token_ids { - let owner = self.owner_of(token_id.clone()); + let owner = self.owner_of(*token_id); if owner.is_none() { return Err(Error::WrongArguments); } @@ -207,7 +211,7 @@ pub trait CEP47: ContractContext { if owner != spender { for token_id in &token_ids { - if !self.is_approved(owner, token_id.clone(), spender) { + if !self.is_approved(owner, *token_id, spender) { return Err(Error::PermissionDenied); } allowances_dict.remove(&owner, token_id); @@ -239,8 +243,8 @@ pub trait CEP47: ContractContext { } for token_id in &token_ids { - owned_tokens_dict.remove_token(&owner, token_id.clone()); - owned_tokens_dict.set_token(&recipient, token_id.clone()); + owned_tokens_dict.remove_token(&owner, token_id); + owned_tokens_dict.set_token(&recipient, token_id); owners_dict.set(token_id, recipient); } diff --git a/cep47/src/data.rs b/cep47/src/data.rs index dc2bfed..990a617 100644 --- a/cep47/src/data.rs +++ b/cep47/src/data.rs @@ -21,7 +21,6 @@ pub const NAME: &str = "name"; pub const META: &str = "meta"; pub const SYMBOL: &str = "symbol"; pub const TOTAL_SUPPLY: &str = "total_supply"; -pub const NONCE: &str = "nonce"; pub struct Owners { dict: Dict, @@ -38,16 +37,16 @@ impl Owners { Dict::init(OWNERS_DICT) } - pub fn get(&self, key: &str) -> Option { - self.dict.get(key) + pub fn get(&self, key: &TokenId) -> Option { + self.dict.get(&key.to_string()) } - pub fn set(&self, key: &str, value: Key) { - self.dict.set(key, value); + pub fn set(&self, key: &TokenId, value: Key) { + self.dict.set(&key.to_string(), value); } - pub fn remove(&self, key: &str) { - self.dict.remove::(key); + pub fn remove(&self, key: &TokenId) { + self.dict.remove::(&key.to_string()); } } @@ -66,16 +65,16 @@ impl Metadata { Dict::init(METADATA_DICT) } - pub fn get(&self, key: &str) -> Option { - self.dict.get(key) + pub fn get(&self, key: &TokenId) -> Option { + self.dict.get(&key.to_string()) } - pub fn set(&self, key: &str, value: Meta) { - self.dict.set(key, value); + pub fn set(&self, key: &TokenId, value: Meta) { + self.dict.set(&key.to_string(), value); } - pub fn remove(&self, key: &str) { - self.dict.remove::(key); + pub fn remove(&self, key: &TokenId) { + self.dict.remove::(&key.to_string()); } } @@ -104,9 +103,8 @@ impl OwnedTokens { self.tokens_dict.get(&key_and_value_to_str(owner, index)) } - pub fn get_index_by_token(&self, owner: &Key, value: &str) -> Option { - self.indexes_dict - .get(&key_and_value_to_str(owner, &value.to_string())) + pub fn get_index_by_token(&self, owner: &Key, value: &TokenId) -> Option { + self.indexes_dict.get(&key_and_value_to_str(owner, value)) } pub fn get_balances(&self, owner: &Key) -> U256 { @@ -119,18 +117,18 @@ impl OwnedTokens { self.balances_dict.set(&key_to_str(owner), value); } - pub fn set_token(&self, owner: &Key, value: TokenId) { + pub fn set_token(&self, owner: &Key, value: &TokenId) { let length = self.get_balances(owner); self.indexes_dict - .set(&key_and_value_to_str(owner, &value), length); + .set(&key_and_value_to_str(owner, value), length); self.tokens_dict - .set(&key_and_value_to_str(owner, &length), value); + .set(&key_and_value_to_str(owner, &length), *value); self.set_balances(owner, length + 1); } - pub fn remove_token(&self, owner: &Key, value: TokenId) { + pub fn remove_token(&self, owner: &Key, value: &TokenId) { let length = self.get_balances(owner); - let index = self.get_index_by_token(owner, &value).unwrap_or_revert(); + let index = self.get_index_by_token(owner, value).unwrap_or_revert(); match length.cmp(&(index + 1)) { core::cmp::Ordering::Equal => { self.tokens_dict @@ -140,7 +138,7 @@ impl OwnedTokens { core::cmp::Ordering::Greater => { let last = self.get_token_by_index(owner, &(length - 1)); self.indexes_dict.set( - &key_and_value_to_str(owner, &last.clone().unwrap_or_revert()), + &key_and_value_to_str(owner, &last.unwrap_or_revert()), index, ); self.tokens_dict.set( @@ -154,7 +152,7 @@ impl OwnedTokens { core::cmp::Ordering::Less => {} } self.indexes_dict - .remove::(&key_and_value_to_str(owner, &value)); + .remove::(&key_and_value_to_str(owner, value)); } } @@ -173,21 +171,25 @@ impl Allowances { Dict::init(ALLOWANCES_DICT) } - pub fn get(&self, owner: &Key, token_id: &str) -> Option { - self.dict - .get(key_and_value_to_str::(owner, &token_id.to_string()).as_str()) + pub fn get(&self, owner: &Key, token_id: &TokenId) -> Option { + self.dict.get(&key_and_value_to_str::( + owner, + &token_id.to_string(), + )) } - pub fn set(&self, owner: &Key, token_id: &str, value: Key) { + pub fn set(&self, owner: &Key, token_id: &TokenId, value: Key) { self.dict.set( - key_and_value_to_str::(owner, &token_id.to_string()).as_str(), + &key_and_value_to_str::(owner, &token_id.to_string()), value, ); } - pub fn remove(&self, owner: &Key, token_id: &str) { - self.dict - .remove::(key_and_value_to_str::(owner, &token_id.to_string()).as_str()); + pub fn remove(&self, owner: &Key, token_id: &TokenId) { + self.dict.remove::(&key_and_value_to_str::( + owner, + &token_id.to_string(), + )); } } @@ -223,14 +225,6 @@ pub fn set_total_supply(total_supply: U256) { set_key(TOTAL_SUPPLY, total_supply); } -pub fn nonce() -> U256 { - get_key(NONCE).unwrap_or_default() -} - -pub fn set_nonce(nonce: U256) { - set_key(NONCE, nonce); -} - pub fn contract_package_hash() -> ContractPackageHash { get_key(CONTRACT_PACKAGE_HASH).unwrap_or_revert() } diff --git a/cep47/src/lib.rs b/cep47/src/lib.rs index bc17bb3..54f38b7 100644 --- a/cep47/src/lib.rs +++ b/cep47/src/lib.rs @@ -10,5 +10,6 @@ pub use cep47::{Error, CEP47}; pub use contract_utils; use alloc::{collections::BTreeMap, string::String}; -pub type TokenId = String; +use casper_types::U256; +pub type TokenId = U256; pub type Meta = BTreeMap; From ffca5182639f33fec121fc74a523b5091c8fd6aa Mon Sep 17 00:00:00 2001 From: astro019 Date: Thu, 30 Dec 2021 01:21:39 +1000 Subject: [PATCH 91/98] add existing token_id checking on mint --- cep47/src/cep47.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cep47/src/cep47.rs b/cep47/src/cep47.rs index 1aa1757..bd4d15b 100644 --- a/cep47/src/cep47.rs +++ b/cep47/src/cep47.rs @@ -96,6 +96,12 @@ pub trait CEP47: ContractContext { return Err(Error::WrongArguments); }; + for token_id in &token_ids { + if None == self.owner_of(*token_id) { + return Err(Error::TokenIdAlreadyExists); + } + } + let owners_dict = Owners::instance(); let owned_tokens_dict = OwnedTokens::instance(); let metadata_dict = Metadata::instance(); From df881fc813624b36a027bac90dd84e9d8378d2e2 Mon Sep 17 00:00:00 2001 From: astro019 Date: Thu, 30 Dec 2021 01:32:14 +1000 Subject: [PATCH 92/98] fix condition issues on existing token_id condition check --- cep47/src/cep47.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cep47/src/cep47.rs b/cep47/src/cep47.rs index bd4d15b..97bc38e 100644 --- a/cep47/src/cep47.rs +++ b/cep47/src/cep47.rs @@ -97,7 +97,7 @@ pub trait CEP47: ContractContext { }; for token_id in &token_ids { - if None == self.owner_of(*token_id) { + if let Some(_) = self.owner_of(*token_id) { return Err(Error::TokenIdAlreadyExists); } } From 46f7d8ad486a3afacde98e4edc7ec015e41c1316 Mon Sep 17 00:00:00 2001 From: astro019 Date: Thu, 30 Dec 2021 01:34:55 +1000 Subject: [PATCH 93/98] fix lint issues --- cep47/src/cep47.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cep47/src/cep47.rs b/cep47/src/cep47.rs index 97bc38e..5811962 100644 --- a/cep47/src/cep47.rs +++ b/cep47/src/cep47.rs @@ -97,7 +97,7 @@ pub trait CEP47: ContractContext { }; for token_id in &token_ids { - if let Some(_) = self.owner_of(*token_id) { + if self.owner_of(*token_id).is_some() { return Err(Error::TokenIdAlreadyExists); } } From 9130b25a14746c77d9c2d652a9152bad3bb031ae Mon Sep 17 00:00:00 2001 From: astro019 Date: Fri, 14 Jan 2022 01:31:58 +1000 Subject: [PATCH 94/98] update code format --- cep47/src/cep47.rs | 36 +++++++++++--------- utils/contract-utils/src/admin_control.rs | 9 ++--- utils/contract-utils/src/contract_context.rs | 2 +- 3 files changed, 24 insertions(+), 23 deletions(-) diff --git a/cep47/src/cep47.rs b/cep47/src/cep47.rs index 5811962..528544b 100644 --- a/cep47/src/cep47.rs +++ b/cep47/src/cep47.rs @@ -6,6 +6,7 @@ use crate::{ use alloc::{string::String, vec::Vec}; use casper_types::{ApiError, Key, U256}; use contract_utils::{ContractContext, ContractStorage}; +use core::convert::TryInto; #[repr(u16)] pub enum Error { @@ -112,8 +113,10 @@ pub trait CEP47: ContractContext { owned_tokens_dict.set_token(&recipient, token_id); } - let minted_tokens_count = U256::from(token_ids.len() as u64); - let new_total_supply = data::total_supply() + minted_tokens_count; + let minted_tokens_count: U256 = From::::from(token_ids.len().try_into().unwrap()); + let new_total_supply = data::total_supply() + .checked_add(minted_tokens_count) + .unwrap(); data::set_total_supply(new_total_supply); self.emit(CEP47Event::Mint { @@ -130,15 +133,17 @@ pub trait CEP47: ContractContext { token_meta: Meta, count: u32, ) -> Result, Error> { - let token_metas = vec![token_meta; count as usize]; + let token_metas = vec![token_meta; count.try_into().unwrap()]; self.mint(recipient, token_ids, token_metas) } fn burn(&mut self, owner: Key, token_ids: Vec) -> Result<(), Error> { let spender = self.get_caller(); - for token_id in &token_ids { - if spender != owner && !self.is_approved(owner, *token_id, spender) { - return Err(Error::PermissionDenied); + if spender != owner { + for token_id in &token_ids { + if !self.is_approved(owner, *token_id, spender) { + return Err(Error::PermissionDenied); + } } } self.burn_internal(owner, token_ids) @@ -170,8 +175,10 @@ pub trait CEP47: ContractContext { allowances_dict.remove(&owner, token_id); } - let burnt_tokens_count = U256::from(token_ids.len() as u64); - let new_total_supply = data::total_supply() - burnt_tokens_count; + let burnt_tokens_count: U256 = From::::from(token_ids.len().try_into().unwrap()); + let new_total_supply = data::total_supply() + .checked_sub(burnt_tokens_count) + .unwrap(); data::set_total_supply(new_total_supply); self.emit(CEP47Event::Burn { owner, token_ids }); @@ -181,14 +188,11 @@ pub trait CEP47: ContractContext { fn approve(&mut self, spender: Key, token_ids: Vec) -> Result<(), Error> { let caller = self.get_caller(); for token_id in &token_ids { - let owner = self.owner_of(*token_id); - if owner.is_none() { - return Err(Error::WrongArguments); - } - if owner.unwrap() != caller { - return Err(Error::PermissionDenied); + match self.owner_of(*token_id) { + None => return Err(Error::WrongArguments), + Some(owner) if owner != caller => return Err(Error::PermissionDenied), + Some(_) => Allowances::instance().set(&caller, token_id, spender), } - Allowances::instance().set(&caller, token_id, spender); } self.emit(CEP47Event::Approve { owner: caller, @@ -212,10 +216,10 @@ pub trait CEP47: ContractContext { recipient: Key, token_ids: Vec, ) -> Result<(), Error> { - let allowances_dict = Allowances::instance(); let spender = self.get_caller(); if owner != spender { + let allowances_dict = Allowances::instance(); for token_id in &token_ids { if !self.is_approved(owner, *token_id, spender) { return Err(Error::PermissionDenied); diff --git a/utils/contract-utils/src/admin_control.rs b/utils/contract-utils/src/admin_control.rs index f759e25..fe921ad 100644 --- a/utils/contract-utils/src/admin_control.rs +++ b/utils/contract-utils/src/admin_control.rs @@ -1,7 +1,4 @@ -use casper_contract::{ - contract_api::{runtime, storage}, - unwrap_or_revert::UnwrapOrRevert, -}; +use casper_contract::contract_api::runtime; use casper_types::{ApiError, Key}; use crate::{ContractContext, ContractStorage, Dict}; @@ -29,7 +26,7 @@ pub trait AdminControl: ContractContext { fn assert_caller_is_admin(&self) { let caller = self.get_caller(); - if !Admins::instance().is_admin(&caller) { + if !self.is_admin(caller) { runtime::revert(ApiError::User(20)); } } @@ -50,7 +47,7 @@ impl Admins { } } pub fn init() { - storage::new_dictionary(ADMINS_DICT).unwrap_or_revert(); + Dict::init(ADMINS_DICT); } pub fn is_admin(&self, key: &Key) -> bool { diff --git a/utils/contract-utils/src/contract_context.rs b/utils/contract-utils/src/contract_context.rs index 2fc178d..911b732 100644 --- a/utils/contract-utils/src/contract_context.rs +++ b/utils/contract-utils/src/contract_context.rs @@ -12,7 +12,7 @@ pub trait ContractContext { element_to_key(caller.unwrap_or_revert()) } - fn self_addr(&mut self) -> Key { + fn self_addr(&self) -> Key { let call_stack = self.storage().call_stack(); element_to_key(call_stack.last().unwrap_or_revert()) } From 2c33c67aa6cb8958e3a6e93389a1b58b1ba6705a Mon Sep 17 00:00:00 2001 From: astro019 Date: Fri, 14 Jan 2022 23:35:32 +1000 Subject: [PATCH 95/98] change contract package initilasation --- cep47/bin/cep47_token.rs | 55 +++++++++++++--------------------------- cep47/src/data.rs | 18 ++++++++++--- 2 files changed, 33 insertions(+), 40 deletions(-) diff --git a/cep47/bin/cep47_token.rs b/cep47/bin/cep47_token.rs index f90a5ee..aab8749 100644 --- a/cep47/bin/cep47_token.rs +++ b/cep47/bin/cep47_token.rs @@ -4,19 +4,13 @@ #[macro_use] extern crate alloc; -use alloc::{ - boxed::Box, - collections::BTreeSet, - format, - string::{String, ToString}, - vec::Vec, -}; +use alloc::{boxed::Box, collections::BTreeSet, format, string::String, vec::Vec}; use casper_contract::{ contract_api::{runtime, storage}, unwrap_or_revert::UnwrapOrRevert, }; use casper_types::{ - contracts::NamedKeys, runtime_args, CLType, CLTyped, CLValue, EntryPoint, EntryPointAccess, + runtime_args, CLType, CLTyped, CLValue, ContractPackageHash, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Group, Key, Parameter, RuntimeArgs, URef, U256, }; use cep47::{Meta, TokenId, CEP47}; @@ -176,20 +170,11 @@ fn get_approved() { #[no_mangle] fn call() { - let (package_hash, access_token) = storage::create_contract_package_at_hash(); - let mut named_keys = NamedKeys::new(); - let contract_package_hash_wrapped = storage::new_uref(package_hash).into(); - named_keys.insert( - "contract_package_hash".to_string(), - contract_package_hash_wrapped, - ); - let (contract_hash, _) = - storage::add_contract_version(package_hash, get_entry_points(), named_keys); - // Read arguments for the constructor call. let name: String = runtime::get_named_arg("name"); let symbol: String = runtime::get_named_arg("symbol"); let meta: Meta = runtime::get_named_arg("meta"); + let contract_name: String = runtime::get_named_arg("contract_name"); // Prepare constructor args let constructor_args = runtime_args! { @@ -198,33 +183,33 @@ fn call() { "meta" => meta }; - // Add the constructor group to the package hash with a single URef. + let (contract_hash, _) = storage::new_contract( + get_entry_points(), + None, + Some(String::from("contract_package_hash")), + None, + ); + + let package_hash: ContractPackageHash = ContractPackageHash::new( + runtime::get_key("contract_package_hash") + .unwrap_or_revert() + .into_hash() + .unwrap_or_revert(), + ); + let constructor_access: URef = storage::create_contract_user_group(package_hash, "constructor", 1, Default::default()) .unwrap_or_revert() .pop() .unwrap_or_revert(); - // Call the constructor entry point - let _: () = - runtime::call_versioned_contract(package_hash, None, "constructor", constructor_args); + let _: () = runtime::call_contract(contract_hash, "constructor", constructor_args); - // Remove all URefs from the constructor group, so no one can call it for the second time. let mut urefs = BTreeSet::new(); urefs.insert(constructor_access); storage::remove_contract_user_group_urefs(package_hash, "constructor", urefs) .unwrap_or_revert(); - // Store contract in the account's named keys. - let contract_name: alloc::string::String = runtime::get_named_arg("contract_name"); - runtime::put_key( - &format!("{}_package_hash", contract_name), - package_hash.into(), - ); - runtime::put_key( - &format!("{}_package_hash_wrapped", contract_name), - contract_package_hash_wrapped, - ); runtime::put_key( &format!("{}_contract_hash", contract_name), contract_hash.into(), @@ -233,10 +218,6 @@ fn call() { &format!("{}_contract_hash_wrapped", contract_name), storage::new_uref(contract_hash).into(), ); - runtime::put_key( - &format!("{}_package_access_token", contract_name), - access_token.into(), - ); } fn get_entry_points() -> EntryPoints { diff --git a/cep47/src/data.rs b/cep47/src/data.rs index 990a617..70c262e 100644 --- a/cep47/src/data.rs +++ b/cep47/src/data.rs @@ -3,8 +3,11 @@ use alloc::{ string::{String, ToString}, vec::Vec, }; -use casper_contract::{contract_api::storage, unwrap_or_revert::UnwrapOrRevert}; -use casper_types::{ContractPackageHash, Key, URef, U256}; +use casper_contract::{ + contract_api::{runtime::get_call_stack, storage}, + unwrap_or_revert::UnwrapOrRevert, +}; +use casper_types::{system::CallStackElement, ContractPackageHash, Key, URef, U256}; use contract_utils::{get_key, key_and_value_to_str, key_to_str, set_key, Dict}; use crate::{event::CEP47Event, Meta, TokenId}; @@ -226,7 +229,16 @@ pub fn set_total_supply(total_supply: U256) { } pub fn contract_package_hash() -> ContractPackageHash { - get_key(CONTRACT_PACKAGE_HASH).unwrap_or_revert() + let call_stacks = get_call_stack(); + let last_entry = call_stacks.last().unwrap_or_revert(); + let package_hash: Option = match last_entry { + CallStackElement::StoredContract { + contract_package_hash, + contract_hash: _, + } => Some(*contract_package_hash), + _ => None, + }; + package_hash.unwrap_or_revert() } pub fn emit(event: &CEP47Event) { From d7cc5cf8530bc19caba3cc19da4fdcff641a1b20 Mon Sep 17 00:00:00 2001 From: astro019 Date: Mon, 17 Jan 2022 20:06:29 +1000 Subject: [PATCH 96/98] upgrade to test2.0 --- Cargo.lock | 194 +++++++++++++++------------- cep47-tests/Cargo.toml | 9 +- cep47-tests/src/cep47_instance.rs | 33 +++-- cep47-tests/src/cep47_tests.rs | 62 ++++----- cep47/Cargo.toml | 4 +- utils/contract-utils/Cargo.toml | 5 +- utils/test-env/Cargo.toml | 8 +- utils/test-env/src/lib.rs | 6 +- utils/test-env/src/test_contract.rs | 35 ++--- utils/test-env/src/test_env.rs | 126 ++++++++++++------ utils/test-env/src/utils.rs | 121 +++++++++++++++++ 11 files changed, 392 insertions(+), 211 deletions(-) create mode 100644 utils/test-env/src/utils.rs diff --git a/Cargo.lock b/Cargo.lock index 801a44f..4b985cf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "anyhow" -version = "1.0.43" +version = "1.0.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28ae2b3dec75a406790005a200b1bd89785afc02517a00ca99ecfe093ee9e6cf" +checksum = "84450d0b4a8bd1ba4144ce8ce718fbc5d071358b1e5384bace6536b3d1f2d5b3" [[package]] name = "autocfg" @@ -69,9 +69,9 @@ dependencies = [ [[package]] name = "blake2" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a5720225ef5daecf08657f23791354e1685a8c91a4c60c7f3d3b2892f978f4" +checksum = "0a4e37d16930f5459780f5621038b6382b9bb37c19016f39fb6b5808d831f174" dependencies = [ "crypto-mac 0.8.0", "digest", @@ -95,9 +95,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "casper-contract" -version = "1.4.1" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d268cab5c7ec026f596abbb3bde5afa72e4dbca5d870f0e8f55fd456dc39239d" +checksum = "e4e145bb5b2cde2f0c76b8571a03ef8a6de37616ef0e6e4b8a9bac937ff39c40" dependencies = [ "casper-types", "hex_fmt", @@ -106,11 +106,10 @@ dependencies = [ [[package]] name = "casper-engine-test-support" -version = "1.4.1" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e52f2b4a1c979eb65abc87d284fb8f09dd764201c051246464da90a53037948c" +checksum = "13aeaa9950a9d0e778d0a94de98a323337b54e6c03bdeeafe44af19ea6005240" dependencies = [ - "casper-contract", "casper-execution-engine", "casper-hashing", "casper-types", @@ -124,9 +123,9 @@ dependencies = [ [[package]] name = "casper-execution-engine" -version = "1.4.1" +version = "1.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f71e7d10ca7cdec6a150cb9e2c87c0dcda757fd067fbee1e345bda7eceae540" +checksum = "dddee9d2f4e3dacdb7c69887cfe0ae1d2ffa6fa8af340d5d0ed4243ab21fbd24" dependencies = [ "anyhow", "base16", @@ -135,7 +134,6 @@ dependencies = [ "casper-types", "chrono", "datasize", - "hex", "hex-buffer-serde 0.2.2", "hex_fmt", "hostname", @@ -167,9 +165,9 @@ dependencies = [ [[package]] name = "casper-hashing" -version = "1.4.1" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5001fe4a9ca2fbebf62152ed1227cca215be1d912fef526a3fcaa9a21f9d7498" +checksum = "5af18f77cbabac69777333e0551accf1cd403995706953d4dabc56d7b56667a8" dependencies = [ "base16", "blake2", @@ -180,13 +178,14 @@ dependencies = [ "itertools", "schemars", "serde", + "thiserror", ] [[package]] name = "casper-types" -version = "1.4.1" +version = "1.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12b42e0c175b4c593a4c10db210a0a95fe2a7ddcb99a8e82c97d7d45c08e01ed" +checksum = "e9da1776d44d053d9b60040b7e70b448ce34608762e989cc1106d083125bf200" dependencies = [ "base16", "base64", @@ -214,9 +213,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.69" +version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2" +checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" [[package]] name = "cep47" @@ -235,6 +234,7 @@ dependencies = [ "blake2", "casper-contract", "casper-engine-test-support", + "casper-execution-engine", "casper-hashing", "casper-types", "contract-utils", @@ -278,9 +278,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.1.5" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66c99696f6c9dd7f35d486b9d04d7e6e202aa3e8c40d553f2fdf5e7e0c6a71ef" +checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" dependencies = [ "libc", ] @@ -313,9 +313,9 @@ dependencies = [ [[package]] name = "ctor" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e98e2ad1a782e33928b96fc3948e7c355e5af34ba4de7670fe8bac2a3b2006d" +checksum = "ccc0a48a9b826acdf4028595adc9db92caea352f7af011a3034acd172a52a0aa" dependencies = [ "quote", "syn", @@ -336,18 +336,18 @@ dependencies = [ [[package]] name = "datasize" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cfa50a16bc31c1e8d1682876a26aa205e6669ac65645ae484064cbbc5263abc" +checksum = "2cdaf1625dae32ea757a4a98e6f59496bb4fe80a41efb0bd57e631f6cb341770" dependencies = [ "datasize_derive", ] [[package]] name = "datasize_derive" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ebcbe9ac751b6e1700a10201b44ae32fa36396b46849fdb4f7ec5fb86326de3" +checksum = "1065db16e6dad1cfa0f50966d8405bb9f6d13f74f34d685b417f301cb32f1d86" dependencies = [ "proc-macro2", "quote", @@ -431,6 +431,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "fastrand" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "779d043b6a0b90cc4c0ed7ee380a6504394cee7efd7db050e3774eee387324b2" +dependencies = [ + "instant", +] + [[package]] name = "ff" version = "0.8.0" @@ -456,9 +465,9 @@ checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" [[package]] name = "generic-array" -version = "0.14.4" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" dependencies = [ "typenum", "version_check", @@ -466,9 +475,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c" dependencies = [ "cfg-if 1.0.0", "libc", @@ -550,29 +559,38 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" +checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" dependencies = [ "autocfg", "hashbrown", "serde", ] +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if 1.0.0", +] + [[package]] name = "itertools" -version = "0.10.1" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf" +checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" dependencies = [ "either", ] [[package]] name = "itoa" -version = "0.4.7" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" [[package]] name = "k256" @@ -593,9 +611,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.99" +version = "0.2.112" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7f823d141fe0a24df1e23b4af4e3c7ba9e5966ec514ea068c93024aa7deb765" +checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" [[package]] name = "linked-hash-map" @@ -660,7 +678,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43db66d1170d347f9a065114077f7dccb00c1b9478c89384490a3425279a4606" dependencies = [ - "num-bigint 0.4.0", + "num-bigint 0.4.3", "num-complex", "num-integer", "num-iter", @@ -681,9 +699,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.0" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e0d047c1062aa51e256408c560894e5251f08925980e53cf1aa5bd00eec6512" +checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" dependencies = [ "autocfg", "num-integer", @@ -750,7 +768,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d41702bd167c2df5520b384281bc111a4b5efcf7fbc4c9c222c815b07e0a6a6a" dependencies = [ "autocfg", - "num-bigint 0.4.0", + "num-bigint 0.4.3", "num-integer", "num-traits", "serde", @@ -767,9 +785,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" +checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" [[package]] name = "opaque-debug" @@ -785,27 +803,27 @@ checksum = "ddfc878dac00da22f8f61e7af3157988424567ab01d9920b962ef7dcbd7cd865" [[package]] name = "pin-project-lite" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" +checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" [[package]] name = "pkg-config" -version = "0.3.19" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" +checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe" [[package]] name = "ppv-lite86" -version = "0.2.10" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" [[package]] name = "proc-macro2" -version = "1.0.28" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" +checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" dependencies = [ "unicode-xid", ] @@ -855,9 +873,9 @@ checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" [[package]] name = "quote" -version = "1.0.9" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d" dependencies = [ "proc-macro2", ] @@ -991,9 +1009,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.5" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" [[package]] name = "schemars" @@ -1022,9 +1040,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.130" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" +checksum = "97565067517b60e2d1ea8b268e59ce036de907ac523ad83a0475da04e818989a" dependencies = [ "serde_derive", ] @@ -1040,9 +1058,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.130" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" +checksum = "ed201699328568d8d08208fdd080e3ff594e6c422e438b6705905da01005d537" dependencies = [ "proc-macro2", "quote", @@ -1062,9 +1080,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.66" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127" +checksum = "c059c05b48c5c0067d4b4b2b4f0732dd65feb52daf7e0ea09cd87e7dadc1af79" dependencies = [ "itoa", "ryu", @@ -1073,9 +1091,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.9.5" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b362ae5752fd2137731f9fa25fd4d9058af34666ca1966fb969119cc35719f12" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" dependencies = [ "block-buffer", "cfg-if 1.0.0", @@ -1108,9 +1126,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.74" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c" +checksum = "a684ac3dcd8913827e18cd09a68384ee66c1de24157e3c556c9ab16d85695fb7" dependencies = [ "proc-macro2", "quote", @@ -1119,9 +1137,9 @@ dependencies = [ [[package]] name = "synstructure" -version = "0.12.5" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "474aaa926faa1603c40b7885a9eaea29b444d1cb2850cb7c0e37bb1a4182f4fa" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" dependencies = [ "proc-macro2", "quote", @@ -1131,13 +1149,13 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.2.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" +checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" dependencies = [ "cfg-if 1.0.0", + "fastrand", "libc", - "rand 0.8.4", "redox_syscall", "remove_dir_all", "winapi", @@ -1149,7 +1167,7 @@ version = "0.1.0" dependencies = [ "casper-contract", "casper-engine-test-support", - "casper-hashing", + "casper-execution-engine", "casper-types", ] @@ -1185,9 +1203,9 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.26" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d" +checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105" dependencies = [ "cfg-if 1.0.0", "pin-project-lite", @@ -1197,9 +1215,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.15" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42e6fa53307c8a17e4ccd4dc81cf5ec38db9209f59b222210375b54ee40d1e2" +checksum = "f4f480b8f81512e825f337ad51e94c1eb5d3bbdf2b363dcd01e2b19a9ffe3f8e" dependencies = [ "proc-macro2", "quote", @@ -1208,18 +1226,18 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.18" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9ff14f98b1a4b289c6248a023c1c2fa1491062964e9fed67ab29c4e4da4a052" +checksum = "1f4ed65637b8390770814083d20756f87bfa2c21bf2f110babdc5438351746e4" dependencies = [ "lazy_static", ] [[package]] name = "typenum" -version = "1.13.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" [[package]] name = "uint" @@ -1251,9 +1269,9 @@ dependencies = [ [[package]] name = "value-bag" -version = "1.0.0-alpha.7" +version = "1.0.0-alpha.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd320e1520f94261153e96f7534476ad869c14022aee1e59af7c778075d840ae" +checksum = "79923f7731dc61ebfba3633098bf3ac533bbd35ccd8c57e7088d9a5eebe0263f" dependencies = [ "ctor", "version_check", @@ -1261,9 +1279,9 @@ dependencies = [ [[package]] name = "version_check" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "wait-timeout" @@ -1346,18 +1364,18 @@ checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" [[package]] name = "zeroize" -version = "1.4.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "377db0846015f7ae377174787dd452e1c5f5a9050bc6f954911d01f116daa0cd" +checksum = "cc222aec311c323c717f56060324f32b82da1ce1dd81d9a09aa6a9030bfe08db" dependencies = [ "zeroize_derive", ] [[package]] name = "zeroize_derive" -version = "1.1.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2c1e130bebaeab2f23886bf9acbaca14b092408c452543c857f66399cd6dab1" +checksum = "81e8f13fef10b63c06356d65d416b070798ddabcadc10d3ece0c5be9b3c7eddb" dependencies = [ "proc-macro2", "quote", diff --git a/cep47-tests/Cargo.toml b/cep47-tests/Cargo.toml index b363d82..b5a4910 100644 --- a/cep47-tests/Cargo.toml +++ b/cep47-tests/Cargo.toml @@ -6,10 +6,11 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -casper-contract = "=1.4.1" -casper-types = "=1.4.1" -casper-hashing = "=1.4.1" -casper-engine-test-support = "=1.4.1" +casper-contract = { version = "1.4.3", default-features = false, features = ["test-support"] } +casper-engine-test-support = { version = "2.0.3", features = ["test-support"] } +casper-execution-engine = "1.4.2" +casper-types = "1.4.4" +casper-hashing = "1.4.3" test-env = { path = "../utils/test-env" } contract-utils = { path = "../utils/contract-utils" } hex = "0.4.3" diff --git a/cep47-tests/src/cep47_instance.rs b/cep47-tests/src/cep47_instance.rs index 494622e..bf6dfc4 100644 --- a/cep47-tests/src/cep47_instance.rs +++ b/cep47-tests/src/cep47_instance.rs @@ -4,8 +4,10 @@ use blake2::{ digest::{Update, VariableOutput}, VarBlake2b, }; -use casper_types::{bytesrepr::ToBytes, runtime_args, CLTyped, Key, RuntimeArgs, U256}; -use test_env::{Sender, TestContract, TestEnv}; +use casper_types::{ + account::AccountHash, bytesrepr::ToBytes, runtime_args, CLTyped, Key, RuntimeArgs, U256, +}; +use test_env::{TestContract, TestEnv}; pub type TokenId = U256; pub type Meta = BTreeMap; @@ -16,7 +18,7 @@ impl CEP47Instance { pub fn new( env: &TestEnv, contract_name: &str, - sender: Sender, + sender: AccountHash, name: &str, symbol: &str, meta: Meta, @@ -34,7 +36,7 @@ impl CEP47Instance { )) } - pub fn constructor(&self, sender: Sender, name: &str, symbol: &str, meta: Meta) { + pub fn constructor(&self, sender: AccountHash, name: &str, symbol: &str, meta: Meta) { self.0.call_contract( sender, "constructor", @@ -47,7 +49,7 @@ impl CEP47Instance { pub fn mint_one>( &self, - sender: Sender, + sender: AccountHash, recipient: T, token_id: TokenId, token_meta: Meta, @@ -65,7 +67,7 @@ impl CEP47Instance { pub fn mint_copies>( &self, - sender: Sender, + sender: AccountHash, recipient: T, token_ids: Vec, token_meta: Meta, @@ -85,7 +87,7 @@ impl CEP47Instance { pub fn mint_many>( &self, - sender: Sender, + sender: AccountHash, recipient: T, token_ids: Vec, token_metas: Vec, @@ -101,7 +103,7 @@ impl CEP47Instance { ) } - pub fn burn_one>(&self, sender: Sender, owner: T, token_id: TokenId) { + pub fn burn_one>(&self, sender: AccountHash, owner: T, token_id: TokenId) { self.0.call_contract( sender, "burn", @@ -112,7 +114,7 @@ impl CEP47Instance { ) } - pub fn burn_many>(&self, sender: Sender, owner: T, token_ids: Vec) { + pub fn burn_many>(&self, sender: AccountHash, owner: T, token_ids: Vec) { self.0.call_contract( sender, "burn", @@ -123,7 +125,12 @@ impl CEP47Instance { ) } - pub fn transfer>(&self, sender: Sender, recipient: T, token_ids: Vec) { + pub fn transfer>( + &self, + sender: AccountHash, + recipient: T, + token_ids: Vec, + ) { self.0.call_contract( sender, "transfer", @@ -136,7 +143,7 @@ impl CEP47Instance { pub fn transfer_from>( &self, - sender: Sender, + sender: AccountHash, owner: T, recipient: T, token_ids: Vec, @@ -152,7 +159,7 @@ impl CEP47Instance { ) } - pub fn approve>(&self, sender: Sender, spender: T, token_ids: Vec) { + pub fn approve>(&self, sender: AccountHash, spender: T, token_ids: Vec) { self.0.call_contract( sender, "approve", @@ -167,7 +174,7 @@ impl CEP47Instance { ) } - pub fn update_token_meta(&self, sender: Sender, token_id: TokenId, token_meta: Meta) { + pub fn update_token_meta(&self, sender: AccountHash, token_id: TokenId, token_meta: Meta) { self.0.call_contract( sender, "update_token_meta", diff --git a/cep47-tests/src/cep47_tests.rs b/cep47-tests/src/cep47_tests.rs index 9512c1a..577d496 100644 --- a/cep47-tests/src/cep47_tests.rs +++ b/cep47-tests/src/cep47_tests.rs @@ -1,8 +1,7 @@ use std::collections::BTreeMap; -use casper_engine_test_support::AccountHash; -use casper_types::{Key, U256}; -use test_env::{Sender, TestEnv}; +use casper_types::{account::AccountHash, Key, U256}; +use test_env::TestEnv; use crate::cep47_instance::{CEP47Instance, Meta, TokenId}; @@ -45,14 +44,7 @@ mod meta { fn deploy() -> (TestEnv, CEP47Instance, AccountHash) { let env = TestEnv::new(); let owner = env.next_user(); - let token = CEP47Instance::new( - &env, - NAME, - Sender(owner), - NAME, - SYMBOL, - meta::contract_meta(), - ); + let token = CEP47Instance::new(&env, NAME, owner, NAME, SYMBOL, meta::contract_meta()); (env, token, owner) } @@ -72,7 +64,7 @@ fn test_token_meta() { let token_id = TokenId::zero(); let token_meta = meta::red_dragon(); - token.mint_one(Sender(owner), user, token_id, token_meta.clone()); + token.mint_one(owner, user, token_id, token_meta.clone()); let user_token_meta = token.token_meta(token_id); assert_eq!(user_token_meta.unwrap(), token_meta); @@ -88,7 +80,7 @@ fn test_mint_one() { let token_id = TokenId::zero(); let token_meta = meta::red_dragon(); - token.mint_one(Sender(owner), user, token_id, token_meta); + token.mint_one(owner, user, token_id, token_meta); let first_user_token = token.get_token_by_index(Key::Account(user), U256::from(0)); let second_user_token = token.get_token_by_index(Key::Account(user), U256::from(1)); assert_eq!(first_user_token, Some(token_id)); @@ -104,7 +96,7 @@ fn test_mint_copies() { let user = env.next_user(); let token_meta = meta::red_dragon(); let token_ids = vec![TokenId::zero(), TokenId::one(), TokenId::from(2)]; - token.mint_copies(Sender(owner), user, token_ids.clone(), token_meta, 3); + token.mint_copies(owner, user, token_ids.clone(), token_meta, 3); let first_user_token = token.get_token_by_index(Key::Account(user), U256::from(0)); let second_user_token = token.get_token_by_index(Key::Account(user), U256::from(1)); let third_user_token = token.get_token_by_index(Key::Account(user), U256::from(2)); @@ -135,7 +127,7 @@ fn test_mint_many() { let user = env.next_user(); let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; let token_ids = vec![TokenId::zero(), TokenId::one()]; - token.mint_many(Sender(owner), user, token_ids.clone(), token_metas); + token.mint_many(owner, user, token_ids.clone(), token_metas); let first_user_token = token.get_token_by_index(Key::Account(user), U256::from(0)); let second_user_token = token.get_token_by_index(Key::Account(user), U256::from(1)); let third_user_token = token.get_token_by_index(Key::Account(user), U256::from(2)); @@ -171,9 +163,9 @@ fn test_burn_many() { TokenId::from(3), ]; - token.mint_many(Sender(owner), user, token_ids.clone(), token_metas); + token.mint_many(owner, user, token_ids.clone(), token_metas); - token.burn_many(Sender(user), user, vec![token_ids[0], token_ids[3]]); + token.burn_many(user, user, vec![token_ids[0], token_ids[3]]); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(user)), U256::from(2)); @@ -204,10 +196,10 @@ fn test_burn_many_from_allowance_with_approve() { TokenId::from(3), ]; - token.mint_many(Sender(owner), user, token_ids.clone(), token_metas); + token.mint_many(owner, user, token_ids.clone(), token_metas); - token.approve(Sender(user), owner, vec![token_ids[0], token_ids[2]]); - token.burn_many(Sender(owner), user, vec![token_ids[0], token_ids[2]]); + token.approve(user, owner, vec![token_ids[0], token_ids[2]]); + token.burn_many(owner, user, vec![token_ids[0], token_ids[2]]); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(user)), U256::from(2)); @@ -239,9 +231,9 @@ fn test_burn_many_from_allowance_without_approve() { TokenId::from(3), ]; - token.mint_many(Sender(owner), user, token_ids.clone(), token_metas); + token.mint_many(owner, user, token_ids.clone(), token_metas); - token.burn_many(Sender(owner), user, vec![token_ids[0], token_ids[1]]); + token.burn_many(owner, user, vec![token_ids[0], token_ids[1]]); } #[test] @@ -250,9 +242,9 @@ fn test_burn_one() { let user = env.next_user(); let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; let token_ids = vec![TokenId::zero(), TokenId::one()]; - token.mint_many(Sender(owner), user, token_ids.clone(), token_metas); + token.mint_many(owner, user, token_ids.clone(), token_metas); - token.burn_one(Sender(user), user, token_ids[0]); + token.burn_one(user, user, token_ids[0]); assert_eq!(token.total_supply(), U256::from(1)); assert_eq!(token.balance_of(Key::Account(user)), U256::from(1)); @@ -270,14 +262,14 @@ fn test_transfer_token() { let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; let token_ids = vec![TokenId::zero(), TokenId::one()]; - token.mint_many(Sender(owner), ali, token_ids.clone(), token_metas); + token.mint_many(owner, ali, token_ids.clone(), token_metas); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(ali)), U256::from(2)); assert_eq!(token.owner_of(token_ids[0]).unwrap(), Key::Account(ali)); assert_eq!(token.owner_of(token_ids[1]).unwrap(), Key::Account(ali)); - token.transfer(Sender(ali), bob, vec![token_ids[0]]); + token.transfer(ali, bob, vec![token_ids[0]]); let new_first_ali_token = token.get_token_by_index(Key::Account(ali), U256::from(0)); let new_second_ali_token = token.get_token_by_index(Key::Account(ali), U256::from(1)); let new_first_bob_token = token.get_token_by_index(Key::Account(bob), U256::from(0)); @@ -309,13 +301,13 @@ fn test_transfer_from_tokens_with_approve() { let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; let token_ids = vec![TokenId::zero(), TokenId::one()]; - token.mint_many(Sender(owner), ali, token_ids.clone(), token_metas); + token.mint_many(owner, ali, token_ids.clone(), token_metas); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(ali)), U256::from(2)); assert_eq!(token.owner_of(token_ids[0]).unwrap(), Key::Account(ali)); assert_eq!(token.owner_of(token_ids[1]).unwrap(), Key::Account(ali)); - token.approve(Sender(ali), owner, vec![TokenId::one()]); - token.transfer_from(Sender(owner), ali, bob, vec![TokenId::one()]); + token.approve(ali, owner, vec![TokenId::one()]); + token.transfer_from(owner, ali, bob, vec![TokenId::one()]); let new_first_ali_token = token.get_token_by_index(Key::Account(ali), U256::from(0)); let new_second_ali_token = token.get_token_by_index(Key::Account(ali), U256::from(1)); let new_first_bob_token = token.get_token_by_index(Key::Account(bob), U256::from(0)); @@ -344,13 +336,13 @@ fn test_transfer_from_tokens_without_approve() { let token_metas = vec![meta::red_dragon(), meta::gold_dragon()]; let token_ids = vec![TokenId::zero(), TokenId::one()]; - token.mint_many(Sender(owner), ali, token_ids.clone(), token_metas); + token.mint_many(owner, ali, token_ids.clone(), token_metas); assert_eq!(token.total_supply(), U256::from(2)); assert_eq!(token.balance_of(Key::Account(ali)), U256::from(2)); assert_eq!(token.owner_of(token_ids[0]).unwrap(), Key::Account(ali)); assert_eq!(token.owner_of(token_ids[1]).unwrap(), Key::Account(ali)); - token.transfer_from(Sender(owner), ali, bob, vec![token_ids[0]]); + token.transfer_from(owner, ali, bob, vec![token_ids[0]]); } #[test] @@ -370,9 +362,9 @@ fn test_approve() { TokenId::from(2), ]; - token.mint_many(Sender(owner), user, token_ids.clone(), token_metas); + token.mint_many(owner, user, token_ids.clone(), token_metas); - token.approve(Sender(user), owner, vec![token_ids[0], token_ids[3]]); + token.approve(user, owner, vec![token_ids[0], token_ids[3]]); assert_eq!( token.get_approved(user, token_ids[0]).unwrap(), Key::Account(owner) @@ -389,8 +381,8 @@ fn test_token_metadata_update() { let user = env.next_user(); let token_id = TokenId::zero(); - token.mint_one(Sender(owner), user, token_id, meta::red_dragon()); + token.mint_one(owner, user, token_id, meta::red_dragon()); - token.update_token_meta(Sender(owner), token_id, meta::gold_dragon()); + token.update_token_meta(owner, token_id, meta::gold_dragon()); assert_eq!(token.token_meta(token_id).unwrap(), meta::gold_dragon()); } diff --git a/cep47/Cargo.toml b/cep47/Cargo.toml index f8f9a4e..a83601a 100644 --- a/cep47/Cargo.toml +++ b/cep47/Cargo.toml @@ -6,8 +6,8 @@ edition = "2018" [dependencies] hex = { version = "0.4.3", default-features = false } -casper-contract = "=1.4.1" -casper-types = "=1.4.1" +casper-contract = "1.4.3" +casper-types = "1.4.4" contract-utils = { path = "../utils/contract-utils" } [[bin]] diff --git a/utils/contract-utils/Cargo.toml b/utils/contract-utils/Cargo.toml index 7dcfd08..3d330d4 100644 --- a/utils/contract-utils/Cargo.toml +++ b/utils/contract-utils/Cargo.toml @@ -5,7 +5,6 @@ authors = ["Maciej Zielinski "] edition = "2018" [dependencies] -casper-contract = "=1.4.1" -casper-types = "=1.4.1" +casper-contract = "1.4.3" +casper-types = "1.4.4" hex = { version = "0.4.3", default-features = false } - diff --git a/utils/test-env/Cargo.toml b/utils/test-env/Cargo.toml index fc8e86f..a2fada7 100644 --- a/utils/test-env/Cargo.toml +++ b/utils/test-env/Cargo.toml @@ -5,10 +5,10 @@ authors = ["Maciej Zielinski "] edition = "2018" [dependencies] -casper-contract = "=1.4.1" -casper-types = "=1.4.1" -casper-hashing = "=1.4.1" -casper-engine-test-support = "=1.4.1" +casper-contract = { version = "1.4.3", default-features = false, features = ["test-support"] } +casper-engine-test-support = { version = "2.0.3", features = ["test-support"] } +casper-execution-engine = "1.4.2" +casper-types = "1.4.4" [features] default = ["casper-contract/std", "casper-types/std", "casper-engine-test-support/test-support", "casper-contract/test-support"] diff --git a/utils/test-env/src/lib.rs b/utils/test-env/src/lib.rs index f2634bf..ac64e57 100644 --- a/utils/test-env/src/lib.rs +++ b/utils/test-env/src/lib.rs @@ -1,7 +1,7 @@ mod test_contract; mod test_env; +mod utils; +use crate::test_env as other_test_env; -use casper_engine_test_support::AccountHash; +pub use other_test_env::TestEnv; pub use test_contract::TestContract; -pub use test_env::TestEnv; -pub struct Sender(pub AccountHash); diff --git a/utils/test-env/src/test_contract.rs b/utils/test-env/src/test_contract.rs index c349192..019ff43 100644 --- a/utils/test-env/src/test_contract.rs +++ b/utils/test-env/src/test_contract.rs @@ -1,7 +1,10 @@ -use casper_engine_test_support::{AccountHash, Code, Hash, Value}; -use casper_types::{bytesrepr::FromBytes, CLTyped, RuntimeArgs}; +use std::path::PathBuf; -use crate::{Sender, TestEnv}; +use casper_types::{ + account::AccountHash, bytesrepr::FromBytes, CLTyped, ContractHash, RuntimeArgs, +}; + +use crate::{utils::DeploySource, TestEnv}; pub struct TestContract { env: TestEnv, @@ -14,18 +17,17 @@ impl TestContract { env: &TestEnv, wasm: &str, name: &str, - sender: Sender, + sender: AccountHash, mut args: RuntimeArgs, ) -> TestContract { - let Sender(contract_owner) = sender; - let session_code = Code::from(wasm); + let session_code = PathBuf::from(wasm); args.insert("contract_name", name).unwrap(); - env.run(sender, session_code, args); + env.run(sender, DeploySource::Code(session_code), args); TestContract { env: env.clone(), name: String::from(name), - contract_owner, + contract_owner: sender, } } @@ -42,20 +44,19 @@ impl TestContract { let contract_name = format!("{}_contract_hash", self.name); self.env .query_account_named_key(self.contract_owner, &[contract_name, key]) - .into_t() - .unwrap() } - pub fn contract_hash(&self) -> Hash { + pub fn contract_hash(&self) -> [u8; 32] { let key = format!("{}_contract_hash_wrapped", self.name); - let value: Value = self - .env - .query_account_named_key(self.contract_owner, &[key]); - value.into_t().unwrap() + self.env + .query_account_named_key(self.contract_owner, &[key]) } - pub fn call_contract(&self, sender: Sender, entry_point: &str, session_args: RuntimeArgs) { - let session_code = Code::Hash(self.contract_hash(), String::from(entry_point)); + pub fn call_contract(&self, sender: AccountHash, entry_point: &str, session_args: RuntimeArgs) { + let session_code = DeploySource::ByHash { + hash: ContractHash::new(self.contract_hash()), + method: entry_point.to_string(), + }; self.env.run(sender, session_code, session_args); } } diff --git a/utils/test-env/src/test_env.rs b/utils/test-env/src/test_env.rs index 409df8b..f73de7b 100644 --- a/utils/test-env/src/test_env.rs +++ b/utils/test-env/src/test_env.rs @@ -1,11 +1,11 @@ use std::sync::{Arc, Mutex}; -use casper_engine_test_support::{ - AccountHash, Code, Hash, SessionBuilder, TestContext, TestContextBuilder, Value, +use casper_engine_test_support::{InMemoryWasmTestBuilder, DEFAULT_RUN_GENESIS_REQUEST}; +use casper_types::{ + account::AccountHash, bytesrepr::FromBytes, CLTyped, Key, PublicKey, RuntimeArgs, SecretKey, }; -use casper_types::{bytesrepr::FromBytes, CLTyped, Key, PublicKey, RuntimeArgs, SecretKey, U512}; -use crate::Sender; +use crate::utils::{deploy, fund_account, query, query_dictionary_item, DeploySource}; #[derive(Clone)] pub struct TestEnv { @@ -19,11 +19,15 @@ impl TestEnv { } } - pub fn run(&self, sender: Sender, session_code: Code, session_args: RuntimeArgs) { - self.state - .lock() - .unwrap() - .run(sender, session_code, session_args); + pub fn run(&self, sender: AccountHash, session_code: DeploySource, session_args: RuntimeArgs) { + deploy( + &mut self.state.lock().unwrap().builder, + &sender, + &session_code, + session_args, + true, + None, + ) } pub fn next_user(&self) -> AccountHash { @@ -32,17 +36,21 @@ impl TestEnv { pub fn query_dictionary( &self, - contract_hash: Hash, + contract_hash: [u8; 32], dict_name: &str, key: String, ) -> Option { self.state .lock() .unwrap() - .query_dictionary(contract_hash, dict_name, key) + .query_dictionary(contract_hash, dict_name.to_string(), key) } - pub fn query_account_named_key(&self, account: AccountHash, path: &[String]) -> Value { + pub fn query_account_named_key( + &self, + account: AccountHash, + path: &[String], + ) -> T { self.state .lock() .unwrap() @@ -57,64 +65,98 @@ impl Default for TestEnv { } struct TestEnvState { - context: TestContext, + builder: InMemoryWasmTestBuilder, accounts: Vec, } impl TestEnvState { pub fn new() -> TestEnvState { - let mut context_builder = TestContextBuilder::new(); - + let mut builder = InMemoryWasmTestBuilder::default(); + builder.run_genesis(&DEFAULT_RUN_GENESIS_REQUEST).commit(); let mut accounts = Vec::new(); for i in 0..10u8 { let secret_key: SecretKey = SecretKey::ed25519_from_bytes([i; 32]).unwrap(); let public_key: PublicKey = (&secret_key).into(); - accounts.push(AccountHash::from(&public_key)); - context_builder = - context_builder.with_public_key(public_key, U512::from(500_000_000_000_000u64)); + let account_hash = AccountHash::from(&public_key); + accounts.push(account_hash); + builder + .exec(fund_account(&account_hash)) + .expect_success() + .commit(); } - TestEnvState { - context: context_builder.build(), - accounts, + TestEnvState { builder, accounts } + } + + pub fn _new_with_users(user_secrets: &[[u8; 32]]) -> TestEnvState { + let mut builder = InMemoryWasmTestBuilder::default(); + builder.run_genesis(&DEFAULT_RUN_GENESIS_REQUEST).commit(); + + let mut accounts = Vec::new(); + for user_secret in user_secrets { + let secret_key: SecretKey = SecretKey::ed25519_from_bytes(user_secret).unwrap(); + let public_key: PublicKey = (&secret_key).into(); + let account_hash = AccountHash::from(&public_key); + accounts.push(account_hash); + builder + .exec(fund_account(&account_hash)) + .expect_success() + .commit(); } + + TestEnvState { builder, accounts } } pub fn next_user(&mut self) -> AccountHash { self.accounts.pop().unwrap() } - pub fn run(&mut self, sender: Sender, session_code: Code, session_args: RuntimeArgs) { - let Sender(sender) = sender; - let session = SessionBuilder::new(session_code, session_args) - .with_address(sender) - .with_authorization_keys(&[sender]) - .build(); - self.context.run(session); + pub fn _run( + &mut self, + sender: AccountHash, + session_code: DeploySource, + session_args: RuntimeArgs, + ) { + deploy( + &mut self.builder, + &sender, + &session_code, + session_args, + true, + None, + ) } pub fn query_dictionary( &self, - contract_hash: Hash, - dict_name: &str, - key: String, + contract_hash: [u8; 32], + dict_name: String, + dictionary_item_key: String, ) -> Option { - match self.context.query_dictionary_item( + match query_dictionary_item( + &self.builder, Key::Hash(contract_hash), - Some(dict_name.to_string()), - key, + Some(dict_name), + dictionary_item_key, ) { - Err(_) => None, - Ok(maybe_value) => { - let value: Option = maybe_value - .into_t() - .unwrap_or_else(|_| panic!("is not expected type.")); - value + Ok(value) => value + .as_cl_value() + .expect("should be cl value.") + .clone() + .into_t() + .expect("Wrong type in query result."), + Err(e) => { + println!("{}", e); + None } } } - pub fn query_account_named_key(&self, account: AccountHash, path: &[String]) -> Value { - self.context.query(account, path).unwrap() + pub fn query_account_named_key( + &self, + account: AccountHash, + path: &[String], + ) -> T { + query(&self.builder, Key::Account(account), path) } } diff --git a/utils/test-env/src/utils.rs b/utils/test-env/src/utils.rs new file mode 100644 index 0000000..b576ac3 --- /dev/null +++ b/utils/test-env/src/utils.rs @@ -0,0 +1,121 @@ +use std::path::PathBuf; + +use casper_engine_test_support::{ + DeployItemBuilder, ExecuteRequestBuilder, InMemoryWasmTestBuilder, ARG_AMOUNT, + DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, +}; +use casper_execution_engine::core::engine_state::ExecuteRequest; +use casper_types::{ + account::AccountHash, bytesrepr::FromBytes, runtime_args, system::mint, CLTyped, ContractHash, + Key, RuntimeArgs, StoredValue, U512, +}; + +pub fn query( + builder: &InMemoryWasmTestBuilder, + base: Key, + path: &[String], +) -> T { + builder + .query(None, base, path) + .expect("should be stored value.") + .as_cl_value() + .expect("should be cl value.") + .clone() + .into_t() + .expect("Wrong type in query result.") +} + +pub fn fund_account(account: &AccountHash) -> ExecuteRequest { + let deploy_item = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) + .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT}) + .with_transfer_args(runtime_args! { + mint::ARG_AMOUNT => U512::from(30_000_000_000_000_u64), + mint::ARG_TARGET => *account, + mint::ARG_ID => >::None + }) + .with_deploy_hash([1; 32]) + .build(); + + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() +} + +pub enum DeploySource { + Code(PathBuf), + ByHash { hash: ContractHash, method: String }, +} + +pub fn deploy( + builder: &mut InMemoryWasmTestBuilder, + deployer: &AccountHash, + source: &DeploySource, + args: RuntimeArgs, + success: bool, + block_time: Option, +) { + let mut deploy_builder = DeployItemBuilder::new() + .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT}) + .with_address(*deployer) + .with_authorization_keys(&[*deployer]); + deploy_builder = match source { + DeploySource::Code(path) => deploy_builder.with_session_code(path, args), + DeploySource::ByHash { hash, method } => { + // let contract_hash = ContractHash::from(*hash); + deploy_builder.with_stored_session_hash(*hash, method, args) + } + }; + + let mut execute_request_builder = + ExecuteRequestBuilder::from_deploy_item(deploy_builder.build()); + if let Some(ustamp) = block_time { + execute_request_builder = execute_request_builder.with_block_time(ustamp) + } + let exec = builder.exec(execute_request_builder.build()); + if success { + exec.expect_success() + } else { + exec.expect_failure() + } + .commit(); +} + +pub fn query_dictionary_item( + builder: &InMemoryWasmTestBuilder, + key: Key, + dictionary_name: Option, + dictionary_item_key: String, +) -> Result { + let empty_path = vec![]; + let dictionary_key_bytes = dictionary_item_key.as_bytes(); + let address = match key { + Key::Account(_) | Key::Hash(_) => { + if let Some(name) = dictionary_name { + let stored_value = builder.query(None, key, &[])?; + + let named_keys = match &stored_value { + StoredValue::Account(account) => account.named_keys(), + StoredValue::Contract(contract) => contract.named_keys(), + _ => { + return Err( + "Provided base key is nether an account or a contract".to_string() + ) + } + }; + + let dictionary_uref = named_keys + .get(&name) + .and_then(Key::as_uref) + .ok_or_else(|| "No dictionary uref was found in named keys".to_string())?; + + Key::dictionary(*dictionary_uref, dictionary_key_bytes) + } else { + return Err("No dictionary name was provided".to_string()); + } + } + Key::URef(uref) => Key::dictionary(uref, dictionary_key_bytes), + Key::Dictionary(address) => Key::Dictionary(address), + _ => return Err("Unsupported key type for a query to a dictionary item".to_string()), + }; + builder.query(None, address, &empty_path) +} From c51f133aa3c409d059c34090752b7012a660746f Mon Sep 17 00:00:00 2001 From: Georges Chouchani Date: Mon, 7 Feb 2022 15:22:23 +0200 Subject: [PATCH 97/98] staking smart contract --- cep47/src/address.rs | 90 ++++++++++++ cep47/src/cep47.rs | 341 +++++++++++++++++-------------------------- cep47/src/data.rs | 293 ++++++++++--------------------------- cep47/src/detail.rs | 78 ++++++++++ cep47/src/event.rs | 33 ++--- cep47/src/lib.rs | 5 +- 6 files changed, 397 insertions(+), 443 deletions(-) create mode 100644 cep47/src/address.rs create mode 100644 cep47/src/detail.rs diff --git a/cep47/src/address.rs b/cep47/src/address.rs new file mode 100644 index 0000000..653e4b3 --- /dev/null +++ b/cep47/src/address.rs @@ -0,0 +1,90 @@ +//! Implementation of an `Address` which refers either an account hash, or a contract hash. +use alloc::vec::Vec; +use casper_types::{ + account::AccountHash, + bytesrepr::{self, FromBytes, ToBytes}, + CLType, CLTyped, ContractPackageHash, Key, +}; + +/// An enum representing an [`AccountHash`] or a [`ContractPackageHash`]. +#[derive(PartialOrd, Ord, PartialEq, Eq, Hash, Clone, Copy, Debug)] +pub enum Address { + /// Represents an account hash. + Account(AccountHash), + /// Represents a contract package hash. + Contract(ContractPackageHash), +} + +impl Address { + /// Returns the inner account hash if `self` is the `Account` variant. + pub fn as_account_hash(&self) -> Option<&AccountHash> { + if let Self::Account(v) = self { + Some(v) + } else { + None + } + } + + /// Returns the inner contract hash if `self` is the `Contract` variant. + pub fn as_contract_package_hash(&self) -> Option<&ContractPackageHash> { + if let Self::Contract(v) = self { + Some(v) + } else { + None + } + } +} + +impl From for Address { + fn from(contract_package_hash: ContractPackageHash) -> Self { + Self::Contract(contract_package_hash) + } +} + +impl From for Address { + fn from(account_hash: AccountHash) -> Self { + Self::Account(account_hash) + } +} + +impl From

for Key { + fn from(address: Address) -> Self { + match address { + Address::Account(account_hash) => Key::Account(account_hash), + Address::Contract(contract_package_hash) => Key::Hash(contract_package_hash.value()), + } + } +} + +impl CLTyped for Address { + fn cl_type() -> casper_types::CLType { + CLType::Key + } +} + +impl ToBytes for Address { + fn to_bytes(&self) -> Result, bytesrepr::Error> { + Key::from(*self).to_bytes() + } + + fn serialized_length(&self) -> usize { + Key::from(*self).serialized_length() + } +} + +impl FromBytes for Address { + fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { + let (key, remainder) = Key::from_bytes(bytes)?; + + let address = match key { + Key::Account(account_hash) => Address::Account(account_hash), + Key::Hash(raw_contract_package_hash) => { + let contract_package_hash = ContractPackageHash::new(raw_contract_package_hash); + Address::Contract(contract_package_hash) + } + _ => return Err(bytesrepr::Error::Formatting), + }; + + Ok((address, remainder)) + } +} diff --git a/cep47/src/cep47.rs b/cep47/src/cep47.rs index 528544b..f5dcd0b 100644 --- a/cep47/src/cep47.rs +++ b/cep47/src/cep47.rs @@ -1,19 +1,24 @@ use crate::{ - data::{self, Allowances, Metadata, OwnedTokens, Owners}, + data::{self, StakedTokens}, event::CEP47Event, Meta, TokenId, }; use alloc::{string::String, vec::Vec}; -use casper_types::{ApiError, Key, U256}; +use casper_types::{ApiError, Key, U256, runtime_args, ContractPackageHash}; use contract_utils::{ContractContext, ContractStorage}; use core::convert::TryInto; - +use casper_contract::contract_api::runtime; +use casper_types::ContractHash; +use crate::detail; #[repr(u16)] pub enum Error { PermissionDenied = 1, WrongArguments = 2, - TokenIdAlreadyExists = 3, - TokenIdDoesntExist = 4, + NotRequiredStake = 3, + BadTiming = 4, + InvalidContext = 5, + NegativeReward =6, + NegativeWithdrawableReward = 7 } impl From for ApiError { @@ -22,261 +27,189 @@ impl From for ApiError { } } -pub trait CEP47: ContractContext { - fn init(&mut self, name: String, symbol: String, meta: Meta) { +pub trait CEP20STK: ContractContext { + fn init(&mut self, + name: String, + address: String, + staking_starts: U256, + staking_ends: U256, + withdraw_starts: U256, + withdraw_ends: U256, + staking_total: U256 + ) { data::set_name(name); - data::set_symbol(symbol); - data::set_meta(meta); - data::set_total_supply(U256::zero()); - Owners::init(); - OwnedTokens::init(); - Metadata::init(); - Allowances::init(); + data::set_address(address); + data::set_staking_starts(staking_starts); + data::set_staking_ends(staking_ends); + data::set_withdraw_starts(withdraw_starts); + data::set_withdraw_ends(withdraw_ends); + data::set_staking_total(staking_total); + StakedTokens::init(); } fn name(&self) -> String { data::name() } - fn symbol(&self) -> String { - data::symbol() + fn address(&self) -> String { + data::address() } - fn meta(&self) -> Meta { - data::meta() + fn staking_starts(&self) -> U256 { + data::staking_starts() } - fn total_supply(&self) -> U256 { - data::total_supply() + fn staking_ends(&self) -> U256 { + data::staking_ends() } - fn balance_of(&self, owner: Key) -> U256 { - OwnedTokens::instance().get_balances(&owner) + fn withdraw_starts(&self) -> U256 { + data::withdraw_starts() } - fn owner_of(&self, token_id: TokenId) -> Option { - Owners::instance().get(&token_id) + fn withdraw_ends(&self) -> U256 { + data::withdraw_ends() } - fn token_meta(&self, token_id: TokenId) -> Option { - Metadata::instance().get(&token_id) + fn staking_total(&self) -> U256 { + data::staking_total() } - fn set_token_meta(&mut self, token_id: TokenId, meta: Meta) -> Result<(), Error> { - if self.owner_of(token_id).is_none() { - return Err(Error::TokenIdDoesntExist); - }; - - let metadata_dict = Metadata::instance(); - metadata_dict.set(&token_id, meta); - - self.emit(CEP47Event::MetadataUpdate { token_id }); - Ok(()) - } - - fn get_token_by_index(&self, owner: Key, index: U256) -> Option { - OwnedTokens::instance().get_token_by_index(&owner, &index) - } - - fn validate_token_ids(&self, token_ids: Vec) -> bool { - for token_id in &token_ids { - if self.owner_of(*token_id).is_some() { - return false; - } + fn amount_staked(&self, staker: Key) -> U256 { + StakedTokens::instance().get_amount_staked_by_address(&staker).unwrap() } - true } - fn mint( + + fn stake( &mut self, - recipient: Key, - token_ids: Vec, - token_metas: Vec, - ) -> Result, Error> { - if token_ids.len() != token_metas.len() { - return Err(Error::WrongArguments); - }; + amount: U256 + ) -> Result { - for token_id in &token_ids { - if self.owner_of(*token_id).is_some() { - return Err(Error::TokenIdAlreadyExists); - } - } + if amount < U256::from(2) { + return Err(Error::NotRequiredStake); + } - let owners_dict = Owners::instance(); - let owned_tokens_dict = OwnedTokens::instance(); - let metadata_dict = Metadata::instance(); + if runtime::get_blocktime() < self.staking_starts() { + return Err(Error::BadTiming); + } - for (token_id, token_meta) in token_ids.iter().zip(&token_metas) { - metadata_dict.set(token_id, token_meta.clone()); - owners_dict.set(token_id, recipient); - owned_tokens_dict.set_token(&recipient, token_id); + if runtime::get_blocktime() >= self.staking_ends() { + return Err(Error::BadTiming); } - let minted_tokens_count: U256 = From::::from(token_ids.len().try_into().unwrap()); - let new_total_supply = data::total_supply() - .checked_add(minted_tokens_count) - .unwrap(); - data::set_total_supply(new_total_supply); + let stakers_dict = StakedTokens::instance(); + let lower_contracthash = + "contract-c9a9e704604260416bf908cb6274e5d765b36164cf1fb9597a0df67ec4063bfa".to_lowercase(); + let contract_hash = ContractHash::from_formatted_str(&lower_contracthash).unwrap(); + + let lower_contractpackagehash = "hash-wasmc4929e7fcb71772c1cb39ebb702a70d036b0ad4f9caf420d3fd377f749dfdb17".to_lowercase(); + let contract_package_hash = ContractPackageHash::from_formatted_str(&lower_contractpackagehash); + + let args = runtime_args! { + "owner" => detail::get_immediate_caller_address()?, + "recipient" => contract_package_hash, + "amount" => amount + + }; + runtime::call_contract(contract_hash,"transfer_from", args); + stakers_dict.add_stake(&Key::from(detail::get_immediate_caller_address()?), &amount); - self.emit(CEP47Event::Mint { - recipient, - token_ids: token_ids.clone(), + self.emit(CEP47Event::Stake { + amount, }); - Ok(token_ids) + Ok(amount) } - fn mint_copies( + + fn withdraw( &mut self, - recipient: Key, - token_ids: Vec, - token_meta: Meta, - count: u32, - ) -> Result, Error> { - let token_metas = vec![token_meta; count.try_into().unwrap()]; - self.mint(recipient, token_ids, token_metas) - } + amount: U256 + ) -> Result { - fn burn(&mut self, owner: Key, token_ids: Vec) -> Result<(), Error> { - let spender = self.get_caller(); - if spender != owner { - for token_id in &token_ids { - if !self.is_approved(owner, *token_id, spender) { - return Err(Error::PermissionDenied); - } - } - } - self.burn_internal(owner, token_ids) - } + if amount < U256::from(2) { + return Err(Error::NotRequiredStake); + } - fn burn_internal(&mut self, owner: Key, token_ids: Vec) -> Result<(), Error> { - let owners_dict = Owners::instance(); - let owned_tokens_dict = OwnedTokens::instance(); - let metadata_dict = Metadata::instance(); - let allowances_dict = Allowances::instance(); - - for token_id in &token_ids { - match owners_dict.get(token_id) { - Some(owner_of_key) => { - if owner_of_key != owner { - return Err(Error::PermissionDenied); - } - } - None => { - return Err(Error::TokenIdDoesntExist); - } - } + if runtime::get_blocktime() < self.staking_starts() { + return Err(Error::BadTiming); } - for token_id in &token_ids { - owned_tokens_dict.remove_token(&owner, token_id); - metadata_dict.remove(token_id); - owners_dict.remove(token_id); - allowances_dict.remove(&owner, token_id); + if runtime::get_blocktime() >= self.staking_ends() { + return Err(Error::BadTiming); } - let burnt_tokens_count: U256 = From::::from(token_ids.len().try_into().unwrap()); - let new_total_supply = data::total_supply() - .checked_sub(burnt_tokens_count) - .unwrap(); - data::set_total_supply(new_total_supply); + let stakers_dict = StakedTokens::instance(); + let lower_contracthash = + "contract-c9a9e704604260416bf908cb6274e5d765b36164cf1fb9597a0df67ec4063bfa".to_lowercase(); + let contract_hash = ContractHash::from_formatted_str(&lower_contracthash).unwrap(); - self.emit(CEP47Event::Burn { owner, token_ids }); - Ok(()) - } + let lower_contractpackagehash = "hash-4929e7fcb71772c1cb39ebb702a70d036b0ad4f9caf420d3fd377f749dfdb17".to_lowercase(); + let contract_package_hash = ContractPackageHash::from_formatted_str(&lower_contractpackagehash); - fn approve(&mut self, spender: Key, token_ids: Vec) -> Result<(), Error> { - let caller = self.get_caller(); - for token_id in &token_ids { - match self.owner_of(*token_id) { - None => return Err(Error::WrongArguments), - Some(owner) if owner != caller => return Err(Error::PermissionDenied), - Some(_) => Allowances::instance().set(&caller, token_id, spender), - } - } - self.emit(CEP47Event::Approve { - owner: caller, - spender, - token_ids, + let args = runtime_args! { + "recipient" => detail::get_immediate_caller_address()?, + "amount" => amount + + }; + runtime::call_contract(contract_hash,"transfer", args); + stakers_dict.withdraw_stake(&Key::from(detail::get_immediate_caller_address()?), &amount); + + self.emit(CEP47Event::Stake { + amount, }); - Ok(()) + Ok(amount) } - fn get_approved(&self, owner: Key, token_id: TokenId) -> Option { - Allowances::instance().get(&owner, &token_id) - } + fn add_reward( + &mut self, + reward_amount: U256, + withdrawable_amount: U256 + ) -> Result { - fn transfer(&mut self, recipient: Key, token_ids: Vec) -> Result<(), Error> { - self.transfer_from(self.get_caller(), recipient, token_ids) - } + if runtime::get_blocktime() >= self.withdraw_starts() { + return Err(Error::PermissionDenied) + } - fn transfer_from( - &mut self, - owner: Key, - recipient: Key, - token_ids: Vec, - ) -> Result<(), Error> { - let spender = self.get_caller(); - - if owner != spender { - let allowances_dict = Allowances::instance(); - for token_id in &token_ids { - if !self.is_approved(owner, *token_id, spender) { - return Err(Error::PermissionDenied); - } - allowances_dict.remove(&owner, token_id); - } + if reward_amount <= U256::from(0) { + return Err(Error::NegativeReward) } - self.transfer_from_internal(owner, recipient, token_ids) - } - fn transfer_from_internal( - &mut self, - owner: Key, - recipient: Key, - token_ids: Vec, - ) -> Result<(), Error> { - let owners_dict = Owners::instance(); - let owned_tokens_dict = OwnedTokens::instance(); - - for token_id in &token_ids { - match owners_dict.get(token_id) { - Some(owner_of_key) => { - if owner_of_key != owner { - return Err(Error::PermissionDenied); - } - } - None => { - return Err(Error::TokenIdDoesntExist); - } - } + if withdrawable_amount < U256::from(0) { + return Err(Error::NegativeWithdrawableReward) } - for token_id in &token_ids { - owned_tokens_dict.remove_token(&owner, token_id); - owned_tokens_dict.set_token(&recipient, token_id); - owners_dict.set(token_id, recipient); + if withdrawable_amount > reward_amount { + return Err(Error::NegativeWithdrawableReward) } - self.emit(CEP47Event::Transfer { - sender: owner, - recipient, - token_ids, + let lower_contracthash = + "contract-c9a9e704604260416bf908cb6274e5d765b36164cf1fb9597a0df67ec4063bfa".to_lowercase(); + let contract_hash = ContractHash::from_formatted_str(&lower_contracthash).unwrap(); + + let lower_contractpackagehash = "hash-wasmc4929e7fcb71772c1cb39ebb702a70d036b0ad4f9caf420d3fd377f749dfdb17".to_lowercase(); + let contract_package_hash = ContractPackageHash::from_formatted_str(&lower_contractpackagehash); + + let args = runtime_args! { + "owner" => detail::get_immediate_caller_address()?, + "recipient" => contract_package_hash, + "amount" => reward_amount + withdrawable_amount + + }; + runtime::call_contract(contract_hash,"transfer_from", args); + + self.emit(CEP47Event::AddReward + { + reward_amount, + withdrawable_amount }); - Ok(()) + Ok(reward_amount) } + - fn is_approved(&self, owner: Key, token_id: TokenId, spender: Key) -> bool { - let allowances_dict = Allowances::instance(); - if let Some(spender_of) = allowances_dict.get(&owner, &token_id) { - if spender_of == spender { - return true; - } - } - false - } + fn emit(&mut self, event: CEP47Event) { data::emit(&event); } -} + diff --git a/cep47/src/data.rs b/cep47/src/data.rs index 70c262e..38ce16b 100644 --- a/cep47/src/data.rs +++ b/cep47/src/data.rs @@ -9,223 +9,114 @@ use casper_contract::{ }; use casper_types::{system::CallStackElement, ContractPackageHash, Key, URef, U256}; use contract_utils::{get_key, key_and_value_to_str, key_to_str, set_key, Dict}; +use crate::detail; +use crate::{event::CEP47Event}; -use crate::{event::CEP47Event, Meta, TokenId}; - -const BALANCES_DICT: &str = "balances"; -pub const ALLOWANCES_DICT: &str = "allowances"; -const METADATA_DICT: &str = "metadata"; -const OWNERS_DICT: &str = "owners"; -const OWNED_TOKENS_BY_INDEX_DICT: &str = "owned_tokens_by_index"; -const OWNED_INDEXES_BY_TOKEN_DICT: &str = "owned_indexes_by_token"; +const STAKERS_DICT: &str = "stakers"; +const AMOUNT_STAKED_BY_ADDRESS_DICT: &str = "amount_staked_by_addresses_dict"; const CONTRACT_PACKAGE_HASH: &str = "contract_package_hash"; -pub const NAME: &str = "name"; -pub const META: &str = "meta"; -pub const SYMBOL: &str = "symbol"; -pub const TOTAL_SUPPLY: &str = "total_supply"; - -pub struct Owners { - dict: Dict, -} +pub const NAME: &str = "address"; +pub const ADDRESS: &str = "address"; +pub const STAKING_STARTS: &str = "staking_starts"; +pub const STAKING_ENDS: &str = "staking_ends"; +pub const WITHDRAW_STARTS: &str = "withdraw_starts"; +pub const WITHDRAW_ENDS: &str = "withdraw_ends"; +pub const STAKING_TOTAL: &str = "staking_total"; -impl Owners { - pub fn instance() -> Owners { - Owners { - dict: Dict::instance(OWNERS_DICT), - } - } - - pub fn init() { - Dict::init(OWNERS_DICT) - } - pub fn get(&self, key: &TokenId) -> Option { - self.dict.get(&key.to_string()) - } - pub fn set(&self, key: &TokenId, value: Key) { - self.dict.set(&key.to_string(), value); - } - pub fn remove(&self, key: &TokenId) { - self.dict.remove::(&key.to_string()); - } -} -pub struct Metadata { - dict: Dict, +pub struct StakedTokens { + addresses_staked_dict: Dict, } -impl Metadata { - pub fn instance() -> Metadata { - Metadata { - dict: Dict::instance(METADATA_DICT), +impl StakedTokens { + pub fn instance() -> StakedTokens { + StakedTokens { + addresses_staked_dict: Dict::instance(AMOUNT_STAKED_BY_ADDRESS_DICT), } } pub fn init() { - Dict::init(METADATA_DICT) + Dict::init(AMOUNT_STAKED_BY_ADDRESS_DICT); } - pub fn get(&self, key: &TokenId) -> Option { - self.dict.get(&key.to_string()) + pub fn get_amount_staked_by_address(&self, address: &Key) -> Option { + self.addresses_staked_dict.get(&key_to_str(address)) } - pub fn set(&self, key: &TokenId, value: Meta) { - self.dict.set(&key.to_string(), value); + + pub fn add_stake(&self, owner: &Key, amount: &U256) { + let staked_amount = self.get_amount_staked_by_address(owner).unwrap(); + let new_amount = staked_amount + amount; + self.addresses_staked_dict + .set(&key_to_str(owner),new_amount); } - pub fn remove(&self, key: &TokenId) { - self.dict.remove::(&key.to_string()); + pub fn withdraw_stake(&self, owner: &Key, amount: &U256) { + let staked_amount = self.get_amount_staked_by_address(owner).unwrap(); + let new_amount = staked_amount - amount; + self.addresses_staked_dict + .set(&key_to_str(owner),new_amount); } } -pub struct OwnedTokens { - tokens_dict: Dict, - indexes_dict: Dict, - balances_dict: Dict, +pub fn name() -> String { + get_key(NAME).unwrap_or_revert() } -impl OwnedTokens { - pub fn instance() -> OwnedTokens { - OwnedTokens { - tokens_dict: Dict::instance(OWNED_TOKENS_BY_INDEX_DICT), - indexes_dict: Dict::instance(OWNED_INDEXES_BY_TOKEN_DICT), - balances_dict: Dict::instance(BALANCES_DICT), - } - } - - pub fn init() { - Dict::init(OWNED_TOKENS_BY_INDEX_DICT); - Dict::init(OWNED_INDEXES_BY_TOKEN_DICT); - Dict::init(BALANCES_DICT); - } - - pub fn get_token_by_index(&self, owner: &Key, index: &U256) -> Option { - self.tokens_dict.get(&key_and_value_to_str(owner, index)) - } - - pub fn get_index_by_token(&self, owner: &Key, value: &TokenId) -> Option { - self.indexes_dict.get(&key_and_value_to_str(owner, value)) - } - - pub fn get_balances(&self, owner: &Key) -> U256 { - self.balances_dict - .get(&key_to_str(owner)) - .unwrap_or_default() - } - - pub fn set_balances(&self, owner: &Key, value: U256) { - self.balances_dict.set(&key_to_str(owner), value); - } - - pub fn set_token(&self, owner: &Key, value: &TokenId) { - let length = self.get_balances(owner); - self.indexes_dict - .set(&key_and_value_to_str(owner, value), length); - self.tokens_dict - .set(&key_and_value_to_str(owner, &length), *value); - self.set_balances(owner, length + 1); - } - - pub fn remove_token(&self, owner: &Key, value: &TokenId) { - let length = self.get_balances(owner); - let index = self.get_index_by_token(owner, value).unwrap_or_revert(); - match length.cmp(&(index + 1)) { - core::cmp::Ordering::Equal => { - self.tokens_dict - .remove::(&key_and_value_to_str(owner, &(length - 1))); - self.set_balances(owner, length - 1); - } - core::cmp::Ordering::Greater => { - let last = self.get_token_by_index(owner, &(length - 1)); - self.indexes_dict.set( - &key_and_value_to_str(owner, &last.unwrap_or_revert()), - index, - ); - self.tokens_dict.set( - &key_and_value_to_str(owner, &index), - last.unwrap_or_revert(), - ); - self.tokens_dict - .remove::(&key_and_value_to_str(owner, &(length - 1))); - self.set_balances(owner, length - 1); - } - core::cmp::Ordering::Less => {} - } - self.indexes_dict - .remove::(&key_and_value_to_str(owner, value)); - } +pub fn set_name(name: String) { + set_key(NAME, name); } -pub struct Allowances { - dict: Dict, +pub fn address() -> String { + get_key(ADDRESS).unwrap_or_revert() } -impl Allowances { - pub fn instance() -> Allowances { - Allowances { - dict: Dict::instance(ALLOWANCES_DICT), - } - } - - pub fn init() { - Dict::init(ALLOWANCES_DICT) - } - - pub fn get(&self, owner: &Key, token_id: &TokenId) -> Option { - self.dict.get(&key_and_value_to_str::( - owner, - &token_id.to_string(), - )) - } +pub fn set_address(address: String) { + set_key(ADDRESS, address); +} - pub fn set(&self, owner: &Key, token_id: &TokenId, value: Key) { - self.dict.set( - &key_and_value_to_str::(owner, &token_id.to_string()), - value, - ); - } +pub fn staking_starts() -> U256 { + get_key(STAKING_STARTS).unwrap_or_revert() +} - pub fn remove(&self, owner: &Key, token_id: &TokenId) { - self.dict.remove::(&key_and_value_to_str::( - owner, - &token_id.to_string(), - )); - } +pub fn set_staking_starts(staking_starts: U256) { + set_key(STAKING_STARTS, staking_starts); } -pub fn name() -> String { - get_key(NAME).unwrap_or_revert() +pub fn staking_ends() -> U256 { + get_key(STAKING_ENDS).unwrap_or_revert() } -pub fn set_name(name: String) { - set_key(NAME, name); +pub fn set_staking_ends(staking_ends: U256) { + set_key(STAKING_ENDS, staking_ends); } -pub fn symbol() -> String { - get_key(SYMBOL).unwrap_or_revert() +pub fn withdraw_starts() -> U256 { + get_key(WITHDRAW_STARTS).unwrap_or_default() } -pub fn set_symbol(symbol: String) { - set_key(SYMBOL, symbol); +pub fn set_withdraw_starts(withdraw_starts: U256) { + set_key(WITHDRAW_STARTS, withdraw_starts); } -pub fn meta() -> Meta { - get_key(META).unwrap_or_revert() +pub fn withdraw_ends() -> U256 { + get_key(WITHDRAW_ENDS).unwrap_or_default() } -pub fn set_meta(meta: Meta) { - set_key(META, meta); +pub fn set_withdraw_ends(withdraw_ends: U256) { + set_key(WITHDRAW_STARTS, withdraw_ends); } -pub fn total_supply() -> U256 { - get_key(TOTAL_SUPPLY).unwrap_or_default() +pub fn staking_total() -> U256 { + get_key(STAKING_TOTAL).unwrap_or_default() } -pub fn set_total_supply(total_supply: U256) { - set_key(TOTAL_SUPPLY, total_supply); +pub fn set_staking_total(staking_total: U256) { + set_key(STAKING_TOTAL, staking_total); } pub fn contract_package_hash() -> ContractPackageHash { @@ -245,65 +136,35 @@ pub fn emit(event: &CEP47Event) { let mut events = Vec::new(); let package = contract_package_hash(); match event { - CEP47Event::Mint { - recipient, - token_ids, + CEP47Event::Stake { + amount } => { - for token_id in token_ids { let mut param = BTreeMap::new(); param.insert(CONTRACT_PACKAGE_HASH, package.to_string()); - param.insert("event_type", "cep47_mint_one".to_string()); - param.insert("recipient", recipient.to_string()); - param.insert("token_id", token_id.to_string()); + param.insert("event_type", "stake".to_string()); + param.insert("staker",Key::from(detail::get_immediate_caller_address().ok().unwrap()).to_formatted_string()); + param.insert("stake_amount", amount.to_string()); events.push(param); - } } - CEP47Event::Burn { owner, token_ids } => { - for token_id in token_ids { + CEP47Event::Withdraw { amount} => { let mut param = BTreeMap::new(); param.insert(CONTRACT_PACKAGE_HASH, package.to_string()); - param.insert("event_type", "cep47_burn_one".to_string()); - param.insert("owner", owner.to_string()); - param.insert("token_id", token_id.to_string()); + param.insert("event_type", "withdraw".to_string()); + param.insert("staker", Key::from(detail::get_immediate_caller_address().ok().unwrap()).to_formatted_string()); + param.insert("withdrawn_amount", amount.to_string()); events.push(param); - } + } - CEP47Event::Approve { - owner, - spender, - token_ids, + CEP47Event::AddReward { + reward_amount, + withdrawable_amount } => { - for token_id in token_ids { let mut param = BTreeMap::new(); param.insert(CONTRACT_PACKAGE_HASH, package.to_string()); - param.insert("event_type", "cep47_approve_token".to_string()); - param.insert("owner", owner.to_string()); - param.insert("spender", spender.to_string()); - param.insert("token_id", token_id.to_string()); + param.insert("event_type", "add_reward".to_string()); + param.insert("reward_amount", reward_amount.to_string()); + param.insert("withdrawable_amount", withdrawable_amount.to_string()); events.push(param); - } - } - CEP47Event::Transfer { - sender, - recipient, - token_ids, - } => { - for token_id in token_ids { - let mut param = BTreeMap::new(); - param.insert(CONTRACT_PACKAGE_HASH, package.to_string()); - param.insert("event_type", "cep47_transfer_token".to_string()); - param.insert("sender", sender.to_string()); - param.insert("recipient", recipient.to_string()); - param.insert("token_id", token_id.to_string()); - events.push(param); - } - } - CEP47Event::MetadataUpdate { token_id } => { - let mut param = BTreeMap::new(); - param.insert(CONTRACT_PACKAGE_HASH, package.to_string()); - param.insert("event_type", "cep47_metadata_update".to_string()); - param.insert("token_id", token_id.to_string()); - events.push(param); } }; for param in events { diff --git a/cep47/src/detail.rs b/cep47/src/detail.rs new file mode 100644 index 0000000..8a2e86e --- /dev/null +++ b/cep47/src/detail.rs @@ -0,0 +1,78 @@ +//! Implementation details. +use core::convert::TryInto; + +use casper_contract::{ + contract_api::{runtime, storage}, + unwrap_or_revert::UnwrapOrRevert, +}; +use casper_types::{bytesrepr::FromBytes, system::CallStackElement, ApiError, CLTyped, URef}; + +use crate::{Error}; +use crate::address::Address; + +/// Gets [`URef`] under a name. +pub(crate) fn get_uref(name: &str) -> URef { + let key = runtime::get_key(name) + .ok_or(ApiError::MissingKey) + .unwrap_or_revert(); + key.try_into().unwrap_or_revert() +} + +/// Reads value from a named key. +pub(crate) fn read_from(name: &str) -> T +where + T: FromBytes + CLTyped, +{ + let uref = get_uref(name); + let value: T = storage::read(uref).unwrap_or_revert().unwrap_or_revert(); + value +} + +/// Gets the immediate call stack element of the current execution. +fn get_immediate_call_stack_item() -> Option { + let call_stack = runtime::get_call_stack(); + call_stack.into_iter().rev().nth(1) +} + +/// Returns address based on a [`CallStackElement`]. +/// +/// For `Session` and `StoredSession` variants it will return account hash, and for `StoredContract` +/// case it will use contract hash as the address. +fn call_stack_element_to_address(call_stack_element: CallStackElement) -> Address { + match call_stack_element { + CallStackElement::Session { account_hash } => Address::from(account_hash), + CallStackElement::StoredSession { account_hash, .. } => { + // Stored session code acts in account's context, so if stored session wants to interact + // with an ERC20 token caller's address will be used. + Address::from(account_hash) + } + CallStackElement::StoredContract { + contract_package_hash, + .. + } => Address::from(contract_package_hash), + } +} + +/// Gets the immediate session caller of the current execution. +/// +/// This function ensures that only session code can execute this function, and disallows stored +/// session/stored contracts. +pub(crate) fn get_immediate_caller_address() -> Result { + get_immediate_call_stack_item() + .map(call_stack_element_to_address) + .ok_or(Error::InvalidContext) +} + +/// Gets the caller address which is stored on the top of the call stack. +/// +/// This is similar to what [`runtime::get_caller`] does but it also supports stored contracts. +pub(crate) fn get_caller_address() -> Result { + let call_stack = runtime::get_call_stack(); + let top_of_the_stack = call_stack + .into_iter() + .rev() + .next() + .ok_or(Error::InvalidContext)?; + let address = call_stack_element_to_address(top_of_the_stack); + Ok(address) +} diff --git a/cep47/src/event.rs b/cep47/src/event.rs index a8cfa53..47f27fa 100644 --- a/cep47/src/event.rs +++ b/cep47/src/event.rs @@ -1,28 +1,17 @@ -use alloc::vec::Vec; -use casper_types::Key; -use crate::TokenId; +use casper_types::U256; + pub enum CEP47Event { - Mint { - recipient: Key, - token_ids: Vec, - }, - Burn { - owner: Key, - token_ids: Vec, - }, - Approve { - owner: Key, - spender: Key, - token_ids: Vec, + Stake { + amount: U256, }, - Transfer { - sender: Key, - recipient: Key, - token_ids: Vec, - }, - MetadataUpdate { - token_id: TokenId, + Withdraw { + amount: U256, }, + AddReward { + reward_amount: U256, + withdrawable_amount: U256 + } + } diff --git a/cep47/src/lib.rs b/cep47/src/lib.rs index 54f38b7..36af22a 100644 --- a/cep47/src/lib.rs +++ b/cep47/src/lib.rs @@ -5,8 +5,11 @@ extern crate alloc; mod cep47; pub mod data; pub mod event; +pub mod detail; +pub mod address; -pub use cep47::{Error, CEP47}; + +pub use cep47::{Error, CEP20STK}; pub use contract_utils; use alloc::{collections::BTreeMap, string::String}; From e26edff89f4f4eac43557e7ba724aae040c35632 Mon Sep 17 00:00:00 2001 From: salmanferrum Date: Thu, 30 Jun 2022 12:29:02 +0500 Subject: [PATCH 98/98] updated-code --- Cargo.lock | 289 ++++++++++++++++---------- Cargo.toml | 2 +- README.md | 3 +- Staking.sol | 253 +++++++++++++++++++++++ cep47-tests/wasm/.gitkeep | 0 cep47/Cargo.toml | 4 +- cep47/bin/cep47_token.rs | 296 ++++++++++----------------- cep47/src/cep47.rs | 59 +++--- cep47/src/data.rs | 20 +- cep47/src/lib.rs | 1 - keys/.DS_Store | Bin 0 -> 6148 bytes keys/ACCOUNT2/public_key (1).pem | 3 + keys/ACCOUNT2/public_key_hex (1).txt | 1 + keys/ACCOUNT2/secret_key (1).pem | 3 + keys/cep47-token.wasm | Bin 0 -> 156936 bytes keys/public_key.pem | 3 + keys/public_key_hex.txt | 1 + keys/rust_sol.wasm | Bin 0 -> 157476 bytes keys/secret_key.pem | 3 + rust-toolchain | 2 +- utils/.DS_Store | Bin 0 -> 6148 bytes utils/contract-utils/Cargo.toml | 4 +- utils/test-env/Cargo.toml | 8 +- 23 files changed, 602 insertions(+), 353 deletions(-) create mode 100644 Staking.sol delete mode 100644 cep47-tests/wasm/.gitkeep create mode 100644 keys/.DS_Store create mode 100644 keys/ACCOUNT2/public_key (1).pem create mode 100644 keys/ACCOUNT2/public_key_hex (1).txt create mode 100644 keys/ACCOUNT2/secret_key (1).pem create mode 100755 keys/cep47-token.wasm create mode 100644 keys/public_key.pem create mode 100644 keys/public_key_hex.txt create mode 100755 keys/rust_sol.wasm create mode 100644 keys/secret_key.pem create mode 100644 utils/.DS_Store diff --git a/Cargo.lock b/Cargo.lock index 4b985cf..2943890 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,15 +4,15 @@ version = 3 [[package]] name = "anyhow" -version = "1.0.52" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84450d0b4a8bd1ba4144ce8ce718fbc5d071358b1e5384bace6536b3d1f2d5b3" +checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc" [[package]] name = "autocfg" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "base16" @@ -95,9 +95,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "casper-contract" -version = "1.4.3" +version = "1.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4e145bb5b2cde2f0c76b8571a03ef8a6de37616ef0e6e4b8a9bac937ff39c40" +checksum = "790b76807d64788758208757b0a17970bf756cb7c392f55b1a22021a34f95991" dependencies = [ "casper-types", "hex_fmt", @@ -106,26 +106,70 @@ dependencies = [ [[package]] name = "casper-engine-test-support" -version = "2.0.3" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13aeaa9950a9d0e778d0a94de98a323337b54e6c03bdeeafe44af19ea6005240" +checksum = "5917452bb3294b982e01b13b80498b4beb639c79bb5842654483fd7677fa6310" dependencies = [ - "casper-execution-engine", + "casper-execution-engine 2.0.0", "casper-hashing", "casper-types", + "filesize", "lmdb", "log", "num-rational 0.4.0", "num-traits", "once_cell", - "rand 0.8.4", + "rand 0.8.5", + "tempfile", ] [[package]] name = "casper-execution-engine" -version = "1.4.4" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e596ca06972bce89990740058a79f846439fee9d82f6e0b6da2511d0e83a6a1" +dependencies = [ + "anyhow", + "base16", + "bincode", + "casper-hashing", + "casper-types", + "chrono", + "datasize", + "hex-buffer-serde 0.2.2", + "hex_fmt", + "hostname", + "itertools", + "libc", + "linked-hash-map", + "lmdb", + "log", + "num", + "num-derive", + "num-rational 0.4.0", + "num-traits", + "once_cell", + "parity-wasm", + "proptest", + "pwasm-utils", + "rand 0.8.5", + "rand_chacha 0.3.1", + "schemars", + "serde", + "serde_bytes", + "serde_json", + "thiserror", + "tracing", + "uint", + "uuid", + "wasmi", +] + +[[package]] +name = "casper-execution-engine" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dddee9d2f4e3dacdb7c69887cfe0ae1d2ffa6fa8af340d5d0ed4243ab21fbd24" +checksum = "9aaaef386bf318fe6b6f832ec5e0230a7236b6d553b1ed937ed26e15b81df255" dependencies = [ "anyhow", "base16", @@ -146,11 +190,12 @@ dependencies = [ "num-derive", "num-rational 0.4.0", "num-traits", + "num_cpus", "once_cell", "parity-wasm", "proptest", "pwasm-utils", - "rand 0.8.4", + "rand 0.8.5", "rand_chacha 0.3.1", "schemars", "serde", @@ -183,9 +228,9 @@ dependencies = [ [[package]] name = "casper-types" -version = "1.4.6" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9da1776d44d053d9b60040b7e70b448ce34608762e989cc1106d083125bf200" +checksum = "a13e82a13d1784104fd021a38da56c69da94e84b26b03c2cf3d8da3895a16c8c" dependencies = [ "base16", "base64", @@ -203,7 +248,7 @@ dependencies = [ "num-traits", "once_cell", "proptest", - "rand 0.8.4", + "rand 0.8.5", "schemars", "serde", "serde_bytes", @@ -213,9 +258,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.72" +version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" [[package]] name = "cep47" @@ -234,7 +279,7 @@ dependencies = [ "blake2", "casper-contract", "casper-engine-test-support", - "casper-execution-engine", + "casper-execution-engine 1.5.0", "casper-hashing", "casper-types", "contract-utils", @@ -278,9 +323,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" +checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" dependencies = [ "libc", ] @@ -313,9 +358,9 @@ dependencies = [ [[package]] name = "ctor" -version = "0.1.21" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccc0a48a9b826acdf4028595adc9db92caea352f7af011a3034acd172a52a0aa" +checksum = "f877be4f7c9f246b183111634f75baa039715e3f46ce860677d3b19a69fb229c" dependencies = [ "quote", "syn", @@ -323,9 +368,9 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "3.2.0" +version = "3.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0" dependencies = [ "byteorder", "digest", @@ -371,9 +416,9 @@ checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" [[package]] name = "dyn-clone" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee2626afccd7561a06cf1367e2950c4718ea04565e20fb5029b6c7d8ad09abcf" +checksum = "21e50f3adc76d6a43f5ed73b698a87d0760ca74617f60f7c3b879003536fdd28" [[package]] name = "ecdsa" @@ -433,9 +478,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "779d043b6a0b90cc4c0ed7ee380a6504394cee7efd7db050e3774eee387324b2" +checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" dependencies = [ "instant", ] @@ -451,6 +496,15 @@ dependencies = [ "subtle", ] +[[package]] +name = "filesize" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12d741e2415d4e2e5bd1c1d00409d1a8865a57892c2d689b504365655d237d43" +dependencies = [ + "winapi", +] + [[package]] name = "fnv" version = "1.0.7" @@ -475,9 +529,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c" +checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" dependencies = [ "cfg-if 1.0.0", "libc", @@ -501,6 +555,15 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + [[package]] name = "hex" version = "0.4.3" @@ -559,9 +622,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" +checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" dependencies = [ "autocfg", "hashbrown", @@ -588,9 +651,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" +checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" [[package]] name = "k256" @@ -611,9 +674,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.112" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" +checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" [[package]] name = "linked-hash-map" @@ -645,9 +708,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.14" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ "cfg-if 1.0.0", "serde", @@ -710,9 +773,9 @@ dependencies = [ [[package]] name = "num-complex" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26873667bbbb7c5182d4a37c1add32cdf09f841af72da53318fdb81543c15085" +checksum = "97fbc387afefefd5e9e39493299f3069e14a140dd34dc19b4c1c1a8fddb6a790" dependencies = [ "num-traits", ] @@ -730,9 +793,9 @@ dependencies = [ [[package]] name = "num-integer" -version = "0.1.44" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" dependencies = [ "autocfg", "num-traits", @@ -740,9 +803,9 @@ dependencies = [ [[package]] name = "num-iter" -version = "0.1.42" +version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" dependencies = [ "autocfg", "num-integer", @@ -776,18 +839,28 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" dependencies = [ "autocfg", ] +[[package]] +name = "num_cpus" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +dependencies = [ + "hermit-abi", + "libc", +] + [[package]] name = "once_cell" -version = "1.9.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" +checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225" [[package]] name = "opaque-debug" @@ -803,15 +876,15 @@ checksum = "ddfc878dac00da22f8f61e7af3157988424567ab01d9920b962ef7dcbd7cd865" [[package]] name = "pin-project-lite" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" [[package]] name = "pkg-config" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe" +checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" [[package]] name = "ppv-lite86" @@ -821,11 +894,11 @@ checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" [[package]] name = "proc-macro2" -version = "1.0.36" +version = "1.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] @@ -840,7 +913,7 @@ dependencies = [ "lazy_static", "num-traits", "quick-error 2.0.1", - "rand 0.8.4", + "rand 0.8.5", "rand_chacha 0.3.1", "rand_xorshift", "regex-syntax", @@ -873,9 +946,9 @@ checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" [[package]] name = "quote" -version = "1.0.14" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d" +checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" dependencies = [ "proc-macro2", ] @@ -894,19 +967,18 @@ checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ "rand_chacha 0.2.2", "rand_core 0.5.1", - "rand_hc 0.2.0", + "rand_hc", ] [[package]] name = "rand" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha 0.3.1", "rand_core 0.6.3", - "rand_hc 0.3.1", ] [[package]] @@ -953,15 +1025,6 @@ dependencies = [ "rand_core 0.5.1", ] -[[package]] -name = "rand_hc" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" -dependencies = [ - "rand_core 0.6.3", -] - [[package]] name = "rand_xorshift" version = "0.3.0" @@ -973,18 +1036,18 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.10" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" dependencies = [ "bitflags", ] [[package]] name = "regex-syntax" -version = "0.6.25" +version = "0.6.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" +checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" [[package]] name = "remove_dir_all" @@ -1009,9 +1072,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" +checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" [[package]] name = "schemars" @@ -1040,27 +1103,27 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.133" +version = "1.0.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97565067517b60e2d1ea8b268e59ce036de907ac523ad83a0475da04e818989a" +checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" dependencies = [ "serde_derive", ] [[package]] name = "serde_bytes" -version = "0.11.5" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16ae07dd2f88a366f15bd0632ba725227018c69a1c8550a927324f8eb8368bb9" +checksum = "212e73464ebcde48d723aa02eb270ba62eff38a9b732df31f33f1b4e145f3a54" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.133" +version = "1.0.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed201699328568d8d08208fdd080e3ff594e6c422e438b6705905da01005d537" +checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" dependencies = [ "proc-macro2", "quote", @@ -1080,9 +1143,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.75" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c059c05b48c5c0067d4b4b2b4f0732dd65feb52daf7e0ea09cd87e7dadc1af79" +checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" dependencies = [ "itoa", "ryu", @@ -1126,13 +1189,13 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.85" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a684ac3dcd8913827e18cd09a68384ee66c1de24157e3c556c9ab16d85695fb7" +checksum = "fbaf6116ab8924f39d52792136fb74fd60a80194cf1b1c6ffa6453eef1c3f942" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", ] [[package]] @@ -1167,24 +1230,24 @@ version = "0.1.0" dependencies = [ "casper-contract", "casper-engine-test-support", - "casper-execution-engine", + "casper-execution-engine 1.5.0", "casper-types", ] [[package]] name = "thiserror" -version = "1.0.30" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.30" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" dependencies = [ "proc-macro2", "quote", @@ -1203,9 +1266,9 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.29" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105" +checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09" dependencies = [ "cfg-if 1.0.0", "pin-project-lite", @@ -1215,9 +1278,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.18" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f480b8f81512e825f337ad51e94c1eb5d3bbdf2b363dcd01e2b19a9ffe3f8e" +checksum = "cc6b8ad3567499f98a1db7a752b07a7c8c7c7c34c332ec00effb2b0027974b7c" dependencies = [ "proc-macro2", "quote", @@ -1226,9 +1289,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.21" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4ed65637b8390770814083d20756f87bfa2c21bf2f110babdc5438351746e4" +checksum = "f54c8ca710e81886d498c2fd3331b56c93aa248d49de2222ad2742247c60072f" dependencies = [ "lazy_static", ] @@ -1241,9 +1304,9 @@ checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" [[package]] name = "uint" -version = "0.9.1" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6470ab50f482bde894a037a57064480a246dbfdd5960bd65a44824693f08da5f" +checksum = "12f03af7ccf01dd611cc450a0d10dbc9b745770d096473e2faf0ca6e2d66d1e0" dependencies = [ "byteorder", "crunchy", @@ -1251,11 +1314,17 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "unicode-ident" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee" + [[package]] name = "unicode-xid" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" +checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04" [[package]] name = "uuid" @@ -1269,9 +1338,9 @@ dependencies = [ [[package]] name = "value-bag" -version = "1.0.0-alpha.8" +version = "1.0.0-alpha.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79923f7731dc61ebfba3633098bf3ac533bbd35ccd8c57e7088d9a5eebe0263f" +checksum = "2209b78d1249f7e6f3293657c9779fe31ced465df091bbd433a1cf88e916ec55" dependencies = [ "ctor", "version_check", @@ -1364,18 +1433,18 @@ checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" [[package]] name = "zeroize" -version = "1.5.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc222aec311c323c717f56060324f32b82da1ce1dd81d9a09aa6a9030bfe08db" +checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" dependencies = [ "zeroize_derive", ] [[package]] name = "zeroize_derive" -version = "1.3.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81e8f13fef10b63c06356d65d416b070798ddabcadc10d3ece0c5be9b3c7eddb" +checksum = "3f8f187641dad4f680d25c4bfc4225b418165984179f26ca76ec4fb6441d3a17" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index b635878..54a520f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,4 +7,4 @@ members = [ [profile.release] codegen-units = 1 -lto = true +lto = true \ No newline at end of file diff --git a/README.md b/README.md index 3305544..5d585ce 100644 --- a/README.md +++ b/README.md @@ -1 +1,2 @@ -# casper-nft-cep47 + +# casper-staking-contract diff --git a/Staking.sol b/Staking.sol new file mode 100644 index 0000000..1d81392 --- /dev/null +++ b/Staking.sol @@ -0,0 +1,253 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.0; + +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import "@openzeppelin/contracts/math/SafeMath.sol"; + +contract Staking { + using SafeMath for uint256; + + // map address to user stake + mapping (address => uint256) stakes; + + //staking details + string public tokenName; + address public tokenAddress; + uint public stakingStarts; + uint public stakingEnds; + uint public stakingTotal; + uint public stakeBalance; + uint public stakedTotal; + uint public withdrawStarts; + uint public withdrawEnds; + uint256 public totalReward; + uint256 public earlyWithdrawReward; + uint256 public rewardBalance; + uint256 public stakedBalance; + + ERC20 public ERC20Interface; + event Staked(address indexed token, address indexed staker_, uint256 requestedAmount_, uint256 stakedAmount_); + event PaidOut(address indexed token, address indexed staker_, uint256 amount_, uint256 reward_); + event Refunded(address indexed token, address indexed staker_, uint256 amount_); + + constructor( + string memory tokenName_, + address tokenAddress_, + uint stakingStarts_, + uint stakingEnds_, + uint withdrawStarts_, + uint withdrawEnds_, + uint stakingTotal_ + ) public { + tokenName = tokenName_; + require(tokenAddress_ != address(0), "Festaking: 0 address"); + tokenAddress = tokenAddress_; + + require(stakingStarts_ > 0, "Festaking: zero staking start time"); + if (stakingStarts_ < now) { + stakingStarts = now; + } else { + stakingStarts = stakingStarts_; + } + + require(stakingEnds_ > stakingStarts, "Festaking: staking end must be after staking starts"); + stakingEnds = stakingEnds_; + + require(stakingTotal_ > 0, "Festaking: stakingTotal must be positive"); + stakingTotal = stakingTotal_; + + require(withdrawStarts_ >= stakingEnds, "Festaking: withdrawStarts must be after staking ends"); + withdrawStarts = withdrawStarts_; + + require(withdrawEnds_ > withdrawStarts, "Festaking: withdrawEnds must be after withdraw starts"); + withdrawEnds = withdrawEnds_; + } + + + + /** + * Requirements: + * - nameOption + */ + function stake (uint256 amount) + public + _positive(amount) + _realAddress(msg.sender) + payable + returns (bool) { + address sender = msg.sender; + return _stakeToken(sender,amount); + } + + modifier _realAddress(address addr) { + require(addr != address(0), "Festaking: zero address"); + _; + } + + modifier _positive(uint256 amount) { + require(amount > 2, "Festaking: negative amount"); + _; + } + + modifier _after(uint eventTime) { + require(now >= eventTime, "Festaking: bad timing for the request"); + _; + } + + modifier _before(uint eventTime) + { + require(now < eventTime, "Festaking: bad timing for the request"); + _; + } + + modifier _hasEnoughToken(address staker, uint256 amount) { + ERC20Interface = ERC20(tokenAddress); + uint256 ourAllowance = ERC20Interface.allowance(staker, address(this)); + require(amount <= ourAllowance, "Festaking: Make sure to add enough allowance"); + _; + } + + function _stakeToken (address stakerAddr,uint amount) + public + _after(stakingStarts) + _before(stakingEnds) + _positive(amount) + _hasEnoughToken(stakerAddr, amount) + returns (bool) + { + uint remainingToken = amount; + // If the amount to be staked is > total staking cap + if(remainingToken > (stakingTotal - remainingToken)){ // stakingTotal = It represents the total staking cap { stakingCap } + remainingToken = (stakingTotal - remainingToken); // Then stake the whatever available stakes are there + } + require(remainingToken > 0, "Festaking: Staking cap is filled"); // If no staking available then stop the staking! + + // The token that are being stakes + total tokens already staked should be < = total available staking + require((remainingToken + stakedTotal) <= stakingTotal, "Festaking: this will increase staking amount pass the cap"); + + if (!_payMe(stakerAddr, remainingToken)) { + return false; + } + emit Staked(tokenAddress, stakerAddr, amount, remainingToken); + + if (remainingToken < amount) { + // Return the unstaked amount to sender (from allowance) + uint256 refund = amount.sub(remainingToken); + // pay/refund remaining funds + if (_payTo(stakerAddr, stakerAddr, refund)) { + emit Refunded(tokenAddress, stakerAddr, refund); + } + } + + stakedTotal = stakedTotal.add(remainingToken); + stakes[stakerAddr] = stakes[stakerAddr].add(remainingToken); + return true; + } + + function _payMe(address payer, uint256 amount) + private + returns (bool) { + return _payTo(payer, address(this), amount); + } + + function _payTo(address allower, address receiver, uint256 amount) + _hasAllowance(allower, amount) + private + returns (bool) { + // Request to transfer amount from the contract to receiver. + // contract does not own the funds, so the allower must have added allowance to the contract + // Allower is the original owner. + ERC20Interface = ERC20(tokenAddress); + return ERC20Interface.transferFrom(allower, receiver, amount); + } + + function _payDirect(address to, uint256 amount) + private + _positive(amount) + returns (bool) { + ERC20Interface = ERC20(tokenAddress); + return ERC20Interface.transfer(to, amount); + } + + function addReward(uint256 rewardAmount, uint256 withdrawableAmount) + public + _before(withdrawStarts) + _hasAllowance(msg.sender, rewardAmount) + returns (bool) { + require(rewardAmount > 0, "Festaking: reward must be positive"); + require(withdrawableAmount >= 0, "Festaking: withdrawable amount cannot be negative"); + require(withdrawableAmount <= rewardAmount, "Festaking: withdrawable amount must be less than or equal to the reward amount"); + address from = msg.sender; + if (!_payMe(from, rewardAmount)) { + return false; + } + + totalReward = totalReward.add(rewardAmount); + rewardBalance = totalReward; + earlyWithdrawReward = earlyWithdrawReward.add(withdrawableAmount); + return true; + } + + function stakeOf() public view returns (address) { + return tokenAddress; + } + + function withdraw(uint256 amount) + public + _after(withdrawStarts) + _positive(amount) + _realAddress(msg.sender) + returns (bool) { + address from = msg.sender; + require(amount <= stakes[from], "Festaking: not enough balance"); + if (now < withdrawEnds) { + return _withdrawEarly(from, amount); + } else { + return _withdrawAfterClose(from, amount); + } + } + + function _withdrawEarly(address from, uint256 amount) + private + _realAddress(from) + returns (bool) { + // This is the formula to calculate reward: + // r = (earlyWithdrawReward / stakedTotal) * (now - stakingEnds) / (withdrawEnds - stakingEnds) + // w = (1+r) * a + uint256 denom = (withdrawEnds.sub(stakingEnds)).mul(stakedTotal); + uint256 reward = ( + ( (now.sub(stakingEnds)).mul(earlyWithdrawReward) ).mul(amount) + ).div(denom); + uint256 payOut = amount.add(reward); + rewardBalance = rewardBalance.sub(reward); + stakedBalance = stakedBalance.sub(amount); + stakes[from] = stakes[from].sub(amount); + if (_payDirect(from, payOut)) { + emit PaidOut(tokenAddress, from, amount, reward); + return true; + } + return false; + } + + function _withdrawAfterClose(address from, uint256 amount) + private + _realAddress(from) + returns (bool) { + uint256 reward = (rewardBalance.mul(amount)).div(stakedBalance); + uint256 payOut = amount.add(reward); + stakes[from] = stakes[from].sub(amount); + if (_payDirect(from, payOut)) { + emit PaidOut(tokenAddress, from, amount, reward); + return true; + } + return false; + } + + modifier _hasAllowance(address allower, uint256 amount) { + // Make sure the allower has provided the right allowance. + ERC20Interface = ERC20(tokenAddress); + uint256 ourAllowance = ERC20Interface.allowance(allower, address(this)); + require(amount <= ourAllowance, "Festaking: Make sure to add enough allowance"); + _; + } +} \ No newline at end of file diff --git a/cep47-tests/wasm/.gitkeep b/cep47-tests/wasm/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/cep47/Cargo.toml b/cep47/Cargo.toml index a83601a..1a5418b 100644 --- a/cep47/Cargo.toml +++ b/cep47/Cargo.toml @@ -2,11 +2,11 @@ name = "cep47" version = "0.2.0" authors = ["astro019 "] -edition = "2018" +edition = "2021" [dependencies] hex = { version = "0.4.3", default-features = false } -casper-contract = "1.4.3" +casper-contract = "1.4.4" casper-types = "1.4.4" contract-utils = { path = "../utils/contract-utils" } diff --git a/cep47/bin/cep47_token.rs b/cep47/bin/cep47_token.rs index aab8749..05fe484 100644 --- a/cep47/bin/cep47_token.rs +++ b/cep47/bin/cep47_token.rs @@ -1,186 +1,162 @@ #![no_main] #![no_std] -#[macro_use] extern crate alloc; -use alloc::{boxed::Box, collections::BTreeSet, format, string::String, vec::Vec}; +use alloc::{boxed::Box, collections::BTreeSet, format, string::String}; +use alloc::vec; use casper_contract::{ contract_api::{runtime, storage}, unwrap_or_revert::UnwrapOrRevert, }; use casper_types::{ - runtime_args, CLType, CLTyped, CLValue, ContractPackageHash, EntryPoint, EntryPointAccess, - EntryPointType, EntryPoints, Group, Key, Parameter, RuntimeArgs, URef, U256, + runtime_args, CLType, CLTyped, Key, Group, Parameter, CLValue, ContractPackageHash, EntryPoint, EntryPointAccess, + EntryPointType, EntryPoints, RuntimeArgs, URef, U256, }; -use cep47::{Meta, TokenId, CEP47}; +use cep47::{CEP20STK}; use contract_utils::{ContractContext, OnChainContractStorage}; #[derive(Default)] -struct NFTToken(OnChainContractStorage); +struct Token(OnChainContractStorage); -impl ContractContext for NFTToken { +impl ContractContext for Token { fn storage(&self) -> &OnChainContractStorage { &self.0 } } -impl CEP47 for NFTToken {} -impl NFTToken { - fn constructor(&mut self, name: String, symbol: String, meta: Meta) { - CEP47::init(self, name, symbol, meta); +impl CEP20STK for Token {} +impl Token { + fn constructor(&mut self, name: String, address: String, staking_starts: u64, staking_ends: u64, withdraw_starts: u64, withdraw_ends: u64, staking_total: U256) { + CEP20STK::init(self, name, address, staking_starts, staking_ends, withdraw_starts, withdraw_ends, staking_total); } } #[no_mangle] fn constructor() { let name = runtime::get_named_arg::("name"); - let symbol = runtime::get_named_arg::("symbol"); - let meta = runtime::get_named_arg::("meta"); - NFTToken::default().constructor(name, symbol, meta); + let address = runtime::get_named_arg::("address"); + let staking_starts: u64 = runtime::get_named_arg::("staking_starts"); + let staking_ends: u64 = runtime::get_named_arg::("staking_ends"); + let withdraw_starts: u64 = runtime::get_named_arg::("withdraw_starts"); + let withdraw_ends: u64 = runtime::get_named_arg::("withdraw_ends"); + let staking_total: U256 = runtime::get_named_arg::("staking_total"); + + Token::default().constructor(name, address, staking_starts, staking_ends, withdraw_starts, withdraw_ends, staking_total); } #[no_mangle] fn name() { - let ret = NFTToken::default().name(); + let ret = Token::default().name(); runtime::ret(CLValue::from_t(ret).unwrap_or_revert()); } #[no_mangle] -fn symbol() { - let ret = NFTToken::default().symbol(); +fn address() { + let ret = Token::default().address(); runtime::ret(CLValue::from_t(ret).unwrap_or_revert()); } #[no_mangle] -fn meta() { - let ret = NFTToken::default().meta(); +fn staking_starts() { + let ret = Token::default().staking_starts(); runtime::ret(CLValue::from_t(ret).unwrap_or_revert()); } #[no_mangle] -fn total_supply() { - let ret = NFTToken::default().total_supply(); +fn staking_ends() { + let ret = Token::default().staking_starts(); runtime::ret(CLValue::from_t(ret).unwrap_or_revert()); } #[no_mangle] -fn balance_of() { - let owner = runtime::get_named_arg::("owner"); - let ret = NFTToken::default().balance_of(owner); +fn withdraw_starts() { + let ret = Token::default().withdraw_starts(); runtime::ret(CLValue::from_t(ret).unwrap_or_revert()); } #[no_mangle] -fn get_token_by_index() { - let owner = runtime::get_named_arg::("owner"); - let index = runtime::get_named_arg::("index"); - let ret = NFTToken::default().get_token_by_index(owner, index); +fn withdraw_ends() { + let ret = Token::default().withdraw_ends(); runtime::ret(CLValue::from_t(ret).unwrap_or_revert()); } #[no_mangle] -fn owner_of() { - let token_id = runtime::get_named_arg::("token_id"); - let ret = NFTToken::default().owner_of(token_id); +fn staking_total() { + let ret = Token::default().staking_total(); runtime::ret(CLValue::from_t(ret).unwrap_or_revert()); } #[no_mangle] -fn token_meta() { - let token_id = runtime::get_named_arg::("token_id"); - let ret = NFTToken::default().token_meta(token_id); +fn amount_staked() { + let staker = runtime::get_named_arg::("staker"); + let ret = Token::default().amount_staked(staker); runtime::ret(CLValue::from_t(ret).unwrap_or_revert()); } #[no_mangle] -fn update_token_meta() { - let token_id = runtime::get_named_arg::("token_id"); - let token_meta = runtime::get_named_arg::("token_meta"); - NFTToken::default() - .set_token_meta(token_id, token_meta) - .unwrap_or_revert(); -} - -#[no_mangle] -fn mint() { - let recipient = runtime::get_named_arg::("recipient"); - let token_ids = runtime::get_named_arg::>("token_ids"); - let token_metas = runtime::get_named_arg::>("token_metas"); - NFTToken::default() - .mint(recipient, token_ids, token_metas) - .unwrap_or_revert(); -} - -#[no_mangle] -fn mint_copies() { - let recipient = runtime::get_named_arg::("recipient"); - let token_ids = runtime::get_named_arg::>("token_ids"); - let token_meta = runtime::get_named_arg::("token_meta"); - let count = runtime::get_named_arg::("count"); - NFTToken::default() - .mint_copies(recipient, token_ids, token_meta, count) - .unwrap_or_revert(); -} - -#[no_mangle] -fn burn() { - let owner = runtime::get_named_arg::("owner"); - let token_ids = runtime::get_named_arg::>("token_ids"); - NFTToken::default() - .burn(owner, token_ids) - .unwrap_or_revert(); -} - -#[no_mangle] -fn transfer() { - let recipient = runtime::get_named_arg::("recipient"); - let token_ids = runtime::get_named_arg::>("token_ids"); - NFTToken::default() - .transfer(recipient, token_ids) - .unwrap_or_revert(); -} - -#[no_mangle] -fn transfer_from() { - let sender = runtime::get_named_arg::("sender"); - let recipient = runtime::get_named_arg::("recipient"); - let token_ids = runtime::get_named_arg::>("token_ids"); - NFTToken::default() - .transfer_from(sender, recipient, token_ids) - .unwrap_or_revert(); +fn stake() { + let amount = runtime::get_named_arg::("amount"); + let ret = Token::default().stake(amount).unwrap_or_revert(); + runtime::ret(CLValue::from_t(ret).unwrap_or_revert()); } #[no_mangle] -fn approve() { - let spender = runtime::get_named_arg::("spender"); - let token_ids = runtime::get_named_arg::>("token_ids"); - NFTToken::default() - .approve(spender, token_ids) - .unwrap_or_revert(); +fn withdraw() { + let amount = runtime::get_named_arg::("amount"); + let ret = Token::default().withdraw(amount).unwrap_or_revert(); + runtime::ret(CLValue::from_t(ret).unwrap_or_revert()); } #[no_mangle] -fn get_approved() { - let owner = runtime::get_named_arg::("owner"); - let token_id = runtime::get_named_arg::("token_id"); - let ret = NFTToken::default().get_approved(owner, token_id); +fn add_reward() { + let reward_amount = runtime::get_named_arg::("reward_amount"); + let withdrawable_amount = runtime::get_named_arg::("withdrawable_amount"); + let ret = Token::default().add_reward(reward_amount,withdrawable_amount).unwrap_or_revert(); runtime::ret(CLValue::from_t(ret).unwrap_or_revert()); } + #[no_mangle] fn call() { // Read arguments for the constructor call. let name: String = runtime::get_named_arg("name"); - let symbol: String = runtime::get_named_arg("symbol"); - let meta: Meta = runtime::get_named_arg("meta"); - let contract_name: String = runtime::get_named_arg("contract_name"); + let address = runtime::get_named_arg::("address"); + let staking_starts: u64 = runtime::get_named_arg::("staking_starts"); + let staking_ends: u64 = runtime::get_named_arg::("staking_ends"); + let withdraw_starts: u64 = runtime::get_named_arg::("withdraw_starts"); + let withdraw_ends: u64 = runtime::get_named_arg::("withdraw_ends"); + let staking_total: U256 = runtime::get_named_arg::("staking_total"); + // let contract_name: String = runtime::get_named_arg("contract_name"); + + /* + +casper-client put-deploy \ + --chain-name casper-test \ + --node-address http://159.65.118.250:7777 \ + --secret-key ./keys/secret_key.pem \ + --session-path ./target/wasm32-unknown-unknown/release/cep47-token.wasm \ + --payment-amount 80000000000 \ + --session-arg "name:string='FerrumX'" \ + --session-arg "address:string='hash-7e3f01576650a939a96c2caa6dcc19df8d2ef1882e4b6603a375234e22e07e4f'" \ + --session-arg "staking_starts:u64='1653993649'" \ + --session-arg "staking_ends:u64='1653994249'" \ + --session-arg "withdraw_starts:u64='1653994549'" \ + --session-arg "withdraw_ends:u64='1653994249'" \ + --session-arg "staking_total:U256='500000'" + + */ + // Prepare constructor args let constructor_args = runtime_args! { "name" => name, - "symbol" => symbol, - "meta" => meta + "address" => address, + "staking_starts" => staking_starts, + "staking_ends" => staking_ends, + "withdraw_starts" => withdraw_starts, + "withdraw_ends" => withdraw_ends, + "staking_total" => staking_total }; let (contract_hash, _) = storage::new_contract( @@ -226,8 +202,12 @@ fn get_entry_points() -> EntryPoints { "constructor", vec![ Parameter::new("name", String::cl_type()), - Parameter::new("symbol", String::cl_type()), - Parameter::new("meta", Meta::cl_type()), + Parameter::new("address", String::cl_type()), + Parameter::new("staking_starts", u64::cl_type()), + Parameter::new("staking_ends", u64::cl_type()), + Parameter::new("withdraw_starts", u64::cl_type()), + Parameter::new("withdraw_ends", u64::cl_type()), + Parameter::new("staking_total", U256::cl_type()) ], <()>::cl_type(), EntryPointAccess::Groups(vec![Group::new("constructor")]), @@ -241,95 +221,45 @@ fn get_entry_points() -> EntryPoints { EntryPointType::Contract, )); entry_points.add_entry_point(EntryPoint::new( - "symbol", + "address", vec![], String::cl_type(), EntryPointAccess::Public, EntryPointType::Contract, - )); + )); entry_points.add_entry_point(EntryPoint::new( - "meta", + "staking_starts", vec![], - Meta::cl_type(), + u64::cl_type(), EntryPointAccess::Public, EntryPointType::Contract, - )); + )); entry_points.add_entry_point(EntryPoint::new( - "total_supply", + "withdraw_starts", vec![], - U256::cl_type(), - EntryPointAccess::Public, - EntryPointType::Contract, - )); - entry_points.add_entry_point(EntryPoint::new( - "balance_of", - vec![Parameter::new("owner", Key::cl_type())], - U256::cl_type(), + u64::cl_type(), EntryPointAccess::Public, EntryPointType::Contract, - )); + )); entry_points.add_entry_point(EntryPoint::new( - "owner_of", - vec![Parameter::new("token_id", TokenId::cl_type())], - CLType::Option(Box::new(CLType::Key)), - EntryPointAccess::Public, - EntryPointType::Contract, - )); - entry_points.add_entry_point(EntryPoint::new( - "token_meta", - vec![Parameter::new("token_id", TokenId::cl_type())], - Meta::cl_type(), - EntryPointAccess::Public, - EntryPointType::Contract, - )); - entry_points.add_entry_point(EntryPoint::new( - "update_token_meta", - vec![ - Parameter::new("token_id", TokenId::cl_type()), - Parameter::new("token_meta", Meta::cl_type()), - ], - <()>::cl_type(), - EntryPointAccess::Public, - EntryPointType::Contract, - )); - entry_points.add_entry_point(EntryPoint::new( - "mint", - vec![ - Parameter::new("recipient", Key::cl_type()), - Parameter::new("token_ids", CLType::List(Box::new(TokenId::cl_type()))), - Parameter::new("token_metas", CLType::List(Box::new(Meta::cl_type()))), - ], - <()>::cl_type(), - EntryPointAccess::Public, - EntryPointType::Contract, - )); - entry_points.add_entry_point(EntryPoint::new( - "mint_copies", - vec![ - Parameter::new("recipient", Key::cl_type()), - Parameter::new("token_ids", CLType::List(Box::new(TokenId::cl_type()))), - Parameter::new("token_meta", Meta::cl_type()), - Parameter::new("count", CLType::U32), - ], - <()>::cl_type(), + "withdraw_ends", + vec![], + u64::cl_type(), EntryPointAccess::Public, EntryPointType::Contract, - )); + )); entry_points.add_entry_point(EntryPoint::new( - "burn", - vec![ - Parameter::new("owner", Key::cl_type()), - Parameter::new("token_ids", CLType::List(Box::new(TokenId::cl_type()))), - ], - <()>::cl_type(), + "staking_total", + vec![], + U256::cl_type(), EntryPointAccess::Public, EntryPointType::Contract, - )); + )); entry_points.add_entry_point(EntryPoint::new( "transfer", vec![ Parameter::new("recipient", Key::cl_type()), - Parameter::new("token_ids", CLType::List(Box::new(TokenId::cl_type()))), + Parameter::new("amount", Key::cl_type()) ], <()>::cl_type(), EntryPointAccess::Public, @@ -340,7 +270,7 @@ fn get_entry_points() -> EntryPoints { vec![ Parameter::new("sender", Key::cl_type()), Parameter::new("recipient", Key::cl_type()), - Parameter::new("token_ids", CLType::List(Box::new(TokenId::cl_type()))), + Parameter::new("amount", Key::cl_type()) ], <()>::cl_type(), EntryPointAccess::Public, @@ -349,8 +279,7 @@ fn get_entry_points() -> EntryPoints { entry_points.add_entry_point(EntryPoint::new( "approve", vec![ - Parameter::new("spender", Key::cl_type()), - Parameter::new("token_ids", CLType::List(Box::new(TokenId::cl_type()))), + Parameter::new("spender", Key::cl_type()) ], <()>::cl_type(), EntryPointAccess::Public, @@ -359,22 +288,11 @@ fn get_entry_points() -> EntryPoints { entry_points.add_entry_point(EntryPoint::new( "get_approved", vec![ - Parameter::new("owner", Key::cl_type()), - Parameter::new("token_id", TokenId::cl_type()), + Parameter::new("owner", Key::cl_type()) ], CLType::Option(Box::new(CLType::Key)), EntryPointAccess::Public, EntryPointType::Contract, )); - entry_points.add_entry_point(EntryPoint::new( - "get_token_by_index", - vec![ - Parameter::new("owner", Key::cl_type()), - Parameter::new("index", U256::cl_type()), - ], - CLType::Option(Box::new(TokenId::cl_type())), - EntryPointAccess::Public, - EntryPointType::Contract, - )); entry_points -} +} \ No newline at end of file diff --git a/cep47/src/cep47.rs b/cep47/src/cep47.rs index f5dcd0b..daf2bdc 100644 --- a/cep47/src/cep47.rs +++ b/cep47/src/cep47.rs @@ -1,15 +1,16 @@ use crate::{ data::{self, StakedTokens}, - event::CEP47Event, - Meta, TokenId, + event::CEP47Event }; -use alloc::{string::String, vec::Vec}; -use casper_types::{ApiError, Key, U256, runtime_args, ContractPackageHash}; +use casper_types::RuntimeArgs; +use alloc::{string::String}; +use casper_types::{ApiError, Key, U256, BlockTime, runtime_args, ContractPackageHash}; use contract_utils::{ContractContext, ContractStorage}; -use core::convert::TryInto; +// use core::convert::TryInto; use casper_contract::contract_api::runtime; use casper_types::ContractHash; use crate::detail; + #[repr(u16)] pub enum Error { PermissionDenied = 1, @@ -31,10 +32,10 @@ pub trait CEP20STK: ContractContext { fn init(&mut self, name: String, address: String, - staking_starts: U256, - staking_ends: U256, - withdraw_starts: U256, - withdraw_ends: U256, + staking_starts: u64, + staking_ends: u64, + withdraw_starts: u64, + withdraw_ends: u64, staking_total: U256 ) { data::set_name(name); @@ -55,19 +56,19 @@ pub trait CEP20STK: ContractContext { data::address() } - fn staking_starts(&self) -> U256 { + fn staking_starts(&self) -> u64 { data::staking_starts() } - fn staking_ends(&self) -> U256 { + fn staking_ends(&self) -> u64 { data::staking_ends() } - fn withdraw_starts(&self) -> U256 { + fn withdraw_starts(&self) -> u64 { data::withdraw_starts() } - fn withdraw_ends(&self) -> U256 { + fn withdraw_ends(&self) -> u64 { data::withdraw_ends() } @@ -78,7 +79,7 @@ pub trait CEP20STK: ContractContext { fn amount_staked(&self, staker: Key) -> U256 { StakedTokens::instance().get_amount_staked_by_address(&staker).unwrap() } - } + fn stake( @@ -89,12 +90,11 @@ pub trait CEP20STK: ContractContext { if amount < U256::from(2) { return Err(Error::NotRequiredStake); } - - if runtime::get_blocktime() < self.staking_starts() { + if runtime::get_blocktime() >= BlockTime::new(self.staking_starts()) { return Err(Error::BadTiming); } - if runtime::get_blocktime() >= self.staking_ends() { + if runtime::get_blocktime() >= BlockTime::new(self.staking_ends()) { return Err(Error::BadTiming); } @@ -104,15 +104,14 @@ pub trait CEP20STK: ContractContext { let contract_hash = ContractHash::from_formatted_str(&lower_contracthash).unwrap(); let lower_contractpackagehash = "hash-wasmc4929e7fcb71772c1cb39ebb702a70d036b0ad4f9caf420d3fd377f749dfdb17".to_lowercase(); - let contract_package_hash = ContractPackageHash::from_formatted_str(&lower_contractpackagehash); + let contract_package_hash = ContractPackageHash::from_formatted_str(&lower_contractpackagehash).unwrap(); let args = runtime_args! { "owner" => detail::get_immediate_caller_address()?, "recipient" => contract_package_hash, "amount" => amount - }; - runtime::call_contract(contract_hash,"transfer_from", args); + runtime::call_contract::(contract_hash,"transfer_from", args); stakers_dict.add_stake(&Key::from(detail::get_immediate_caller_address()?), &amount); self.emit(CEP47Event::Stake { @@ -130,12 +129,11 @@ pub trait CEP20STK: ContractContext { if amount < U256::from(2) { return Err(Error::NotRequiredStake); } - - if runtime::get_blocktime() < self.staking_starts() { + if runtime::get_blocktime() >= BlockTime::new(self.staking_starts()) { return Err(Error::BadTiming); } - if runtime::get_blocktime() >= self.staking_ends() { + if runtime::get_blocktime() >= BlockTime::new(self.staking_ends()) { return Err(Error::BadTiming); } @@ -145,14 +143,14 @@ pub trait CEP20STK: ContractContext { let contract_hash = ContractHash::from_formatted_str(&lower_contracthash).unwrap(); let lower_contractpackagehash = "hash-4929e7fcb71772c1cb39ebb702a70d036b0ad4f9caf420d3fd377f749dfdb17".to_lowercase(); - let contract_package_hash = ContractPackageHash::from_formatted_str(&lower_contractpackagehash); + let _contract_package_hash = ContractPackageHash::from_formatted_str(&lower_contractpackagehash).unwrap(); let args = runtime_args! { "recipient" => detail::get_immediate_caller_address()?, "amount" => amount }; - runtime::call_contract(contract_hash,"transfer", args); + runtime::call_contract::(contract_hash,"transfer", args); stakers_dict.withdraw_stake(&Key::from(detail::get_immediate_caller_address()?), &amount); self.emit(CEP47Event::Stake { @@ -166,8 +164,7 @@ pub trait CEP20STK: ContractContext { reward_amount: U256, withdrawable_amount: U256 ) -> Result { - - if runtime::get_blocktime() >= self.withdraw_starts() { + if runtime::get_blocktime() >= BlockTime::new(self.withdraw_starts()) { return Err(Error::PermissionDenied) } @@ -188,7 +185,7 @@ pub trait CEP20STK: ContractContext { let contract_hash = ContractHash::from_formatted_str(&lower_contracthash).unwrap(); let lower_contractpackagehash = "hash-wasmc4929e7fcb71772c1cb39ebb702a70d036b0ad4f9caf420d3fd377f749dfdb17".to_lowercase(); - let contract_package_hash = ContractPackageHash::from_formatted_str(&lower_contractpackagehash); + let contract_package_hash = ContractPackageHash::from_formatted_str(&lower_contractpackagehash).unwrap(); let args = runtime_args! { "owner" => detail::get_immediate_caller_address()?, @@ -196,7 +193,7 @@ pub trait CEP20STK: ContractContext { "amount" => reward_amount + withdrawable_amount }; - runtime::call_contract(contract_hash,"transfer_from", args); + runtime::call_contract::(contract_hash,"transfer_from", args); self.emit(CEP47Event::AddReward { @@ -207,9 +204,7 @@ pub trait CEP20STK: ContractContext { } - - fn emit(&mut self, event: CEP47Event) { data::emit(&event); } - +} diff --git a/cep47/src/data.rs b/cep47/src/data.rs index 38ce16b..04c96e0 100644 --- a/cep47/src/data.rs +++ b/cep47/src/data.rs @@ -8,7 +8,7 @@ use casper_contract::{ unwrap_or_revert::UnwrapOrRevert, }; use casper_types::{system::CallStackElement, ContractPackageHash, Key, URef, U256}; -use contract_utils::{get_key, key_and_value_to_str, key_to_str, set_key, Dict}; +use contract_utils::{get_key, key_to_str, set_key, Dict}; use crate::detail; use crate::{event::CEP47Event}; @@ -16,7 +16,7 @@ const STAKERS_DICT: &str = "stakers"; const AMOUNT_STAKED_BY_ADDRESS_DICT: &str = "amount_staked_by_addresses_dict"; const CONTRACT_PACKAGE_HASH: &str = "contract_package_hash"; -pub const NAME: &str = "address"; +pub const NAME: &str = "name"; pub const ADDRESS: &str = "address"; pub const STAKING_STARTS: &str = "staking_starts"; pub const STAKING_ENDS: &str = "staking_ends"; @@ -79,35 +79,35 @@ pub fn set_address(address: String) { set_key(ADDRESS, address); } -pub fn staking_starts() -> U256 { +pub fn staking_starts() -> u64 { get_key(STAKING_STARTS).unwrap_or_revert() } -pub fn set_staking_starts(staking_starts: U256) { +pub fn set_staking_starts(staking_starts: u64) { set_key(STAKING_STARTS, staking_starts); } -pub fn staking_ends() -> U256 { +pub fn staking_ends() -> u64 { get_key(STAKING_ENDS).unwrap_or_revert() } -pub fn set_staking_ends(staking_ends: U256) { +pub fn set_staking_ends(staking_ends: u64) { set_key(STAKING_ENDS, staking_ends); } -pub fn withdraw_starts() -> U256 { +pub fn withdraw_starts() -> u64 { get_key(WITHDRAW_STARTS).unwrap_or_default() } -pub fn set_withdraw_starts(withdraw_starts: U256) { +pub fn set_withdraw_starts(withdraw_starts: u64) { set_key(WITHDRAW_STARTS, withdraw_starts); } -pub fn withdraw_ends() -> U256 { +pub fn withdraw_ends() -> u64 { get_key(WITHDRAW_ENDS).unwrap_or_default() } -pub fn set_withdraw_ends(withdraw_ends: U256) { +pub fn set_withdraw_ends(withdraw_ends: u64) { set_key(WITHDRAW_STARTS, withdraw_ends); } diff --git a/cep47/src/lib.rs b/cep47/src/lib.rs index 36af22a..9ac417d 100644 --- a/cep47/src/lib.rs +++ b/cep47/src/lib.rs @@ -1,5 +1,4 @@ #![no_std] -#[macro_use] extern crate alloc; mod cep47; diff --git a/keys/.DS_Store b/keys/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..0b521057c1bb58414fc111f2eb1ce2b9204453e0 GIT binary patch literal 6148 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 literal 0 HcmV?d00001 diff --git a/keys/public_key.pem b/keys/public_key.pem new file mode 100644 index 0000000..de7d8cd --- /dev/null +++ b/keys/public_key.pem @@ -0,0 +1,3 @@ +-----BEGIN PUBLIC KEY----- +MCowBQYDK2VwAyEAf7vM85pjmhpfRp4/shDZ81W1Mr14b5RUCfD8moxjE7E= +-----END PUBLIC KEY----- diff --git a/keys/public_key_hex.txt b/keys/public_key_hex.txt new file mode 100644 index 0000000..eaf5f4e --- /dev/null +++ b/keys/public_key_hex.txt @@ -0,0 +1 @@ +017fbbccf39a639a1a5f469e3fb210d9f355b532bd786f945409f0fc9a8c6313b1 \ No newline at end of file diff --git a/keys/rust_sol.wasm b/keys/rust_sol.wasm new file mode 100755 index 0000000000000000000000000000000000000000..bcd53cd302e009042a6540ba96cfc01ccf559c6c GIT binary patch literal 157476 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

99VpO7?x&4f1XS2#>#)O(3fxA zHVgJu)pA}wbdJS;(?lc9YLaX8w%nFT$=$$Y%;OedrKxDquyQer>F?)qakJsrVB1?T z^)rr%1V3&4dvo#j2HmyJ*0g>S(~Z7`v_v1x%?H>P86Fs~ycbik6^tIp<=^&NE0x{> zQ9YmU0TFrGc`pH$0u&&|R)yPuS7 z-7u0=c+rX!O*MoDe&iaRFBny5DWLS4l`eY{gnSMI2;qHkLF$Ho;OlR`v|4#5*QoHK zsxGyrco>51u^q$Nx>n*m0nx%V(%p>Ufk zfUxLma=pd8ctBt6WY)TSE0{?#17u=i>9y8U74IWbeno&`)Qj8?;fjD?%JVt$1`d6R zf@T4^T%a3!t=h*2Hb~L-9bIB{G|-Ad#kwOmT$tjf_JQX0_CQ#fGSO>t@$x3x8{|P_ zf_=tv@^YN%aSbOq3}t97Q)Yu8zYFk%Shcnmw>xt==GrQY+ZJQ^Te%pzp+HgQv};B#`%go<#uK!Vg66&y`1NS^kADDZ$jIAF0Z=07=G{7 zY2sB_X>RZ8fv2aB{PW^noK~8xdZ6qLXmp+V*K)-*)%BGz&{oDfAKU3OUdZ*HE0Cm= zubi0s9V#w-H@CejP~Q|6ymK-Pt-q3IM!f%$Q4OacpUM@RJcfC4E%s~!>c8}En|F6{ z5{V0;*dQuxS^9&PZh~?+RRSftqnXzRc?#Gc?bUL!T4}JC@hc_oscH_KK4_Oy(PjkNTYlJUpe|Qp(p9*!)eRU<@N6#=!da@q z^W-W?PMsY$LqJ=s4%=9Dm}c>$z;aAJ;h&gJ+9bvX<7u1U$PO_K zj-RmEAkduBxIvig)(>S)RjyItIj%uqQjPtp21;})&aUxCCs?SJ!SLF@OQazQf(rDd|V{~eIjj&~_QS1&!=@_Dh%~w4(_QbHUCq|5kto?MK zFK(smrf*^{2r+WqV9j<)5sYN-A!JFmCNbnqw=F5k8%v#HbxCj9k#`c``tVQ7VV3rz zHZU~CbH zb@-OA6l(OkT)j*=7lYwkB4;*#|Bh{F#e{t2?|i={n6(~~l*Vx2@`a-9=3McCNY7wo zV%udh?B};zKf;9QE<3`T`LY42`RQiIY&>EfuKB#*_SVmC`gYjw5Qkl^QNJtdAM)rK zb>^F!x$cD)lUKi@zUm74USs|zo?`P&EPcBap}w=I2yXQ8U_9wf$|D|UYZH^Wzw$p7 zSbAcT*VBw_i8Vf(Ce*x5L|Cp-e)eH1`reZFy(eIj<~`PO)cFyp#vVhw3P&IZftL#( z3RcCvz=2>A#u48V2&bR7C?cF@L`{Irc6uMMT=V$_44X>aJ4E8-+5OO9{*3KZI0#I=2;)3mk&Mcu3b! zNmTDPNT?br8iv8H2Wj^a_M6DD>zgG$_SfU;WS<{+>9K%*Fp;+QrA7t1d_=F&=eNhN z$Vi@r8*B(vWP;T115ycJ{FG`2w^Cg0W16N4`AKu69L!3fL~qQMv4MDOuCMVL^rN&s zxl}8rmW%b}eP?u|6h?iVWml@cqz|9^R*8&P#FzY?z6PQxDNdw&86Uf?Xm6`(cvKCP zK9ZXIlE4i1<@&whwQYChE*BZ71Xs&fgZ87W0fiG{j2r#+9BJ#~p_S5rgb(|w?eH&# za70^pN~YQtby=U`aqinYmeUb?h|k3>>mend$sLtm1oqX%PeOWzK~lnK?pE89AmUJw zR#xKAMsLcssd))U-kz89kNik}cs-l)O90Dpq>^^5MyC3RWt57Y*tkS2MKv^31Er5d z`*NK4|58wM3E9KMi92$w<7T~ZIVnh5#pJhP;>){p`LbEeyn4P2FPGk*%O$_-vco-N zvj)wj;pN%gxjgfJ$8hj$cscl)Tn@Ue$9%85%~F@-VDj5A*}5<0^3z9+hEXDu{7ilu zChqpWxa>in>T9{$**%NRe%k)nX_`wx>3h%OQnhCEv=o%`yBL(JE|Ixgen?fS?hM2J z#*2)l+kV?W8ThKz?WVmN4wixv&E;iQ_-wO>;~msnJ?^8fNt59g?9b1uEfvYonyeRe z+xF{IhsBHYK&9ON?w~dV-MhgvWA>wxMXkrwa$;I;v^a_b{v^n-NELAU#$;Ya!VqNl9npfPE!%O*NHc=eIweG{ywu+ltO1Vb)Ckbqi zHY;u+_fEt+K>4kzHgNxDo%^>`!VN5b+LHF;Uy)Uha@~APqO1>#6h7@I^cq3{&n-Hf z2mxgAcwruxRM5Spb$=|~&${QzhpX~{rMfIvDC}4YlcRVjAz5;6&BGw=f(n?9-!(6C z0`tyw?mqTvUOP?&S|Q0=c_5&PEkJrCKcFGHIuGxZA}Z%LH9Cc*E99mUD%Yq~b0~m- zJH6`E=S8~YT2!aPB890ARU!mXnCcLKHe(2;uuf?qP2&ipp%nrvEL2*klul{UJPZo! zlz_?T)Z4n~R7kQ`9!O0&oyyQqT&EOoAI}ckHoz(>EL|ZcL5fasoyr0T@i>|75^aNw zY~<0RlVw69z3T4|q)(JlU$4He^{iH{)Yhi(Ekuj zVg1)ap)#lrhQJEzzZNQ`|5`NE{}6-1`Y(lg)_<)kknnQ)pP`|+{wv;<>3@hxDgDm^ z2)GlSjr(su>?orCTRFD9L-bg#MfEr=Qc90Q0Db6j2&S+eYa!WM!=;(4E``7f>#-Ip zrN>${)Z-9?!g?%)GJ4!?Y#WlSRRxk-PLDG*6xU9p`o}QE8dmqaRw8$(Z%&R3n1W5bZgun?{qqOzxR>N#kNcb^O0>} zy_E|6K2d177FFo5NGXL50ra8JA(+Ant%W|32|9Mxo!`MWI8Iwemn@%PDk* zhT;mXcvq&-Atu3Tx5X7Y3n1W5^vWP&w#zBy$9)%VA#dCBX@d#ktyJw#i)zcYsA`8r zN~v}Tpbym!!MvfKH#M1_A(m2>q2ia;Sb}M`q3lT}kuxz053wn18?;a<+n_~5+Yn+< zxLvf+pJWnhdL$vhqqu%c-J8x5-<{jE>DlstCDk-=HBh2g}bieTsho8x#HQm)qAsf>8ZO3&UtQ0PaMYyP{_<>Z3>b;T3D5M4F%-1Zim?^O~ ztMKkut#7fb93UqDDexpNabunAF(5|hJ$@Ku%MtCyHp8{704rr-O+V4!xzbf-N8K1t zEpgyGzA7v2Yv|$B4-ta_vahg)s8oi#H+?`=aLF&6+d?j7$Mz=g7Lb3`v%-dznNxpzkk~;e{C9<+ za_wRHx4d7C@v8<(gbn2k(v!E|SUuny+VsL&+|KSAq+Wbano+LNHd~L+c~+Q}HddHk z7?;ejcmqCA>+yetOL8r4c+@+=)skY?u8d3wIG(d${3Xx758YG=2~HMm7tV z?a_UcmfxDex(fqd#G6`wB~$<8TD+CDP%wPm;NXO`pBj`k8{{`nx!*G?s}0r_WYxk5 zH`VbST*YvUr;-Omh9S}73%9gIv~0%hs+g?AFms#z*iU*1Fi*)^*TmYi$iGwED=>-k zp`$GH0!rf>#H}5Cm8g(hi>r_pQgbQS;)YU+rf>*Hc-!2BHWcwDtz-R`aoc;e9Y2uS zYP0t`X*0PNZ!;|vwprmwofZu&rptx7tDZN$PX)qFaw}H;q#W5d?L9+MdtVPbC`_}s z72eBX;9S(rOWg$RplVC(r}S{o5>%n>^YUVp_60j}`g!5dPBnFVN*r&)07J7_A)iZ-UELE{jqz6pPIP4haL4knOJ`GbY4ar5 znYTVZ(>as!n z%mNM>L5>G4nJTtf#@{V6F4rDpT;8|Vt5_BX1vfgMXLZw2B_%KIcYE7hKwQ)u>9q&d zO0u;tr7$M;1*PjUGF9&DeyUriHL10}jU*X2w17fP{+d8TgPC>?Wit(DD{u&D;iUiWUE7u8Zw zwpk8Bg)f!cnaS9SUYOT|`@T6jI@XXy28=tndM*!`&weard7j};&TVt%)a71s)iJX ziR@41He%Y)b_<6L6D5Vi=bJ~fsu8JbphVHf_rU8}U%$H+eGqs0Z^V6`J$}RK)wQ#$ z=dN{kM}G09Q>)h=J#+fp+L5E@jvhI6YV}zAx}U!3-0?G~ue$2y(=S~+a?^pIxUPNX zbo)sAx~tEeUcIh;{>Z7DR}Ze;eD>VYgGY}ZT3EXN=&|{^rR$fEtt=i}ICA~Wp{3R9 zj~!i}Uz}fAnwwi(T3J1G@YL~NSUa+I%R$s|=IFt*YbbgKl^tb8XAl0uxwX~RgQt(2 zKYqiJbE{Xbodv!xuC;2{;`65(wc0ho_aB0&gZMs7$d1<)*AD`(AIG2n{$||o$DeNp zeuA7@6Mt-zQT*{=x99wwe`EL?$KM40dZ78p*|V!_U#h68SU9x?dgqH?O%Yt z+rXS1`1Idj;l5`fLV~V5wR-x%PY~X*v*+}SFZXFMjlA{W|2Y`>l;Hd8-1jWpZkV1X zSq^(a*WkVb4M}_l!puM$ZfvT24TElOF9zT5p7<=bvt9CiyJ`TSA7(V^?Z{hpj$M@a%Baey49(PaNXeaoL zy!UNE9Qo{0{Dtp48Q(n)v1ML6^3rS1uO0;sM~~ceexQ~@gKg{o{GPjnVH#{xtaNyg_*^frJ3cKm6=1cGqba^bF=fa3$u%}OS8+f zE3=2@X69z+=H}+-7UmY`mgbh{R^|@P&&oaRW%1C`%+l=A+|vBg!qVc>($ezM%F?0b zndRB#x#jugh2_QNrRC-2mE}V#Gb^(zb1U;J3oDB&ODoGOD=UW%0mVb8{t!SPLa{@5 z)IM|bx%Qds+iOQo->}-g{>)nY?5X2NSNRBr=Z14Px?fgLA8Q{!eQfn*?ON?$j<=*u zo{3M&J9*B3M^BwOd-K{V-aCKhBzoAj)uT7Bojrbj^%PjU);_j+_T1W;Tkyk?Q){b7 Ij@|Nq0fWuLQ2+n{ literal 0 HcmV?d00001 diff --git a/keys/secret_key.pem b/keys/secret_key.pem new file mode 100644 index 0000000..f7e3346 --- /dev/null +++ b/keys/secret_key.pem @@ -0,0 +1,3 @@ +-----BEGIN PRIVATE KEY----- +MC4CAQAwBQYDK2VwBCIEIJEoNtQENWy3J4Td/BAa912jdHI1Gf9NAuy8k3NNNUmq +-----END PRIVATE KEY----- diff --git a/rust-toolchain b/rust-toolchain index 18433b9..5b1e74b 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -nightly-2021-06-17 \ No newline at end of file +nightly-2022-01-03 \ No newline at end of file diff --git a/utils/.DS_Store b/utils/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..652124e7fc2049a6749e0e1572908c24926dcd54 GIT binary patch literal 6148 zcmeHKOKQVF43*L>QVJ!@LKmHV=pr|8f_s8oAkBxiVAmmWx}KZ#GQCpweHw`nV~5a9 z2}J_U8*8K)`Ax7QBI4^p((;i!TrX|(%Nc)zz8!nLn zxw~83Sw-)-x8wV(>5U576))r2vMM*4{QdVi|FX*SMNuu_hrQ$H=;3Q}K4$gnn9b{P zUUM9Q^J-etF8%)2c%P4E?xWb{b0Xi?US-vpW6Q6Zm(eEKxi|yPfHQD844`I<3~m&C zbOxLOXW+nqd>;Z-Ff)vb>C=HBwE)0A%txTY1!^c;i@_QWdoaJu zFe+*|u{9rTC$n`ZoKDC7A-NN0iat66&OnoaD}5YF{eL>$|2KpD$r*44{uKk<&u94* zuVl5g^>R{c19T1*5x=N-2*D(kV)#lazJn%#J;(%@8Ae4|ApS=n(cptK@TUy?0Hy0y Apa1{> literal 0 HcmV?d00001 diff --git a/utils/contract-utils/Cargo.toml b/utils/contract-utils/Cargo.toml index 3d330d4..732e3a2 100644 --- a/utils/contract-utils/Cargo.toml +++ b/utils/contract-utils/Cargo.toml @@ -5,6 +5,6 @@ authors = ["Maciej Zielinski "] edition = "2018" [dependencies] -casper-contract = "1.4.3" -casper-types = "1.4.4" +casper-contract = "1.4.4" +casper-types = "1.5.0" hex = { version = "0.4.3", default-features = false } diff --git a/utils/test-env/Cargo.toml b/utils/test-env/Cargo.toml index a2fada7..edc2cde 100644 --- a/utils/test-env/Cargo.toml +++ b/utils/test-env/Cargo.toml @@ -5,10 +5,10 @@ authors = ["Maciej Zielinski "] edition = "2018" [dependencies] -casper-contract = { version = "1.4.3", default-features = false, features = ["test-support"] } -casper-engine-test-support = { version = "2.0.3", features = ["test-support"] } -casper-execution-engine = "1.4.2" -casper-types = "1.4.4" +casper-contract = { version = "1.4.4", default-features = false, features = ["test-support"] } +casper-engine-test-support = { version = "2.1.0", features = ["test-support"] } +casper-execution-engine = "1.5.0" +casper-types = "1.5.0" [features] default = ["casper-contract/std", "casper-types/std", "casper-engine-test-support/test-support", "casper-contract/test-support"]

$wm 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 TA;jhhZbM+5?C5ky+sFPFt3KgL literal 0 HcmV?d00001 diff --git a/dragons-nft-tests/Cargo.toml b/dragons-nft-tests/Cargo.toml index d331919..90e8431 100644 --- a/dragons-nft-tests/Cargo.toml +++ b/dragons-nft-tests/Cargo.toml @@ -11,6 +11,7 @@ casper-contract = "1.2.0" casper-types = "1.2.0" casper-engine-test-support = "1.2.0" maplit = "1.0.2" +cep47-test = { path = "../cep47-test" } [features] default = ["casper-contract/std", "casper-types/std", "casper-contract/test-support"] From 2d244ec2842ca6d92c9adc3081528afda4f3cc07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Zieli=C5=84ski?= Date: Mon, 19 Jul 2021 10:16:40 +0200 Subject: [PATCH 41/98] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b201a8e..3305544 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -# casper-nft-cep46 \ No newline at end of file +# casper-nft-cep47 From d3591184ec335f01914a466748526d1691359cb1 Mon Sep 17 00:00:00 2001 From: Maciej Zielinski Date: Tue, 20 Jul 2021 13:49:37 +0200 Subject: [PATCH 42/98] new_uref-based solution --- cep47/src/lib.rs | 45 +- dragons-nft-scripts/.env | 0 dragons-nft-scripts/.gitignore | 2 + dragons-nft-scripts/package-lock.json | 1262 +++++++++++++++++++++++++ dragons-nft-scripts/package.json | 22 + dragons-nft-scripts/src/index.js | 189 ++++ 6 files changed, 1512 insertions(+), 8 deletions(-) create mode 100644 dragons-nft-scripts/.env create mode 100644 dragons-nft-scripts/.gitignore create mode 100644 dragons-nft-scripts/package-lock.json create mode 100644 dragons-nft-scripts/package.json create mode 100644 dragons-nft-scripts/src/index.js diff --git a/cep47/src/lib.rs b/cep47/src/lib.rs index f750f4d..a46e964 100644 --- a/cep47/src/lib.rs +++ b/cep47/src/lib.rs @@ -12,14 +12,7 @@ use casper_contract::{ contract_api::{runtime, storage}, unwrap_or_revert::UnwrapOrRevert, }; -use casper_types::{ - account::AccountHash, - bytesrepr::{FromBytes, ToBytes}, - contracts::NamedKeys, - AccessRights, ApiError, AsymmetricType, CLType, CLTyped, CLValue, ContractPackageHash, - EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Key, Parameter, PublicKey, URef, - U256, -}; +use casper_types::{AccessRights, ApiError, AsymmetricType, CLType, CLTyped, CLValue, ContractPackageHash, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, HashAddr, Key, Parameter, PublicKey, U256, URef, account::AccountHash, bytesrepr::{FromBytes, ToBytes}, contracts::NamedKeys}; pub use cep47_logic::Meta; use cep47_logic::{CEP47Contract, CEP47Storage, TokenId, WithStorage}; @@ -110,6 +103,7 @@ impl CEP47Storage for CasperCEP47Storage { let meta = self.meta(); let mut hasher = DefaultHasher::new(); + for token_meta in token_metas.clone() { let token_info = (meta.clone(), token_meta.clone()); Hash::hash(&token_info, &mut hasher); @@ -119,6 +113,8 @@ impl CEP47Storage for CasperCEP47Storage { total_supply = total_supply + 1; set_key(&meta_key(&token_id), token_meta); set_key(&owner_key(&token_id), recipient.clone()); + + emit_mint_one_event(&recipient, &token_id); } recipient_balance = recipient_balance + U256::from(token_metas.len() as u64); set_key( @@ -127,6 +123,7 @@ impl CEP47Storage for CasperCEP47Storage { ); set_key(&token_key(&recipient.to_account_hash()), recipient_tokens); set_key("total_supply", total_supply); + } fn mint_copies(&mut self, recipient: PublicKey, token_meta: Meta, count: U256) { let token_metas: Vec = vec![token_meta; count.as_usize()]; @@ -361,6 +358,8 @@ pub extern "C" fn transfer_token() { } let recipient: PublicKey = runtime::get_named_arg("recipient"); let token_id: TokenId = runtime::get_named_arg("token_id"); + emit_transfer_token_event(&sender, &recipient, &token_id); + let mut contract = CasperCEP47Contract::new(); let res = contract.transfer_token(sender, recipient, token_id); res.unwrap_or_revert(); @@ -621,6 +620,7 @@ pub fn deploy( storage::new_uref(U256::zero()).into(), ); named_keys.insert("paused".to_string(), storage::new_uref(paused).into()); + named_keys.insert("contract_package_hash".to_string(), storage::new_uref(contract_package_hash).into()); let (contract_hash, _) = storage::add_contract_version(contract_package_hash, entry_points, named_keys); @@ -713,3 +713,32 @@ pub fn endpoint( pub fn ret(value: T) { runtime::ret(CLValue::from_t(value).unwrap_or_revert()) } + +pub fn emit_mint_one_event(recipient: &PublicKey, token_id: &TokenId) { + let mut event = BTreeMap::new(); + event.insert("contract_package_hash", package_hash().to_string()); + event.insert("event_type", "cep47_mint_one".to_string()); + event.insert("recipient", recipient.to_string()); + event.insert("token_id", token_id.to_string()); + emit_event(event); +} + +pub fn emit_transfer_token_event(sender: &PublicKey, recipient: &PublicKey, token_id: &TokenId) { + let mut event = BTreeMap::new(); + event.insert("contract_package_hash", package_hash().to_string()); + event.insert("event_type", "cep47_trasnfer_token".to_string()); + event.insert("sender", sender.to_string()); + event.insert("recipient", recipient.to_string()); + event.insert("token_id", token_id.to_string()); + emit_event(event); +} + +pub fn emit_event(event: BTreeMap<&str, String>) { + let _: URef = storage::new_uref(event); +} + +pub fn package_hash() -> ContractPackageHash { + let key: [u8; 32] = get_key("contract_package_hash") + .unwrap_or_revert_with(ApiError::User(1)); + key.into() +} \ No newline at end of file diff --git a/dragons-nft-scripts/.env b/dragons-nft-scripts/.env new file mode 100644 index 0000000..e69de29 diff --git a/dragons-nft-scripts/.gitignore b/dragons-nft-scripts/.gitignore new file mode 100644 index 0000000..b947077 --- /dev/null +++ b/dragons-nft-scripts/.gitignore @@ -0,0 +1,2 @@ +node_modules/ +dist/ diff --git a/dragons-nft-scripts/package-lock.json b/dragons-nft-scripts/package-lock.json new file mode 100644 index 0000000..dd11968 --- /dev/null +++ b/dragons-nft-scripts/package-lock.json @@ -0,0 +1,1262 @@ +{ + "name": "dragons-nft-scripts", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@ethersproject/bignumber": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.4.0.tgz", + "integrity": "sha512-OXUu9f9hO3vGRIPxU40cignXZVaYyfx6j9NNMjebKdnaCL3anCLSSy8/b8d03vY6dh7duCC0kW72GEC4tZer2w==", + "requires": { + "@ethersproject/bytes": "^5.4.0", + "@ethersproject/logger": "^5.4.0", + "bn.js": "^4.11.9" + } + }, + "@ethersproject/bytes": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.4.0.tgz", + "integrity": "sha512-H60ceqgTHbhzOj4uRc/83SCN9d+BSUnOkrr2intevqdtEMO1JFVZ1XL84OEZV+QjV36OaZYxtnt4lGmxcGsPfA==", + "requires": { + "@ethersproject/logger": "^5.4.0" + } + }, + "@ethersproject/constants": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.4.0.tgz", + "integrity": "sha512-tzjn6S7sj9+DIIeKTJLjK9WGN2Tj0P++Z8ONEIlZjyoTkBuODN+0VfhAyYksKi43l1Sx9tX2VlFfzjfmr5Wl3Q==", + "requires": { + "@ethersproject/bignumber": "^5.4.0" + } + }, + "@ethersproject/logger": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.4.0.tgz", + "integrity": "sha512-xYdWGGQ9P2cxBayt64d8LC8aPFJk6yWCawQi/4eJ4+oJdMMjEBMrIcIMZ9AxhwpPVmnBPrsB10PcXGmGAqgUEQ==" + }, + "@open-rpc/client-js": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@open-rpc/client-js/-/client-js-1.7.0.tgz", + "integrity": "sha512-cRGJbXTgdhJNU49vWzJIATRmKBLP2x6tuHJzX9Jg3N8f1VEkge0riUEek2LFIrZiM4TdUp8XV4Ns1W0SZzdfSw==", + "requires": { + "isomorphic-fetch": "^3.0.0", + "isomorphic-ws": "^4.0.1", + "strict-event-emitter-types": "^2.0.0", + "ws": "^7.0.0" + } + }, + "@types/bn.js": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", + "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", + "requires": { + "@types/node": "*" + } + }, + "@types/eccrypto": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@types/eccrypto/-/eccrypto-1.1.3.tgz", + "integrity": "sha512-3O0qER6JMYReqVbcQTGmXeMHdw3O+rVps63tlo5g5zoB3altJS8yzSvboSivwVWeYO9o5jSATu7P0UIqYZPgow==", + "requires": { + "@types/expect": "^1.20.4", + "@types/node": "*" + } + }, + "@types/elliptic": { + "version": "6.4.13", + "resolved": "https://registry.npmjs.org/@types/elliptic/-/elliptic-6.4.13.tgz", + "integrity": "sha512-e8iyLJ8vMLpWxXpVWrIt0ujqsfHWgVe5XAz9IMhBYoDirK6th7J+mHjzp797OLc62ZX419nrlwwzsNAA0a0mKg==", + "requires": { + "@types/bn.js": "*" + } + }, + "@types/eslint": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.28.0.tgz", + "integrity": "sha512-07XlgzX0YJUn4iG1ocY4IX9DzKSmMGUs6ESKlxWhZRaa0fatIWaHWUVapcuGa8r5HFnTqzj+4OCjd5f7EZ/i/A==", + "requires": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "@types/eslint-scope": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.1.tgz", + "integrity": "sha512-SCFeogqiptms4Fg29WpOTk5nHIzfpKCemSN63ksBQYKTcXoJEmJagV+DhVmbapZzY4/5YaOV1nZwrsU79fFm1g==", + "requires": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "@types/estree": { + "version": "0.0.50", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz", + "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==" + }, + "@types/expect": { + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/@types/expect/-/expect-1.20.4.tgz", + "integrity": "sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg==" + }, + "@types/json-schema": { + "version": "7.0.8", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.8.tgz", + "integrity": "sha512-YSBPTLTVm2e2OoQIDYx8HaeWJ5tTToLH67kXR7zYNGupXMEHa2++G8k+DczX2cFVgalypqtyZIcU19AFcmOpmg==" + }, + "@types/node": { + "version": "16.3.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.3.3.tgz", + "integrity": "sha512-8h7k1YgQKxKXWckzFCMfsIwn0Y61UK6tlD6y2lOb3hTOIMlK3t9/QwHOhc81TwU+RMf0As5fj7NPjroERCnejQ==" + }, + "@types/pbkdf2": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", + "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", + "requires": { + "@types/node": "*" + } + }, + "@types/secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==", + "requires": { + "@types/node": "*" + } + }, + "@webassemblyjs/ast": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", + "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", + "requires": { + "@webassemblyjs/helper-numbers": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", + "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==" + }, + "@webassemblyjs/helper-api-error": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", + "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==" + }, + "@webassemblyjs/helper-buffer": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", + "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==" + }, + "@webassemblyjs/helper-numbers": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", + "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", + "requires": { + "@webassemblyjs/floating-point-hex-parser": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", + "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==" + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", + "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", + "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", + "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", + "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==" + }, + "@webassemblyjs/wasm-edit": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", + "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/helper-wasm-section": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-opt": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "@webassemblyjs/wast-printer": "1.11.1" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", + "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", + "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", + "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", + "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@xtuc/long": "4.2.2" + } + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" + }, + "acorn": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", + "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==" + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==" + }, + "asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + } + }, + "axios": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", + "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "requires": { + "follow-redirects": "^1.10.0" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "base-x": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz", + "integrity": "sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "optional": true, + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "bip66": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", + "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", + "optional": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "blakejs": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.1.tgz", + "integrity": "sha512-bLG6PHOCZJKNshTjGRBvET0vTciwQE6zFKOKKXPDJfwFBd4Ac0yBfPZqcGvGJap50l7ktvlpFqc2jGVaUgbJgg==" + }, + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserslist": { + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", + "requires": { + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", + "escalade": "^3.1.1", + "node-releases": "^1.1.71" + } + }, + "bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", + "requires": { + "base-x": "^3.0.2" + } + }, + "bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "requires": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" + }, + "caniuse-lite": { + "version": "1.0.30001245", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001245.tgz", + "integrity": "sha512-768fM9j1PKXpOCKws6eTo3RHmvTUsG9UrpT4WoREFeZgJBTi4/X9g565azS/rVUGtqb8nt7FjLeF5u4kukERnA==" + }, + "casper-cep47-js-client": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/casper-cep47-js-client/-/casper-cep47-js-client-0.1.1.tgz", + "integrity": "sha512-g96zFG6lQghdlCxxlDI2j+Ov4U783PX+z8bLGDRqCEicG3pbXhyWQ+dckcHPDnBZraLxg9JizAvxMvzRwCFtfw==", + "requires": { + "@ethersproject/bignumber": "^5.0.8", + "casper-js-sdk": "^2.1.0" + } + }, + "casper-js-sdk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/casper-js-sdk/-/casper-js-sdk-2.1.0.tgz", + "integrity": "sha512-fUfTVUs7Kdvsg+yq474+wYD9tvwHhRXmmBuHjkRuPoCUzY8DeAw/CjbYfQb5Ztq+MDRtd2QqcstadZA7RDeOug==", + "requires": { + "@ethersproject/bignumber": "^5.0.8", + "@ethersproject/bytes": "^5.0.5", + "@ethersproject/constants": "^5.0.5", + "@open-rpc/client-js": "^1.6.2", + "@types/eccrypto": "^1.1.2", + "axios": "^0.21.1", + "blakejs": "^1.1.0", + "eccrypto": "^1.1.6", + "eslint-plugin-prettier": "^3.4.0", + "ethereum-cryptography": "^0.1.3", + "glob": "^7.1.6", + "humanize-duration": "^3.24.0", + "jsbi": "^3.1.2", + "key-encoder": "^2.0.3", + "reflect-metadata": "^0.1.13", + "rxjs": "^6.5.3", + "ts-results": "^3.2.1", + "tweetnacl-ts": "^1.0.3", + "tweetnacl-util": "^0.15.0", + "typedjson": "^1.6.0-rc2", + "webpack": "^5.24.3" + } + }, + "chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==" + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "colorette": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==" + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "drbg.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", + "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", + "optional": true, + "requires": { + "browserify-aes": "^1.0.6", + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4" + } + }, + "eccrypto": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/eccrypto/-/eccrypto-1.1.6.tgz", + "integrity": "sha512-d78ivVEzu7Tn0ZphUUaL43+jVPKTMPFGtmgtz1D0LrFn7cY3K8CdrvibuLz2AAkHBLKZtR8DMbB2ukRYFk987A==", + "requires": { + "acorn": "7.1.1", + "elliptic": "6.5.4", + "es6-promise": "4.2.8", + "nan": "2.14.0", + "secp256k1": "3.7.1" + } + }, + "electron-to-chromium": { + "version": "1.3.780", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.780.tgz", + "integrity": "sha512-2KQ9OYm9WMUNpAPA/4aerURl3hwRc9tNlpsiEj3Y8Gf7LVf26NzyLIX2v0hSagQwrS9+cWab+28A2GPKDoVNRA==" + }, + "elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "requires": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "enhanced-resolve": { + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz", + "integrity": "sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==", + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + } + }, + "es-module-lexer": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.7.1.tgz", + "integrity": "sha512-MgtWFl5No+4S3TmhDmCz2ObFGm6lEpTnzbQi+Dd+pw4mlTIZTmM2iAs5gRlmx5zS9luzobCSBSI90JM/1/JgOw==" + }, + "es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, + "eslint-plugin-prettier": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.0.tgz", + "integrity": "sha512-UDK6rJT6INSfcOo545jiaOwB701uAIt2/dR7WnFQoGCVl1/EMqdANBmwUaqqQ45aXprsTGzSa39LI1PyuRBxxw==", + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==" + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" + }, + "ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "requires": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + }, + "dependencies": { + "secp256k1": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz", + "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==", + "requires": { + "elliptic": "^6.5.2", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + } + } + } + }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==" + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "optional": true + }, + "follow-redirects": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz", + "integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" + }, + "graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "humanize-duration": { + "version": "3.27.0", + "resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.27.0.tgz", + "integrity": "sha512-qLo/08cNc3Tb0uD7jK0jAcU5cnqCM0n568918E7R2XhMr/+7F37p4EY062W/stg7tmzvknNn9b/1+UhVRzsYrQ==" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "isomorphic-fetch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", + "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", + "requires": { + "node-fetch": "^2.6.1", + "whatwg-fetch": "^3.4.1" + } + }, + "isomorphic-ws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", + "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==" + }, + "jest-worker": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.0.6.tgz", + "integrity": "sha512-qupxcj/dRuA3xHPMUd40gr2EaAurFbkwzOh7wfPaeE9id7hyjURRQoqNfHifHK3XjJU6YJJUQKILGUnwGPEOCA==", + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + } + }, + "jsbi": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/jsbi/-/jsbi-3.1.5.tgz", + "integrity": "sha512-w2BY0VOYC1ahe+w6Qhl4SFoPvPsZ9NPHY4bwass+LCgU7RK3PBoVQlQ3G1s7vI8W3CYyJiEXcbKF7FIM/L8q3Q==" + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "keccak": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.1.tgz", + "integrity": "sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA==", + "requires": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + } + }, + "key-encoder": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/key-encoder/-/key-encoder-2.0.3.tgz", + "integrity": "sha512-fgBtpAGIr/Fy5/+ZLQZIPPhsZEcbSlYu/Wu96tNDFNSjSACw5lEIOFeaVdQ/iwrb8oxjlWi6wmWdH76hV6GZjg==", + "requires": { + "@types/elliptic": "^6.4.9", + "asn1.js": "^5.0.1", + "bn.js": "^4.11.8", + "elliptic": "^6.4.1" + } + }, + "loader-runner": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", + "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==" + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "mime-db": { + "version": "1.48.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", + "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==" + }, + "mime-types": { + "version": "2.1.31", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", + "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", + "requires": { + "mime-db": "1.48.0" + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" + }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + }, + "node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" + }, + "node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" + }, + "node-gyp-build": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", + "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==" + }, + "node-releases": { + "version": "1.1.73", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz", + "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "requires": { + "fast-diff": "^1.1.2" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "reflect-metadata": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", + "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "requires": { + "tslib": "^1.9.0" + } + }, + "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==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "schema-utils": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", + "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + }, + "scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" + }, + "secp256k1": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.7.1.tgz", + "integrity": "sha512-1cf8sbnRreXrQFdH6qsg2H71Xw91fCCS9Yp021GnUNJzWJS/py96fS4lHbnTnouLp08Xj6jBoBB6V78Tdbdu5g==", + "optional": true, + "requires": { + "bindings": "^1.5.0", + "bip66": "^1.1.5", + "bn.js": "^4.11.8", + "create-hash": "^1.2.0", + "drbg.js": "^1.0.1", + "elliptic": "^6.4.1", + "nan": "^2.14.0", + "safe-buffer": "^5.1.2" + } + }, + "serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "requires": { + "randombytes": "^2.1.0" + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "strict-event-emitter-types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strict-event-emitter-types/-/strict-event-emitter-types-2.0.0.tgz", + "integrity": "sha512-Nk/brWYpD85WlOgzw5h173aci0Teyv8YdIAEtV+N88nDB0dLlazZyJMIsN6eo1/AR61l+p6CJTG1JIyFaoNEEA==" + }, + "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==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "tapable": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", + "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==" + }, + "terser": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.7.1.tgz", + "integrity": "sha512-b3e+d5JbHAe/JSjwsC3Zn55wsBIM7AsHLjKxT31kGCldgbpFePaFo+PiddtO6uwRZWRw7sPXmAN8dTW61xmnSg==", + "requires": { + "commander": "^2.20.0", + "source-map": "~0.7.2", + "source-map-support": "~0.5.19" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" + } + } + }, + "terser-webpack-plugin": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.4.tgz", + "integrity": "sha512-C2WkFwstHDhVEmsmlCxrXUtVklS+Ir1A7twrYzrDrQQOIMOaVAYykaoo/Aq1K0QRkMoY2hhvDQY1cm4jnIMFwA==", + "requires": { + "jest-worker": "^27.0.2", + "p-limit": "^3.1.0", + "schema-utils": "^3.0.0", + "serialize-javascript": "^6.0.0", + "source-map": "^0.6.1", + "terser": "^5.7.0" + } + }, + "ts-results": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ts-results/-/ts-results-3.3.0.tgz", + "integrity": "sha512-FWqxGX2NHp5oCyaMd96o2y2uMQmSu8Dey6kvyuFdRJ2AzfmWo3kWa4UsPlCGlfQ/qu03m09ZZtppMoY8EMHuiA==" + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "tweetnacl-ts": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl-ts/-/tweetnacl-ts-1.0.3.tgz", + "integrity": "sha512-C5I/dWf6xjAXaCDlf84T4HvozU/8ycAlq5WRllF1hAeeq5390tfXD+bNas5bhEV0HMSOx8bsQYpLjPl8wfnEeQ==", + "requires": { + "tslib": "^1" + } + }, + "tweetnacl-util": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", + "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==" + }, + "typedjson": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/typedjson/-/typedjson-1.7.0.tgz", + "integrity": "sha512-MnRgQLwtEcdHqQG0FkT8ebpBG53Wgr/axYRbiD2WL5NcYx8Z2AoCpXvtTfLnuPqOBKG/9JpXq0O/nl2m4wqJYw==", + "requires": { + "tslib": "^2.0.1" + }, + "dependencies": { + "tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" + } + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "requires": { + "punycode": "^2.1.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "watchpack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.2.0.tgz", + "integrity": "sha512-up4YAn/XHgZHIxFBVCdlMiWDj6WaLKpwVeGQk2I5thdYxF/KmF0aaz6TfJZ/hfl1h/XlcDr7k1KH7ThDagpFaA==", + "requires": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + } + }, + "webpack": { + "version": "5.45.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.45.1.tgz", + "integrity": "sha512-68VT2ZgG9EHs6h6UxfV2SEYewA9BA3SOLSnC2NEbJJiEwbAiueDL033R1xX0jzjmXvMh0oSeKnKgbO2bDXIEyQ==", + "requires": { + "@types/eslint-scope": "^3.7.0", + "@types/estree": "^0.0.50", + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/wasm-edit": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "acorn": "^8.4.1", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.8.0", + "es-module-lexer": "^0.7.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.4", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.1.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.1.3", + "watchpack": "^2.2.0", + "webpack-sources": "^2.3.0" + }, + "dependencies": { + "acorn": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", + "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==" + } + } + }, + "webpack-sources": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.0.tgz", + "integrity": "sha512-WyOdtwSvOML1kbgtXbTDnEW0jkJ7hZr/bDByIwszhWd/4XX1A3XMkrbFMsuH4+/MfLlZCUzlAdg4r7jaGKEIgQ==", + "requires": { + "source-list-map": "^2.0.1", + "source-map": "^0.6.1" + } + }, + "whatwg-fetch": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", + "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "ws": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz", + "integrity": "sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==" + }, + "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==" + } + } +} diff --git a/dragons-nft-scripts/package.json b/dragons-nft-scripts/package.json new file mode 100644 index 0000000..b1c7c91 --- /dev/null +++ b/dragons-nft-scripts/package.json @@ -0,0 +1,22 @@ +{ + "name": "dragons-nft-scripts", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "install_contract": "node src/index.js install_contract", + "mint_one": "node src/index.js mint_one", + "mint_copies": "node src/index.js mint_copies", + "name": "node src/index.js name", + "total_supply": "node src/index.js total_supply", + "print_account": "node src/index.js print_account", + "balance_of": "node src/index.js balance_of", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "casper-js-sdk": "2.1.0", + "casper-cep47-js-client": "0.1.1" + } +} diff --git a/dragons-nft-scripts/src/index.js b/dragons-nft-scripts/src/index.js new file mode 100644 index 0000000..d48f09a --- /dev/null +++ b/dragons-nft-scripts/src/index.js @@ -0,0 +1,189 @@ +const { Keys, CLPublicKey } = require("casper-js-sdk"); +const { CEP47Client, utils } = require("casper-cep47-js-client"); + +const NODE_ADDRESS = 'http://3.143.158.19:7777/rpc'; +// const NODE_ADDRESS = 'http://localhost:40101/rpc'; +const INSTALL_PAYMENT_AMOUNT = '200000000000'; +const MINT_ONE_PAYMENT_AMOUNT = '2000000000'; +const MINT_COPIES_PAYMENT_AMOUNT = '100000000000'; +const BURN_ONE_PAYMENT_AMOUNT = '2000000000'; +const CHAIN_NAME = 'integration-test'; +// const CHAIN_NAME = 'casper-net-1'; +const WASM_PATH = "./../target/wasm32-unknown-unknown/release/dragons-nft.wasm"; +const TOKEN_NAME = 'event_nft_2'; +const TOKEN_SYMBOL = 'DRAG'; +const TOKEN_META = new Map([ + ['origin', 'fire'], + ['lifetime', 'infinite'] +]); +const KEY_PAIR_PATH = '/home/ziel/workspace/casperlabs/integration-key/master'; +const KEYS = Keys.Ed25519.parseKeyFiles( + `${KEY_PAIR_PATH}/public_key.pem`, + `${KEY_PAIR_PATH}/secret_key.pem` +); +const MINT_ONE_META_SIZE = 4; +const MINT_COPIES_META_SIZE = 10; +const MINT_MANY_META_SIZE = 10; +const MINT_COPIES_COUNT = 5; +const CONTRACT_HASH = '854db6358ec33c9d5049421f141165bd373d387fb14bb1dfa3319cdc8c873597'; + +const cep47 = new CEP47Client(NODE_ADDRESS, CHAIN_NAME); + +const install = async () => { + const deployHash = await cep47.install( + KEYS, TOKEN_NAME, TOKEN_SYMBOL, TOKEN_META, INSTALL_PAYMENT_AMOUNT, WASM_PATH); + console.log(`Contract Installed`); + console.log(`... DeployHash: ${deployHash}`); +}; + +const mintOne = async () => { + cep47.setContractHash(CONTRACT_HASH); + let meta = randomMetaMap(MINT_ONE_META_SIZE); + const deployHash = await cep47.mintOne(KEYS, KEYS.publicKey, meta, MINT_ONE_PAYMENT_AMOUNT); + console.log(`Mint One`); + console.log(`... DeployHash: ${deployHash}`); +} + +const pause = async () => { + cep47.setContractHash(CONTRACT_HASH); + const deployHash = await cep47.pause(KEYS, MINT_ONE_PAYMENT_AMOUNT); + console.log(`Pause`); + console.log(`... DeployHash: ${deployHash}`); +} + +const mintCopies = async () => { + cep47.setContractHash(CONTRACT_HASH); + let meta = randomMetaMap(MINT_COPIES_META_SIZE); + const deployHash = await cep47.mintCopies( + KEYS, KEYS.publicKey, meta, MINT_COPIES_COUNT, MINT_COPIES_PAYMENT_AMOUNT); + console.log(`Mint Copies`); + console.log(`... DeployHash: ${deployHash}`); +} + +const mintMany = async () => { + cep47.setContractHash(CONTRACT_HASH); + let meta = randomMetaArray(MINT_MANY_META_SIZE); + const deployHash = await cep47.mintMany( + KEYS, KEYS.publicKey, meta, MINT_COPIES_PAYMENT_AMOUNT); + console.log(`Mint Many`); + console.log(`... DeployHash: ${deployHash}`); +} + +const burnOne = async (tokenId) => { + cep47.setContractHash(CONTRACT_HASH); + const deployHash = await cep47.burnOne(KEYS, KEYS.publicKey, tokenId, BURN_ONE_PAYMENT_AMOUNT); + console.log(`Burn One`); + console.log(`... DeployHash: ${deployHash}`); +} + +const getName = async () => { + cep47.setContractHash(CONTRACT_HASH); + const value = await cep47.name(); + console.log(`Contract Name: ${value}`); +} + +const balanceOf = async () => { + cep47.setContractHash(CONTRACT_HASH); + const balance = await cep47.balanceOf(CLPublicKey.fromHex("01694a09937e05f5a60b5f56d1d108f65ae716c45879fca79fca89ec1c20e15431")); + console.log(`Balance: ${balance.value()}`); +} + +const tokensOf = async (publicKeyHex) => { + cep47.setContractHash(CONTRACT_HASH); + const value = await cep47.getTokensOf(CLPublicKey.fromHex(publicKeyHex)); + console.log(`Tokens: ${JSON.stringify(value, null, 2)}`); +} +const ownerOf = async (tokenId) => { + cep47.setContractHash(CONTRACT_HASH); + const value = await cep47.getOwnerOf(tokenId); + console.log(`Owner public key hex: ${value}`); +} + +const tokenMeta = async (tokenId) => { + cep47.setContractHash(CONTRACT_HASH); + const value = await cep47.getTokenMeta(tokenId); + console.log('Token meta', value); +} + +const printAccount = async () => { + let account = await utils.getAccountInfo(NODE_ADDRESS, KEYS.publicKey); + console.log(account); +} + +const getSimpleValue = async (name) => { + cep47.setContractHash(CONTRACT_HASH); + const value = await cep47[name](); + console.log(name, value); +}; + +const randomMetaMap = (size) => { + let data = new Map(); + for (let i = 0; i < size; i++) { + data.set(`key${i}`, `value${i}`); + } + return data; +} + +const randomMetaArray = (size) => { + let arr = []; + for (let i = 0; i < size; i++) { + const item = randomMetaMap(3); + } + return arr; +} + +const command = process.argv.slice(2)[0]; +const arg1 = process.argv.slice(2)[1]; + +switch (command) { + case 'install_contract': + install(); + break; + case 'mint_one': + mintOne(); + break; + case 'mint_copies': + mintCopies(); + break; + case 'mint_many': + mintMany(); + break; + case 'name': + getSimpleValue("name"); + break; + case 'symbol': + getSimpleValue("symbol"); + break; + case 'meta': + getSimpleValue("meta"); + break; + case 'is_paused': + getSimpleValue("isPaused"); + break; + case 'burn_one': + burnOne(arg1); + break; + case 'total_supply': + getSimpleValue("totalSupply"); + break; + case 'balance_of': + balanceOf(); + break; + case 'owner_of': + ownerOf(arg1); + break; + case 'get_token_meta': + tokenMeta(arg1); + break; + case 'tokens_of': + tokensOf(arg1); + break; + case 'pause': + pause(); + break; + case 'print_account': + printAccount(); + break; + default: + console.log(`Command unknown ${command}`) +} From 86f2de733244e9faed3247a513cc0507ca4416c0 Mon Sep 17 00:00:00 2001 From: Maciej Zielinski Date: Wed, 21 Jul 2021 17:40:25 +0200 Subject: [PATCH 43/98] Remove attach, dettach. Add events. --- cep47-logic/src/lib.rs | 27 ------ cep47-logic/src/tests.rs | 53 ----------- cep47/Cargo.toml | 2 - cep47/src/lib.rs | 186 +++++++++++++++++++-------------------- 4 files changed, 89 insertions(+), 179 deletions(-) diff --git a/cep47-logic/src/lib.rs b/cep47-logic/src/lib.rs index 13fb923..c3c1e56 100644 --- a/cep47-logic/src/lib.rs +++ b/cep47-logic/src/lib.rs @@ -172,29 +172,6 @@ pub trait CEP47Contract: WithStorage { self.storage_mut().set_tokens(recipient, recipient_tokens); Ok(()) } - - // URef releated function. - fn detach(&mut self, owner: PublicKey, token_id: TokenId) -> Option { - let mut tokens = self.storage().get_tokens(owner.clone()); - if !tokens.contains(&token_id) { - None - } else { - tokens.retain(|x| x != &token_id); - self.storage_mut().set_tokens(owner, tokens); - self.storage_mut().new_uref(token_id) - } - } - - fn attach(&mut self, token_uref: URef, recipient: PublicKey) { - let token_id = self.storage_mut().del_uref(token_uref).unwrap(); - let mut tokens = self.storage().get_tokens(recipient.clone()); - tokens.push(token_id); - self.storage_mut().set_tokens(recipient, tokens); - } - - fn token_id(&self, token_uref: URef) -> TokenId { - self.storage().token_id(token_uref).unwrap() - } } pub trait CEP47Storage { @@ -221,8 +198,4 @@ pub trait CEP47Storage { fn mint_copies(&mut self, recipient: PublicKey, token_metas: Meta, count: U256); fn burn_one(&mut self, owner: PublicKey, token_id: TokenId); fn burn_many(&mut self, owner: PublicKey, token_ids: Vec); - - fn new_uref(&mut self, token_id: TokenId) -> Option; - fn del_uref(&mut self, token_uref: URef) -> Option; - fn token_id(&self, token_uref: URef) -> Option; } diff --git a/cep47-logic/src/tests.rs b/cep47-logic/src/tests.rs index 622ff05..d844b39 100644 --- a/cep47-logic/src/tests.rs +++ b/cep47-logic/src/tests.rs @@ -209,33 +209,6 @@ impl CEP47Storage for TestStorage { self.balances.insert(owner.clone(), owner_new_balance - 1); self.tokens.insert(owner, owner_new_tokens); } - - fn new_uref(&mut self, token_id: TokenId) -> Option { - let mut rng = rand::thread_rng(); - let val: [u8; 32] = rng.gen(); - let uref = URef::new(val, AccessRights::READ_ADD_WRITE); - if self.urefs.contains_key(&uref) { - None - } else { - self.urefs.insert(uref, token_id); - Some(uref) - } - } - - fn del_uref(&mut self, token_uref: URef) -> Option { - let token_id = self.token_id(token_uref); - if token_id.is_none() { - None - } else { - let token_id = token_id.unwrap(); - self.urefs.remove(&token_uref); - Some(token_id) - } - } - - fn token_id(&self, token_uref: URef) -> Option { - self.urefs.get(&token_uref).map(|x| x.clone()) - } } struct TestContract { @@ -510,29 +483,3 @@ fn test_transfer_many_tokens() { assert_eq!(owner_of_second_token_id.unwrap(), bob); assert_eq!(owner_of_third_token_id.unwrap(), bob); } - -#[test] -fn test_attach_and_detach() { - let mut contract = TestContract::new(); - let ali = PublicKey::ed25519_from_bytes([3u8; 32]).unwrap(); - let bob = PublicKey::ed25519_from_bytes([6u8; 32]).unwrap(); - - contract.mint_one(ali.clone(), meta::banana()); - let token_id: TokenId = contract.tokens(ali.clone())[0].clone(); - - let token_uref: URef = contract.detach(ali.clone(), token_id.clone()).unwrap(); - assert_eq!(contract.balance_of(ali.clone()), U256::zero()); - assert_eq!(contract.total_supply(), U256::one()); - assert!(contract.tokens(ali).is_empty()); - - assert_eq!(contract.token_id(token_uref.clone()), token_id.clone()); - assert_eq!( - contract.token_meta(token_id.clone()).unwrap(), - meta::banana() - ); - - contract.attach(token_uref, bob.clone()); - assert_eq!(contract.balance_of(bob.clone()), U256::one()); - assert_eq!(contract.total_supply(), U256::one()); - assert_eq!(contract.tokens(bob), vec![token_id]); -} diff --git a/cep47/Cargo.toml b/cep47/Cargo.toml index 99eddd1..692596f 100644 --- a/cep47/Cargo.toml +++ b/cep47/Cargo.toml @@ -33,5 +33,3 @@ no_burn_one = [] no_transfer_token = [] no_transfer_many_tokens = [] no_transfer_all_tokens = [] -no_attach = [] -no_detach = [] diff --git a/cep47/src/lib.rs b/cep47/src/lib.rs index a46e964..ddb70d4 100644 --- a/cep47/src/lib.rs +++ b/cep47/src/lib.rs @@ -12,7 +12,14 @@ use casper_contract::{ contract_api::{runtime, storage}, unwrap_or_revert::UnwrapOrRevert, }; -use casper_types::{AccessRights, ApiError, AsymmetricType, CLType, CLTyped, CLValue, ContractPackageHash, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, HashAddr, Key, Parameter, PublicKey, U256, URef, account::AccountHash, bytesrepr::{FromBytes, ToBytes}, contracts::NamedKeys}; +use casper_types::{ + account::AccountHash, + bytesrepr::{FromBytes, ToBytes}, + contracts::NamedKeys, + AccessRights, ApiError, AsymmetricType, CLType, CLTyped, CLValue, ContractPackageHash, + EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, HashAddr, Key, Parameter, PublicKey, + URef, U256, +}; pub use cep47_logic::Meta; use cep47_logic::{CEP47Contract, CEP47Storage, TokenId, WithStorage}; @@ -20,6 +27,7 @@ use core::convert::TryInto; use std::{ collections::hash_map::DefaultHasher, hash::{Hash, Hasher}, + ops::AddAssign, }; pub struct CasperCEP47Storage {} @@ -33,9 +41,11 @@ impl CEP47Storage for CasperCEP47Storage { fn name(&self) -> String { get_key::("name").unwrap() } + fn symbol(&self) -> String { get_key::("symbol").unwrap() } + fn meta(&self) -> Meta { get_key::("meta").unwrap() } @@ -49,21 +59,27 @@ impl CEP47Storage for CasperCEP47Storage { owner_balance.unwrap() } } + fn onwer_of(&self, token_id: TokenId) -> Option { get_key::(&owner_key(&token_id)) } + fn total_supply(&self) -> U256 { get_key::("total_supply").unwrap() } + fn token_meta(&self, token_id: TokenId) -> Option { get_key::(&meta_key(&token_id)) } + fn is_paused(&self) -> bool { get_key::("paused").unwrap() } + fn pause(&mut self) { set_key("paused", true); } + fn unpause(&mut self) { set_key("paused", false); } @@ -77,6 +93,7 @@ impl CEP47Storage for CasperCEP47Storage { owner_tokens.unwrap() } } + fn set_tokens(&mut self, owner: PublicKey, token_ids: Vec) { let owner_prev_balance = self.balance_of(owner.clone()); let owner_new_balance = U256::from(token_ids.len() as u64); @@ -96,6 +113,7 @@ impl CEP47Storage for CasperCEP47Storage { prev_total_supply - owner_prev_balance + owner_new_balance, ); } + fn mint_many(&mut self, recipient: PublicKey, token_metas: Vec) { let mut recipient_tokens = self.get_tokens(recipient.clone()); let mut recipient_balance = self.balance_of(recipient.clone()); @@ -103,19 +121,28 @@ impl CEP47Storage for CasperCEP47Storage { let meta = self.meta(); let mut hasher = DefaultHasher::new(); + let mut nonce: u64 = get_event_nonce(); + let block_hash: u64 = runtime::get_blocktime().into(); for token_meta in token_metas.clone() { - let token_info = (meta.clone(), token_meta.clone()); + // Derive new unique token id. + let token_info = (block_hash, nonce, meta.clone()); Hash::hash(&token_info, &mut hasher); - let token_id = TokenId::from(hasher.finish().to_string()); + nonce = nonce + 1; + recipient_tokens.push(token_id.clone()); total_supply = total_supply + 1; set_key(&meta_key(&token_id), token_meta); set_key(&owner_key(&token_id), recipient.clone()); + // Emit event. emit_mint_one_event(&recipient, &token_id); } + + // Update nonce. + set_event_nonce(nonce); + recipient_balance = recipient_balance + U256::from(token_metas.len() as u64); set_key( &balance_key(&recipient.to_account_hash()), @@ -123,12 +150,13 @@ impl CEP47Storage for CasperCEP47Storage { ); set_key(&token_key(&recipient.to_account_hash()), recipient_tokens); set_key("total_supply", total_supply); - } + fn mint_copies(&mut self, recipient: PublicKey, token_meta: Meta, count: U256) { let token_metas: Vec = vec![token_meta; count.as_usize()]; self.mint_many(recipient, token_metas); } + fn burn_many(&mut self, owner: PublicKey, token_ids: Vec) { let mut owner_tokens = self.get_tokens(owner.clone()); let mut owner_balance = self.balance_of(owner.clone()); @@ -144,11 +172,14 @@ impl CEP47Storage for CasperCEP47Storage { remove_key(&owner_key(&token_id)); owner_balance = owner_balance - 1; total_supply = total_supply - 1; + + emit_burn_one_event(&owner, &token_id); } set_key(&balance_key(&owner.to_account_hash()), owner_balance); set_key(&token_key(&owner.to_account_hash()), owner_tokens); set_key("total_supply", total_supply); } + fn burn_one(&mut self, owner: PublicKey, token_id: TokenId) { let mut owner_tokens = self.get_tokens(owner.clone()); let owner_balance = self.balance_of(owner.clone()); @@ -163,47 +194,14 @@ impl CEP47Storage for CasperCEP47Storage { set_key(&balance_key(&owner.to_account_hash()), owner_balance - 1); set_key(&token_key(&owner.to_account_hash()), owner_tokens); set_key("total_supply", total_supply - 1); - } - fn new_uref(&mut self, token_id: TokenId) -> Option { - let value_ref = - storage::new_uref(token_id).with_access_rights(AccessRights::READ_ADD_WRITE); - let value_key = uref_key(&value_ref); - let prev_value_ref = get_key::(&value_key); - if prev_value_ref.is_some() { - None - } else { - set_key(&value_key, value_ref); - Some(value_ref) - } - } - fn del_uref(&mut self, token_uref: URef) -> Option { - let token_id = self.token_id(token_uref); - if token_id.is_some() { - let value_key = uref_key(&token_uref); - remove_key(&value_key); - token_id - } else { - None - } - } - fn token_id(&self, token_uref: URef) -> Option { - let value_key = uref_key(&token_uref); - let prev_value_ref = get_key::(&value_key); - if prev_value_ref.is_some() { - let res = storage::read::(prev_value_ref.unwrap()); - if res.is_err() { - None - } else { - res.unwrap() - } - } else { - None - } + emit_burn_one_event(&owner, &token_id); } } + pub struct CasperCEP47Contract { storage: CasperCEP47Storage, } + impl CasperCEP47Contract { pub fn new() -> CasperCEP47Contract { CasperCEP47Contract { @@ -211,6 +209,7 @@ impl CasperCEP47Contract { } } } + impl WithStorage for CasperCEP47Contract { fn storage(&self) -> &CasperCEP47Storage { &self.storage @@ -219,6 +218,7 @@ impl WithStorage for CasperCEP47Contract { &mut self.storage } } + impl CEP47Contract for CasperCEP47Contract {} #[cfg(not(feature = "no_name"))] @@ -358,6 +358,7 @@ pub extern "C" fn transfer_token() { } let recipient: PublicKey = runtime::get_named_arg("recipient"); let token_id: TokenId = runtime::get_named_arg("token_id"); + emit_transfer_token_event(&sender, &recipient, &token_id); let mut contract = CasperCEP47Contract::new(); @@ -375,6 +376,11 @@ pub extern "C" fn transfer_many_tokens() { } let recipient: PublicKey = runtime::get_named_arg("recipient"); let token_ids: Vec = runtime::get_named_arg("token_ids"); + + for token_id in &token_ids { + emit_transfer_token_event(&sender, &recipient, &token_id); + } + let mut contract = CasperCEP47Contract::new(); let res = contract.transfer_many_tokens(sender, recipient, token_ids); res.unwrap_or_revert(); @@ -389,28 +395,12 @@ pub extern "C" fn transfer_all_tokens() { runtime::revert(ApiError::PermissionDenied); } let recipient: PublicKey = runtime::get_named_arg("recipient"); - let mut contract = CasperCEP47Contract::new(); - let res = contract.transfer_all_tokens(sender, recipient); - res.unwrap_or_revert(); -} -#[cfg(not(feature = "no_attach"))] -#[no_mangle] -pub extern "C" fn attach() { - let token_uref: URef = runtime::get_named_arg("token_uref"); - let recipient: PublicKey = runtime::get_named_arg("recipient"); - let mut contract = CasperCEP47Contract::new(); - contract.attach(token_uref, recipient); -} + emit_transfer_all_tokens_event(&sender, &recipient); -#[cfg(not(feature = "no_detach"))] -#[no_mangle] -pub extern "C" fn detach() { - let owner: PublicKey = runtime::get_named_arg("owner"); - let token_id: TokenId = runtime::get_named_arg("token_id"); let mut contract = CasperCEP47Contract::new(); - let res = contract.detach(owner, token_id.clone()); // For test purpose - set_key(&test_uref_key(&token_id), res); + let res = contract.transfer_all_tokens(sender, recipient); + res.unwrap_or_revert(); } pub fn get_entrypoints(package_hash: Option) -> EntryPoints { @@ -511,10 +501,11 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints }, )); entry_points.add_entry_point(endpoint( - "burn_many", + "mint_copies", vec![ - Parameter::new("owner", CLType::PublicKey), - Parameter::new("token_ids", CLType::List(Box::new(CLType::String))), + Parameter::new("recipient", CLType::PublicKey), + Parameter::new("token_meta", CLType::String), + Parameter::new("count", CLType::U256), ], CLType::Unit, if secure { @@ -537,11 +528,10 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints }, )); entry_points.add_entry_point(endpoint( - "mint_copies", + "burn_many", vec![ - Parameter::new("recipient", CLType::PublicKey), - Parameter::new("token_meta", CLType::String), - Parameter::new("count", CLType::U256), + Parameter::new("owner", CLType::PublicKey), + Parameter::new("token_ids", CLType::List(Box::new(CLType::String))), ], CLType::Unit, if secure { @@ -579,24 +569,6 @@ pub fn get_entrypoints(package_hash: Option) -> EntryPoints CLType::Unit, None, )); - entry_points.add_entry_point(endpoint( - "attach", - vec![ - Parameter::new("token_uref", CLType::URef), - Parameter::new("recipient", CLType::PublicKey), - ], - CLType::Unit, - None, - )); - entry_points.add_entry_point(endpoint( - "detach", - vec![ - Parameter::new("owner", CLType::PublicKey), - Parameter::new("token_id", CLType::String), - ], - CLType::Unit, - None, - )); entry_points } @@ -620,7 +592,10 @@ pub fn deploy( storage::new_uref(U256::zero()).into(), ); named_keys.insert("paused".to_string(), storage::new_uref(paused).into()); - named_keys.insert("contract_package_hash".to_string(), storage::new_uref(contract_package_hash).into()); + named_keys.insert( + "contract_package_hash".to_string(), + storage::new_uref(contract_package_hash).into(), + ); let (contract_hash, _) = storage::add_contract_version(contract_package_hash, entry_points, named_keys); @@ -680,14 +655,6 @@ fn meta_key(token_id: &TokenId) -> String { format!("metas_{}", token_id) } -fn uref_key(uref: &URef) -> String { - format!("uref_{}", uref) -} - -fn test_uref_key(token_id: &TokenId) -> String { - format!("turef_{}", token_id) -} - fn token_key(account: &AccountHash) -> String { format!("tokens_{}", account) } @@ -723,22 +690,47 @@ pub fn emit_mint_one_event(recipient: &PublicKey, token_id: &TokenId) { emit_event(event); } +pub fn emit_burn_one_event(owner: &PublicKey, token_id: &TokenId) { + let mut event = BTreeMap::new(); + event.insert("contract_package_hash", package_hash().to_string()); + event.insert("event_type", "cep47_burn_one".to_string()); + event.insert("owner", owner.to_string()); + event.insert("token_id", token_id.to_string()); + emit_event(event); +} + pub fn emit_transfer_token_event(sender: &PublicKey, recipient: &PublicKey, token_id: &TokenId) { let mut event = BTreeMap::new(); event.insert("contract_package_hash", package_hash().to_string()); - event.insert("event_type", "cep47_trasnfer_token".to_string()); + event.insert("event_type", "cep47_transfer_token".to_string()); event.insert("sender", sender.to_string()); event.insert("recipient", recipient.to_string()); event.insert("token_id", token_id.to_string()); emit_event(event); } +pub fn emit_transfer_all_tokens_event(sender: &PublicKey, recipient: &PublicKey) { + let mut event = BTreeMap::new(); + event.insert("contract_package_hash", package_hash().to_string()); + event.insert("event_type", "cep47_transfer_all_tokens".to_string()); + event.insert("sender", sender.to_string()); + event.insert("recipient", recipient.to_string()); + emit_event(event); +} + pub fn emit_event(event: BTreeMap<&str, String>) { let _: URef = storage::new_uref(event); } pub fn package_hash() -> ContractPackageHash { - let key: [u8; 32] = get_key("contract_package_hash") - .unwrap_or_revert_with(ApiError::User(1)); + let key: [u8; 32] = get_key("contract_package_hash").unwrap_or_revert(); key.into() -} \ No newline at end of file +} + +fn get_event_nonce() -> u64 { + get_key("event_nonce").unwrap_or_default() +} + +fn set_event_nonce(nonce: u64) { + set_key("event_nonce", nonce); +} From 692cf01f2df05c88f62227667aa90626749dabc7 Mon Sep 17 00:00:00 2001 From: Jan Hoffmann Date: Wed, 21 Jul 2021 17:45:38 +0200 Subject: [PATCH 44/98] dragons nft upgrade --- .gitignore | 3 +- dragons-nft-scripts/log.json | 388 + dragons-nft-scripts/package-lock.json | 13366 +++++++++++++++++++++--- dragons-nft-scripts/package.json | 4 +- dragons-nft-scripts/src/index.js | 67 +- 5 files changed, 12586 insertions(+), 1242 deletions(-) create mode 100644 dragons-nft-scripts/log.json diff --git a/.gitignore b/.gitignore index 08ee105..e9bcfca 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ target Cargo.lock -dragons-nft-tests/wasm/*.wasm \ No newline at end of file +dragons-nft-tests/wasm/*.wasm +node_modules diff --git a/dragons-nft-scripts/log.json b/dragons-nft-scripts/log.json new file mode 100644 index 0000000..9425ca0 --- /dev/null +++ b/dragons-nft-scripts/log.json @@ -0,0 +1,388 @@ +{ + "api_version": "1.0.0", + "stored_value": { + "Contract": { + "contract_package_hash": "contract-package-wasmde2e302af2be3b54419c4a6e4f61c111d45fb03afab72a62c88fa723fcb21ee8", + "contract_wasm_hash": "contract-wasm-f36d165331fcd1451fd5508713242faf6b90f8ddd38bf66c6d70d46c215dc748", + "named_keys": [ + { + "name": "balances_5ce1390973f940679134da9f0fd43920ce0d800c6480d9bd91c2dfd9b4df5147", + "key": "uref-6c24b4eedf93f7f33636506e380308995409390c03201209ff987bb2cbc6504b-007" + }, + { + "name": "contract_package_hash", + "key": "uref-3ce2d3936293a6e1ed8c42b642b736d5743a5a9fb05090302d7c16bfcb2853af-007" + }, + { + "name": "meta", + "key": "uref-0c5c957ce405fb2428b3233270fabaed5a5222b6788efc9ee9f45bf4723cafa4-007" + }, + { + "name": "metas_17533245468374124908", + "key": "uref-b6c5b203da4e6ea64c0a477e0f146fcbe8d5c63239632c49352cced7e8ffde83-007" + }, + { + "name": "name", + "key": "uref-bd7f1b143441d713d57b89c1c27455920ea2974cfeb8770af9316227cb277486-007" + }, + { + "name": "owners_17533245468374124908", + "key": "uref-ac6e00efb078f2fb5413e8087fa36f36e7c8495a07736699c9c6dd9eda6793d0-007" + }, + { + "name": "paused", + "key": "uref-61ee0b199eceef9caa519b47a246890300b1d6a5d01f48202beaa10248dd40fe-007" + }, + { + "name": "symbol", + "key": "uref-9c8883fa4ae6afeaef516e4b22c2209e26cf8d5bce545615c6ccb7a48374b2d7-007" + }, + { + "name": "tokens_5ce1390973f940679134da9f0fd43920ce0d800c6480d9bd91c2dfd9b4df5147", + "key": "uref-695b1890926765c5399c3ce6fc711e460656476c3752dfc5170767a017322693-007" + }, + { + "name": "total_supply", + "key": "uref-5e86a907b13a4a888130347b4d58c4de57ce082223bb6e807c9b7b1cd77aca22-007" + } + ], + "entry_points": [ + { + "name": "attach", + "args": [ + { + "name": "token_uref", + "cl_type": "URef" + }, + { + "name": "recipient", + "cl_type": "PublicKey" + } + ], + "ret": "Unit", + "access": "Public", + "entry_point_type": "Contract" + }, + { + "name": "balance_of", + "args": [ + { + "name": "account", + "cl_type": "PublicKey" + } + ], + "ret": "U256", + "access": "Public", + "entry_point_type": "Contract" + }, + { + "name": "burn_many", + "args": [ + { + "name": "owner", + "cl_type": "PublicKey" + }, + { + "name": "token_ids", + "cl_type": { + "List": "String" + } + } + ], + "ret": "Unit", + "access": "Public", + "entry_point_type": "Contract" + }, + { + "name": "burn_one", + "args": [ + { + "name": "owner", + "cl_type": "PublicKey" + }, + { + "name": "token_id", + "cl_type": { + "List": "String" + } + } + ], + "ret": "Unit", + "access": "Public", + "entry_point_type": "Contract" + }, + { + "name": "detach", + "args": [ + { + "name": "owner", + "cl_type": "PublicKey" + }, + { + "name": "token_id", + "cl_type": "String" + } + ], + "ret": "Unit", + "access": "Public", + "entry_point_type": "Contract" + }, + { + "name": "is_paused", + "args": [], + "ret": "Bool", + "access": "Public", + "entry_point_type": "Contract" + }, + { + "name": "meta", + "args": [], + "ret": "String", + "access": "Public", + "entry_point_type": "Contract" + }, + { + "name": "mint_copies", + "args": [ + { + "name": "recipient", + "cl_type": "PublicKey" + }, + { + "name": "token_meta", + "cl_type": "String" + }, + { + "name": "count", + "cl_type": "U256" + } + ], + "ret": "Unit", + "access": "Public", + "entry_point_type": "Contract" + }, + { + "name": "mint_many", + "args": [ + { + "name": "recipient", + "cl_type": "PublicKey" + }, + { + "name": "token_metas", + "cl_type": { + "List": "String" + } + } + ], + "ret": "Unit", + "access": "Public", + "entry_point_type": "Contract" + }, + { + "name": "mint_one", + "args": [ + { + "name": "recipient", + "cl_type": "PublicKey" + }, + { + "name": "token_meta", + "cl_type": "String" + } + ], + "ret": "Unit", + "access": "Public", + "entry_point_type": "Contract" + }, + { + "name": "name", + "args": [], + "ret": "String", + "access": "Public", + "entry_point_type": "Contract" + }, + { + "name": "owner_of", + "args": [ + { + "name": "token_id", + "cl_type": "String" + } + ], + "ret": { + "Option": "PublicKey" + }, + "access": "Public", + "entry_point_type": "Contract" + }, + { + "name": "pause", + "args": [], + "ret": "Unit", + "access": "Public", + "entry_point_type": "Contract" + }, + { + "name": "symbol", + "args": [], + "ret": "String", + "access": "Public", + "entry_point_type": "Contract" + }, + { + "name": "token_meta", + "args": [ + { + "name": "token_id", + "cl_type": "String" + } + ], + "ret": { + "Option": "String" + }, + "access": "Public", + "entry_point_type": "Contract" + }, + { + "name": "tokens", + "args": [ + { + "name": "owner", + "cl_type": "PublicKey" + } + ], + "ret": { + "List": "String" + }, + "access": "Public", + "entry_point_type": "Contract" + }, + { + "name": "total_supply", + "args": [ + { + "name": "owner", + "cl_type": "PublicKey" + } + ], + "ret": { + "List": "String" + }, + "access": "Public", + "entry_point_type": "Contract" + }, + { + "name": "transfer_all_tokens", + "args": [ + { + "name": "sender", + "cl_type": "PublicKey" + }, + { + "name": "recipient", + "cl_type": "PublicKey" + } + ], + "ret": "Unit", + "access": "Public", + "entry_point_type": "Contract" + }, + { + "name": "transfer_many_tokens", + "args": [ + { + "name": "sender", + "cl_type": "PublicKey" + }, + { + "name": "recipient", + "cl_type": "PublicKey" + }, + { + "name": "token_ids", + "cl_type": { + "List": "String" + } + } + ], + "ret": "Unit", + "access": "Public", + "entry_point_type": "Contract" + }, + { + "name": "transfer_token", + "args": [ + { + "name": "sender", + "cl_type": "PublicKey" + }, + { + "name": "recipient", + "cl_type": "PublicKey" + }, + { + "name": "token_id", + "cl_type": "String" + } + ], + "ret": "Unit", + "access": "Public", + "entry_point_type": "Contract" + }, + { + "name": "unpause", + "args": [], + "ret": "Unit", + "access": "Public", + "entry_point_type": "Contract" + } + ], + "protocol_version": "1.0.0" + } + }, + "merkle_proof": "0100000001133c24a6e7a953cec7c6dff35e1f19c6bc97a01e83f6e971c11d10151477ee8f03de2e302af2be3b54419c4a6e4f61c111d45fb03afab72a62c88fa723fcb21ee8f36d165331fcd1451fd5508713242faf6b90f8ddd38bf66c6d70d46c215dc7480a0000004900000062616c616e6365735f35636531333930393733663934303637393133346461396630666434333932306365306438303063363438306439626439316332646664396234646635313437026c24b4eedf93f7f33636506e380308995409390c03201209ff987bb2cbc6504b0715000000636f6e74726163745f7061636b6167655f68617368023ce2d3936293a6e1ed8c42b642b736d5743a5a9fb05090302d7c16bfcb2853af07040000006d657461020c5c957ce405fb2428b3233270fabaed5a5222b6788efc9ee9f45bf4723cafa4071a0000006d657461735f313735333332343534363833373431323439303802b6c5b203da4e6ea64c0a477e0f146fcbe8d5c63239632c49352cced7e8ffde8307040000006e616d6502bd7f1b143441d713d57b89c1c27455920ea2974cfeb8770af9316227cb277486071b0000006f776e6572735f313735333332343534363833373431323439303802ac6e00efb078f2fb5413e8087fa36f36e7c8495a07736699c9c6dd9eda6793d007060000007061757365640261ee0b199eceef9caa519b47a246890300b1d6a5d01f48202beaa10248dd40fe070600000073796d626f6c029c8883fa4ae6afeaef516e4b22c2209e26cf8d5bce545615c6ccb7a48374b2d70747000000746f6b656e735f3563653133393039373366393430363739313334646139663066643433393230636530643830306336343830643962643931633264666439623464663531343702695b1890926765c5399c3ce6fc711e460656476c3752dfc5170767a017322693070c000000746f74616c5f737570706c79025e86a907b13a4a888130347b4d58c4de57ce082223bb6e807c9b7b1cd77aca2207150000000600000061747461636806000000617474616368020000000a000000746f6b656e5f757265660c09000000726563697069656e74160901010a00000062616c616e63655f6f660a00000062616c616e63655f6f6601000000070000006163636f756e7416070101090000006275726e5f6d616e79090000006275726e5f6d616e7902000000050000006f776e65721609000000746f6b656e5f6964730e0a090101080000006275726e5f6f6e65080000006275726e5f6f6e6502000000050000006f776e65721608000000746f6b656e5f69640e0a090101060000006465746163680600000064657461636802000000050000006f776e65721608000000746f6b656e5f69640a0901010900000069735f7061757365640900000069735f70617573656400000000000101040000006d657461040000006d657461000000000a01010b0000006d696e745f636f706965730b0000006d696e745f636f706965730300000009000000726563697069656e74160a000000746f6b656e5f6d6574610a05000000636f756e7407090101090000006d696e745f6d616e79090000006d696e745f6d616e790200000009000000726563697069656e74160b000000746f6b656e5f6d657461730e0a090101080000006d696e745f6f6e65080000006d696e745f6f6e650200000009000000726563697069656e74160a000000746f6b656e5f6d6574610a090101040000006e616d65040000006e616d65000000000a0101080000006f776e65725f6f66080000006f776e65725f6f660100000008000000746f6b656e5f69640a0d160101050000007061757365050000007061757365000000000901010600000073796d626f6c0600000073796d626f6c000000000a01010a000000746f6b656e5f6d6574610a000000746f6b656e5f6d6574610100000008000000746f6b656e5f69640a0d0a010106000000746f6b656e7306000000746f6b656e7301000000050000006f776e6572160e0a01010c000000746f74616c5f737570706c790c000000746f74616c5f737570706c7901000000050000006f776e6572160e0a0101130000007472616e736665725f616c6c5f746f6b656e73130000007472616e736665725f616c6c5f746f6b656e73020000000600000073656e6465721609000000726563697069656e7416090101140000007472616e736665725f6d616e795f746f6b656e73140000007472616e736665725f6d616e795f746f6b656e73030000000600000073656e6465721609000000726563697069656e741609000000746f6b656e5f6964730e0a0901010e0000007472616e736665725f746f6b656e0e0000007472616e736665725f746f6b656e030000000600000073656e6465721609000000726563697069656e741608000000746f6b656e5f69640a09010107000000756e706175736507000000756e7061757365000000000901010100000000000000000000000200000000130e00000012003f5b082099df8f41592be59fdac9e0397ac1b4ba2270ec3e9cfeef7ed769a6b31f00099e755e0329106e4e618858cc1b96b1251448099080c05118e8dd846d42b90f27001c696f52a052d9a7df04c2fc622f2e0dd98688a7ec32f5bd42be9d6f844f37132a00607bfc73940a11ea03c78bf2b0e01433d5be0b7888d6f0d9adeb178a79e01e554600aff02519c89249401d7ea122db629b0fa641722352673a73ec2dc35d5cafa8e75a0079b92bfa00f5058e4fc579306405ef034155739f755059f6794405941b9734a65e0061c97301fbd4ead9fb4a8737cd816f54409fc9ed4f86ca480ee875006b28f5086b009934e9a721247e9ff5da74ba3386fda784bb27dcb09a0c4c83fd8744a4b5aa5a9a001a11b9e48a1709b3b1d75bf502d3d6b0a81e44ed88cb03ceec47308023aed319a500320c588a3fae69b918d3e213305c4b46160dd79f47d9154933592601f7859511a70003718e3338b9a532e906de6238987d014ac94aa27f8304ec009043aa79b2723dde00c8c7d3a0d03d922021bcd79c6bc93efe0aef44d651eb40f5504d057a7b7ff9c4df001c7d83f484ba65421d7b8f9ed06b86299d217c0d2e1211cad52b1883b437dee0f300ec7f76566c95fcfb783ead420c554bdbd5bfdfc23600cfcba8b321882457882e00010700000000011eb2a3081e5d3596f032b47b2acaebe37241a34209a131741d95c9fce7fdafd002015fd25d362a2b4376f9c5997ef27244134257bdfddc3e1b8ab0b283747e66208e03014634904112272b45c943106d96b1bb7f1bdddc8d21ea56caedb69bbb3e4305e804018ad5dea911b4fb12e6d95ba70df2d823ba8e0923fe5b156f1f39c6c20e1b84c705014074fbd1ea05450c65ad5f776c2983dd9ad550d328e8eab523f9f1bbe7b438a206015eacaebe1945d427b031f9ac430d23b3eb8a6d19e1a9ed7a3fb4e8ad3da47bea07012f3b47e854327d4e52030674ce47cdb54392dbac99e6fa3d4700cd47310deebd" +} +JSON undefined true +undefined +undefined +undefined +undefined +undefined +undefined +undefined +undefined +undefined +undefined +undefined +undefined +undefined +undefined +undefined +undefined +undefined +undefined +undefined +undefined +undefined +e { + Contract: e { + contractPackageHash: 'contract-package-wasmde2e302af2be3b54419c4a6e4f61c111d45fb03afab72a62c88fa723fcb21ee8', + contractWasmHash: 'contract-wasm-f36d165331fcd1451fd5508713242faf6b90f8ddd38bf66c6d70d46c215dc748', + entrypoints: [ + undefined, undefined, undefined, + undefined, undefined, undefined, + undefined, undefined, undefined, + undefined, undefined, undefined, + undefined, undefined, undefined, + undefined, undefined, undefined, + undefined, undefined, undefined + ], + protocolVersion: '1.0.0', + namedKeys: [ + [e], [e], [e], [e], + [e], [e], [e], [e], + [e], [e] + ] + } +} diff --git a/dragons-nft-scripts/package-lock.json b/dragons-nft-scripts/package-lock.json index dd11968..768a988 100644 --- a/dragons-nft-scripts/package-lock.json +++ b/dragons-nft-scripts/package-lock.json @@ -4,1259 +4,12187 @@ "lockfileVersion": 1, "requires": true, "dependencies": { - "@ethersproject/bignumber": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.4.0.tgz", - "integrity": "sha512-OXUu9f9hO3vGRIPxU40cignXZVaYyfx6j9NNMjebKdnaCL3anCLSSy8/b8d03vY6dh7duCC0kW72GEC4tZer2w==", - "requires": { - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "bn.js": "^4.11.9" - } - }, - "@ethersproject/bytes": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.4.0.tgz", - "integrity": "sha512-H60ceqgTHbhzOj4uRc/83SCN9d+BSUnOkrr2intevqdtEMO1JFVZ1XL84OEZV+QjV36OaZYxtnt4lGmxcGsPfA==", - "requires": { - "@ethersproject/logger": "^5.4.0" - } - }, - "@ethersproject/constants": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.4.0.tgz", - "integrity": "sha512-tzjn6S7sj9+DIIeKTJLjK9WGN2Tj0P++Z8ONEIlZjyoTkBuODN+0VfhAyYksKi43l1Sx9tX2VlFfzjfmr5Wl3Q==", - "requires": { - "@ethersproject/bignumber": "^5.4.0" - } - }, - "@ethersproject/logger": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.4.0.tgz", - "integrity": "sha512-xYdWGGQ9P2cxBayt64d8LC8aPFJk6yWCawQi/4eJ4+oJdMMjEBMrIcIMZ9AxhwpPVmnBPrsB10PcXGmGAqgUEQ==" - }, - "@open-rpc/client-js": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@open-rpc/client-js/-/client-js-1.7.0.tgz", - "integrity": "sha512-cRGJbXTgdhJNU49vWzJIATRmKBLP2x6tuHJzX9Jg3N8f1VEkge0riUEek2LFIrZiM4TdUp8XV4Ns1W0SZzdfSw==", - "requires": { - "isomorphic-fetch": "^3.0.0", - "isomorphic-ws": "^4.0.1", - "strict-event-emitter-types": "^2.0.0", - "ws": "^7.0.0" - } - }, - "@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", - "requires": { - "@types/node": "*" - } - }, - "@types/eccrypto": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@types/eccrypto/-/eccrypto-1.1.3.tgz", - "integrity": "sha512-3O0qER6JMYReqVbcQTGmXeMHdw3O+rVps63tlo5g5zoB3altJS8yzSvboSivwVWeYO9o5jSATu7P0UIqYZPgow==", - "requires": { - "@types/expect": "^1.20.4", - "@types/node": "*" - } - }, - "@types/elliptic": { - "version": "6.4.13", - "resolved": "https://registry.npmjs.org/@types/elliptic/-/elliptic-6.4.13.tgz", - "integrity": "sha512-e8iyLJ8vMLpWxXpVWrIt0ujqsfHWgVe5XAz9IMhBYoDirK6th7J+mHjzp797OLc62ZX419nrlwwzsNAA0a0mKg==", - "requires": { - "@types/bn.js": "*" - } - }, - "@types/eslint": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.28.0.tgz", - "integrity": "sha512-07XlgzX0YJUn4iG1ocY4IX9DzKSmMGUs6ESKlxWhZRaa0fatIWaHWUVapcuGa8r5HFnTqzj+4OCjd5f7EZ/i/A==", - "requires": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "@types/eslint-scope": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.1.tgz", - "integrity": "sha512-SCFeogqiptms4Fg29WpOTk5nHIzfpKCemSN63ksBQYKTcXoJEmJagV+DhVmbapZzY4/5YaOV1nZwrsU79fFm1g==", - "requires": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "@types/estree": { - "version": "0.0.50", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz", - "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==" - }, - "@types/expect": { - "version": "1.20.4", - "resolved": "https://registry.npmjs.org/@types/expect/-/expect-1.20.4.tgz", - "integrity": "sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg==" - }, - "@types/json-schema": { - "version": "7.0.8", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.8.tgz", - "integrity": "sha512-YSBPTLTVm2e2OoQIDYx8HaeWJ5tTToLH67kXR7zYNGupXMEHa2++G8k+DczX2cFVgalypqtyZIcU19AFcmOpmg==" - }, - "@types/node": { - "version": "16.3.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.3.3.tgz", - "integrity": "sha512-8h7k1YgQKxKXWckzFCMfsIwn0Y61UK6tlD6y2lOb3hTOIMlK3t9/QwHOhc81TwU+RMf0As5fj7NPjroERCnejQ==" - }, - "@types/pbkdf2": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", - "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", - "requires": { - "@types/node": "*" - } - }, - "@types/secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==", - "requires": { - "@types/node": "*" - } - }, - "@webassemblyjs/ast": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", - "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", - "requires": { - "@webassemblyjs/helper-numbers": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", - "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==" - }, - "@webassemblyjs/helper-api-error": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", - "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==" - }, - "@webassemblyjs/helper-buffer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", - "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==" - }, - "@webassemblyjs/helper-numbers": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", - "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", - "requires": { - "@webassemblyjs/floating-point-hex-parser": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", - "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==" - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", - "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", - "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", - "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", - "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", - "requires": { - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/utf8": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", - "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==" - }, - "@webassemblyjs/wasm-edit": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", - "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", - "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/helper-wasm-section": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-opt": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "@webassemblyjs/wast-printer": "1.11.1" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", - "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", - "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", - "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", - "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", - "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", - "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", - "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", - "requires": { - "@webassemblyjs/ast": "1.11.1", - "@xtuc/long": "4.2.2" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" - }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" - }, - "acorn": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", - "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==" - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==" - }, - "asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - } - }, - "axios": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", - "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", - "requires": { - "follow-redirects": "^1.10.0" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "base-x": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz", - "integrity": "sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bip66": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", - "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", - "optional": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "blakejs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.1.tgz", - "integrity": "sha512-bLG6PHOCZJKNshTjGRBvET0vTciwQE6zFKOKKXPDJfwFBd4Ac0yBfPZqcGvGJap50l7ktvlpFqc2jGVaUgbJgg==" - }, - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserslist": { - "version": "4.16.6", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", - "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", - "requires": { - "caniuse-lite": "^1.0.30001219", - "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.723", - "escalade": "^3.1.1", - "node-releases": "^1.1.71" - } - }, - "bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", - "requires": { - "base-x": "^3.0.2" - } - }, - "bs58check": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", - "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", - "requires": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" - } - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" - }, - "caniuse-lite": { - "version": "1.0.30001245", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001245.tgz", - "integrity": "sha512-768fM9j1PKXpOCKws6eTo3RHmvTUsG9UrpT4WoREFeZgJBTi4/X9g565azS/rVUGtqb8nt7FjLeF5u4kukERnA==" - }, "casper-cep47-js-client": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/casper-cep47-js-client/-/casper-cep47-js-client-0.1.1.tgz", - "integrity": "sha512-g96zFG6lQghdlCxxlDI2j+Ov4U783PX+z8bLGDRqCEicG3pbXhyWQ+dckcHPDnBZraLxg9JizAvxMvzRwCFtfw==", + "version": "file:../../casper-cep47-js-client", "requires": { "@ethersproject/bignumber": "^5.0.8", - "casper-js-sdk": "^2.1.0" + "casper-js-sdk": "file:../../casper-js-sdk" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "requires": { + "@babel/highlight": "^7.14.5" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==" + }, + "@babel/highlight": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@ethersproject/bignumber": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.4.0.tgz", + "integrity": "sha512-OXUu9f9hO3vGRIPxU40cignXZVaYyfx6j9NNMjebKdnaCL3anCLSSy8/b8d03vY6dh7duCC0kW72GEC4tZer2w==", + "requires": { + "@ethersproject/bytes": "^5.4.0", + "@ethersproject/logger": "^5.4.0", + "bn.js": "^4.11.9" + } + }, + "@ethersproject/bytes": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.4.0.tgz", + "integrity": "sha512-H60ceqgTHbhzOj4uRc/83SCN9d+BSUnOkrr2intevqdtEMO1JFVZ1XL84OEZV+QjV36OaZYxtnt4lGmxcGsPfA==", + "requires": { + "@ethersproject/logger": "^5.4.0" + } + }, + "@ethersproject/logger": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.4.0.tgz", + "integrity": "sha512-xYdWGGQ9P2cxBayt64d8LC8aPFJk6yWCawQi/4eJ4+oJdMMjEBMrIcIMZ9AxhwpPVmnBPrsB10PcXGmGAqgUEQ==" + }, + "@tsconfig/node10": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==" + }, + "@tsconfig/node12": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==" + }, + "@tsconfig/node14": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==" + }, + "@tsconfig/node16": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.1.tgz", + "integrity": "sha512-FTgBI767POY/lKNDNbIzgAX6miIDBs6NTCbdlDb8TrWovHsSvaVIZDlTqym29C6UqhzwcJx4CYr+AlrMywA0cA==" + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" + }, + "casper-js-sdk": { + "version": "file:../../casper-js-sdk", + "requires": { + "@ethersproject/bignumber": "^5.0.8", + "@ethersproject/bytes": "^5.0.5", + "@ethersproject/constants": "^5.0.5", + "@open-rpc/client-js": "^1.6.2", + "@types/eccrypto": "^1.1.2", + "blakejs": "^1.1.0", + "eccrypto": "^1.1.6", + "eslint-plugin-prettier": "^3.4.0", + "ethereum-cryptography": "^0.1.3", + "glob": "^7.1.6", + "humanize-duration": "^3.24.0", + "key-encoder": "^2.0.3", + "reflect-metadata": "^0.1.13", + "ts-results": "^3.2.1", + "tweetnacl-ts": "^1.0.3", + "tweetnacl-util": "^0.15.0", + "typedjson": "^1.6.0-rc2", + "webpack": "^5.24.3" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", + "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", + "requires": { + "@babel/highlight": "^7.12.13" + } + }, + "@babel/compat-data": { + "version": "7.13.15", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.13.15.tgz", + "integrity": "sha512-ltnibHKR1VnrU4ymHyQ/CXtNXI6yZC0oJThyW78Hft8XndANwi+9H+UIklBDraIjFEJzw8wmcM427oDd9KS5wA==" + }, + "@babel/core": { + "version": "7.13.16", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.16.tgz", + "integrity": "sha512-sXHpixBiWWFti0AV2Zq7avpTasr6sIAu7Y396c608541qAU2ui4a193m0KSQmfPSKFZLnQ3cvlKDOm3XkuXm3Q==", + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.13.16", + "@babel/helper-compilation-targets": "^7.13.16", + "@babel/helper-module-transforms": "^7.13.14", + "@babel/helpers": "^7.13.16", + "@babel/parser": "^7.13.16", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.15", + "@babel/types": "^7.13.16", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + }, + "dependencies": { + "@babel/generator": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.1.tgz", + "integrity": "sha512-TMGhsXMXCP/O1WtQmZjpEYDhCYC9vFhayWZPJSZCGkPJgUqX0rF0wwtrYvnzVxIjcF80tkUertXVk5cwqi5cAQ==", + "requires": { + "@babel/types": "^7.14.1", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "@babel/types": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.1.tgz", + "integrity": "sha512-S13Qe85fzLs3gYRUnrpyeIrBJIMYv33qSTg1qoBwiG6nPKwUWAD9odSzWhEedpwOIzSEI6gbdQIWEMiCI42iBA==", + "requires": { + "@babel/helper-validator-identifier": "^7.14.0", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/helper-validator-identifier": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", + "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "@babel/helper-compilation-targets": { + "version": "7.13.16", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz", + "integrity": "sha512-3gmkYIrpqsLlieFwjkGgLaSHmhnvlAYzZLlYVjlW+QwI+1zE17kGxuJGmIqDQdYp56XdmGeD+Bswx0UTyG18xA==", + "requires": { + "@babel/compat-data": "^7.13.15", + "@babel/helper-validator-option": "^7.12.17", + "browserslist": "^4.14.5", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "@babel/helper-function-name": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", + "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", + "requires": { + "@babel/helper-get-function-arity": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", + "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz", + "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==", + "requires": { + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-module-imports": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz", + "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==", + "requires": { + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-module-transforms": { + "version": "7.13.14", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.13.14.tgz", + "integrity": "sha512-QuU/OJ0iAOSIatyVZmfqB0lbkVP0kDRiKj34xy+QNsnVZi/PA6BoSoreeqnxxa9EHFAIL0R9XOaAR/G9WlIy5g==", + "requires": { + "@babel/helper-module-imports": "^7.13.12", + "@babel/helper-replace-supers": "^7.13.12", + "@babel/helper-simple-access": "^7.13.12", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/helper-validator-identifier": "^7.12.11", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.13", + "@babel/types": "^7.13.14" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", + "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-replace-supers": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz", + "integrity": "sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw==", + "requires": { + "@babel/helper-member-expression-to-functions": "^7.13.12", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-simple-access": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz", + "integrity": "sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==", + "requires": { + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", + "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==" + }, + "@babel/helper-validator-option": { + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz", + "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==" + }, + "@babel/helpers": { + "version": "7.13.17", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.13.17.tgz", + "integrity": "sha512-Eal4Gce4kGijo1/TGJdqp3WuhllaMLSrW6XcL0ulyUAQOuxHcCafZE8KHg9857gcTehsm/v7RcOx2+jp0Ryjsg==", + "requires": { + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.17", + "@babel/types": "^7.13.17" + } + }, + "@babel/highlight": { + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.10.tgz", + "integrity": "sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg==", + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "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==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/parser": { + "version": "7.13.16", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.16.tgz", + "integrity": "sha512-6bAg36mCwuqLO0hbR+z7PHuqWiCeP7Dzg73OpQwsAB1Eb8HnGEz5xYBzCfbu+YjoaJsJs+qheDxVAuqbt3ILEw==" + }, + "@babel/template": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", + "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "@babel/traverse": { + "version": "7.13.17", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.17.tgz", + "integrity": "sha512-BMnZn0R+X6ayqm3C3To7o1j7Q020gWdqdyP50KEoVqaCO2c/Im7sYZSmVgvefp8TTMQ+9CtwuBp0Z1CZ8V3Pvg==", + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.13.16", + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/parser": "^7.13.16", + "@babel/types": "^7.13.17", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "dependencies": { + "@babel/generator": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.1.tgz", + "integrity": "sha512-TMGhsXMXCP/O1WtQmZjpEYDhCYC9vFhayWZPJSZCGkPJgUqX0rF0wwtrYvnzVxIjcF80tkUertXVk5cwqi5cAQ==", + "requires": { + "@babel/types": "^7.14.1", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "@babel/types": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.1.tgz", + "integrity": "sha512-S13Qe85fzLs3gYRUnrpyeIrBJIMYv33qSTg1qoBwiG6nPKwUWAD9odSzWhEedpwOIzSEI6gbdQIWEMiCI42iBA==", + "requires": { + "@babel/helper-validator-identifier": "^7.14.0", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/helper-validator-identifier": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", + "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==" + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "@babel/types": { + "version": "7.13.17", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.17.tgz", + "integrity": "sha512-RawydLgxbOPDlTLJNtoIypwdmAy//uQIzlKt2+iBiJaRlVuI6QLUxVAyWGNfOzp8Yu4L4lLIacoCyTNtpb4wiA==", + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", + "to-fast-properties": "^2.0.0" + } + }, + "@discoveryjs/json-ext": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz", + "integrity": "sha512-HyYEUDeIj5rRQU2Hk5HTB2uHsbRQpF70nvMhVzi+VJR0X+xNEhjPui4/kBf3VeH/wqD28PT4sVOm8qqLjBrSZg==" + }, + "@eslint/eslintrc": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.0.tgz", + "integrity": "sha512-2ZPCc+uNbjV5ERJr+aKSPRwZgKd2z11x0EgLvb1PURmUrn9QNRXFqje0Ldq454PfAVyaJYyrDvvIKSFP4NnBog==", + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "requires": { + "type-fest": "^0.8.1" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" + } + } + }, + "@ethersproject/bignumber": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.1.1.tgz", + "integrity": "sha512-AVz5iqz7+70RIqoQTznsdJ6DOVBYciNlvO+AlQmPTB6ofCvoihI9bQdr6wljsX+d5W7Yc4nyvQvP4JMzg0Agig==", + "requires": { + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "bn.js": "^4.4.0" + } + }, + "@ethersproject/bytes": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.1.0.tgz", + "integrity": "sha512-sGTxb+LVjFxJcJeUswAIK6ncgOrh3D8c192iEJd7mLr95V6du119rRfYT/b87WPkZ5I3gRBUYIYXtdgCWACe8g==", + "requires": { + "@ethersproject/logger": "^5.1.0" + } + }, + "@ethersproject/constants": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.1.0.tgz", + "integrity": "sha512-0/SuHrxc8R8k+JiLmJymxHJbojUDWBQqO+b+XFdwaP0jGzqC09YDy/CAlSZB6qHsBifY8X3I89HcK/oMqxRdBw==", + "requires": { + "@ethersproject/bignumber": "^5.1.0" + } + }, + "@ethersproject/logger": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.1.0.tgz", + "integrity": "sha512-wtUaD1lBX10HBXjjKV9VHCBnTdUaKQnQ2XSET1ezglqLdPdllNOIlLfhyCRqXm5xwcjExVI5ETokOYfjPtaAlw==" + }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" + } + } + }, + "@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==" + }, + "@nodelib/fs.scandir": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", + "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==", + "requires": { + "@nodelib/fs.stat": "2.0.4", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz", + "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==" + }, + "@nodelib/fs.walk": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz", + "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==", + "requires": { + "@nodelib/fs.scandir": "2.1.4", + "fastq": "^1.6.0" + } + }, + "@open-rpc/client-js": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@open-rpc/client-js/-/client-js-1.6.3.tgz", + "integrity": "sha512-KNlYB258FgMUopHUXqPAU4JZMAO/8HnGN7LcL/mXnwH/Qcd0GAMVwLLIXc5d9BBqtmDox8wxxAXGBCajRhyczA==", + "requires": { + "isomorphic-fetch": "^3.0.0", + "isomorphic-ws": "^4.0.1", + "strict-event-emitter-types": "^2.0.0", + "ws": "^7.0.0" + } + }, + "@sindresorhus/is": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.0.1.tgz", + "integrity": "sha512-Qm9hBEBu18wt1PO2flE7LPb30BHMQt1eQgbV76YntdNk73XZGpn3izvGTYxbGgzXKgbCjiia0uxTd3aTNQrY/g==" + }, + "@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==", + "requires": { + "defer-to-connect": "^2.0.0" + } + }, + "@types/bn.js": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", + "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", + "requires": { + "@types/node": "*" + } + }, + "@types/body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==", + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/cacheable-request": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", + "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", + "requires": { + "@types/http-cache-semantics": "*", + "@types/keyv": "*", + "@types/node": "*", + "@types/responselike": "*" + } + }, + "@types/chai": { + "version": "4.2.16", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.16.tgz", + "integrity": "sha512-vI5iOAsez9+roLS3M3+Xx7w+WRuDtSmF8bQkrbcIJ2sC1PcDgVoA0WGpa+bIrJ+y8zqY2oi//fUctkxtIcXJCw==" + }, + "@types/connect": { + "version": "3.4.34", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz", + "integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==", + "requires": { + "@types/node": "*" + } + }, + "@types/eccrypto": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/eccrypto/-/eccrypto-1.1.2.tgz", + "integrity": "sha512-qmB/iGIoqDdCMHAcJiOKI4ZBI1Z3kBQGYQCkgNP/Z9ge5w/EVx5uxQYkGOFpllm6l2N/B3qXcn9vjqXGaV1vRQ==", + "requires": { + "@types/expect": "^1.20.4", + "@types/node": "*" + } + }, + "@types/elliptic": { + "version": "6.4.12", + "resolved": "https://registry.npmjs.org/@types/elliptic/-/elliptic-6.4.12.tgz", + "integrity": "sha512-gP1KsqoouLJGH6IJa28x7PXb3cRqh83X8HCLezd2dF+XcAIMKYv53KV+9Zn6QA561E120uOqZBQ+Jy/cl+fviw==", + "requires": { + "@types/bn.js": "*" + } + }, + "@types/eslint": { + "version": "7.2.10", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.10.tgz", + "integrity": "sha512-kUEPnMKrqbtpCq/KTaGFFKAcz6Ethm2EjCoKIDaCmfRBWLbFuTcOJfTlorwbnboXBzahqWLgUp1BQeKHiJzPUQ==", + "requires": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "@types/eslint-scope": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.0.tgz", + "integrity": "sha512-O/ql2+rrCUe2W2rs7wMR+GqPRcgB6UiqN5RhrR5xruFlY7l9YLMn0ZkDzjoHLeiFkR8MCQZVudUuuvQ2BLC9Qw==", + "requires": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "@types/estree": { + "version": "0.0.47", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.47.tgz", + "integrity": "sha512-c5ciR06jK8u9BstrmJyO97m+klJrrhCf9u3rLu3DEAJBirxRqSCvDQoYKmxuYwQI5SZChAWu+tq9oVlGRuzPAg==" + }, + "@types/expect": { + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/@types/expect/-/expect-1.20.4.tgz", + "integrity": "sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg==" + }, + "@types/express": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.11.tgz", + "integrity": "sha512-no+R6rW60JEc59977wIxreQVsIEOAYwgCqldrA/vkpCnbD7MqTefO97lmoBe4WE0F156bC4uLSP1XHDOySnChg==", + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.19.tgz", + "integrity": "sha512-DJOSHzX7pCiSElWaGR8kCprwibCB/3yW6vcT8VG3P0SJjnv19gnWG/AZMfM60Xj/YJIp/YCaDHyvzsFVeniARA==", + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, + "@types/http-cache-semantics": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", + "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" + }, + "@types/humanize-duration": { + "version": "3.18.1", + "resolved": "https://registry.npmjs.org/@types/humanize-duration/-/humanize-duration-3.18.1.tgz", + "integrity": "sha512-MUgbY3CF7hg/a/jogixmAufLjJBQT7WEf8Q+kYJkOc47ytngg1IuZobCngdTjAgY83JWEogippge5O5fplaQlw==" + }, + "@types/json-schema": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==" + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=" + }, + "@types/keyv": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.2.tgz", + "integrity": "sha512-/FvAK2p4jQOaJ6CGDHJTqZcUtbZe820qIeTg7o0Shg7drB4JHeL+V/dhSaly7NXx6u8eSee+r7coT+yuJEvDLg==", + "requires": { + "@types/node": "*" + } + }, + "@types/mime": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" + }, + "@types/mocha": { + "version": "5.2.7", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", + "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==" + }, + "@types/node": { + "version": "14.14.41", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.41.tgz", + "integrity": "sha512-dueRKfaJL4RTtSa7bWeTK1M+VH+Gns73oCgzvYfHZywRCoPSd8EkXBL0mZ9unPTveBn+D9phZBaxuzpwjWkW0g==" + }, + "@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==" + }, + "@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" + }, + "@types/pbkdf2": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", + "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", + "requires": { + "@types/node": "*" + } + }, + "@types/qs": { + "version": "6.9.6", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.6.tgz", + "integrity": "sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA==" + }, + "@types/range-parser": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", + "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==" + }, + "@types/responselike": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", + "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", + "requires": { + "@types/node": "*" + } + }, + "@types/secp256k1": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.2.tgz", + "integrity": "sha512-QMg+9v0bbNJ2peLuHRWxzmy0HRJIG6gFZNhaRSp7S3ggSbCCxiqQB2/ybvhXyhHOCequpNkrx7OavNhrWOsW0A==", + "requires": { + "@types/node": "*" + } + }, + "@types/serve-static": { + "version": "1.13.9", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.9.tgz", + "integrity": "sha512-ZFqF6qa48XsPdjXV5Gsz0Zqmux2PerNd3a/ktL45mHpa19cuMi/cL8tcxdAx497yRh+QtYPuofjT9oWw9P7nkA==", + "requires": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "@typescript-eslint/eslint-plugin": { + "version": "4.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.22.0.tgz", + "integrity": "sha512-U8SP9VOs275iDXaL08Ln1Fa/wLXfj5aTr/1c0t0j6CdbOnxh+TruXu1p4I0NAvdPBQgoPjHsgKn28mOi0FzfoA==", + "requires": { + "@typescript-eslint/experimental-utils": "4.22.0", + "@typescript-eslint/scope-manager": "4.22.0", + "debug": "^4.1.1", + "functional-red-black-tree": "^1.0.1", + "lodash": "^4.17.15", + "regexpp": "^3.0.0", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + } + }, + "@typescript-eslint/experimental-utils": { + "version": "4.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.22.0.tgz", + "integrity": "sha512-xJXHHl6TuAxB5AWiVrGhvbGL8/hbiCQ8FiWwObO3r0fnvBdrbWEDy1hlvGQOAWc6qsCWuWMKdVWlLAEMpxnddg==", + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/scope-manager": "4.22.0", + "@typescript-eslint/types": "4.22.0", + "@typescript-eslint/typescript-estree": "4.22.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + } + }, + "@typescript-eslint/parser": { + "version": "4.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.22.0.tgz", + "integrity": "sha512-z/bGdBJJZJN76nvAY9DkJANYgK3nlRstRRi74WHm3jjgf2I8AglrSY+6l7ogxOmn55YJ6oKZCLLy+6PW70z15Q==", + "requires": { + "@typescript-eslint/scope-manager": "4.22.0", + "@typescript-eslint/types": "4.22.0", + "@typescript-eslint/typescript-estree": "4.22.0", + "debug": "^4.1.1" + } + }, + "@typescript-eslint/scope-manager": { + "version": "4.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.22.0.tgz", + "integrity": "sha512-OcCO7LTdk6ukawUM40wo61WdeoA7NM/zaoq1/2cs13M7GyiF+T4rxuA4xM+6LeHWjWbss7hkGXjFDRcKD4O04Q==", + "requires": { + "@typescript-eslint/types": "4.22.0", + "@typescript-eslint/visitor-keys": "4.22.0" + } + }, + "@typescript-eslint/types": { + "version": "4.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.22.0.tgz", + "integrity": "sha512-sW/BiXmmyMqDPO2kpOhSy2Py5w6KvRRsKZnV0c4+0nr4GIcedJwXAq+RHNK4lLVEZAJYFltnnk1tJSlbeS9lYA==" + }, + "@typescript-eslint/typescript-estree": { + "version": "4.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.22.0.tgz", + "integrity": "sha512-TkIFeu5JEeSs5ze/4NID+PIcVjgoU3cUQUIZnH3Sb1cEn1lBo7StSV5bwPuJQuoxKXlzAObjYTilOEKRuhR5yg==", + "requires": { + "@typescript-eslint/types": "4.22.0", + "@typescript-eslint/visitor-keys": "4.22.0", + "debug": "^4.1.1", + "globby": "^11.0.1", + "is-glob": "^4.0.1", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "4.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.22.0.tgz", + "integrity": "sha512-nnMu4F+s4o0sll6cBSsTeVsT4cwxB7zECK3dFxzEjPBii9xLpq4yqqsy/FU5zMfan6G60DKZSCXAa3sHJZrcYw==", + "requires": { + "@typescript-eslint/types": "4.22.0", + "eslint-visitor-keys": "^2.0.0" + } + }, + "@webassemblyjs/ast": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.0.tgz", + "integrity": "sha512-kX2W49LWsbthrmIRMbQZuQDhGtjyqXfEmmHyEi4XWnSZtPmxY0+3anPIzsnRb45VH/J55zlOfWvZuY47aJZTJg==", + "requires": { + "@webassemblyjs/helper-numbers": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.0.tgz", + "integrity": "sha512-Q/aVYs/VnPDVYvsCBL/gSgwmfjeCb4LW8+TMrO3cSzJImgv8lxxEPM2JA5jMrivE7LSz3V+PFqtMbls3m1exDA==" + }, + "@webassemblyjs/helper-api-error": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.0.tgz", + "integrity": "sha512-baT/va95eXiXb2QflSx95QGT5ClzWpGaa8L7JnJbgzoYeaA27FCvuBXU758l+KXWRndEmUXjP0Q5fibhavIn8w==" + }, + "@webassemblyjs/helper-buffer": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.0.tgz", + "integrity": "sha512-u9HPBEl4DS+vA8qLQdEQ6N/eJQ7gT7aNvMIo8AAWvAl/xMrcOSiI2M0MAnMCy3jIFke7bEee/JwdX1nUpCtdyA==" + }, + "@webassemblyjs/helper-numbers": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.0.tgz", + "integrity": "sha512-DhRQKelIj01s5IgdsOJMKLppI+4zpmcMQ3XboFPLwCpSNH6Hqo1ritgHgD0nqHeSYqofA6aBN/NmXuGjM1jEfQ==", + "requires": { + "@webassemblyjs/floating-point-hex-parser": "1.11.0", + "@webassemblyjs/helper-api-error": "1.11.0", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.0.tgz", + "integrity": "sha512-MbmhvxXExm542tWREgSFnOVo07fDpsBJg3sIl6fSp9xuu75eGz5lz31q7wTLffwL3Za7XNRCMZy210+tnsUSEA==" + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.0.tgz", + "integrity": "sha512-3Eb88hcbfY/FCukrg6i3EH8H2UsD7x8Vy47iVJrP967A9JGqgBVL9aH71SETPx1JrGsOUVLo0c7vMCN22ytJew==", + "requires": { + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-buffer": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0", + "@webassemblyjs/wasm-gen": "1.11.0" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.0.tgz", + "integrity": "sha512-KXzOqpcYQwAfeQ6WbF6HXo+0udBNmw0iXDmEK5sFlmQdmND+tr773Ti8/5T/M6Tl/413ArSJErATd8In3B+WBA==", + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.0.tgz", + "integrity": "sha512-aqbsHa1mSQAbeeNcl38un6qVY++hh8OpCOzxhixSYgbRfNWcxJNJQwe2rezK9XEcssJbbWIkblaJRwGMS9zp+g==", + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.0.tgz", + "integrity": "sha512-A/lclGxH6SpSLSyFowMzO/+aDEPU4hvEiooCMXQPcQFPPJaYcPQNKGOCLUySJsYJ4trbpr+Fs08n4jelkVTGVw==" + }, + "@webassemblyjs/wasm-edit": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.0.tgz", + "integrity": "sha512-JHQ0damXy0G6J9ucyKVXO2j08JVJ2ntkdJlq1UTiUrIgfGMmA7Ik5VdC/L8hBK46kVJgujkBIoMtT8yVr+yVOQ==", + "requires": { + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-buffer": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0", + "@webassemblyjs/helper-wasm-section": "1.11.0", + "@webassemblyjs/wasm-gen": "1.11.0", + "@webassemblyjs/wasm-opt": "1.11.0", + "@webassemblyjs/wasm-parser": "1.11.0", + "@webassemblyjs/wast-printer": "1.11.0" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.0.tgz", + "integrity": "sha512-BEUv1aj0WptCZ9kIS30th5ILASUnAPEvE3tVMTrItnZRT9tXCLW2LEXT8ezLw59rqPP9klh9LPmpU+WmRQmCPQ==", + "requires": { + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0", + "@webassemblyjs/ieee754": "1.11.0", + "@webassemblyjs/leb128": "1.11.0", + "@webassemblyjs/utf8": "1.11.0" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.0.tgz", + "integrity": "sha512-tHUSP5F4ywyh3hZ0+fDQuWxKx3mJiPeFufg+9gwTpYp324mPCQgnuVKwzLTZVqj0duRDovnPaZqDwoyhIO8kYg==", + "requires": { + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-buffer": "1.11.0", + "@webassemblyjs/wasm-gen": "1.11.0", + "@webassemblyjs/wasm-parser": "1.11.0" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.0.tgz", + "integrity": "sha512-6L285Sgu9gphrcpDXINvm0M9BskznnzJTE7gYkjDbxET28shDqp27wpruyx3C2S/dvEwiigBwLA1cz7lNUi0kw==", + "requires": { + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-api-error": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0", + "@webassemblyjs/ieee754": "1.11.0", + "@webassemblyjs/leb128": "1.11.0", + "@webassemblyjs/utf8": "1.11.0" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.0.tgz", + "integrity": "sha512-Fg5OX46pRdTgB7rKIUojkh9vXaVN6sGYCnEiJN1GYkb0RPwShZXp6KTDqmoMdQPKhcroOXh3fEzmkWmCYaKYhQ==", + "requires": { + "@webassemblyjs/ast": "1.11.0", + "@xtuc/long": "4.2.2" + } + }, + "@webpack-cli/configtest": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.0.2.tgz", + "integrity": "sha512-3OBzV2fBGZ5TBfdW50cha1lHDVf9vlvRXnjpVbJBa20pSZQaSkMJZiwA8V2vD9ogyeXn8nU5s5A6mHyf5jhMzA==" + }, + "@webpack-cli/info": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.2.3.tgz", + "integrity": "sha512-lLek3/T7u40lTqzCGpC6CAbY6+vXhdhmwFRxZLMnRm6/sIF/7qMpT8MocXCRQfz0JAh63wpbXLMnsQ5162WS7Q==", + "requires": { + "envinfo": "^7.7.3" + } + }, + "@webpack-cli/serve": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.3.1.tgz", + "integrity": "sha512-0qXvpeYO6vaNoRBI52/UsbcaBydJCggoBBnIo/ovQQdn6fug0BgwsjorV1hVS7fMqGVTZGcVxv8334gjmbj5hw==" + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "acorn": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.1.1.tgz", + "integrity": "sha512-xYiIVjNuqtKXMxlRMDc6mZUhXehod4a3gbZ1qRlM7icK4EbxUFNLhWoPblCvFtB2Y9CIqHP3CF/rdxLItaQv8g==" + }, + "acorn-jsx": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==" + }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==" + }, + "ansi-align": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", + "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", + "requires": { + "string-width": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==" + }, + "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==", + "requires": { + "type-fest": "^0.21.3" + }, + "dependencies": { + "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==" + } + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "append-transform": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", + "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", + "requires": { + "default-require-extensions": "^3.0.0" + } + }, + "archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=" + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-differ": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-2.1.0.tgz", + "integrity": "sha512-KbUpJgx909ZscOc/7CLATBFam7P1Z1QRQInvgT0UztM9Q72aGKCunKASAl7WNW0tnPmPyEMeMhdsfWhfmW037w==" + }, + "array-filter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz", + "integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=" + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==" + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" + }, + "asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + } + }, + "assert": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-2.0.0.tgz", + "integrity": "sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A==", + "requires": { + "es6-object-assign": "^1.1.0", + "is-nan": "^1.2.1", + "object-is": "^1.0.1", + "util": "^0.12.0" + } + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==" + }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==" + }, + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "requires": { + "lodash": "^4.17.14" + } + }, + "available-typed-arrays": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz", + "integrity": "sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ==", + "requires": { + "array-filter": "^1.0.0" + } + }, + "axios": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", + "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "requires": { + "follow-redirects": "^1.10.0" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "base-x": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz", + "integrity": "sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "optional": true, + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "bip66": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", + "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", + "optional": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "blakejs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", + "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" + }, + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "boxen": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", + "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", + "requires": { + "ansi-align": "^3.0.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "cli-boxes": "^2.2.0", + "string-width": "^4.1.0", + "term-size": "^2.1.0", + "type-fest": "^0.8.1", + "widest-line": "^3.1.0" + }, + "dependencies": { + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" + } + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", + "requires": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + }, + "dependencies": { + "bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" + } + } + }, + "browserify-sign": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", + "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", + "requires": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.3", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" + } + } + }, + "browserslist": { + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.4.tgz", + "integrity": "sha512-d7rCxYV8I9kj41RH8UKYnvDYCRENUlHRgyXy/Rhr/1BaeLGfiCptEdFE8MIrvGfWbBFNjVYx76SQWvNX1j+/cQ==", + "requires": { + "caniuse-lite": "^1.0.30001208", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.712", + "escalade": "^3.1.1", + "node-releases": "^1.1.71" + } + }, + "bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", + "requires": { + "base-x": "^3.0.2" + } + }, + "bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "requires": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=" + }, + "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==" + }, + "cacheable-request": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", + "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", + "requires": { + "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" + }, + "dependencies": { + "normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==" + } + } + }, + "caching-transform": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", + "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", + "requires": { + "hasha": "^5.0.0", + "make-dir": "^3.0.0", + "package-hash": "^4.0.0", + "write-file-atomic": "^3.0.0" + } + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "caniuse-lite": { + "version": "1.0.30001214", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001214.tgz", + "integrity": "sha512-O2/SCpuaU3eASWVaesQirZv1MSjUNOvmugaD8zNSJqw6Vv5SGwoOpA9LJs3pNPfM745nxqPvfZY3MQKY4AKHYg==" + }, + "chai": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", + "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=" + }, + "chokidar": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.3.1", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + } + }, + "chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==" + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==" + }, + "cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==" + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "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==", + "requires": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "dependencies": { + "slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + } + } + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "requires": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + } + }, + "clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "requires": { + "mimic-response": "^1.0.0" + } + }, + "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==", + "requires": { + "color-name": "~1.1.4" + } + }, + "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==" + }, + "colorette": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==" + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "comment-parser": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.1.2.tgz", + "integrity": "sha512-AOdq0i8ghZudnYv8RUnHrhTgafUGs61Rdz9jemU5x2lnZwAWyOq7vySo626K59e1fVKH1xSRorJwPVRLSWOoAQ==" + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" + }, + "compare-versions": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz", + "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "concurrently": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-6.0.2.tgz", + "integrity": "sha512-u+1Q0dJG5BidgUTpz9CU16yoHTt/oApFDQ3mbvHwSDgMjU7aGqy0q8ZQyaZyaNxdwRKTD872Ux3Twc6//sWA+Q==", + "requires": { + "chalk": "^4.1.0", + "date-fns": "^2.16.1", + "lodash": "^4.17.21", + "read-pkg": "^5.2.0", + "rxjs": "^6.6.3", + "spawn-command": "^0.0.2-1", + "supports-color": "^8.1.0", + "tree-kill": "^1.2.2", + "yargs": "^16.2.0" + }, + "dependencies": { + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "configstore": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", + "requires": { + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + } + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "requires": { + "safe-buffer": "~5.1.1" + }, + "dependencies": { + "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==" + } + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cosmiconfig": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", + "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==", + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + } + }, + "create-ecdh": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==" + }, + "date-fns": { + "version": "2.21.1", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.21.1.tgz", + "integrity": "sha512-m1WR0xGiC6j6jNFAyW4Nvh4WxAi4JF4w9jRJwSI8nBmNcyZXPcP9VUQG+6gHQXAmqaGEKDKhOqAtENDC941UkA==" + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "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==", + "requires": { + "mimic-response": "^3.1.0" + }, + "dependencies": { + "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==" + } + } + }, + "dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=" + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "requires": { + "type-detect": "^4.0.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" + }, + "default-require-extensions": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", + "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==", + "requires": { + "strip-bom": "^4.0.0" + } + }, + "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==" + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "requires": { + "object-keys": "^1.0.12" + } + }, + "des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "requires": { + "path-type": "^4.0.0" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "requires": { + "esutils": "^2.0.2" + } + }, + "dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "requires": { + "is-obj": "^2.0.0" + }, + "dependencies": { + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==" + } + } + }, + "drbg.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", + "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", + "optional": true, + "requires": { + "browserify-aes": "^1.0.6", + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4" + } + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" + }, + "eccrypto": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/eccrypto/-/eccrypto-1.1.6.tgz", + "integrity": "sha512-d78ivVEzu7Tn0ZphUUaL43+jVPKTMPFGtmgtz1D0LrFn7cY3K8CdrvibuLz2AAkHBLKZtR8DMbB2ukRYFk987A==", + "requires": { + "acorn": "7.1.1", + "elliptic": "6.5.4", + "es6-promise": "4.2.8", + "nan": "2.14.0", + "secp256k1": "3.7.1" + }, + "dependencies": { + "acorn": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", + "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==" + }, + "secp256k1": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.7.1.tgz", + "integrity": "sha512-1cf8sbnRreXrQFdH6qsg2H71Xw91fCCS9Yp021GnUNJzWJS/py96fS4lHbnTnouLp08Xj6jBoBB6V78Tdbdu5g==", + "optional": true, + "requires": { + "bindings": "^1.5.0", + "bip66": "^1.1.5", + "bn.js": "^4.11.8", + "create-hash": "^1.2.0", + "drbg.js": "^1.0.1", + "elliptic": "^6.4.1", + "nan": "^2.14.0", + "safe-buffer": "^5.1.2" + } + } + } + }, + "electron-to-chromium": { + "version": "1.3.719", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.719.tgz", + "integrity": "sha512-heM78GKSqrIzO9Oz0/y22nTBN7bqSP1Pla2SyU9DiSnQD+Ea9SyyN5RWWlgqsqeBLNDkSlE9J9EHFmdMPzxB/g==" + }, + "elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "requires": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "email-addresses": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-3.1.0.tgz", + "integrity": "sha512-k0/r7GrWVL32kZlGwfPNgB2Y/mMXVTq/decgLczm/j34whdaspNrZO8CnXPf1laaHxI6ptUlsnAxN+UAPw+fzg==" + }, + "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==" + }, + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" + }, + "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==", + "requires": { + "once": "^1.4.0" + } + }, + "enhanced-resolve": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.0.tgz", + "integrity": "sha512-Sl3KRpJA8OpprrtaIswVki3cWPiPKxXuFxJXBp+zNb6s6VwNWwFRUdtmzd2ReUut8n+sCPx7QCtQ7w5wfJhSgQ==", + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + } + }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "requires": { + "ansi-colors": "^4.1.1" + } + }, + "envinfo": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", + "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==" + }, + "errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "requires": { + "prr": "~1.0.1" + } + }, + "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==", + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0.tgz", + "integrity": "sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw==", + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.2", + "is-string": "^1.0.5", + "object-inspect": "^1.9.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.0" + } + }, + "es-module-lexer": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.4.1.tgz", + "integrity": "sha512-ooYciCUtfw6/d2w56UVeqHPcoCFAiJdz5XOkYpv/Txl1HMUozpXjz/2RIQgqwKdXNDPSF1W7mJCFse3G+HDyAA==" + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==" + }, + "es6-object-assign": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", + "integrity": "sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw=" + }, + "es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, + "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==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "eslint": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.24.0.tgz", + "integrity": "sha512-k9gaHeHiFmGCDQ2rEfvULlSLruz6tgfA8DEn+rY9/oYPFFTlz55mM/Q/Rij1b2Y42jwZiK3lXvNTw6w6TXzcKQ==", + "requires": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash": "^4.17.21", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.4", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" + } + } + }, + "eslint-config-prettier": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.2.0.tgz", + "integrity": "sha512-dWV9EVeSo2qodOPi1iBYU/x6F6diHv8uujxbxr77xExs3zTAlNXvVZKiyLsQGNz7yPV2K49JY5WjPzNIuDc2Bw==" + }, + "eslint-plugin-jsdoc": { + "version": "32.3.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-32.3.0.tgz", + "integrity": "sha512-zyx7kajDK+tqS1bHuY5sapkad8P8KT0vdd/lE55j47VPG2MeenSYuIY/M/Pvmzq5g0+3JB+P3BJGUXmHxtuKPQ==", + "requires": { + "comment-parser": "1.1.2", + "debug": "^4.3.1", + "jsdoctypeparser": "^9.0.0", + "lodash": "^4.17.20", + "regextras": "^0.7.1", + "semver": "^7.3.4", + "spdx-expression-parse": "^3.0.1" + } + }, + "eslint-plugin-prefer-arrow": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-prefer-arrow/-/eslint-plugin-prefer-arrow-1.2.3.tgz", + "integrity": "sha512-J9I5PKCOJretVuiZRGvPQxCbllxGAV/viI20JO3LYblAodofBxyMnZAJ+WGeClHgANnSJberTNoFWWjrWKBuXQ==" + }, + "eslint-plugin-prettier": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.0.tgz", + "integrity": "sha512-UDK6rJT6INSfcOo545jiaOwB701uAIt2/dR7WnFQoGCVl1/EMqdANBmwUaqqQ45aXprsTGzSa39LI1PyuRBxxw==", + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "requires": { + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" + } + } + }, + "eslint-visitor-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", + "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==" + }, + "espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "requires": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "dependencies": { + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" + } + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==" + } + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==" + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "requires": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "requires": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==" + }, + "fast-glob": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", + "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + }, + "fastest-levenshtein": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", + "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==" + }, + "fastq": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", + "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==", + "requires": { + "reusify": "^1.0.4" + } + }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "requires": { + "flat-cache": "^3.0.4" + } + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "optional": true + }, + "filename-reserved-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-1.0.0.tgz", + "integrity": "sha1-5hz4BfDeHJhFZ9A4bcXfUO5a9+Q=" + }, + "filenamify": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-1.2.1.tgz", + "integrity": "sha1-qfL/0RxQO+0wABUCknI3jx8TZaU=", + "requires": { + "filename-reserved-regex": "^1.0.0", + "strip-outer": "^1.0.0", + "trim-repeated": "^1.0.0" + } + }, + "filenamify-url": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/filenamify-url/-/filenamify-url-1.0.0.tgz", + "integrity": "sha1-syvYExnvWGO3MHi+1Q9GpPeXX1A=", + "requires": { + "filenamify": "^1.0.0", + "humanize-url": "^1.0.0" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-cache-dir": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "find-versions": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-4.0.0.tgz", + "integrity": "sha512-wgpWy002tA+wgmO27buH/9KzyEOQnKsG/R0yrcjPT9BOFm0zRBVQbZ95nRGXWMywS8YR5knRbpohio0bcJABxQ==", + "requires": { + "semver-regex": "^3.1.2" + } + }, + "flat": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", + "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", + "requires": { + "is-buffer": "~2.0.3" + } + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", + "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==" + }, + "follow-redirects": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.3.tgz", + "integrity": "sha512-DUgl6+HDzB0iEptNQEXLx/KhTmDb8tZUHSeLqpnjpknR70H0nC2t9N73BK6fN4hOvJ84pKlIQVQ4k5FFlBedKA==" + }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" + }, + "foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + } + }, + "fromentries": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", + "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==" + }, + "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==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" + }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" + }, + "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==" + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=" + }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, + "get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" + }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==" + }, + "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==", + "requires": { + "pump": "^3.0.0" + } + }, + "gh-pages": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-3.1.0.tgz", + "integrity": "sha512-3b1rly9kuf3/dXsT8+ZxP0UhNLOo1CItj+3e31yUVcaph/yDsJ9RzD7JOw5o5zpBTJVQLlJAASNkUfepi9fe2w==", + "requires": { + "async": "^2.6.1", + "commander": "^2.18.0", + "email-addresses": "^3.0.1", + "filenamify-url": "^1.0.0", + "find-cache-dir": "^3.3.1", + "fs-extra": "^8.1.0", + "globby": "^6.1.0" + }, + "dependencies": { + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "requires": { + "array-uniq": "^1.0.1" + } + }, + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "requires": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + } + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "requires": { + "is-glob": "^4.0.1" + } + }, + "glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" + }, + "global-dirs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.1.0.tgz", + "integrity": "sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==", + "requires": { + "ini": "1.3.7" + } + }, + "globals": { + "version": "13.8.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.8.0.tgz", + "integrity": "sha512-rHtdA6+PDBIjeEvA91rpqzEvk/k3/i7EeNQiryiWuJH0Hw9cpyJMAt2jtbAwUaRdhD+573X4vWw6IcjKPasi9Q==", + "requires": { + "type-fest": "^0.20.2" + }, + "dependencies": { + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==" + } + } + }, + "globby": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz", + "integrity": "sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==", + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + } + }, + "google-protobuf": { + "version": "3.15.8", + "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.15.8.tgz", + "integrity": "sha512-2jtfdqTaSxk0cuBJBtTTWsot4WtR9RVr2rXg7x7OoqiuOKopPrwXpM1G4dXIkLcUNRh3RKzz76C8IOkksZSeOw==" + }, + "got": { + "version": "11.8.2", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.2.tgz", + "integrity": "sha512-D0QywKgIe30ODs+fm8wMZiAcZjypcCodPNuMz5H9Mny7RJ+IjJ10BdmGW7OM7fHXP+O7r6ZwapQ/YQmMSvB0UQ==", + "requires": { + "@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.1", + "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" + } + }, + "graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==" + }, + "handlebars": { + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "requires": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4", + "wordwrap": "^1.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" + }, + "has-yarn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", + "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==" + }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hasha": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", + "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", + "requires": { + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" + }, + "dependencies": { + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" + } + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" + }, + "highlight.js": { + "version": "10.7.2", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.2.tgz", + "integrity": "sha512-oFLl873u4usRM9K63j4ME9u3etNF0PLiJhSQ8rdfuL51Wn3zkD6drf9ZW0dOzjnZI22YYG24z30JcmfCZjMgYg==" + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "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==" + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" + }, + "http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" + }, + "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==", + "requires": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + } + }, + "human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==" + }, + "humanize-duration": { + "version": "3.25.2", + "resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.25.2.tgz", + "integrity": "sha512-zSerjahuzBazDaE8skjMI7Xmrt/EirvW5cDsXgysx8tYIjcgCMnI5Y5985y3LxYeLah9L5cQY3WEw1k7GRWbfg==" + }, + "humanize-url": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/humanize-url/-/humanize-url-1.0.1.tgz", + "integrity": "sha1-9KuZ4NKIF0yk4eUEB8VfuuRk7/8=", + "requires": { + "normalize-url": "^1.0.0", + "strip-url-auth": "^1.0.0" + } + }, + "husky": { + "version": "4.3.8", + "resolved": "https://registry.npmjs.org/husky/-/husky-4.3.8.tgz", + "integrity": "sha512-LCqqsB0PzJQ/AlCgfrfzRe3e3+NvmefAdKQhRYpxS4u6clblBoDdzzvHi8fmxKRzvMxPY/1WZWzomPZww0Anow==", + "requires": { + "chalk": "^4.0.0", + "ci-info": "^2.0.0", + "compare-versions": "^3.6.0", + "cosmiconfig": "^7.0.0", + "find-versions": "^4.0.0", + "opencollective-postinstall": "^2.0.2", + "pkg-dir": "^5.0.0", + "please-upgrade-node": "^3.2.0", + "slash": "^3.0.0", + "which-pm-runs": "^1.0.0" + }, + "dependencies": { + "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==", + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "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==", + "requires": { + "p-locate": "^5.0.0" + } + }, + "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==", + "requires": { + "p-limit": "^3.0.2" + } + }, + "pkg-dir": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", + "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", + "requires": { + "find-up": "^5.0.0" + } + } + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==" + }, + "ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=" + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=" + }, + "import-local": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", + "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + }, + "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==" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ini": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", + "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==" + }, + "interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==" + }, + "is-arguments": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", + "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==", + "requires": { + "call-bind": "^1.0.0" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + }, + "is-bigint": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.1.tgz", + "integrity": "sha512-J0ELF4yHFxHy0cmSxZuheDOz2luOdVvqjwmEcj8H/L1JHeuEDSDbeRP+Dk9kFVk5RTFzbucJ2Kb9F7ixY2QaCg==" + }, + "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==", + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-boolean-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.0.tgz", + "integrity": "sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA==", + "requires": { + "call-bind": "^1.0.0" + } + }, + "is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==" + }, + "is-callable": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==" + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", + "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", + "requires": { + "has": "^1.0.3" + } + }, + "is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==" + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "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==" + }, + "is-generator-function": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.8.tgz", + "integrity": "sha512-2Omr/twNtufVZFr1GhxjOMFPAj2sjc/dKaIqBhvo4qciXfJmITGH6ZGd8eZYNHza8t1y0e01AuqRhJwfWp26WQ==" + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-installed-globally": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", + "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", + "requires": { + "global-dirs": "^2.0.1", + "is-path-inside": "^3.0.1" + } + }, + "is-nan": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", + "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + } + }, + "is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==" + }, + "is-npm": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", + "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==" + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "is-number-object": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz", + "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==" + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" + }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==" + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "requires": { + "isobject": "^3.0.1" + } + }, + "is-regex": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", + "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", + "requires": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.1" + } + }, + "is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=" + }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" + }, + "is-string": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==" + }, + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-typed-array": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.5.tgz", + "integrity": "sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug==", + "requires": { + "available-typed-arrays": "^1.0.2", + "call-bind": "^1.0.2", + "es-abstract": "^1.18.0-next.2", + "foreach": "^2.0.5", + "has-symbols": "^1.0.1" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==" + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" + }, + "is-yarn-global": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "isomorphic-fetch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", + "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", + "requires": { + "node-fetch": "^2.6.1", + "whatwg-fetch": "^3.4.1" + } + }, + "isomorphic-ws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", + "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==" + }, + "istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==" + }, + "istanbul-lib-hook": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", + "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", + "requires": { + "append-transform": "^2.0.0" + } + }, + "istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "requires": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "istanbul-lib-processinfo": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz", + "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==", + "requires": { + "archy": "^1.0.0", + "cross-spawn": "^7.0.0", + "istanbul-lib-coverage": "^3.0.0-alpha.1", + "make-dir": "^3.0.0", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "uuid": "^3.3.3" + }, + "dependencies": { + "p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, + "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==", + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", + "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + } + }, + "istanbul-reports": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", + "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbi": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/jsbi/-/jsbi-3.1.4.tgz", + "integrity": "sha512-52QRRFSsi9impURE8ZUbzAMCLjPm4THO7H2fcuIvaaeFTbSysvkodbQQXIVsNgq/ypDbq6dJiuGKL0vZ/i9hUg==" + }, + "jsdoctypeparser": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/jsdoctypeparser/-/jsdoctypeparser-9.0.0.tgz", + "integrity": "sha512-jrTA2jJIL6/DAEILBEh2/w9QxCuwmvNXIry39Ay/HVfhE3o2yVV0U44blYkqdHA/OKloJEqvJy0xU+GSdE2SIw==" + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + }, + "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==" + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" + }, + "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==" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=" + }, + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "requires": { + "minimist": "^1.2.5" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "keccak": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.1.tgz", + "integrity": "sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA==", + "requires": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + } + }, + "key-encoder": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/key-encoder/-/key-encoder-2.0.3.tgz", + "integrity": "sha512-fgBtpAGIr/Fy5/+ZLQZIPPhsZEcbSlYu/Wu96tNDFNSjSACw5lEIOFeaVdQ/iwrb8oxjlWi6wmWdH76hV6GZjg==", + "requires": { + "@types/elliptic": "^6.4.9", + "asn1.js": "^5.0.1", + "bn.js": "^4.11.8", + "elliptic": "^6.4.1" + } + }, + "keyv": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.3.tgz", + "integrity": "sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA==", + "requires": { + "json-buffer": "3.0.1" + } + }, + "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==" + }, + "latest-version": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", + "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", + "requires": { + "package-json": "^6.3.0" + } + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=" + }, + "lint-staged": { + "version": "10.5.4", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-10.5.4.tgz", + "integrity": "sha512-EechC3DdFic/TdOPgj/RB3FicqE6932LTHCUm0Y2fsD9KGlLB+RwJl2q1IYBIvEsKzDOgn0D4gll+YxG5RsrKg==", + "requires": { + "chalk": "^4.1.0", + "cli-truncate": "^2.1.0", + "commander": "^6.2.0", + "cosmiconfig": "^7.0.0", + "debug": "^4.2.0", + "dedent": "^0.7.0", + "enquirer": "^2.3.6", + "execa": "^4.1.0", + "listr2": "^3.2.2", + "log-symbols": "^4.0.0", + "micromatch": "^4.0.2", + "normalize-path": "^3.0.0", + "please-upgrade-node": "^3.2.0", + "string-argv": "0.3.1", + "stringify-object": "^3.3.0" + }, + "dependencies": { + "commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==" + } + } + }, + "listr2": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.7.1.tgz", + "integrity": "sha512-cNd368GTrk8351/ov/IV+BSwyf9sJRgI0UIvfORonCZA1u9UHAtAlqSEv9dgafoQIA1CgB3nu4No79pJtK2LHw==", + "requires": { + "chalk": "^4.1.0", + "cli-truncate": "^2.1.0", + "figures": "^3.2.0", + "indent-string": "^4.0.0", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rxjs": "^6.6.7", + "through": "^2.3.8", + "wrap-ansi": "^7.0.0" + } + }, + "loader-runner": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", + "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==" + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" + }, + "lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=" + }, + "lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=" + }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=" + }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, + "log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "requires": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "dependencies": { + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + } + } + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" + }, + "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==", + "requires": { + "yallist": "^4.0.0" + } + }, + "lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==" + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "marked": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-1.0.0.tgz", + "integrity": "sha512-Wo+L1pWTVibfrSr+TTtMuiMfNzmZWiOPeO7rZsQUY5bgsxpHesBEcIWJloWVTFnrMXnf/TL30eTFSGJddmQAng==" + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "memory-fs": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", + "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "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" + } + }, + "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==" + }, + "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==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" + }, + "micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, + "mime-db": { + "version": "1.47.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", + "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==" + }, + "mime-types": { + "version": "2.1.30", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", + "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", + "requires": { + "mime-db": "1.47.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "mkdirp": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz", + "integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==", + "requires": { + "minimist": "^1.2.5" + } + }, + "mocha": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.3.tgz", + "integrity": "sha512-0R/3FvjIGH3eEuG17ccFPk117XL2rWxatr81a57D+r/x2uTYZRbdZ4oVidEUMh2W2TJDa7MdAb12Lm2/qrKajg==", + "requires": { + "ansi-colors": "3.2.3", + "browser-stdout": "1.3.1", + "debug": "3.2.6", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "find-up": "3.0.0", + "glob": "7.1.3", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.13.1", + "log-symbols": "2.2.0", + "minimatch": "3.0.4", + "mkdirp": "0.5.4", + "ms": "2.1.1", + "node-environment-flags": "1.0.5", + "object.assign": "4.1.0", + "strip-json-comments": "2.0.1", + "supports-color": "6.0.0", + "which": "1.3.1", + "wide-align": "1.1.3", + "yargs": "13.3.2", + "yargs-parser": "13.1.2", + "yargs-unparser": "1.6.0" + }, + "dependencies": { + "ansi-colors": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", + "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==" + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "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==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "requires": { + "chalk": "^2.0.1" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + }, + "supports-color": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", + "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "mri": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.1.6.tgz", + "integrity": "sha512-oi1b3MfbyGa7FJMP9GmLTttni5JoICpYBRlq+x5V16fZbLsnL9N3wFqqIm/nIG43FjUFkFh9Epzp/kzUGUnJxQ==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "multimatch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-3.0.0.tgz", + "integrity": "sha512-22foS/gqQfANZ3o+W7ST2x25ueHDVNWl/b9OlGcLpy/iKxjCpvcNCM51YCenUi7Mt/jAjjqv8JwZRs8YP5sRjA==", + "requires": { + "array-differ": "^2.0.3", + "array-union": "^1.0.2", + "arrify": "^1.0.1", + "minimatch": "^3.0.4" + }, + "dependencies": { + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "requires": { + "array-uniq": "^1.0.1" + } + } + } + }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" + }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + }, + "node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" + }, + "node-environment-flags": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", + "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==", + "requires": { + "object.getownpropertydescriptors": "^2.0.3", + "semver": "^5.7.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" + }, + "node-gyp-build": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", + "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==" + }, + "node-preload": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", + "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", + "requires": { + "process-on-spawn": "^1.0.0" + } + }, + "node-releases": { + "version": "1.1.71", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz", + "integrity": "sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==" + }, + "nodemon": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.7.tgz", + "integrity": "sha512-XHzK69Awgnec9UzHr1kc8EomQh4sjTQ8oRf8TsGrSmHDx9/UmiGG9E/mM3BuTfNeFwdNBvrqQq/RHL0xIeyFOA==", + "requires": { + "chokidar": "^3.2.2", + "debug": "^3.2.6", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.0.4", + "pstree.remy": "^1.1.7", + "semver": "^5.7.1", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.3", + "update-notifier": "^4.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "requires": { + "abbrev": "1" + } + }, + "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==", + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "normalize-url": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", + "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", + "requires": { + "object-assign": "^4.0.1", + "prepend-http": "^1.0.0", + "query-string": "^4.1.0", + "sort-keys": "^1.0.0" + } + }, + "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==", + "requires": { + "path-key": "^3.0.0" + } + }, + "nyc": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", + "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", + "requires": { + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "caching-transform": "^4.0.0", + "convert-source-map": "^1.7.0", + "decamelize": "^1.2.0", + "find-cache-dir": "^3.2.0", + "find-up": "^4.1.0", + "foreground-child": "^2.0.0", + "get-package-type": "^0.1.0", + "glob": "^7.1.6", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-hook": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-processinfo": "^2.0.2", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "make-dir": "^3.0.0", + "node-preload": "^0.2.1", + "p-map": "^3.0.0", + "process-on-spawn": "^1.0.0", + "resolve-from": "^5.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "spawn-wrap": "^2.0.0", + "test-exclude": "^6.0.0", + "yargs": "^15.0.2" + }, + "dependencies": { + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-inspect": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.2.tgz", + "integrity": "sha512-gz58rdPpadwztRrPjZE9DZLOABUpTGdcANUgOwBFO1C+HZZhePoP83M65WGDmbpwFYJSWqavbl4SgDn4k8RYTA==" + }, + "object-is": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", + "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "object.getownpropertydescriptors": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz", + "integrity": "sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "opencollective-postinstall": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz", + "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==" + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==" + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "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==", + "requires": { + "p-limit": "^2.2.0" + }, + "dependencies": { + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + } + } + }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "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==" + }, + "package-hash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", + "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", + "requires": { + "graceful-fs": "^4.1.15", + "hasha": "^5.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + } + }, + "package-json": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", + "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", + "requires": { + "got": "^9.6.0", + "registry-auth-token": "^4.0.0", + "registry-url": "^5.0.0", + "semver": "^6.2.0" + }, + "dependencies": { + "@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==" + }, + "@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "requires": { + "defer-to-connect": "^1.0.1" + } + }, + "cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "dependencies": { + "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==", + "requires": { + "pump": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" + } + } + }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "requires": { + "mimic-response": "^1.0.0" + } + }, + "defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==" + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "requires": { + "pump": "^3.0.0" + } + }, + "got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "requires": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + } + }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" + }, + "keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "requires": { + "json-buffer": "3.0.0" + } + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" + }, + "normalize-url": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==" + }, + "p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==" + }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "requires": { + "lowercase-keys": "^1.0.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-asn1": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "requires": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "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==", + "requires": { + "@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" + } + }, + "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==" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" + }, + "pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==" + }, + "pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "picomatch": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", + "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==" + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "requires": { + "pinkie": "^2.0.0" + } + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "requires": { + "find-up": "^4.0.0" + } + }, + "please-upgrade-node": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", + "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", + "requires": { + "semver-compare": "^1.0.0" + } + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" + }, + "prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" + }, + "prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==" + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "requires": { + "fast-diff": "^1.1.2" + } + }, + "pretty-quick": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-1.11.1.tgz", + "integrity": "sha512-kSXCkcETfak7EQXz6WOkCeCqpbC4GIzrN/vaneTGMP/fAtD8NerA9bPhCUqHAks1geo7biZNl5uEMPceeneLuA==", + "requires": { + "chalk": "^2.3.0", + "execa": "^0.8.0", + "find-up": "^2.1.0", + "ignore": "^3.3.7", + "mri": "^1.1.0", + "multimatch": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "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==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.8.0.tgz", + "integrity": "sha1-2NdrvBtVIX7RkP1t1J08d07PyNo=", + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "requires": { + "locate-path": "^2.0.0" + } + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==" + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "requires": { + "path-key": "^2.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + } + } + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" + }, + "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==" + }, + "process-on-spawn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", + "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", + "requires": { + "fromentries": "^1.2.0" + } + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==" + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "pupa": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", + "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", + "requires": { + "escape-goat": "^2.0.0" + } + }, + "query-string": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", + "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", + "requires": { + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + } + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" + }, + "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==" + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + } + } + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "requires": { + "picomatch": "^2.2.1" + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "requires": { + "resolve": "^1.1.6" + } + }, + "reflect-metadata": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", + "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" + }, + "regexpp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==" + }, + "regextras": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/regextras/-/regextras-0.7.1.tgz", + "integrity": "sha512-9YXf6xtW+qzQ+hcMQXx95MOvfqXFgsKDZodX3qZB0x2n5Z94ioetIITsBtvJbiOyxa/6s9AtyweBLCdPmPko/w==" + }, + "registry-auth-token": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", + "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", + "requires": { + "rc": "^1.2.8" + } + }, + "registry-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", + "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", + "requires": { + "rc": "^1.2.8" + } + }, + "release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", + "requires": { + "es6-error": "^4.0.1" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" + }, + "resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "resolve-alpn": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.1.2.tgz", + "integrity": "sha512-8OyfzhAtA32LVUsJSke3auIyINcwdh5l3cvYKdKO0nvsYSKuiLfTM5i78PJswFPT8y6cPW+L1v6/hE95chcpDA==" + }, + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "requires": { + "resolve-from": "^5.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" + } + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" + }, + "responselike": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", + "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", + "requires": { + "lowercase-keys": "^2.0.0" + } + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "requires": { + "glob": "^7.1.3" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "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==", + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "requires": { + "tslib": "^1.9.0" + } + }, + "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==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "schema-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", + "requires": { + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + }, + "scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" + }, + "secp256k1": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz", + "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==", + "requires": { + "elliptic": "^6.5.2", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=" + }, + "semver-diff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", + "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", + "requires": { + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "semver-regex": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-3.1.2.tgz", + "integrity": "sha512-bXWyL6EAKOJa81XG1OZ/Yyuq+oT0b2YLlxx7c+mrdYPaPbnj6WgVULXhinMIeZGufuUBu/eVRqXEhiv4imfwxA==" + }, + "serialize-javascript": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "requires": { + "randombytes": "^2.1.0" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "requires": { + "kind-of": "^6.0.2" + } + }, + "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==", + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + }, + "shelljs": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz", + "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==", + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + } + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + }, + "sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", + "requires": { + "is-plain-obj": "^1.0.0" + } + }, + "source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "spawn-command": { + "version": "0.0.2-1", + "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", + "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=" + }, + "spawn-wrap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", + "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", + "requires": { + "foreground-child": "^2.0.0", + "is-windows": "^1.0.2", + "make-dir": "^3.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "which": "^2.0.1" + }, + "dependencies": { + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==" + }, + "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==", + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz", + "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==" + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "stream-browserify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", + "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", + "requires": { + "inherits": "~2.0.4", + "readable-stream": "^3.5.0" + } + }, + "stream-http": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz", + "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==", + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "xtend": "^4.0.2" + } + }, + "strict-event-emitter-types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strict-event-emitter-types/-/strict-event-emitter-types-2.0.0.tgz", + "integrity": "sha512-Nk/brWYpD85WlOgzw5h173aci0Teyv8YdIAEtV+N88nDB0dLlazZyJMIsN6eo1/AR61l+p6CJTG1JIyFaoNEEA==" + }, + "strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" + }, + "string-argv": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", + "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==" + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "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==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "requires": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" + }, + "strip-outer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", + "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", + "requires": { + "escape-string-regexp": "^1.0.2" + } + }, + "strip-url-auth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-url-auth/-/strip-url-auth-1.0.1.tgz", + "integrity": "sha1-IrD6OkE4WzO+PzMVUbu4N/oM164=" + }, + "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==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "table": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/table/-/table-6.3.2.tgz", + "integrity": "sha512-I9/Ca6Huf2oxFag7crD0DhA+arIdfLtWunSn0NIXSzjtUlDgIBGVZY7SsMkNPNT3Psd/z4gza0nuEpmra9eRbg==", + "requires": { + "ajv": "^8.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "lodash.clonedeep": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0" + }, + "dependencies": { + "ajv": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.1.0.tgz", + "integrity": "sha512-B/Sk2Ix7A36fs/ZkuGLIR86EdjbgR6fsAcbx9lOP/QBSXujDNbVmIS/U4Itz5k8fPFDeVZl/zQ/gJW4Jrq6XjQ==", + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + } + } + }, + "tapable": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", + "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==" + }, + "term-size": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", + "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==" + }, + "terser": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.6.1.tgz", + "integrity": "sha512-yv9YLFQQ+3ZqgWCUk+pvNJwgUTdlIxUk1WTN+RnaFJe2L7ipG2csPT0ra2XRm7Cs8cxN7QXmK1rFzEwYEQkzXw==", + "requires": { + "commander": "^2.20.0", + "source-map": "~0.7.2", + "source-map-support": "~0.5.19" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" + } + } + }, + "terser-webpack-plugin": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.1.tgz", + "integrity": "sha512-5XNNXZiR8YO6X6KhSGXfY0QrGrCRlSwAEjIIrlRQR4W8nP69TaJUlh3bkuac6zzgspiGPfKEHcY295MMVExl5Q==", + "requires": { + "jest-worker": "^26.6.2", + "p-limit": "^3.1.0", + "schema-utils": "^3.0.0", + "serialize-javascript": "^5.0.1", + "source-map": "^0.6.1", + "terser": "^5.5.1" + } + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" + }, + "to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==" + }, + "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==", + "requires": { + "is-number": "^7.0.0" + } + }, + "touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "requires": { + "nopt": "~1.0.10" + } + }, + "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==" + }, + "trim-repeated": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", + "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=", + "requires": { + "escape-string-regexp": "^1.0.2" + } + }, + "ts-loader": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-8.1.0.tgz", + "integrity": "sha512-YiQipGGAFj2zBfqLhp28yUvPP9jUGqHxRzrGYuc82Z2wM27YIHbElXiaZDc93c3x0mz4zvBmS6q/DgExpdj37A==", + "requires": { + "chalk": "^4.1.0", + "enhanced-resolve": "^4.0.0", + "loader-utils": "^2.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4" + }, + "dependencies": { + "enhanced-resolve": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz", + "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==", + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.5.0", + "tapable": "^1.0.0" + } + }, + "tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==" + } + } + }, + "ts-node": { + "version": "8.10.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz", + "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==", + "requires": { + "arg": "^4.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.17", + "yn": "3.1.1" + }, + "dependencies": { + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" + } + } + }, + "ts-protoc-gen": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/ts-protoc-gen/-/ts-protoc-gen-0.10.0.tgz", + "integrity": "sha512-EEbgDWNHK3CvcNhmib94I4HMO23qLddjLRdXW8EUE11VJxbi3n5J0l2DiX/L1pijOaPTkbEoRK+zQinKgKGqsw==", + "requires": { + "google-protobuf": "^3.6.1" + } + }, + "ts-results": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ts-results/-/ts-results-3.2.1.tgz", + "integrity": "sha512-cMvWPLvxM39fSQgSHRT2d+dwQfpK+ttfj5FpPuXum9m/pm6iDmgsirpWXp/3/ErmZqx1x+rAhJi/33NQqCCM3Q==" + }, + "tsconfig-paths": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", + "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "requires": { + "minimist": "^1.2.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" + } + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "tslint": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz", + "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==", + "requires": { + "@babel/code-frame": "^7.0.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^4.0.1", + "glob": "^7.1.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.3", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.13.0", + "tsutils": "^2.29.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "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==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "requires": { + "tslib": "^1.8.1" + } + } + } + }, + "tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "requires": { + "tslib": "^1.8.1" + } + }, + "tweetnacl-ts": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl-ts/-/tweetnacl-ts-1.0.3.tgz", + "integrity": "sha512-C5I/dWf6xjAXaCDlf84T4HvozU/8ycAlq5WRllF1hAeeq5390tfXD+bNas5bhEV0HMSOx8bsQYpLjPl8wfnEeQ==", + "requires": { + "tslib": "^1" + } + }, + "tweetnacl-util": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", + "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==" + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" + }, + "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==" + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "typedjson": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/typedjson/-/typedjson-1.7.0.tgz", + "integrity": "sha512-MnRgQLwtEcdHqQG0FkT8ebpBG53Wgr/axYRbiD2WL5NcYx8Z2AoCpXvtTfLnuPqOBKG/9JpXq0O/nl2m4wqJYw==", + "requires": { + "tslib": "^2.0.1" + }, + "dependencies": { + "tslib": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" + } + } + }, + "typedoc": { + "version": "0.17.8", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.17.8.tgz", + "integrity": "sha512-/OyrHCJ8jtzu+QZ+771YaxQ9s4g5Z3XsQE3Ma7q+BL392xxBn4UMvvCdVnqKC2T/dz03/VXSLVKOP3lHmDdc/w==", + "requires": { + "fs-extra": "^8.1.0", + "handlebars": "^4.7.6", + "highlight.js": "^10.0.0", + "lodash": "^4.17.15", + "lunr": "^2.3.8", + "marked": "1.0.0", + "minimatch": "^3.0.0", + "progress": "^2.0.3", + "shelljs": "^0.8.4", + "typedoc-default-themes": "^0.10.2" + } + }, + "typedoc-default-themes": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/typedoc-default-themes/-/typedoc-default-themes-0.10.2.tgz", + "integrity": "sha512-zo09yRj+xwLFE3hyhJeVHWRSPuKEIAsFK5r2u47KL/HBKqpwdUSanoaz5L34IKiSATFrjG5ywmIu98hPVMfxZg==", + "requires": { + "lunr": "^2.3.8" + } + }, + "typescript": { + "version": "3.9.9", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.9.tgz", + "integrity": "sha512-kdMjTiekY+z/ubJCATUPlRDl39vXYiMV9iyeMuEuXZh2we6zz80uovNN2WlAxmmdE/Z/YQe+EbOEXB5RHEED3w==" + }, + "uglify-js": { + "version": "3.13.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.4.tgz", + "integrity": "sha512-kv7fCkIXyQIilD5/yQy8O+uagsYIOt5cZvs890W40/e/rvjMSzJw81o9Bg0tkURxzZBROtDQhW2LFjOGoK3RZw==", + "optional": true + }, + "unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "requires": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + } + }, + "undefsafe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz", + "integrity": "sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==", + "requires": { + "debug": "^2.2.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "requires": { + "crypto-random-string": "^2.0.0" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "update-notifier": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", + "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==", + "requires": { + "boxen": "^4.2.0", + "chalk": "^3.0.0", + "configstore": "^5.0.1", + "has-yarn": "^2.1.0", + "import-lazy": "^2.1.0", + "is-ci": "^2.0.0", + "is-installed-globally": "^0.3.1", + "is-npm": "^4.0.0", + "is-yarn-global": "^0.3.0", + "latest-version": "^5.0.0", + "pupa": "^2.0.1", + "semver-diff": "^3.1.1", + "xdg-basedir": "^4.0.0" + }, + "dependencies": { + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "requires": { + "punycode": "^2.1.0" + } + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" + } + } + }, + "url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "requires": { + "prepend-http": "^2.0.0" + }, + "dependencies": { + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" + } + } + }, + "util": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.3.tgz", + "integrity": "sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog==", + "requires": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "safe-buffer": "^5.1.2", + "which-typed-array": "^1.1.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + }, + "v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==" + }, + "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==", + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "watchpack": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.1.1.tgz", + "integrity": "sha512-Oo7LXCmc1eE1AjyuSBmtC3+Wy4HcV8PxWh2kP6fOl8yTlNS7r0K9l1ao2lrrUza7V39Y3D/BbJgY8VeSlc5JKw==", + "requires": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + } + }, + "webpack": { + "version": "5.35.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.35.0.tgz", + "integrity": "sha512-au3gu55yYF/h6NXFr0KZPZAYxS6Nlc595BzYPke8n0CSff5WXcoixtjh5LC/8mXunkRKxhymhXmBY0+kEbR6jg==", + "requires": { + "@types/eslint-scope": "^3.7.0", + "@types/estree": "^0.0.47", + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/wasm-edit": "1.11.0", + "@webassemblyjs/wasm-parser": "1.11.0", + "acorn": "^8.0.4", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.8.0", + "es-module-lexer": "^0.4.0", + "eslint-scope": "^5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.4", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.0.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.1.1", + "watchpack": "^2.0.0", + "webpack-sources": "^2.1.1" + } + }, + "webpack-cli": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.6.0.tgz", + "integrity": "sha512-9YV+qTcGMjQFiY7Nb1kmnupvb1x40lfpj8pwdO/bom+sQiP4OBMKjHq29YQrlDWDPZO9r/qWaRRywKaRDKqBTA==", + "requires": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^1.0.2", + "@webpack-cli/info": "^1.2.3", + "@webpack-cli/serve": "^1.3.1", + "colorette": "^1.2.1", + "commander": "^7.0.0", + "enquirer": "^2.3.6", + "execa": "^5.0.0", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^2.2.0", + "rechoir": "^0.7.0", + "v8-compile-cache": "^2.2.0", + "webpack-merge": "^5.7.3" + }, + "dependencies": { + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==" + }, + "execa": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.0.0.tgz", + "integrity": "sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==", + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + } + }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==" + }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==" + }, + "interpret": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", + "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==" + }, + "rechoir": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.0.tgz", + "integrity": "sha512-ADsDEH2bvbjltXEP+hTIAmeFekTFK0V2BTxMkok6qILyAJEXV0AFfoWcAq4yfll5VdIMd/RVXq0lR+wQi5ZU3Q==", + "requires": { + "resolve": "^1.9.0" + } + } + } + }, + "webpack-merge": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.7.3.tgz", + "integrity": "sha512-6/JUQv0ELQ1igjGDzHkXbVDRxkfA57Zw7PfiupdLFJYrgFqY5ZP8xxbpp2lU3EPwYx89ht5Z/aDkD40hFCm5AA==", + "requires": { + "clone-deep": "^4.0.1", + "wildcard": "^2.0.0" + } + }, + "webpack-node-externals": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/webpack-node-externals/-/webpack-node-externals-2.5.2.tgz", + "integrity": "sha512-aHdl/y2N7PW2Sx7K+r3AxpJO+aDMcYzMQd60Qxefq3+EwhewSbTBqNumOsCE1JsCUNoyfGj5465N0sSf6hc/5w==" + }, + "webpack-sources": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.2.0.tgz", + "integrity": "sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w==", + "requires": { + "source-list-map": "^2.0.1", + "source-map": "^0.6.1" + } + }, + "whatwg-fetch": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", + "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==" + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "requires": { + "isexe": "^2.0.0" + } + }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + }, + "which-pm-runs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", + "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=" + }, + "which-typed-array": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.4.tgz", + "integrity": "sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA==", + "requires": { + "available-typed-arrays": "^1.0.2", + "call-bind": "^1.0.0", + "es-abstract": "^1.18.0-next.1", + "foreach": "^2.0.5", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.1", + "is-typed-array": "^1.1.3" + } + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "requires": { + "string-width": "^1.0.2 || 2" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "requires": { + "string-width": "^4.0.0" + } + }, + "wildcard": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", + "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==" + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" + }, + "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==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "ws": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz", + "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==" + }, + "xdg-basedir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==" + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "requires": { + "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" + } + }, + "yargs-parser": { + "version": "20.2.7", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz", + "integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==" + }, + "yargs-unparser": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", + "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "requires": { + "flat": "^4.1.0", + "lodash": "^4.17.15", + "yargs": "^13.3.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "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==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" + }, + "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==" + } + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "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==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" + }, + "dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "is-core-module": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", + "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", + "requires": { + "has": "^1.0.3" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "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==" + }, + "prettier": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz", + "integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==" + }, + "resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "ts-node": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.0.0.tgz", + "integrity": "sha512-ROWeOIUvfFbPZkoDis0L/55Fk+6gFQNZwwKPLinacRl6tsxstTF1DbAcLKkovwnpKMVvOMHP1TIbnwXwtLg1gg==", + "requires": { + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.17", + "yn": "3.1.1" + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "tslint": { + "version": "5.20.1", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.20.1.tgz", + "integrity": "sha512-EcMxhzCFt8k+/UP5r8waCf/lzmeSyVlqxqMEDQE7rWYiQky8KpIBz1JAoYXfROHrPZ1XXd43q8yQnULOLiBRQg==", + "requires": { + "@babel/code-frame": "^7.0.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^4.0.1", + "glob": "^7.1.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.8.0", + "tsutils": "^2.29.0" + } + }, + "tslint-config-prettier": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz", + "integrity": "sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==" + }, + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "requires": { + "tslib": "^1.8.1" + } + }, + "typescript": { + "version": "3.9.10", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", + "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" + } } }, "casper-js-sdk": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/casper-js-sdk/-/casper-js-sdk-2.1.0.tgz", - "integrity": "sha512-fUfTVUs7Kdvsg+yq474+wYD9tvwHhRXmmBuHjkRuPoCUzY8DeAw/CjbYfQb5Ztq+MDRtd2QqcstadZA7RDeOug==", + "version": "file:../../casper-js-sdk", "requires": { "@ethersproject/bignumber": "^5.0.8", "@ethersproject/bytes": "^5.0.5", "@ethersproject/constants": "^5.0.5", "@open-rpc/client-js": "^1.6.2", "@types/eccrypto": "^1.1.2", - "axios": "^0.21.1", "blakejs": "^1.1.0", "eccrypto": "^1.1.6", "eslint-plugin-prettier": "^3.4.0", "ethereum-cryptography": "^0.1.3", "glob": "^7.1.6", "humanize-duration": "^3.24.0", - "jsbi": "^3.1.2", "key-encoder": "^2.0.3", "reflect-metadata": "^0.1.13", - "rxjs": "^6.5.3", "ts-results": "^3.2.1", "tweetnacl-ts": "^1.0.3", "tweetnacl-util": "^0.15.0", "typedjson": "^1.6.0-rc2", "webpack": "^5.24.3" - } - }, - "chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==" - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "colorette": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", - "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==" - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "drbg.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", - "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", - "optional": true, - "requires": { - "browserify-aes": "^1.0.6", - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4" - } - }, - "eccrypto": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/eccrypto/-/eccrypto-1.1.6.tgz", - "integrity": "sha512-d78ivVEzu7Tn0ZphUUaL43+jVPKTMPFGtmgtz1D0LrFn7cY3K8CdrvibuLz2AAkHBLKZtR8DMbB2ukRYFk987A==", - "requires": { - "acorn": "7.1.1", - "elliptic": "6.5.4", - "es6-promise": "4.2.8", - "nan": "2.14.0", - "secp256k1": "3.7.1" - } - }, - "electron-to-chromium": { - "version": "1.3.780", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.780.tgz", - "integrity": "sha512-2KQ9OYm9WMUNpAPA/4aerURl3hwRc9tNlpsiEj3Y8Gf7LVf26NzyLIX2v0hSagQwrS9+cWab+28A2GPKDoVNRA==" - }, - "elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "requires": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "enhanced-resolve": { - "version": "5.8.2", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz", - "integrity": "sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==", - "requires": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - } - }, - "es-module-lexer": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.7.1.tgz", - "integrity": "sha512-MgtWFl5No+4S3TmhDmCz2ObFGm6lEpTnzbQi+Dd+pw4mlTIZTmM2iAs5gRlmx5zS9luzobCSBSI90JM/1/JgOw==" - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" - }, - "eslint-plugin-prettier": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.0.tgz", - "integrity": "sha512-UDK6rJT6INSfcOo545jiaOwB701uAIt2/dR7WnFQoGCVl1/EMqdANBmwUaqqQ45aXprsTGzSa39LI1PyuRBxxw==", - "requires": { - "prettier-linter-helpers": "^1.0.0" - } - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "requires": { - "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==" - } - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" - }, - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" }, "dependencies": { - "secp256k1": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz", - "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==", + "@babel/code-frame": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", + "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", "requires": { - "elliptic": "^6.5.2", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" + "@babel/highlight": "^7.12.13" } - } - } - }, - "events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==" - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "optional": true - }, - "follow-redirects": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz", - "integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==" - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" - }, - "graceful-fs": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "humanize-duration": { - "version": "3.27.0", - "resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.27.0.tgz", - "integrity": "sha512-qLo/08cNc3Tb0uD7jK0jAcU5cnqCM0n568918E7R2XhMr/+7F37p4EY062W/stg7tmzvknNn9b/1+UhVRzsYrQ==" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "isomorphic-fetch": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", - "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", - "requires": { - "node-fetch": "^2.6.1", - "whatwg-fetch": "^3.4.1" - } - }, - "isomorphic-ws": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", - "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==" - }, - "jest-worker": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.0.6.tgz", - "integrity": "sha512-qupxcj/dRuA3xHPMUd40gr2EaAurFbkwzOh7wfPaeE9id7hyjURRQoqNfHifHK3XjJU6YJJUQKILGUnwGPEOCA==", - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - } - }, - "jsbi": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/jsbi/-/jsbi-3.1.5.tgz", - "integrity": "sha512-w2BY0VOYC1ahe+w6Qhl4SFoPvPsZ9NPHY4bwass+LCgU7RK3PBoVQlQ3G1s7vI8W3CYyJiEXcbKF7FIM/L8q3Q==" - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "keccak": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.1.tgz", - "integrity": "sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA==", - "requires": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - } - }, - "key-encoder": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/key-encoder/-/key-encoder-2.0.3.tgz", - "integrity": "sha512-fgBtpAGIr/Fy5/+ZLQZIPPhsZEcbSlYu/Wu96tNDFNSjSACw5lEIOFeaVdQ/iwrb8oxjlWi6wmWdH76hV6GZjg==", - "requires": { - "@types/elliptic": "^6.4.9", - "asn1.js": "^5.0.1", - "bn.js": "^4.11.8", - "elliptic": "^6.4.1" - } - }, - "loader-runner": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", - "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==" - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, - "mime-db": { - "version": "1.48.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", - "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==" - }, - "mime-types": { - "version": "2.1.31", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", - "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", - "requires": { - "mime-db": "1.48.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "nan": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" - }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" - }, - "node-addon-api": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" - }, - "node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" - }, - "node-gyp-build": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", - "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==" - }, - "node-releases": { - "version": "1.1.73", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz", - "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==" - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "requires": { - "fast-diff": "^1.1.2" - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "reflect-metadata": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", - "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "requires": { - "tslib": "^1.9.0" - } - }, - "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==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", - "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - }, - "scrypt-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" - }, - "secp256k1": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.7.1.tgz", - "integrity": "sha512-1cf8sbnRreXrQFdH6qsg2H71Xw91fCCS9Yp021GnUNJzWJS/py96fS4lHbnTnouLp08Xj6jBoBB6V78Tdbdu5g==", - "optional": true, - "requires": { - "bindings": "^1.5.0", - "bip66": "^1.1.5", - "bn.js": "^4.11.8", - "create-hash": "^1.2.0", - "drbg.js": "^1.0.1", - "elliptic": "^6.4.1", - "nan": "^2.14.0", - "safe-buffer": "^5.1.2" - } - }, - "serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "requires": { - "randombytes": "^2.1.0" - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "strict-event-emitter-types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strict-event-emitter-types/-/strict-event-emitter-types-2.0.0.tgz", - "integrity": "sha512-Nk/brWYpD85WlOgzw5h173aci0Teyv8YdIAEtV+N88nDB0dLlazZyJMIsN6eo1/AR61l+p6CJTG1JIyFaoNEEA==" - }, - "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==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "requires": { - "has-flag": "^4.0.0" - } - }, - "tapable": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", - "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==" - }, - "terser": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.7.1.tgz", - "integrity": "sha512-b3e+d5JbHAe/JSjwsC3Zn55wsBIM7AsHLjKxT31kGCldgbpFePaFo+PiddtO6uwRZWRw7sPXmAN8dTW61xmnSg==", - "requires": { - "commander": "^2.20.0", - "source-map": "~0.7.2", - "source-map-support": "~0.5.19" - }, - "dependencies": { + }, + "@babel/compat-data": { + "version": "7.13.15", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.13.15.tgz", + "integrity": "sha512-ltnibHKR1VnrU4ymHyQ/CXtNXI6yZC0oJThyW78Hft8XndANwi+9H+UIklBDraIjFEJzw8wmcM427oDd9KS5wA==" + }, + "@babel/core": { + "version": "7.13.16", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.16.tgz", + "integrity": "sha512-sXHpixBiWWFti0AV2Zq7avpTasr6sIAu7Y396c608541qAU2ui4a193m0KSQmfPSKFZLnQ3cvlKDOm3XkuXm3Q==", + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.13.16", + "@babel/helper-compilation-targets": "^7.13.16", + "@babel/helper-module-transforms": "^7.13.14", + "@babel/helpers": "^7.13.16", + "@babel/parser": "^7.13.16", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.15", + "@babel/types": "^7.13.16", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + }, + "dependencies": {} + }, + "@babel/helper-compilation-targets": { + "version": "7.13.16", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz", + "integrity": "sha512-3gmkYIrpqsLlieFwjkGgLaSHmhnvlAYzZLlYVjlW+QwI+1zE17kGxuJGmIqDQdYp56XdmGeD+Bswx0UTyG18xA==", + "requires": { + "@babel/compat-data": "^7.13.15", + "@babel/helper-validator-option": "^7.12.17", + "browserslist": "^4.14.5", + "semver": "^6.3.0" + }, + "dependencies": {} + }, + "@babel/helper-function-name": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", + "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", + "requires": { + "@babel/helper-get-function-arity": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", + "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz", + "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==", + "requires": { + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-module-imports": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz", + "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==", + "requires": { + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-module-transforms": { + "version": "7.13.14", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.13.14.tgz", + "integrity": "sha512-QuU/OJ0iAOSIatyVZmfqB0lbkVP0kDRiKj34xy+QNsnVZi/PA6BoSoreeqnxxa9EHFAIL0R9XOaAR/G9WlIy5g==", + "requires": { + "@babel/helper-module-imports": "^7.13.12", + "@babel/helper-replace-supers": "^7.13.12", + "@babel/helper-simple-access": "^7.13.12", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/helper-validator-identifier": "^7.12.11", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.13", + "@babel/types": "^7.13.14" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", + "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-replace-supers": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz", + "integrity": "sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw==", + "requires": { + "@babel/helper-member-expression-to-functions": "^7.13.12", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-simple-access": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz", + "integrity": "sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==", + "requires": { + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", + "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==" + }, + "@babel/helper-validator-option": { + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz", + "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==" + }, + "@babel/helpers": { + "version": "7.13.17", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.13.17.tgz", + "integrity": "sha512-Eal4Gce4kGijo1/TGJdqp3WuhllaMLSrW6XcL0ulyUAQOuxHcCafZE8KHg9857gcTehsm/v7RcOx2+jp0Ryjsg==", + "requires": { + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.17", + "@babel/types": "^7.13.17" + } + }, + "@babel/highlight": { + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.10.tgz", + "integrity": "sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg==", + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": {} + }, + "@babel/parser": { + "version": "7.13.16", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.16.tgz", + "integrity": "sha512-6bAg36mCwuqLO0hbR+z7PHuqWiCeP7Dzg73OpQwsAB1Eb8HnGEz5xYBzCfbu+YjoaJsJs+qheDxVAuqbt3ILEw==" + }, + "@babel/template": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", + "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "@babel/traverse": { + "version": "7.13.17", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.17.tgz", + "integrity": "sha512-BMnZn0R+X6ayqm3C3To7o1j7Q020gWdqdyP50KEoVqaCO2c/Im7sYZSmVgvefp8TTMQ+9CtwuBp0Z1CZ8V3Pvg==", + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.13.16", + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/parser": "^7.13.16", + "@babel/types": "^7.13.17", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "dependencies": {} + }, + "@babel/types": { + "version": "7.13.17", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.17.tgz", + "integrity": "sha512-RawydLgxbOPDlTLJNtoIypwdmAy//uQIzlKt2+iBiJaRlVuI6QLUxVAyWGNfOzp8Yu4L4lLIacoCyTNtpb4wiA==", + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", + "to-fast-properties": "^2.0.0" + } + }, + "@discoveryjs/json-ext": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz", + "integrity": "sha512-HyYEUDeIj5rRQU2Hk5HTB2uHsbRQpF70nvMhVzi+VJR0X+xNEhjPui4/kBf3VeH/wqD28PT4sVOm8qqLjBrSZg==" + }, + "@eslint/eslintrc": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.0.tgz", + "integrity": "sha512-2ZPCc+uNbjV5ERJr+aKSPRwZgKd2z11x0EgLvb1PURmUrn9QNRXFqje0Ldq454PfAVyaJYyrDvvIKSFP4NnBog==", + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": {} + }, + "@ethersproject/bignumber": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.1.1.tgz", + "integrity": "sha512-AVz5iqz7+70RIqoQTznsdJ6DOVBYciNlvO+AlQmPTB6ofCvoihI9bQdr6wljsX+d5W7Yc4nyvQvP4JMzg0Agig==", + "requires": { + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "bn.js": "^4.4.0" + } + }, + "@ethersproject/bytes": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.1.0.tgz", + "integrity": "sha512-sGTxb+LVjFxJcJeUswAIK6ncgOrh3D8c192iEJd7mLr95V6du119rRfYT/b87WPkZ5I3gRBUYIYXtdgCWACe8g==", + "requires": { + "@ethersproject/logger": "^5.1.0" + } + }, + "@ethersproject/constants": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.1.0.tgz", + "integrity": "sha512-0/SuHrxc8R8k+JiLmJymxHJbojUDWBQqO+b+XFdwaP0jGzqC09YDy/CAlSZB6qHsBifY8X3I89HcK/oMqxRdBw==", + "requires": { + "@ethersproject/bignumber": "^5.1.0" + } + }, + "@ethersproject/logger": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.1.0.tgz", + "integrity": "sha512-wtUaD1lBX10HBXjjKV9VHCBnTdUaKQnQ2XSET1ezglqLdPdllNOIlLfhyCRqXm5xwcjExVI5ETokOYfjPtaAlw==" + }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "dependencies": {} + }, + "@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==" + }, + "@nodelib/fs.scandir": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", + "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==", + "requires": { + "@nodelib/fs.stat": "2.0.4", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz", + "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==" + }, + "@nodelib/fs.walk": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz", + "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==", + "requires": { + "@nodelib/fs.scandir": "2.1.4", + "fastq": "^1.6.0" + } + }, + "@open-rpc/client-js": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@open-rpc/client-js/-/client-js-1.6.3.tgz", + "integrity": "sha512-KNlYB258FgMUopHUXqPAU4JZMAO/8HnGN7LcL/mXnwH/Qcd0GAMVwLLIXc5d9BBqtmDox8wxxAXGBCajRhyczA==", + "requires": { + "isomorphic-fetch": "^3.0.0", + "isomorphic-ws": "^4.0.1", + "strict-event-emitter-types": "^2.0.0", + "ws": "^7.0.0" + } + }, + "@sindresorhus/is": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.0.1.tgz", + "integrity": "sha512-Qm9hBEBu18wt1PO2flE7LPb30BHMQt1eQgbV76YntdNk73XZGpn3izvGTYxbGgzXKgbCjiia0uxTd3aTNQrY/g==" + }, + "@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==", + "requires": { + "defer-to-connect": "^2.0.0" + } + }, + "@types/bn.js": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", + "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", + "requires": { + "@types/node": "*" + } + }, + "@types/body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==", + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/cacheable-request": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", + "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", + "requires": { + "@types/http-cache-semantics": "*", + "@types/keyv": "*", + "@types/node": "*", + "@types/responselike": "*" + } + }, + "@types/chai": { + "version": "4.2.16", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.16.tgz", + "integrity": "sha512-vI5iOAsez9+roLS3M3+Xx7w+WRuDtSmF8bQkrbcIJ2sC1PcDgVoA0WGpa+bIrJ+y8zqY2oi//fUctkxtIcXJCw==" + }, + "@types/connect": { + "version": "3.4.34", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz", + "integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==", + "requires": { + "@types/node": "*" + } + }, + "@types/eccrypto": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/eccrypto/-/eccrypto-1.1.2.tgz", + "integrity": "sha512-qmB/iGIoqDdCMHAcJiOKI4ZBI1Z3kBQGYQCkgNP/Z9ge5w/EVx5uxQYkGOFpllm6l2N/B3qXcn9vjqXGaV1vRQ==", + "requires": { + "@types/expect": "^1.20.4", + "@types/node": "*" + } + }, + "@types/elliptic": { + "version": "6.4.12", + "resolved": "https://registry.npmjs.org/@types/elliptic/-/elliptic-6.4.12.tgz", + "integrity": "sha512-gP1KsqoouLJGH6IJa28x7PXb3cRqh83X8HCLezd2dF+XcAIMKYv53KV+9Zn6QA561E120uOqZBQ+Jy/cl+fviw==", + "requires": { + "@types/bn.js": "*" + } + }, + "@types/eslint": { + "version": "7.2.10", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.10.tgz", + "integrity": "sha512-kUEPnMKrqbtpCq/KTaGFFKAcz6Ethm2EjCoKIDaCmfRBWLbFuTcOJfTlorwbnboXBzahqWLgUp1BQeKHiJzPUQ==", + "requires": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "@types/eslint-scope": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.0.tgz", + "integrity": "sha512-O/ql2+rrCUe2W2rs7wMR+GqPRcgB6UiqN5RhrR5xruFlY7l9YLMn0ZkDzjoHLeiFkR8MCQZVudUuuvQ2BLC9Qw==", + "requires": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "@types/estree": { + "version": "0.0.47", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.47.tgz", + "integrity": "sha512-c5ciR06jK8u9BstrmJyO97m+klJrrhCf9u3rLu3DEAJBirxRqSCvDQoYKmxuYwQI5SZChAWu+tq9oVlGRuzPAg==" + }, + "@types/expect": { + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/@types/expect/-/expect-1.20.4.tgz", + "integrity": "sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg==" + }, + "@types/express": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.11.tgz", + "integrity": "sha512-no+R6rW60JEc59977wIxreQVsIEOAYwgCqldrA/vkpCnbD7MqTefO97lmoBe4WE0F156bC4uLSP1XHDOySnChg==", + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.19.tgz", + "integrity": "sha512-DJOSHzX7pCiSElWaGR8kCprwibCB/3yW6vcT8VG3P0SJjnv19gnWG/AZMfM60Xj/YJIp/YCaDHyvzsFVeniARA==", + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, + "@types/http-cache-semantics": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", + "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" + }, + "@types/humanize-duration": { + "version": "3.18.1", + "resolved": "https://registry.npmjs.org/@types/humanize-duration/-/humanize-duration-3.18.1.tgz", + "integrity": "sha512-MUgbY3CF7hg/a/jogixmAufLjJBQT7WEf8Q+kYJkOc47ytngg1IuZobCngdTjAgY83JWEogippge5O5fplaQlw==" + }, + "@types/json-schema": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==" + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=" + }, + "@types/keyv": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.2.tgz", + "integrity": "sha512-/FvAK2p4jQOaJ6CGDHJTqZcUtbZe820qIeTg7o0Shg7drB4JHeL+V/dhSaly7NXx6u8eSee+r7coT+yuJEvDLg==", + "requires": { + "@types/node": "*" + } + }, + "@types/mime": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" + }, + "@types/mocha": { + "version": "5.2.7", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", + "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==" + }, + "@types/node": { + "version": "14.14.41", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.41.tgz", + "integrity": "sha512-dueRKfaJL4RTtSa7bWeTK1M+VH+Gns73oCgzvYfHZywRCoPSd8EkXBL0mZ9unPTveBn+D9phZBaxuzpwjWkW0g==" + }, + "@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==" + }, + "@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" + }, + "@types/pbkdf2": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", + "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", + "requires": { + "@types/node": "*" + } + }, + "@types/qs": { + "version": "6.9.6", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.6.tgz", + "integrity": "sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA==" + }, + "@types/range-parser": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", + "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==" + }, + "@types/responselike": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", + "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", + "requires": { + "@types/node": "*" + } + }, + "@types/secp256k1": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.2.tgz", + "integrity": "sha512-QMg+9v0bbNJ2peLuHRWxzmy0HRJIG6gFZNhaRSp7S3ggSbCCxiqQB2/ybvhXyhHOCequpNkrx7OavNhrWOsW0A==", + "requires": { + "@types/node": "*" + } + }, + "@types/serve-static": { + "version": "1.13.9", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.9.tgz", + "integrity": "sha512-ZFqF6qa48XsPdjXV5Gsz0Zqmux2PerNd3a/ktL45mHpa19cuMi/cL8tcxdAx497yRh+QtYPuofjT9oWw9P7nkA==", + "requires": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "@typescript-eslint/eslint-plugin": { + "version": "4.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.22.0.tgz", + "integrity": "sha512-U8SP9VOs275iDXaL08Ln1Fa/wLXfj5aTr/1c0t0j6CdbOnxh+TruXu1p4I0NAvdPBQgoPjHsgKn28mOi0FzfoA==", + "requires": { + "@typescript-eslint/experimental-utils": "4.22.0", + "@typescript-eslint/scope-manager": "4.22.0", + "debug": "^4.1.1", + "functional-red-black-tree": "^1.0.1", + "lodash": "^4.17.15", + "regexpp": "^3.0.0", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + } + }, + "@typescript-eslint/experimental-utils": { + "version": "4.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.22.0.tgz", + "integrity": "sha512-xJXHHl6TuAxB5AWiVrGhvbGL8/hbiCQ8FiWwObO3r0fnvBdrbWEDy1hlvGQOAWc6qsCWuWMKdVWlLAEMpxnddg==", + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/scope-manager": "4.22.0", + "@typescript-eslint/types": "4.22.0", + "@typescript-eslint/typescript-estree": "4.22.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + } + }, + "@typescript-eslint/parser": { + "version": "4.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.22.0.tgz", + "integrity": "sha512-z/bGdBJJZJN76nvAY9DkJANYgK3nlRstRRi74WHm3jjgf2I8AglrSY+6l7ogxOmn55YJ6oKZCLLy+6PW70z15Q==", + "requires": { + "@typescript-eslint/scope-manager": "4.22.0", + "@typescript-eslint/types": "4.22.0", + "@typescript-eslint/typescript-estree": "4.22.0", + "debug": "^4.1.1" + } + }, + "@typescript-eslint/scope-manager": { + "version": "4.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.22.0.tgz", + "integrity": "sha512-OcCO7LTdk6ukawUM40wo61WdeoA7NM/zaoq1/2cs13M7GyiF+T4rxuA4xM+6LeHWjWbss7hkGXjFDRcKD4O04Q==", + "requires": { + "@typescript-eslint/types": "4.22.0", + "@typescript-eslint/visitor-keys": "4.22.0" + } + }, + "@typescript-eslint/types": { + "version": "4.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.22.0.tgz", + "integrity": "sha512-sW/BiXmmyMqDPO2kpOhSy2Py5w6KvRRsKZnV0c4+0nr4GIcedJwXAq+RHNK4lLVEZAJYFltnnk1tJSlbeS9lYA==" + }, + "@typescript-eslint/typescript-estree": { + "version": "4.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.22.0.tgz", + "integrity": "sha512-TkIFeu5JEeSs5ze/4NID+PIcVjgoU3cUQUIZnH3Sb1cEn1lBo7StSV5bwPuJQuoxKXlzAObjYTilOEKRuhR5yg==", + "requires": { + "@typescript-eslint/types": "4.22.0", + "@typescript-eslint/visitor-keys": "4.22.0", + "debug": "^4.1.1", + "globby": "^11.0.1", + "is-glob": "^4.0.1", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "4.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.22.0.tgz", + "integrity": "sha512-nnMu4F+s4o0sll6cBSsTeVsT4cwxB7zECK3dFxzEjPBii9xLpq4yqqsy/FU5zMfan6G60DKZSCXAa3sHJZrcYw==", + "requires": { + "@typescript-eslint/types": "4.22.0", + "eslint-visitor-keys": "^2.0.0" + } + }, + "@webassemblyjs/ast": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.0.tgz", + "integrity": "sha512-kX2W49LWsbthrmIRMbQZuQDhGtjyqXfEmmHyEi4XWnSZtPmxY0+3anPIzsnRb45VH/J55zlOfWvZuY47aJZTJg==", + "requires": { + "@webassemblyjs/helper-numbers": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.0.tgz", + "integrity": "sha512-Q/aVYs/VnPDVYvsCBL/gSgwmfjeCb4LW8+TMrO3cSzJImgv8lxxEPM2JA5jMrivE7LSz3V+PFqtMbls3m1exDA==" + }, + "@webassemblyjs/helper-api-error": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.0.tgz", + "integrity": "sha512-baT/va95eXiXb2QflSx95QGT5ClzWpGaa8L7JnJbgzoYeaA27FCvuBXU758l+KXWRndEmUXjP0Q5fibhavIn8w==" + }, + "@webassemblyjs/helper-buffer": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.0.tgz", + "integrity": "sha512-u9HPBEl4DS+vA8qLQdEQ6N/eJQ7gT7aNvMIo8AAWvAl/xMrcOSiI2M0MAnMCy3jIFke7bEee/JwdX1nUpCtdyA==" + }, + "@webassemblyjs/helper-numbers": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.0.tgz", + "integrity": "sha512-DhRQKelIj01s5IgdsOJMKLppI+4zpmcMQ3XboFPLwCpSNH6Hqo1ritgHgD0nqHeSYqofA6aBN/NmXuGjM1jEfQ==", + "requires": { + "@webassemblyjs/floating-point-hex-parser": "1.11.0", + "@webassemblyjs/helper-api-error": "1.11.0", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.0.tgz", + "integrity": "sha512-MbmhvxXExm542tWREgSFnOVo07fDpsBJg3sIl6fSp9xuu75eGz5lz31q7wTLffwL3Za7XNRCMZy210+tnsUSEA==" + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.0.tgz", + "integrity": "sha512-3Eb88hcbfY/FCukrg6i3EH8H2UsD7x8Vy47iVJrP967A9JGqgBVL9aH71SETPx1JrGsOUVLo0c7vMCN22ytJew==", + "requires": { + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-buffer": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0", + "@webassemblyjs/wasm-gen": "1.11.0" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.0.tgz", + "integrity": "sha512-KXzOqpcYQwAfeQ6WbF6HXo+0udBNmw0iXDmEK5sFlmQdmND+tr773Ti8/5T/M6Tl/413ArSJErATd8In3B+WBA==", + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.0.tgz", + "integrity": "sha512-aqbsHa1mSQAbeeNcl38un6qVY++hh8OpCOzxhixSYgbRfNWcxJNJQwe2rezK9XEcssJbbWIkblaJRwGMS9zp+g==", + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.0.tgz", + "integrity": "sha512-A/lclGxH6SpSLSyFowMzO/+aDEPU4hvEiooCMXQPcQFPPJaYcPQNKGOCLUySJsYJ4trbpr+Fs08n4jelkVTGVw==" + }, + "@webassemblyjs/wasm-edit": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.0.tgz", + "integrity": "sha512-JHQ0damXy0G6J9ucyKVXO2j08JVJ2ntkdJlq1UTiUrIgfGMmA7Ik5VdC/L8hBK46kVJgujkBIoMtT8yVr+yVOQ==", + "requires": { + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-buffer": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0", + "@webassemblyjs/helper-wasm-section": "1.11.0", + "@webassemblyjs/wasm-gen": "1.11.0", + "@webassemblyjs/wasm-opt": "1.11.0", + "@webassemblyjs/wasm-parser": "1.11.0", + "@webassemblyjs/wast-printer": "1.11.0" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.0.tgz", + "integrity": "sha512-BEUv1aj0WptCZ9kIS30th5ILASUnAPEvE3tVMTrItnZRT9tXCLW2LEXT8ezLw59rqPP9klh9LPmpU+WmRQmCPQ==", + "requires": { + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0", + "@webassemblyjs/ieee754": "1.11.0", + "@webassemblyjs/leb128": "1.11.0", + "@webassemblyjs/utf8": "1.11.0" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.0.tgz", + "integrity": "sha512-tHUSP5F4ywyh3hZ0+fDQuWxKx3mJiPeFufg+9gwTpYp324mPCQgnuVKwzLTZVqj0duRDovnPaZqDwoyhIO8kYg==", + "requires": { + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-buffer": "1.11.0", + "@webassemblyjs/wasm-gen": "1.11.0", + "@webassemblyjs/wasm-parser": "1.11.0" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.0.tgz", + "integrity": "sha512-6L285Sgu9gphrcpDXINvm0M9BskznnzJTE7gYkjDbxET28shDqp27wpruyx3C2S/dvEwiigBwLA1cz7lNUi0kw==", + "requires": { + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-api-error": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0", + "@webassemblyjs/ieee754": "1.11.0", + "@webassemblyjs/leb128": "1.11.0", + "@webassemblyjs/utf8": "1.11.0" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.0.tgz", + "integrity": "sha512-Fg5OX46pRdTgB7rKIUojkh9vXaVN6sGYCnEiJN1GYkb0RPwShZXp6KTDqmoMdQPKhcroOXh3fEzmkWmCYaKYhQ==", + "requires": { + "@webassemblyjs/ast": "1.11.0", + "@xtuc/long": "4.2.2" + } + }, + "@webpack-cli/configtest": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.0.2.tgz", + "integrity": "sha512-3OBzV2fBGZ5TBfdW50cha1lHDVf9vlvRXnjpVbJBa20pSZQaSkMJZiwA8V2vD9ogyeXn8nU5s5A6mHyf5jhMzA==" + }, + "@webpack-cli/info": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.2.3.tgz", + "integrity": "sha512-lLek3/T7u40lTqzCGpC6CAbY6+vXhdhmwFRxZLMnRm6/sIF/7qMpT8MocXCRQfz0JAh63wpbXLMnsQ5162WS7Q==", + "requires": { + "envinfo": "^7.7.3" + } + }, + "@webpack-cli/serve": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.3.1.tgz", + "integrity": "sha512-0qXvpeYO6vaNoRBI52/UsbcaBydJCggoBBnIo/ovQQdn6fug0BgwsjorV1hVS7fMqGVTZGcVxv8334gjmbj5hw==" + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "acorn": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.1.1.tgz", + "integrity": "sha512-xYiIVjNuqtKXMxlRMDc6mZUhXehod4a3gbZ1qRlM7icK4EbxUFNLhWoPblCvFtB2Y9CIqHP3CF/rdxLItaQv8g==" + }, + "acorn-jsx": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==" + }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==" + }, + "ansi-align": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", + "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", + "requires": { + "string-width": "^3.0.0" + }, + "dependencies": {} + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==" + }, + "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==", + "requires": { + "type-fest": "^0.21.3" + }, + "dependencies": {} + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "append-transform": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", + "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", + "requires": { + "default-require-extensions": "^3.0.0" + } + }, + "archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=" + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-differ": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-2.1.0.tgz", + "integrity": "sha512-KbUpJgx909ZscOc/7CLATBFam7P1Z1QRQInvgT0UztM9Q72aGKCunKASAl7WNW0tnPmPyEMeMhdsfWhfmW037w==" + }, + "array-filter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz", + "integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=" + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==" + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" + }, + "asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + } + }, + "assert": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-2.0.0.tgz", + "integrity": "sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A==", + "requires": { + "es6-object-assign": "^1.1.0", + "is-nan": "^1.2.1", + "object-is": "^1.0.1", + "util": "^0.12.0" + } + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==" + }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==" + }, + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "requires": { + "lodash": "^4.17.14" + } + }, + "available-typed-arrays": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz", + "integrity": "sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ==", + "requires": { + "array-filter": "^1.0.0" + } + }, + "axios": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", + "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "requires": { + "follow-redirects": "^1.10.0" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "base-x": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz", + "integrity": "sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "optional": true, + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "bip66": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", + "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", + "optional": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "blakejs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", + "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" + }, + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "boxen": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", + "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", + "requires": { + "ansi-align": "^3.0.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "cli-boxes": "^2.2.0", + "string-width": "^4.1.0", + "term-size": "^2.1.0", + "type-fest": "^0.8.1", + "widest-line": "^3.1.0" + }, + "dependencies": {} + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", + "requires": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + }, + "dependencies": {} + }, + "browserify-sign": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", + "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", + "requires": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.3", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": {} + }, + "browserslist": { + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.4.tgz", + "integrity": "sha512-d7rCxYV8I9kj41RH8UKYnvDYCRENUlHRgyXy/Rhr/1BaeLGfiCptEdFE8MIrvGfWbBFNjVYx76SQWvNX1j+/cQ==", + "requires": { + "caniuse-lite": "^1.0.30001208", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.712", + "escalade": "^3.1.1", + "node-releases": "^1.1.71" + } + }, + "bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", + "requires": { + "base-x": "^3.0.2" + } + }, + "bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "requires": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=" + }, + "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==" + }, + "cacheable-request": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", + "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", + "requires": { + "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" + }, + "dependencies": {} + }, + "caching-transform": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", + "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", + "requires": { + "hasha": "^5.0.0", + "make-dir": "^3.0.0", + "package-hash": "^4.0.0", + "write-file-atomic": "^3.0.0" + } + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "caniuse-lite": { + "version": "1.0.30001214", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001214.tgz", + "integrity": "sha512-O2/SCpuaU3eASWVaesQirZv1MSjUNOvmugaD8zNSJqw6Vv5SGwoOpA9LJs3pNPfM745nxqPvfZY3MQKY4AKHYg==" + }, + "chai": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", + "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=" + }, + "chokidar": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.3.1", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + } + }, + "chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==" + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==" + }, + "cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==" + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "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==", + "requires": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "dependencies": {} + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "requires": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + } + }, + "clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "requires": { + "mimic-response": "^1.0.0" + } + }, + "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==", + "requires": { + "color-name": "~1.1.4" + } + }, + "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==" + }, + "colorette": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==" + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "comment-parser": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.1.2.tgz", + "integrity": "sha512-AOdq0i8ghZudnYv8RUnHrhTgafUGs61Rdz9jemU5x2lnZwAWyOq7vySo626K59e1fVKH1xSRorJwPVRLSWOoAQ==" + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" + }, + "compare-versions": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz", + "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "concurrently": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-6.0.2.tgz", + "integrity": "sha512-u+1Q0dJG5BidgUTpz9CU16yoHTt/oApFDQ3mbvHwSDgMjU7aGqy0q8ZQyaZyaNxdwRKTD872Ux3Twc6//sWA+Q==", + "requires": { + "chalk": "^4.1.0", + "date-fns": "^2.16.1", + "lodash": "^4.17.21", + "read-pkg": "^5.2.0", + "rxjs": "^6.6.3", + "spawn-command": "^0.0.2-1", + "supports-color": "^8.1.0", + "tree-kill": "^1.2.2", + "yargs": "^16.2.0" + }, + "dependencies": {} + }, + "configstore": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", + "requires": { + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + } + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "requires": { + "safe-buffer": "~5.1.1" + }, + "dependencies": {} + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cosmiconfig": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", + "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==", + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + } + }, + "create-ecdh": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==" + }, + "date-fns": { + "version": "2.21.1", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.21.1.tgz", + "integrity": "sha512-m1WR0xGiC6j6jNFAyW4Nvh4WxAi4JF4w9jRJwSI8nBmNcyZXPcP9VUQG+6gHQXAmqaGEKDKhOqAtENDC941UkA==" + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "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==", + "requires": { + "mimic-response": "^3.1.0" + }, + "dependencies": {} + }, + "dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=" + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "requires": { + "type-detect": "^4.0.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" + }, + "default-require-extensions": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", + "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==", + "requires": { + "strip-bom": "^4.0.0" + } + }, + "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==" + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "requires": { + "object-keys": "^1.0.12" + } + }, + "des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "requires": { + "path-type": "^4.0.0" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "requires": { + "esutils": "^2.0.2" + } + }, + "dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "requires": { + "is-obj": "^2.0.0" + }, + "dependencies": {} + }, + "drbg.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", + "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", + "optional": true, + "requires": { + "browserify-aes": "^1.0.6", + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4" + } + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" + }, + "eccrypto": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/eccrypto/-/eccrypto-1.1.6.tgz", + "integrity": "sha512-d78ivVEzu7Tn0ZphUUaL43+jVPKTMPFGtmgtz1D0LrFn7cY3K8CdrvibuLz2AAkHBLKZtR8DMbB2ukRYFk987A==", + "requires": { + "acorn": "7.1.1", + "elliptic": "6.5.4", + "es6-promise": "4.2.8", + "nan": "2.14.0", + "secp256k1": "3.7.1" + }, + "dependencies": {} + }, + "electron-to-chromium": { + "version": "1.3.719", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.719.tgz", + "integrity": "sha512-heM78GKSqrIzO9Oz0/y22nTBN7bqSP1Pla2SyU9DiSnQD+Ea9SyyN5RWWlgqsqeBLNDkSlE9J9EHFmdMPzxB/g==" + }, + "elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "requires": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "email-addresses": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-3.1.0.tgz", + "integrity": "sha512-k0/r7GrWVL32kZlGwfPNgB2Y/mMXVTq/decgLczm/j34whdaspNrZO8CnXPf1laaHxI6ptUlsnAxN+UAPw+fzg==" + }, + "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==" + }, + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" + }, + "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==", + "requires": { + "once": "^1.4.0" + } + }, + "enhanced-resolve": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.0.tgz", + "integrity": "sha512-Sl3KRpJA8OpprrtaIswVki3cWPiPKxXuFxJXBp+zNb6s6VwNWwFRUdtmzd2ReUut8n+sCPx7QCtQ7w5wfJhSgQ==", + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + } + }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "requires": { + "ansi-colors": "^4.1.1" + } + }, + "envinfo": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", + "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==" + }, + "errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "requires": { + "prr": "~1.0.1" + } + }, + "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==", + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0.tgz", + "integrity": "sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw==", + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.2", + "is-string": "^1.0.5", + "object-inspect": "^1.9.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.0" + } + }, + "es-module-lexer": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.4.1.tgz", + "integrity": "sha512-ooYciCUtfw6/d2w56UVeqHPcoCFAiJdz5XOkYpv/Txl1HMUozpXjz/2RIQgqwKdXNDPSF1W7mJCFse3G+HDyAA==" + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==" + }, + "es6-object-assign": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", + "integrity": "sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw=" + }, + "es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, + "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==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "eslint": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.24.0.tgz", + "integrity": "sha512-k9gaHeHiFmGCDQ2rEfvULlSLruz6tgfA8DEn+rY9/oYPFFTlz55mM/Q/Rij1b2Y42jwZiK3lXvNTw6w6TXzcKQ==", + "requires": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash": "^4.17.21", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.4", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": {} + }, + "eslint-config-prettier": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.2.0.tgz", + "integrity": "sha512-dWV9EVeSo2qodOPi1iBYU/x6F6diHv8uujxbxr77xExs3zTAlNXvVZKiyLsQGNz7yPV2K49JY5WjPzNIuDc2Bw==" + }, + "eslint-plugin-jsdoc": { + "version": "32.3.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-32.3.0.tgz", + "integrity": "sha512-zyx7kajDK+tqS1bHuY5sapkad8P8KT0vdd/lE55j47VPG2MeenSYuIY/M/Pvmzq5g0+3JB+P3BJGUXmHxtuKPQ==", + "requires": { + "comment-parser": "1.1.2", + "debug": "^4.3.1", + "jsdoctypeparser": "^9.0.0", + "lodash": "^4.17.20", + "regextras": "^0.7.1", + "semver": "^7.3.4", + "spdx-expression-parse": "^3.0.1" + } + }, + "eslint-plugin-prefer-arrow": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-prefer-arrow/-/eslint-plugin-prefer-arrow-1.2.3.tgz", + "integrity": "sha512-J9I5PKCOJretVuiZRGvPQxCbllxGAV/viI20JO3LYblAodofBxyMnZAJ+WGeClHgANnSJberTNoFWWjrWKBuXQ==" + }, + "eslint-plugin-prettier": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.0.tgz", + "integrity": "sha512-UDK6rJT6INSfcOo545jiaOwB701uAIt2/dR7WnFQoGCVl1/EMqdANBmwUaqqQ45aXprsTGzSa39LI1PyuRBxxw==", + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "requires": { + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": {} + }, + "eslint-visitor-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", + "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==" + }, + "espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "requires": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "dependencies": {} + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": {} + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": {} + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "requires": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "requires": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==" + }, + "fast-glob": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", + "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + }, + "fastest-levenshtein": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", + "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==" + }, + "fastq": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", + "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==", + "requires": { + "reusify": "^1.0.4" + } + }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "requires": { + "flat-cache": "^3.0.4" + } + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "optional": true + }, + "filename-reserved-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-1.0.0.tgz", + "integrity": "sha1-5hz4BfDeHJhFZ9A4bcXfUO5a9+Q=" + }, + "filenamify": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-1.2.1.tgz", + "integrity": "sha1-qfL/0RxQO+0wABUCknI3jx8TZaU=", + "requires": { + "filename-reserved-regex": "^1.0.0", + "strip-outer": "^1.0.0", + "trim-repeated": "^1.0.0" + } + }, + "filenamify-url": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/filenamify-url/-/filenamify-url-1.0.0.tgz", + "integrity": "sha1-syvYExnvWGO3MHi+1Q9GpPeXX1A=", + "requires": { + "filenamify": "^1.0.0", + "humanize-url": "^1.0.0" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-cache-dir": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "find-versions": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-4.0.0.tgz", + "integrity": "sha512-wgpWy002tA+wgmO27buH/9KzyEOQnKsG/R0yrcjPT9BOFm0zRBVQbZ95nRGXWMywS8YR5knRbpohio0bcJABxQ==", + "requires": { + "semver-regex": "^3.1.2" + } + }, + "flat": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", + "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", + "requires": { + "is-buffer": "~2.0.3" + } + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", + "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==" + }, + "follow-redirects": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.3.tgz", + "integrity": "sha512-DUgl6+HDzB0iEptNQEXLx/KhTmDb8tZUHSeLqpnjpknR70H0nC2t9N73BK6fN4hOvJ84pKlIQVQ4k5FFlBedKA==" + }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" + }, + "foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + } + }, + "fromentries": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", + "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==" + }, + "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==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" + }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" + }, + "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==" + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=" + }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, + "get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" + }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==" + }, + "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==", + "requires": { + "pump": "^3.0.0" + } + }, + "gh-pages": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-3.1.0.tgz", + "integrity": "sha512-3b1rly9kuf3/dXsT8+ZxP0UhNLOo1CItj+3e31yUVcaph/yDsJ9RzD7JOw5o5zpBTJVQLlJAASNkUfepi9fe2w==", + "requires": { + "async": "^2.6.1", + "commander": "^2.18.0", + "email-addresses": "^3.0.1", + "filenamify-url": "^1.0.0", + "find-cache-dir": "^3.3.1", + "fs-extra": "^8.1.0", + "globby": "^6.1.0" + }, + "dependencies": {} + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "requires": { + "is-glob": "^4.0.1" + } + }, + "glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" + }, + "global-dirs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.1.0.tgz", + "integrity": "sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==", + "requires": { + "ini": "1.3.7" + } + }, + "globals": { + "version": "13.8.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.8.0.tgz", + "integrity": "sha512-rHtdA6+PDBIjeEvA91rpqzEvk/k3/i7EeNQiryiWuJH0Hw9cpyJMAt2jtbAwUaRdhD+573X4vWw6IcjKPasi9Q==", + "requires": { + "type-fest": "^0.20.2" + }, + "dependencies": {} + }, + "globby": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz", + "integrity": "sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==", + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + } + }, + "google-protobuf": { + "version": "3.15.8", + "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.15.8.tgz", + "integrity": "sha512-2jtfdqTaSxk0cuBJBtTTWsot4WtR9RVr2rXg7x7OoqiuOKopPrwXpM1G4dXIkLcUNRh3RKzz76C8IOkksZSeOw==" + }, + "got": { + "version": "11.8.2", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.2.tgz", + "integrity": "sha512-D0QywKgIe30ODs+fm8wMZiAcZjypcCodPNuMz5H9Mny7RJ+IjJ10BdmGW7OM7fHXP+O7r6ZwapQ/YQmMSvB0UQ==", + "requires": { + "@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.1", + "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" + } + }, + "graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==" + }, + "handlebars": { + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "requires": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4", + "wordwrap": "^1.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" + }, + "has-yarn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", + "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==" + }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hasha": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", + "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", + "requires": { + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" + }, + "dependencies": {} + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" + }, + "highlight.js": { + "version": "10.7.2", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.2.tgz", + "integrity": "sha512-oFLl873u4usRM9K63j4ME9u3etNF0PLiJhSQ8rdfuL51Wn3zkD6drf9ZW0dOzjnZI22YYG24z30JcmfCZjMgYg==" + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "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==" + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" + }, + "http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" + }, + "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==", + "requires": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + } + }, + "human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==" + }, + "humanize-duration": { + "version": "3.25.2", + "resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.25.2.tgz", + "integrity": "sha512-zSerjahuzBazDaE8skjMI7Xmrt/EirvW5cDsXgysx8tYIjcgCMnI5Y5985y3LxYeLah9L5cQY3WEw1k7GRWbfg==" + }, + "humanize-url": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/humanize-url/-/humanize-url-1.0.1.tgz", + "integrity": "sha1-9KuZ4NKIF0yk4eUEB8VfuuRk7/8=", + "requires": { + "normalize-url": "^1.0.0", + "strip-url-auth": "^1.0.0" + } + }, + "husky": { + "version": "4.3.8", + "resolved": "https://registry.npmjs.org/husky/-/husky-4.3.8.tgz", + "integrity": "sha512-LCqqsB0PzJQ/AlCgfrfzRe3e3+NvmefAdKQhRYpxS4u6clblBoDdzzvHi8fmxKRzvMxPY/1WZWzomPZww0Anow==", + "requires": { + "chalk": "^4.0.0", + "ci-info": "^2.0.0", + "compare-versions": "^3.6.0", + "cosmiconfig": "^7.0.0", + "find-versions": "^4.0.0", + "opencollective-postinstall": "^2.0.2", + "pkg-dir": "^5.0.0", + "please-upgrade-node": "^3.2.0", + "slash": "^3.0.0", + "which-pm-runs": "^1.0.0" + }, + "dependencies": {} + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==" + }, + "ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=" + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=" + }, + "import-local": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", + "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + }, + "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==" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ini": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", + "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==" + }, + "interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==" + }, + "is-arguments": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", + "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==", + "requires": { + "call-bind": "^1.0.0" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + }, + "is-bigint": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.1.tgz", + "integrity": "sha512-J0ELF4yHFxHy0cmSxZuheDOz2luOdVvqjwmEcj8H/L1JHeuEDSDbeRP+Dk9kFVk5RTFzbucJ2Kb9F7ixY2QaCg==" + }, + "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==", + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-boolean-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.0.tgz", + "integrity": "sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA==", + "requires": { + "call-bind": "^1.0.0" + } + }, + "is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==" + }, + "is-callable": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==" + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", + "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", + "requires": { + "has": "^1.0.3" + } + }, + "is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==" + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "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==" + }, + "is-generator-function": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.8.tgz", + "integrity": "sha512-2Omr/twNtufVZFr1GhxjOMFPAj2sjc/dKaIqBhvo4qciXfJmITGH6ZGd8eZYNHza8t1y0e01AuqRhJwfWp26WQ==" + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-installed-globally": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", + "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", + "requires": { + "global-dirs": "^2.0.1", + "is-path-inside": "^3.0.1" + } + }, + "is-nan": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", + "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + } + }, + "is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==" + }, + "is-npm": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", + "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==" + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "is-number-object": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz", + "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==" + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" + }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==" + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "requires": { + "isobject": "^3.0.1" + } + }, + "is-regex": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", + "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", + "requires": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.1" + } + }, + "is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=" + }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" + }, + "is-string": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==" + }, + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-typed-array": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.5.tgz", + "integrity": "sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug==", + "requires": { + "available-typed-arrays": "^1.0.2", + "call-bind": "^1.0.2", + "es-abstract": "^1.18.0-next.2", + "foreach": "^2.0.5", + "has-symbols": "^1.0.1" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==" + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" + }, + "is-yarn-global": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "isomorphic-fetch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", + "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", + "requires": { + "node-fetch": "^2.6.1", + "whatwg-fetch": "^3.4.1" + } + }, + "isomorphic-ws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", + "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==" + }, + "istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==" + }, + "istanbul-lib-hook": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", + "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", + "requires": { + "append-transform": "^2.0.0" + } + }, + "istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "requires": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + }, + "dependencies": {} + }, + "istanbul-lib-processinfo": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz", + "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==", + "requires": { + "archy": "^1.0.0", + "cross-spawn": "^7.0.0", + "istanbul-lib-coverage": "^3.0.0-alpha.1", + "make-dir": "^3.0.0", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "uuid": "^3.3.3" + }, + "dependencies": {} + }, + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", + "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + } + }, + "istanbul-reports": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", + "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbi": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/jsbi/-/jsbi-3.1.4.tgz", + "integrity": "sha512-52QRRFSsi9impURE8ZUbzAMCLjPm4THO7H2fcuIvaaeFTbSysvkodbQQXIVsNgq/ypDbq6dJiuGKL0vZ/i9hUg==" + }, + "jsdoctypeparser": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/jsdoctypeparser/-/jsdoctypeparser-9.0.0.tgz", + "integrity": "sha512-jrTA2jJIL6/DAEILBEh2/w9QxCuwmvNXIry39Ay/HVfhE3o2yVV0U44blYkqdHA/OKloJEqvJy0xU+GSdE2SIw==" + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + }, + "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==" + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" + }, + "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==" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=" + }, + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "requires": { + "minimist": "^1.2.5" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "keccak": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.1.tgz", + "integrity": "sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA==", + "requires": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + } + }, + "key-encoder": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/key-encoder/-/key-encoder-2.0.3.tgz", + "integrity": "sha512-fgBtpAGIr/Fy5/+ZLQZIPPhsZEcbSlYu/Wu96tNDFNSjSACw5lEIOFeaVdQ/iwrb8oxjlWi6wmWdH76hV6GZjg==", + "requires": { + "@types/elliptic": "^6.4.9", + "asn1.js": "^5.0.1", + "bn.js": "^4.11.8", + "elliptic": "^6.4.1" + } + }, + "keyv": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.3.tgz", + "integrity": "sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA==", + "requires": { + "json-buffer": "3.0.1" + } + }, + "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==" + }, + "latest-version": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", + "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", + "requires": { + "package-json": "^6.3.0" + } + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=" + }, + "lint-staged": { + "version": "10.5.4", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-10.5.4.tgz", + "integrity": "sha512-EechC3DdFic/TdOPgj/RB3FicqE6932LTHCUm0Y2fsD9KGlLB+RwJl2q1IYBIvEsKzDOgn0D4gll+YxG5RsrKg==", + "requires": { + "chalk": "^4.1.0", + "cli-truncate": "^2.1.0", + "commander": "^6.2.0", + "cosmiconfig": "^7.0.0", + "debug": "^4.2.0", + "dedent": "^0.7.0", + "enquirer": "^2.3.6", + "execa": "^4.1.0", + "listr2": "^3.2.2", + "log-symbols": "^4.0.0", + "micromatch": "^4.0.2", + "normalize-path": "^3.0.0", + "please-upgrade-node": "^3.2.0", + "string-argv": "0.3.1", + "stringify-object": "^3.3.0" + }, + "dependencies": {} + }, + "listr2": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.7.1.tgz", + "integrity": "sha512-cNd368GTrk8351/ov/IV+BSwyf9sJRgI0UIvfORonCZA1u9UHAtAlqSEv9dgafoQIA1CgB3nu4No79pJtK2LHw==", + "requires": { + "chalk": "^4.1.0", + "cli-truncate": "^2.1.0", + "figures": "^3.2.0", + "indent-string": "^4.0.0", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rxjs": "^6.6.7", + "through": "^2.3.8", + "wrap-ansi": "^7.0.0" + } + }, + "loader-runner": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", + "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==" + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" + }, + "lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=" + }, + "lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=" + }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=" + }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, + "log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "requires": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "dependencies": {} + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" + }, + "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==", + "requires": { + "yallist": "^4.0.0" + } + }, + "lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==" + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "requires": { + "semver": "^6.0.0" + }, + "dependencies": {} + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "marked": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-1.0.0.tgz", + "integrity": "sha512-Wo+L1pWTVibfrSr+TTtMuiMfNzmZWiOPeO7rZsQUY5bgsxpHesBEcIWJloWVTFnrMXnf/TL30eTFSGJddmQAng==" + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "memory-fs": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", + "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + }, + "dependencies": {} + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" + }, + "micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, + "mime-db": { + "version": "1.47.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", + "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==" + }, + "mime-types": { + "version": "2.1.30", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", + "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", + "requires": { + "mime-db": "1.47.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "mkdirp": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz", + "integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==", + "requires": { + "minimist": "^1.2.5" + } + }, + "mocha": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.3.tgz", + "integrity": "sha512-0R/3FvjIGH3eEuG17ccFPk117XL2rWxatr81a57D+r/x2uTYZRbdZ4oVidEUMh2W2TJDa7MdAb12Lm2/qrKajg==", + "requires": { + "ansi-colors": "3.2.3", + "browser-stdout": "1.3.1", + "debug": "3.2.6", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "find-up": "3.0.0", + "glob": "7.1.3", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.13.1", + "log-symbols": "2.2.0", + "minimatch": "3.0.4", + "mkdirp": "0.5.4", + "ms": "2.1.1", + "node-environment-flags": "1.0.5", + "object.assign": "4.1.0", + "strip-json-comments": "2.0.1", + "supports-color": "6.0.0", + "which": "1.3.1", + "wide-align": "1.1.3", + "yargs": "13.3.2", + "yargs-parser": "13.1.2", + "yargs-unparser": "1.6.0" + }, + "dependencies": {} + }, + "mri": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.1.6.tgz", + "integrity": "sha512-oi1b3MfbyGa7FJMP9GmLTttni5JoICpYBRlq+x5V16fZbLsnL9N3wFqqIm/nIG43FjUFkFh9Epzp/kzUGUnJxQ==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "multimatch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-3.0.0.tgz", + "integrity": "sha512-22foS/gqQfANZ3o+W7ST2x25ueHDVNWl/b9OlGcLpy/iKxjCpvcNCM51YCenUi7Mt/jAjjqv8JwZRs8YP5sRjA==", + "requires": { + "array-differ": "^2.0.3", + "array-union": "^1.0.2", + "arrify": "^1.0.1", + "minimatch": "^3.0.4" + }, + "dependencies": {} + }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" + }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + }, + "node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" + }, + "node-environment-flags": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", + "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==", + "requires": { + "object.getownpropertydescriptors": "^2.0.3", + "semver": "^5.7.0" + }, + "dependencies": {} + }, + "node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" + }, + "node-gyp-build": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", + "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==" + }, + "node-preload": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", + "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", + "requires": { + "process-on-spawn": "^1.0.0" + } + }, + "node-releases": { + "version": "1.1.71", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz", + "integrity": "sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==" + }, + "nodemon": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.7.tgz", + "integrity": "sha512-XHzK69Awgnec9UzHr1kc8EomQh4sjTQ8oRf8TsGrSmHDx9/UmiGG9E/mM3BuTfNeFwdNBvrqQq/RHL0xIeyFOA==", + "requires": { + "chokidar": "^3.2.2", + "debug": "^3.2.6", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.0.4", + "pstree.remy": "^1.1.7", + "semver": "^5.7.1", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.3", + "update-notifier": "^4.1.0" + }, + "dependencies": {} + }, + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "requires": { + "abbrev": "1" + } + }, + "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==", + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": {} + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "normalize-url": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", + "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", + "requires": { + "object-assign": "^4.0.1", + "prepend-http": "^1.0.0", + "query-string": "^4.1.0", + "sort-keys": "^1.0.0" + } + }, + "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==", + "requires": { + "path-key": "^3.0.0" + } + }, + "nyc": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", + "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", + "requires": { + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "caching-transform": "^4.0.0", + "convert-source-map": "^1.7.0", + "decamelize": "^1.2.0", + "find-cache-dir": "^3.2.0", + "find-up": "^4.1.0", + "foreground-child": "^2.0.0", + "get-package-type": "^0.1.0", + "glob": "^7.1.6", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-hook": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-processinfo": "^2.0.2", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "make-dir": "^3.0.0", + "node-preload": "^0.2.1", + "p-map": "^3.0.0", + "process-on-spawn": "^1.0.0", + "resolve-from": "^5.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "spawn-wrap": "^2.0.0", + "test-exclude": "^6.0.0", + "yargs": "^15.0.2" + }, + "dependencies": {} + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-inspect": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.2.tgz", + "integrity": "sha512-gz58rdPpadwztRrPjZE9DZLOABUpTGdcANUgOwBFO1C+HZZhePoP83M65WGDmbpwFYJSWqavbl4SgDn4k8RYTA==" + }, + "object-is": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", + "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "object.getownpropertydescriptors": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz", + "integrity": "sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "opencollective-postinstall": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz", + "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==" + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==" + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "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==", + "requires": { + "p-limit": "^2.2.0" + }, + "dependencies": {} + }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "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==" + }, + "package-hash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", + "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", + "requires": { + "graceful-fs": "^4.1.15", + "hasha": "^5.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + } + }, + "package-json": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", + "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", + "requires": { + "got": "^9.6.0", + "registry-auth-token": "^4.0.0", + "registry-url": "^5.0.0", + "semver": "^6.2.0" + }, + "dependencies": {} + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-asn1": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "requires": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "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==", + "requires": { + "@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" + } + }, + "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==" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" + }, + "pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==" + }, + "pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "picomatch": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", + "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==" + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "requires": { + "pinkie": "^2.0.0" + } + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "requires": { + "find-up": "^4.0.0" + } + }, + "please-upgrade-node": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", + "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", + "requires": { + "semver-compare": "^1.0.0" + } + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" + }, + "prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" + }, + "prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==" + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "requires": { + "fast-diff": "^1.1.2" + } + }, + "pretty-quick": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-1.11.1.tgz", + "integrity": "sha512-kSXCkcETfak7EQXz6WOkCeCqpbC4GIzrN/vaneTGMP/fAtD8NerA9bPhCUqHAks1geo7biZNl5uEMPceeneLuA==", + "requires": { + "chalk": "^2.3.0", + "execa": "^0.8.0", + "find-up": "^2.1.0", + "ignore": "^3.3.7", + "mri": "^1.1.0", + "multimatch": "^3.0.0" + }, + "dependencies": {} + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" + }, + "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==" + }, + "process-on-spawn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", + "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", + "requires": { + "fromentries": "^1.2.0" + } + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==" + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "pupa": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", + "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", + "requires": { + "escape-goat": "^2.0.0" + } + }, + "query-string": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", + "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", + "requires": { + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + } + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" + }, + "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==" + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": {} + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "requires": { + "picomatch": "^2.2.1" + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "requires": { + "resolve": "^1.1.6" + } + }, + "reflect-metadata": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", + "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" + }, + "regexpp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==" + }, + "regextras": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/regextras/-/regextras-0.7.1.tgz", + "integrity": "sha512-9YXf6xtW+qzQ+hcMQXx95MOvfqXFgsKDZodX3qZB0x2n5Z94ioetIITsBtvJbiOyxa/6s9AtyweBLCdPmPko/w==" + }, + "registry-auth-token": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", + "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", + "requires": { + "rc": "^1.2.8" + } + }, + "registry-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", + "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", + "requires": { + "rc": "^1.2.8" + } + }, + "release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", + "requires": { + "es6-error": "^4.0.1" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" + }, + "resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "resolve-alpn": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.1.2.tgz", + "integrity": "sha512-8OyfzhAtA32LVUsJSke3auIyINcwdh5l3cvYKdKO0nvsYSKuiLfTM5i78PJswFPT8y6cPW+L1v6/hE95chcpDA==" + }, + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "requires": { + "resolve-from": "^5.0.0" + }, + "dependencies": {} + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" + }, + "responselike": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", + "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", + "requires": { + "lowercase-keys": "^2.0.0" + } + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "requires": { + "glob": "^7.1.3" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "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==", + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "requires": { + "tslib": "^1.9.0" + } + }, + "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==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "schema-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", + "requires": { + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + }, + "scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" + }, + "secp256k1": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz", + "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==", + "requires": { + "elliptic": "^6.5.2", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=" + }, + "semver-diff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", + "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", + "requires": { + "semver": "^6.3.0" + }, + "dependencies": {} + }, + "semver-regex": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-3.1.2.tgz", + "integrity": "sha512-bXWyL6EAKOJa81XG1OZ/Yyuq+oT0b2YLlxx7c+mrdYPaPbnj6WgVULXhinMIeZGufuUBu/eVRqXEhiv4imfwxA==" + }, + "serialize-javascript": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "requires": { + "randombytes": "^2.1.0" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "requires": { + "kind-of": "^6.0.2" + } + }, + "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==", + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + }, + "shelljs": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz", + "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==", + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + } + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + }, + "sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", + "requires": { + "is-plain-obj": "^1.0.0" + } + }, + "source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" + }, "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" - } - } - }, - "terser-webpack-plugin": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.4.tgz", - "integrity": "sha512-C2WkFwstHDhVEmsmlCxrXUtVklS+Ir1A7twrYzrDrQQOIMOaVAYykaoo/Aq1K0QRkMoY2hhvDQY1cm4jnIMFwA==", - "requires": { - "jest-worker": "^27.0.2", - "p-limit": "^3.1.0", - "schema-utils": "^3.0.0", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1", - "terser": "^5.7.0" - } - }, - "ts-results": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/ts-results/-/ts-results-3.3.0.tgz", - "integrity": "sha512-FWqxGX2NHp5oCyaMd96o2y2uMQmSu8Dey6kvyuFdRJ2AzfmWo3kWa4UsPlCGlfQ/qu03m09ZZtppMoY8EMHuiA==" - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "tweetnacl-ts": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl-ts/-/tweetnacl-ts-1.0.3.tgz", - "integrity": "sha512-C5I/dWf6xjAXaCDlf84T4HvozU/8ycAlq5WRllF1hAeeq5390tfXD+bNas5bhEV0HMSOx8bsQYpLjPl8wfnEeQ==", - "requires": { - "tslib": "^1" - } - }, - "tweetnacl-util": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", - "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==" - }, - "typedjson": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/typedjson/-/typedjson-1.7.0.tgz", - "integrity": "sha512-MnRgQLwtEcdHqQG0FkT8ebpBG53Wgr/axYRbiD2WL5NcYx8Z2AoCpXvtTfLnuPqOBKG/9JpXq0O/nl2m4wqJYw==", - "requires": { - "tslib": "^2.0.1" - }, - "dependencies": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "spawn-command": { + "version": "0.0.2-1", + "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", + "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=" + }, + "spawn-wrap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", + "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", + "requires": { + "foreground-child": "^2.0.0", + "is-windows": "^1.0.2", + "make-dir": "^3.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "which": "^2.0.1" + }, + "dependencies": {} + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==" + }, + "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==", + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz", + "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==" + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "stream-browserify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", + "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", + "requires": { + "inherits": "~2.0.4", + "readable-stream": "^3.5.0" + } + }, + "stream-http": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz", + "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==", + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "xtend": "^4.0.2" + } + }, + "strict-event-emitter-types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strict-event-emitter-types/-/strict-event-emitter-types-2.0.0.tgz", + "integrity": "sha512-Nk/brWYpD85WlOgzw5h173aci0Teyv8YdIAEtV+N88nDB0dLlazZyJMIsN6eo1/AR61l+p6CJTG1JIyFaoNEEA==" + }, + "strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" + }, + "string-argv": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", + "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==" + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "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==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "requires": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" + }, + "strip-outer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", + "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", + "requires": { + "escape-string-regexp": "^1.0.2" + } + }, + "strip-url-auth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-url-auth/-/strip-url-auth-1.0.1.tgz", + "integrity": "sha1-IrD6OkE4WzO+PzMVUbu4N/oM164=" + }, + "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==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "table": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/table/-/table-6.3.2.tgz", + "integrity": "sha512-I9/Ca6Huf2oxFag7crD0DhA+arIdfLtWunSn0NIXSzjtUlDgIBGVZY7SsMkNPNT3Psd/z4gza0nuEpmra9eRbg==", + "requires": { + "ajv": "^8.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "lodash.clonedeep": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0" + }, + "dependencies": {} + }, + "tapable": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", + "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==" + }, + "term-size": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", + "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==" + }, + "terser": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.6.1.tgz", + "integrity": "sha512-yv9YLFQQ+3ZqgWCUk+pvNJwgUTdlIxUk1WTN+RnaFJe2L7ipG2csPT0ra2XRm7Cs8cxN7QXmK1rFzEwYEQkzXw==", + "requires": { + "commander": "^2.20.0", + "source-map": "~0.7.2", + "source-map-support": "~0.5.19" + }, + "dependencies": {} + }, + "terser-webpack-plugin": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.1.tgz", + "integrity": "sha512-5XNNXZiR8YO6X6KhSGXfY0QrGrCRlSwAEjIIrlRQR4W8nP69TaJUlh3bkuac6zzgspiGPfKEHcY295MMVExl5Q==", + "requires": { + "jest-worker": "^26.6.2", + "p-limit": "^3.1.0", + "schema-utils": "^3.0.0", + "serialize-javascript": "^5.0.1", + "source-map": "^0.6.1", + "terser": "^5.5.1" + } + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" + }, + "to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==" + }, + "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==", + "requires": { + "is-number": "^7.0.0" + } + }, + "touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "requires": { + "nopt": "~1.0.10" + } + }, + "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==" + }, + "trim-repeated": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", + "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=", + "requires": { + "escape-string-regexp": "^1.0.2" + } + }, + "ts-loader": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-8.1.0.tgz", + "integrity": "sha512-YiQipGGAFj2zBfqLhp28yUvPP9jUGqHxRzrGYuc82Z2wM27YIHbElXiaZDc93c3x0mz4zvBmS6q/DgExpdj37A==", + "requires": { + "chalk": "^4.1.0", + "enhanced-resolve": "^4.0.0", + "loader-utils": "^2.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4" + }, + "dependencies": {} + }, + "ts-node": { + "version": "8.10.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz", + "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==", + "requires": { + "arg": "^4.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.17", + "yn": "3.1.1" + }, + "dependencies": {} + }, + "ts-protoc-gen": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/ts-protoc-gen/-/ts-protoc-gen-0.10.0.tgz", + "integrity": "sha512-EEbgDWNHK3CvcNhmib94I4HMO23qLddjLRdXW8EUE11VJxbi3n5J0l2DiX/L1pijOaPTkbEoRK+zQinKgKGqsw==", + "requires": { + "google-protobuf": "^3.6.1" + } + }, + "ts-results": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ts-results/-/ts-results-3.2.1.tgz", + "integrity": "sha512-cMvWPLvxM39fSQgSHRT2d+dwQfpK+ttfj5FpPuXum9m/pm6iDmgsirpWXp/3/ErmZqx1x+rAhJi/33NQqCCM3Q==" + }, + "tsconfig-paths": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", + "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + }, + "dependencies": {} + }, "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "tslint": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz", + "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==", + "requires": { + "@babel/code-frame": "^7.0.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^4.0.1", + "glob": "^7.1.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.3", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.13.0", + "tsutils": "^2.29.0" + }, + "dependencies": {} + }, + "tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "requires": { + "tslib": "^1.8.1" + } + }, + "tweetnacl-ts": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl-ts/-/tweetnacl-ts-1.0.3.tgz", + "integrity": "sha512-C5I/dWf6xjAXaCDlf84T4HvozU/8ycAlq5WRllF1hAeeq5390tfXD+bNas5bhEV0HMSOx8bsQYpLjPl8wfnEeQ==", + "requires": { + "tslib": "^1" + } + }, + "tweetnacl-util": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", + "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==" + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" + }, + "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==" + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "typedjson": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/typedjson/-/typedjson-1.7.0.tgz", + "integrity": "sha512-MnRgQLwtEcdHqQG0FkT8ebpBG53Wgr/axYRbiD2WL5NcYx8Z2AoCpXvtTfLnuPqOBKG/9JpXq0O/nl2m4wqJYw==", + "requires": { + "tslib": "^2.0.1" + }, + "dependencies": {} + }, + "typedoc": { + "version": "0.17.8", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.17.8.tgz", + "integrity": "sha512-/OyrHCJ8jtzu+QZ+771YaxQ9s4g5Z3XsQE3Ma7q+BL392xxBn4UMvvCdVnqKC2T/dz03/VXSLVKOP3lHmDdc/w==", + "requires": { + "fs-extra": "^8.1.0", + "handlebars": "^4.7.6", + "highlight.js": "^10.0.0", + "lodash": "^4.17.15", + "lunr": "^2.3.8", + "marked": "1.0.0", + "minimatch": "^3.0.0", + "progress": "^2.0.3", + "shelljs": "^0.8.4", + "typedoc-default-themes": "^0.10.2" + } + }, + "typedoc-default-themes": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/typedoc-default-themes/-/typedoc-default-themes-0.10.2.tgz", + "integrity": "sha512-zo09yRj+xwLFE3hyhJeVHWRSPuKEIAsFK5r2u47KL/HBKqpwdUSanoaz5L34IKiSATFrjG5ywmIu98hPVMfxZg==", + "requires": { + "lunr": "^2.3.8" + } + }, + "typescript": { + "version": "3.9.9", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.9.tgz", + "integrity": "sha512-kdMjTiekY+z/ubJCATUPlRDl39vXYiMV9iyeMuEuXZh2we6zz80uovNN2WlAxmmdE/Z/YQe+EbOEXB5RHEED3w==" + }, + "uglify-js": { + "version": "3.13.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.4.tgz", + "integrity": "sha512-kv7fCkIXyQIilD5/yQy8O+uagsYIOt5cZvs890W40/e/rvjMSzJw81o9Bg0tkURxzZBROtDQhW2LFjOGoK3RZw==", + "optional": true + }, + "unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "requires": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + } + }, + "undefsafe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz", + "integrity": "sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==", + "requires": { + "debug": "^2.2.0" + }, + "dependencies": {} + }, + "unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "requires": { + "crypto-random-string": "^2.0.0" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "update-notifier": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", + "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==", + "requires": { + "boxen": "^4.2.0", + "chalk": "^3.0.0", + "configstore": "^5.0.1", + "has-yarn": "^2.1.0", + "import-lazy": "^2.1.0", + "is-ci": "^2.0.0", + "is-installed-globally": "^0.3.1", + "is-npm": "^4.0.0", + "is-yarn-global": "^0.3.0", + "latest-version": "^5.0.0", + "pupa": "^2.0.1", + "semver-diff": "^3.1.1", + "xdg-basedir": "^4.0.0" + }, + "dependencies": {} + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "requires": { + "punycode": "^2.1.0" + } + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": {} + }, + "url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "requires": { + "prepend-http": "^2.0.0" + }, + "dependencies": {} + }, + "util": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.3.tgz", + "integrity": "sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog==", + "requires": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "safe-buffer": "^5.1.2", + "which-typed-array": "^1.1.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + }, + "v8-compile-cache": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", - "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" - } - } - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "requires": { - "punycode": "^2.1.0" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "watchpack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.2.0.tgz", - "integrity": "sha512-up4YAn/XHgZHIxFBVCdlMiWDj6WaLKpwVeGQk2I5thdYxF/KmF0aaz6TfJZ/hfl1h/XlcDr7k1KH7ThDagpFaA==", - "requires": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - } - }, - "webpack": { - "version": "5.45.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.45.1.tgz", - "integrity": "sha512-68VT2ZgG9EHs6h6UxfV2SEYewA9BA3SOLSnC2NEbJJiEwbAiueDL033R1xX0jzjmXvMh0oSeKnKgbO2bDXIEyQ==", - "requires": { - "@types/eslint-scope": "^3.7.0", - "@types/estree": "^0.0.50", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "acorn": "^8.4.1", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.8.0", - "es-module-lexer": "^0.7.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.4", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", - "watchpack": "^2.2.0", - "webpack-sources": "^2.3.0" - }, - "dependencies": { - "acorn": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", - "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==" + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==" + }, + "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==", + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "watchpack": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.1.1.tgz", + "integrity": "sha512-Oo7LXCmc1eE1AjyuSBmtC3+Wy4HcV8PxWh2kP6fOl8yTlNS7r0K9l1ao2lrrUza7V39Y3D/BbJgY8VeSlc5JKw==", + "requires": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + } + }, + "webpack": { + "version": "5.35.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.35.0.tgz", + "integrity": "sha512-au3gu55yYF/h6NXFr0KZPZAYxS6Nlc595BzYPke8n0CSff5WXcoixtjh5LC/8mXunkRKxhymhXmBY0+kEbR6jg==", + "requires": { + "@types/eslint-scope": "^3.7.0", + "@types/estree": "^0.0.47", + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/wasm-edit": "1.11.0", + "@webassemblyjs/wasm-parser": "1.11.0", + "acorn": "^8.0.4", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.8.0", + "es-module-lexer": "^0.4.0", + "eslint-scope": "^5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.4", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.0.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.1.1", + "watchpack": "^2.0.0", + "webpack-sources": "^2.1.1" + } + }, + "webpack-cli": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.6.0.tgz", + "integrity": "sha512-9YV+qTcGMjQFiY7Nb1kmnupvb1x40lfpj8pwdO/bom+sQiP4OBMKjHq29YQrlDWDPZO9r/qWaRRywKaRDKqBTA==", + "requires": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^1.0.2", + "@webpack-cli/info": "^1.2.3", + "@webpack-cli/serve": "^1.3.1", + "colorette": "^1.2.1", + "commander": "^7.0.0", + "enquirer": "^2.3.6", + "execa": "^5.0.0", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^2.2.0", + "rechoir": "^0.7.0", + "v8-compile-cache": "^2.2.0", + "webpack-merge": "^5.7.3" + }, + "dependencies": {} + }, + "webpack-merge": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.7.3.tgz", + "integrity": "sha512-6/JUQv0ELQ1igjGDzHkXbVDRxkfA57Zw7PfiupdLFJYrgFqY5ZP8xxbpp2lU3EPwYx89ht5Z/aDkD40hFCm5AA==", + "requires": { + "clone-deep": "^4.0.1", + "wildcard": "^2.0.0" + } + }, + "webpack-node-externals": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/webpack-node-externals/-/webpack-node-externals-2.5.2.tgz", + "integrity": "sha512-aHdl/y2N7PW2Sx7K+r3AxpJO+aDMcYzMQd60Qxefq3+EwhewSbTBqNumOsCE1JsCUNoyfGj5465N0sSf6hc/5w==" + }, + "webpack-sources": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.2.0.tgz", + "integrity": "sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w==", + "requires": { + "source-list-map": "^2.0.1", + "source-map": "^0.6.1" + } + }, + "whatwg-fetch": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", + "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==" + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "requires": { + "isexe": "^2.0.0" + } + }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + }, + "which-pm-runs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", + "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=" + }, + "which-typed-array": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.4.tgz", + "integrity": "sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA==", + "requires": { + "available-typed-arrays": "^1.0.2", + "call-bind": "^1.0.0", + "es-abstract": "^1.18.0-next.1", + "foreach": "^2.0.5", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.1", + "is-typed-array": "^1.1.3" + } + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "requires": { + "string-width": "^1.0.2 || 2" + }, + "dependencies": {} + }, + "widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "requires": { + "string-width": "^4.0.0" + } + }, + "wildcard": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", + "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==" + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" + }, + "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==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "ws": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz", + "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==" + }, + "xdg-basedir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==" + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "requires": { + "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" + } + }, + "yargs-parser": { + "version": "20.2.7", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz", + "integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==" + }, + "yargs-unparser": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", + "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "requires": { + "flat": "^4.1.0", + "lodash": "^4.17.15", + "yargs": "^13.3.0" + }, + "dependencies": {} + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" + }, + "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==" } } - }, - "webpack-sources": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.0.tgz", - "integrity": "sha512-WyOdtwSvOML1kbgtXbTDnEW0jkJ7hZr/bDByIwszhWd/4XX1A3XMkrbFMsuH4+/MfLlZCUzlAdg4r7jaGKEIgQ==", - "requires": { - "source-list-map": "^2.0.1", - "source-map": "^0.6.1" - } - }, - "whatwg-fetch": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", - "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==" - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "ws": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz", - "integrity": "sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==" - }, - "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==" } } } diff --git a/dragons-nft-scripts/package.json b/dragons-nft-scripts/package.json index b1c7c91..acd5b71 100644 --- a/dragons-nft-scripts/package.json +++ b/dragons-nft-scripts/package.json @@ -16,7 +16,7 @@ "author": "", "license": "ISC", "dependencies": { - "casper-js-sdk": "2.1.0", - "casper-cep47-js-client": "0.1.1" + "casper-js-sdk": "/Users/janhoffmann/Work/casperlabs/casper-js-sdk", + "casper-cep47-js-client": "/Users/janhoffmann/Work/casperlabs/casper-cep47-js-client" } } diff --git a/dragons-nft-scripts/src/index.js b/dragons-nft-scripts/src/index.js index d48f09a..c66e258 100644 --- a/dragons-nft-scripts/src/index.js +++ b/dragons-nft-scripts/src/index.js @@ -1,14 +1,15 @@ -const { Keys, CLPublicKey } = require("casper-js-sdk"); -const { CEP47Client, utils } = require("casper-cep47-js-client"); +const { CLValueBuilder, Keys, CLPublicKey } = require("casper-js-sdk"); +const { CEP47Client, utils, constants } = require("casper-cep47-js-client"); -const NODE_ADDRESS = 'http://3.143.158.19:7777/rpc'; -// const NODE_ADDRESS = 'http://localhost:40101/rpc'; +// const NODE_ADDRESS = 'http://3.143.158.19:7777/rpc'; +const NODE_ADDRESS = 'http://localhost:40101/rpc'; +const EVENT_STREAM_ADDRESS = 'http://localhost:60101/events'; const INSTALL_PAYMENT_AMOUNT = '200000000000'; const MINT_ONE_PAYMENT_AMOUNT = '2000000000'; const MINT_COPIES_PAYMENT_AMOUNT = '100000000000'; const BURN_ONE_PAYMENT_AMOUNT = '2000000000'; -const CHAIN_NAME = 'integration-test'; -// const CHAIN_NAME = 'casper-net-1'; +// const CHAIN_NAME = 'integration-test'; +const CHAIN_NAME = 'casper-net-1'; const WASM_PATH = "./../target/wasm32-unknown-unknown/release/dragons-nft.wasm"; const TOKEN_NAME = 'event_nft_2'; const TOKEN_SYMBOL = 'DRAG'; @@ -16,7 +17,8 @@ const TOKEN_META = new Map([ ['origin', 'fire'], ['lifetime', 'infinite'] ]); -const KEY_PAIR_PATH = '/home/ziel/workspace/casperlabs/integration-key/master'; +// const KEY_PAIR_PATH = '/home/ziel/workspace/casperlabs/integration-key/master'; +const KEY_PAIR_PATH = '/Users/janhoffmann/casper-node/utils/nctl/assets/net-1/faucet'; const KEYS = Keys.Ed25519.parseKeyFiles( `${KEY_PAIR_PATH}/public_key.pem`, `${KEY_PAIR_PATH}/secret_key.pem` @@ -25,9 +27,9 @@ const MINT_ONE_META_SIZE = 4; const MINT_COPIES_META_SIZE = 10; const MINT_MANY_META_SIZE = 10; const MINT_COPIES_COUNT = 5; -const CONTRACT_HASH = '854db6358ec33c9d5049421f141165bd373d387fb14bb1dfa3319cdc8c873597'; +const CONTRACT_HASH = '60fe137c02d042419c52647c175c7683a3fdce71f3496a21463d61c478af27f4'; -const cep47 = new CEP47Client(NODE_ADDRESS, CHAIN_NAME); +const cep47 = new CEP47Client(NODE_ADDRESS, CHAIN_NAME, EVENT_STREAM_ADDRESS); const install = async () => { const deployHash = await cep47.install( @@ -37,7 +39,7 @@ const install = async () => { }; const mintOne = async () => { - cep47.setContractHash(CONTRACT_HASH); + await cep47.setContractHash(CONTRACT_HASH); let meta = randomMetaMap(MINT_ONE_META_SIZE); const deployHash = await cep47.mintOne(KEYS, KEYS.publicKey, meta, MINT_ONE_PAYMENT_AMOUNT); console.log(`Mint One`); @@ -45,14 +47,14 @@ const mintOne = async () => { } const pause = async () => { - cep47.setContractHash(CONTRACT_HASH); + await cep47.setContractHash(CONTRACT_HASH); const deployHash = await cep47.pause(KEYS, MINT_ONE_PAYMENT_AMOUNT); console.log(`Pause`); console.log(`... DeployHash: ${deployHash}`); } const mintCopies = async () => { - cep47.setContractHash(CONTRACT_HASH); + await cep47.setContractHash(CONTRACT_HASH); let meta = randomMetaMap(MINT_COPIES_META_SIZE); const deployHash = await cep47.mintCopies( KEYS, KEYS.publicKey, meta, MINT_COPIES_COUNT, MINT_COPIES_PAYMENT_AMOUNT); @@ -61,7 +63,7 @@ const mintCopies = async () => { } const mintMany = async () => { - cep47.setContractHash(CONTRACT_HASH); + await cep47.setContractHash(CONTRACT_HASH); let meta = randomMetaArray(MINT_MANY_META_SIZE); const deployHash = await cep47.mintMany( KEYS, KEYS.publicKey, meta, MINT_COPIES_PAYMENT_AMOUNT); @@ -70,37 +72,37 @@ const mintMany = async () => { } const burnOne = async (tokenId) => { - cep47.setContractHash(CONTRACT_HASH); + await cep47.setContractHash(CONTRACT_HASH); const deployHash = await cep47.burnOne(KEYS, KEYS.publicKey, tokenId, BURN_ONE_PAYMENT_AMOUNT); console.log(`Burn One`); console.log(`... DeployHash: ${deployHash}`); } const getName = async () => { - cep47.setContractHash(CONTRACT_HASH); + await cep47.setContractHash(CONTRACT_HASH); const value = await cep47.name(); console.log(`Contract Name: ${value}`); } const balanceOf = async () => { - cep47.setContractHash(CONTRACT_HASH); + await cep47.setContractHash(CONTRACT_HASH); const balance = await cep47.balanceOf(CLPublicKey.fromHex("01694a09937e05f5a60b5f56d1d108f65ae716c45879fca79fca89ec1c20e15431")); console.log(`Balance: ${balance.value()}`); } const tokensOf = async (publicKeyHex) => { - cep47.setContractHash(CONTRACT_HASH); + await cep47.setContractHash(CONTRACT_HASH); const value = await cep47.getTokensOf(CLPublicKey.fromHex(publicKeyHex)); console.log(`Tokens: ${JSON.stringify(value, null, 2)}`); } const ownerOf = async (tokenId) => { - cep47.setContractHash(CONTRACT_HASH); + await cep47.setContractHash(CONTRACT_HASH); const value = await cep47.getOwnerOf(tokenId); console.log(`Owner public key hex: ${value}`); } const tokenMeta = async (tokenId) => { - cep47.setContractHash(CONTRACT_HASH); + await cep47.setContractHash(CONTRACT_HASH); const value = await cep47.getTokenMeta(tokenId); console.log('Token meta', value); } @@ -110,8 +112,27 @@ const printAccount = async () => { console.log(account); } +const getContractData = async () => { + const stateRootHash = await utils.getStateRootHash(NODE_ADDRESS); + const contractData = await utils.getContractData(NODE_ADDRESS, stateRootHash, CONTRACT_HASH); + console.log(contractData); +} + +const listenTo = async () => { + await cep47.setContractHash(CONTRACT_HASH); + const { stopListening } = cep47.onEvent([constants.CEP47Events.Mint], (eventName, data) => { + console.log("+", eventName, data); + }) + + console.log('Listening to...'); + setTimeout(() => { + console.log("Stopping"); + stopListening(); + }, 10000); +} + const getSimpleValue = async (name) => { - cep47.setContractHash(CONTRACT_HASH); + await cep47.setContractHash(CONTRACT_HASH); const value = await cep47[name](); console.log(name, value); }; @@ -184,6 +205,12 @@ switch (command) { case 'print_account': printAccount(); break; + case 'get_contract': + getContractData(); + break; + case 'listen_to': + listenTo(); + break; default: console.log(`Command unknown ${command}`) } From 97042e0a4d1a70f9b97175637566171e33b14eb5 Mon Sep 17 00:00:00 2001 From: Jan Hoffmann Date: Wed, 21 Jul 2021 18:28:36 +0200 Subject: [PATCH 45/98] added transfer and transferAll --- dragons-nft-scripts/src/index.js | 49 ++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 8 deletions(-) diff --git a/dragons-nft-scripts/src/index.js b/dragons-nft-scripts/src/index.js index c66e258..4c826c8 100644 --- a/dragons-nft-scripts/src/index.js +++ b/dragons-nft-scripts/src/index.js @@ -7,11 +7,11 @@ const EVENT_STREAM_ADDRESS = 'http://localhost:60101/events'; const INSTALL_PAYMENT_AMOUNT = '200000000000'; const MINT_ONE_PAYMENT_AMOUNT = '2000000000'; const MINT_COPIES_PAYMENT_AMOUNT = '100000000000'; -const BURN_ONE_PAYMENT_AMOUNT = '2000000000'; +const BURN_ONE_PAYMENT_AMOUNT = '12000000000'; // const CHAIN_NAME = 'integration-test'; const CHAIN_NAME = 'casper-net-1'; const WASM_PATH = "./../target/wasm32-unknown-unknown/release/dragons-nft.wasm"; -const TOKEN_NAME = 'event_nft_2'; +const TOKEN_NAME = 'event_nft_3'; const TOKEN_SYMBOL = 'DRAG'; const TOKEN_META = new Map([ ['origin', 'fire'], @@ -27,7 +27,7 @@ const MINT_ONE_META_SIZE = 4; const MINT_COPIES_META_SIZE = 10; const MINT_MANY_META_SIZE = 10; const MINT_COPIES_COUNT = 5; -const CONTRACT_HASH = '60fe137c02d042419c52647c175c7683a3fdce71f3496a21463d61c478af27f4'; +const CONTRACT_HASH = 'cd02755c7e42c3f191f005d2e3a42324488056be0361935bdbcb6b4722dab14b'; const cep47 = new CEP47Client(NODE_ADDRESS, CHAIN_NAME, EVENT_STREAM_ADDRESS); @@ -118,17 +118,44 @@ const getContractData = async () => { console.log(contractData); } +const transferToken = async () => { + await cep47.setContractHash(CONTRACT_HASH); + await cep47.transferToken( + KEYS, + KEYS.publicKey, + CLPublicKey.fromHex('017b4822b849f197acf4f49d91315887f913128a9673a2d7ea834cf13c2e6fc606'), '17873237509455618405', + MINT_ONE_PAYMENT_AMOUNT * 100 + ); +} + +const transferAll = async () => { + await cep47.setContractHash(CONTRACT_HASH); + await cep47.transferAllTokens( + KEYS, + KEYS.publicKey, + CLPublicKey.fromHex('017b4822b849f197acf4f49d91315887f913128a9673a2d7ea834cf13c2e6fc606'), + MINT_ONE_PAYMENT_AMOUNT * 100 + ); +} + const listenTo = async () => { await cep47.setContractHash(CONTRACT_HASH); - const { stopListening } = cep47.onEvent([constants.CEP47Events.Mint], (eventName, data) => { + const { stopListening } = cep47.onEvent( + [ + constants.CEP47Events.Mint, + constants.CEP47Events.TransferToken, + constants.CEP47Events.TransferAllTokens, + constants.CEP47Events.BurnOne + ], + (eventName, data) => { console.log("+", eventName, data); }) console.log('Listening to...'); - setTimeout(() => { - console.log("Stopping"); - stopListening(); - }, 10000); + // setTimeout(() => { + // console.log("Stopping"); + // stopListening(); + // }, 10000); } const getSimpleValue = async (name) => { @@ -208,6 +235,12 @@ switch (command) { case 'get_contract': getContractData(); break; + case 'transfer_token': + transferToken(); + break; + case 'transfer_all': + transferAll(); + break; case 'listen_to': listenTo(); break; From f2ed19385512b9af5b82a2c06137daa5a66bf7d9 Mon Sep 17 00:00:00 2001 From: Maciej Zielinski Date: Wed, 21 Jul 2021 18:31:44 +0200 Subject: [PATCH 46/98] Update rust-toolchain. --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index cfafc52..18433b9 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -nightly-2020-12-16 \ No newline at end of file +nightly-2021-06-17 \ No newline at end of file From 4af1dad4582027f56f7c5e88784a587eb5ea6265 Mon Sep 17 00:00:00 2001 From: Maciej Zielinski Date: Wed, 21 Jul 2021 18:34:37 +0200 Subject: [PATCH 47/98] dragons nft scripts package.json upgrade --- dragons-nft-scripts/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dragons-nft-scripts/package.json b/dragons-nft-scripts/package.json index acd5b71..ed07995 100644 --- a/dragons-nft-scripts/package.json +++ b/dragons-nft-scripts/package.json @@ -16,7 +16,7 @@ "author": "", "license": "ISC", "dependencies": { - "casper-js-sdk": "/Users/janhoffmann/Work/casperlabs/casper-js-sdk", - "casper-cep47-js-client": "/Users/janhoffmann/Work/casperlabs/casper-cep47-js-client" + "casper-js-sdk": "2.2.0", + "casper-cep47-js-client": "0.2.0" } } From 27af89aa7762795d063d10c7e72489abedeff8eb Mon Sep 17 00:00:00 2001 From: Maciej Zielinski Date: Wed, 21 Jul 2021 18:42:12 +0200 Subject: [PATCH 48/98] Disable clippy for now. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 3478233..0bea48a 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ copy-wasm-file-to-test: test: build-contract copy-wasm-file-to-test test-only clippy: - cargo clippy --all-targets --all + echo 1 check-lint: clippy cargo fmt --all -- --check From f4a7d5a878b3b0e3af1b315ef6e3f33917449d45 Mon Sep 17 00:00:00 2001 From: Jan Hoffmann Date: Thu, 22 Jul 2021 12:30:43 +0200 Subject: [PATCH 49/98] package lock updated --- dragons-nft-scripts/package-lock.json | 13337 +++--------------------- 1 file changed, 1190 insertions(+), 12147 deletions(-) diff --git a/dragons-nft-scripts/package-lock.json b/dragons-nft-scripts/package-lock.json index 768a988..5ba13d1 100644 --- a/dragons-nft-scripts/package-lock.json +++ b/dragons-nft-scripts/package-lock.json @@ -4,7097 +4,426 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@ethersproject/bignumber": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.4.0.tgz", + "integrity": "sha512-OXUu9f9hO3vGRIPxU40cignXZVaYyfx6j9NNMjebKdnaCL3anCLSSy8/b8d03vY6dh7duCC0kW72GEC4tZer2w==", + "requires": { + "@ethersproject/bytes": "^5.4.0", + "@ethersproject/logger": "^5.4.0", + "bn.js": "^4.11.9" + } + }, + "@ethersproject/bytes": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.4.0.tgz", + "integrity": "sha512-H60ceqgTHbhzOj4uRc/83SCN9d+BSUnOkrr2intevqdtEMO1JFVZ1XL84OEZV+QjV36OaZYxtnt4lGmxcGsPfA==", + "requires": { + "@ethersproject/logger": "^5.4.0" + } + }, + "@ethersproject/constants": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.4.0.tgz", + "integrity": "sha512-tzjn6S7sj9+DIIeKTJLjK9WGN2Tj0P++Z8ONEIlZjyoTkBuODN+0VfhAyYksKi43l1Sx9tX2VlFfzjfmr5Wl3Q==", + "requires": { + "@ethersproject/bignumber": "^5.4.0" + } + }, + "@ethersproject/logger": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.4.0.tgz", + "integrity": "sha512-xYdWGGQ9P2cxBayt64d8LC8aPFJk6yWCawQi/4eJ4+oJdMMjEBMrIcIMZ9AxhwpPVmnBPrsB10PcXGmGAqgUEQ==" + }, + "@open-rpc/client-js": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@open-rpc/client-js/-/client-js-1.7.0.tgz", + "integrity": "sha512-cRGJbXTgdhJNU49vWzJIATRmKBLP2x6tuHJzX9Jg3N8f1VEkge0riUEek2LFIrZiM4TdUp8XV4Ns1W0SZzdfSw==", + "requires": { + "isomorphic-fetch": "^3.0.0", + "isomorphic-ws": "^4.0.1", + "strict-event-emitter-types": "^2.0.0", + "ws": "^7.0.0" + } + }, + "@types/bn.js": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", + "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", + "requires": { + "@types/node": "*" + } + }, + "@types/eccrypto": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@types/eccrypto/-/eccrypto-1.1.3.tgz", + "integrity": "sha512-3O0qER6JMYReqVbcQTGmXeMHdw3O+rVps63tlo5g5zoB3altJS8yzSvboSivwVWeYO9o5jSATu7P0UIqYZPgow==", + "requires": { + "@types/expect": "^1.20.4", + "@types/node": "*" + } + }, + "@types/elliptic": { + "version": "6.4.13", + "resolved": "https://registry.npmjs.org/@types/elliptic/-/elliptic-6.4.13.tgz", + "integrity": "sha512-e8iyLJ8vMLpWxXpVWrIt0ujqsfHWgVe5XAz9IMhBYoDirK6th7J+mHjzp797OLc62ZX419nrlwwzsNAA0a0mKg==", + "requires": { + "@types/bn.js": "*" + } + }, + "@types/eslint": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.28.0.tgz", + "integrity": "sha512-07XlgzX0YJUn4iG1ocY4IX9DzKSmMGUs6ESKlxWhZRaa0fatIWaHWUVapcuGa8r5HFnTqzj+4OCjd5f7EZ/i/A==", + "requires": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "@types/eslint-scope": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.1.tgz", + "integrity": "sha512-SCFeogqiptms4Fg29WpOTk5nHIzfpKCemSN63ksBQYKTcXoJEmJagV+DhVmbapZzY4/5YaOV1nZwrsU79fFm1g==", + "requires": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "@types/estree": { + "version": "0.0.50", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz", + "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==" + }, + "@types/expect": { + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/@types/expect/-/expect-1.20.4.tgz", + "integrity": "sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg==" + }, + "@types/json-schema": { + "version": "7.0.8", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.8.tgz", + "integrity": "sha512-YSBPTLTVm2e2OoQIDYx8HaeWJ5tTToLH67kXR7zYNGupXMEHa2++G8k+DczX2cFVgalypqtyZIcU19AFcmOpmg==" + }, + "@types/node": { + "version": "16.4.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.4.0.tgz", + "integrity": "sha512-HrJuE7Mlqcjj+00JqMWpZ3tY8w7EUd+S0U3L1+PQSWiXZbOgyQDvi+ogoUxaHApPJq5diKxYBQwA3iIlNcPqOg==" + }, + "@types/pbkdf2": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", + "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", + "requires": { + "@types/node": "*" + } + }, + "@types/secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==", + "requires": { + "@types/node": "*" + } + }, + "@webassemblyjs/ast": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", + "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", + "requires": { + "@webassemblyjs/helper-numbers": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", + "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==" + }, + "@webassemblyjs/helper-api-error": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", + "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==" + }, + "@webassemblyjs/helper-buffer": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", + "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==" + }, + "@webassemblyjs/helper-numbers": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", + "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", + "requires": { + "@webassemblyjs/floating-point-hex-parser": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", + "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==" + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", + "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", + "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", + "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", + "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==" + }, + "@webassemblyjs/wasm-edit": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", + "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/helper-wasm-section": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-opt": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "@webassemblyjs/wast-printer": "1.11.1" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", + "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", + "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", + "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", + "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@xtuc/long": "4.2.2" + } + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" + }, + "acorn": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", + "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==" + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==" + }, + "asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "base-x": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz", + "integrity": "sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "optional": true, + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "bip66": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", + "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", + "optional": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "blakejs": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.1.tgz", + "integrity": "sha512-bLG6PHOCZJKNshTjGRBvET0vTciwQE6zFKOKKXPDJfwFBd4Ac0yBfPZqcGvGJap50l7ktvlpFqc2jGVaUgbJgg==" + }, + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserslist": { + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", + "requires": { + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", + "escalade": "^3.1.1", + "node-releases": "^1.1.71" + } + }, + "bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", + "requires": { + "base-x": "^3.0.2" + } + }, + "bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "requires": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" + }, + "caniuse-lite": { + "version": "1.0.30001246", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001246.tgz", + "integrity": "sha512-Tc+ff0Co/nFNbLOrziBXmMVtpt9S2c2Y+Z9Nk9Khj09J+0zR9ejvIW5qkZAErCbOrVODCx/MN+GpB5FNBs5GFA==" + }, "casper-cep47-js-client": { - "version": "file:../../casper-cep47-js-client", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/casper-cep47-js-client/-/casper-cep47-js-client-0.2.0.tgz", + "integrity": "sha512-zc+3LeDsIEzc9wp7f3Tw5+nxNJgz/WwcnZ3nmpM2LM7BCzka9y46M7ZNNVn/IVhlDme5kHhEcDTpgnWkHTdECw==", "requires": { "@ethersproject/bignumber": "^5.0.8", - "casper-js-sdk": "file:../../casper-js-sdk" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", - "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", - "requires": { - "@babel/highlight": "^7.14.5" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", - "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==" - }, - "@babel/highlight": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", - "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", - "requires": { - "@babel/helper-validator-identifier": "^7.14.5", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@ethersproject/bignumber": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.4.0.tgz", - "integrity": "sha512-OXUu9f9hO3vGRIPxU40cignXZVaYyfx6j9NNMjebKdnaCL3anCLSSy8/b8d03vY6dh7duCC0kW72GEC4tZer2w==", - "requires": { - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "bn.js": "^4.11.9" - } - }, - "@ethersproject/bytes": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.4.0.tgz", - "integrity": "sha512-H60ceqgTHbhzOj4uRc/83SCN9d+BSUnOkrr2intevqdtEMO1JFVZ1XL84OEZV+QjV36OaZYxtnt4lGmxcGsPfA==", - "requires": { - "@ethersproject/logger": "^5.4.0" - } - }, - "@ethersproject/logger": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.4.0.tgz", - "integrity": "sha512-xYdWGGQ9P2cxBayt64d8LC8aPFJk6yWCawQi/4eJ4+oJdMMjEBMrIcIMZ9AxhwpPVmnBPrsB10PcXGmGAqgUEQ==" - }, - "@tsconfig/node10": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", - "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==" - }, - "@tsconfig/node12": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", - "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==" - }, - "@tsconfig/node14": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", - "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==" - }, - "@tsconfig/node16": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.1.tgz", - "integrity": "sha512-FTgBI767POY/lKNDNbIzgAX6miIDBs6NTCbdlDb8TrWovHsSvaVIZDlTqym29C6UqhzwcJx4CYr+AlrMywA0cA==" - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" - }, - "casper-js-sdk": { - "version": "file:../../casper-js-sdk", - "requires": { - "@ethersproject/bignumber": "^5.0.8", - "@ethersproject/bytes": "^5.0.5", - "@ethersproject/constants": "^5.0.5", - "@open-rpc/client-js": "^1.6.2", - "@types/eccrypto": "^1.1.2", - "blakejs": "^1.1.0", - "eccrypto": "^1.1.6", - "eslint-plugin-prettier": "^3.4.0", - "ethereum-cryptography": "^0.1.3", - "glob": "^7.1.6", - "humanize-duration": "^3.24.0", - "key-encoder": "^2.0.3", - "reflect-metadata": "^0.1.13", - "ts-results": "^3.2.1", - "tweetnacl-ts": "^1.0.3", - "tweetnacl-util": "^0.15.0", - "typedjson": "^1.6.0-rc2", - "webpack": "^5.24.3" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", - "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", - "requires": { - "@babel/highlight": "^7.12.13" - } - }, - "@babel/compat-data": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.13.15.tgz", - "integrity": "sha512-ltnibHKR1VnrU4ymHyQ/CXtNXI6yZC0oJThyW78Hft8XndANwi+9H+UIklBDraIjFEJzw8wmcM427oDd9KS5wA==" - }, - "@babel/core": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.16.tgz", - "integrity": "sha512-sXHpixBiWWFti0AV2Zq7avpTasr6sIAu7Y396c608541qAU2ui4a193m0KSQmfPSKFZLnQ3cvlKDOm3XkuXm3Q==", - "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.13.16", - "@babel/helper-compilation-targets": "^7.13.16", - "@babel/helper-module-transforms": "^7.13.14", - "@babel/helpers": "^7.13.16", - "@babel/parser": "^7.13.16", - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.15", - "@babel/types": "^7.13.16", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", - "semver": "^6.3.0", - "source-map": "^0.5.0" - }, - "dependencies": { - "@babel/generator": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.1.tgz", - "integrity": "sha512-TMGhsXMXCP/O1WtQmZjpEYDhCYC9vFhayWZPJSZCGkPJgUqX0rF0wwtrYvnzVxIjcF80tkUertXVk5cwqi5cAQ==", - "requires": { - "@babel/types": "^7.14.1", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - }, - "dependencies": { - "@babel/types": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.1.tgz", - "integrity": "sha512-S13Qe85fzLs3gYRUnrpyeIrBJIMYv33qSTg1qoBwiG6nPKwUWAD9odSzWhEedpwOIzSEI6gbdQIWEMiCI42iBA==", - "requires": { - "@babel/helper-validator-identifier": "^7.14.0", - "to-fast-properties": "^2.0.0" - } - } - } - }, - "@babel/helper-validator-identifier": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", - "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==" - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - } - } - }, - "@babel/helper-compilation-targets": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz", - "integrity": "sha512-3gmkYIrpqsLlieFwjkGgLaSHmhnvlAYzZLlYVjlW+QwI+1zE17kGxuJGmIqDQdYp56XdmGeD+Bswx0UTyG18xA==", - "requires": { - "@babel/compat-data": "^7.13.15", - "@babel/helper-validator-option": "^7.12.17", - "browserslist": "^4.14.5", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } - } - }, - "@babel/helper-function-name": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", - "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", - "requires": { - "@babel/helper-get-function-arity": "^7.12.13", - "@babel/template": "^7.12.13", - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", - "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", - "requires": { - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz", - "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==", - "requires": { - "@babel/types": "^7.13.12" - } - }, - "@babel/helper-module-imports": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz", - "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==", - "requires": { - "@babel/types": "^7.13.12" - } - }, - "@babel/helper-module-transforms": { - "version": "7.13.14", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.13.14.tgz", - "integrity": "sha512-QuU/OJ0iAOSIatyVZmfqB0lbkVP0kDRiKj34xy+QNsnVZi/PA6BoSoreeqnxxa9EHFAIL0R9XOaAR/G9WlIy5g==", - "requires": { - "@babel/helper-module-imports": "^7.13.12", - "@babel/helper-replace-supers": "^7.13.12", - "@babel/helper-simple-access": "^7.13.12", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/helper-validator-identifier": "^7.12.11", - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.13", - "@babel/types": "^7.13.14" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", - "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", - "requires": { - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-replace-supers": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz", - "integrity": "sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw==", - "requires": { - "@babel/helper-member-expression-to-functions": "^7.13.12", - "@babel/helper-optimise-call-expression": "^7.12.13", - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.12" - } - }, - "@babel/helper-simple-access": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz", - "integrity": "sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==", - "requires": { - "@babel/types": "^7.13.12" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", - "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", - "requires": { - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==" - }, - "@babel/helper-validator-option": { - "version": "7.12.17", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz", - "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==" - }, - "@babel/helpers": { - "version": "7.13.17", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.13.17.tgz", - "integrity": "sha512-Eal4Gce4kGijo1/TGJdqp3WuhllaMLSrW6XcL0ulyUAQOuxHcCafZE8KHg9857gcTehsm/v7RcOx2+jp0Ryjsg==", - "requires": { - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.17", - "@babel/types": "^7.13.17" - } - }, - "@babel/highlight": { - "version": "7.13.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.10.tgz", - "integrity": "sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg==", - "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "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==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/parser": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.16.tgz", - "integrity": "sha512-6bAg36mCwuqLO0hbR+z7PHuqWiCeP7Dzg73OpQwsAB1Eb8HnGEz5xYBzCfbu+YjoaJsJs+qheDxVAuqbt3ILEw==" - }, - "@babel/template": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", - "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", - "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/parser": "^7.12.13", - "@babel/types": "^7.12.13" - } - }, - "@babel/traverse": { - "version": "7.13.17", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.17.tgz", - "integrity": "sha512-BMnZn0R+X6ayqm3C3To7o1j7Q020gWdqdyP50KEoVqaCO2c/Im7sYZSmVgvefp8TTMQ+9CtwuBp0Z1CZ8V3Pvg==", - "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.13.16", - "@babel/helper-function-name": "^7.12.13", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/parser": "^7.13.16", - "@babel/types": "^7.13.17", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "dependencies": { - "@babel/generator": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.1.tgz", - "integrity": "sha512-TMGhsXMXCP/O1WtQmZjpEYDhCYC9vFhayWZPJSZCGkPJgUqX0rF0wwtrYvnzVxIjcF80tkUertXVk5cwqi5cAQ==", - "requires": { - "@babel/types": "^7.14.1", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - }, - "dependencies": { - "@babel/types": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.1.tgz", - "integrity": "sha512-S13Qe85fzLs3gYRUnrpyeIrBJIMYv33qSTg1qoBwiG6nPKwUWAD9odSzWhEedpwOIzSEI6gbdQIWEMiCI42iBA==", - "requires": { - "@babel/helper-validator-identifier": "^7.14.0", - "to-fast-properties": "^2.0.0" - } - } - } - }, - "@babel/helper-validator-identifier": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", - "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==" - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - } - } - }, - "@babel/types": { - "version": "7.13.17", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.17.tgz", - "integrity": "sha512-RawydLgxbOPDlTLJNtoIypwdmAy//uQIzlKt2+iBiJaRlVuI6QLUxVAyWGNfOzp8Yu4L4lLIacoCyTNtpb4wiA==", - "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "to-fast-properties": "^2.0.0" - } - }, - "@discoveryjs/json-ext": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz", - "integrity": "sha512-HyYEUDeIj5rRQU2Hk5HTB2uHsbRQpF70nvMhVzi+VJR0X+xNEhjPui4/kBf3VeH/wqD28PT4sVOm8qqLjBrSZg==" - }, - "@eslint/eslintrc": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.0.tgz", - "integrity": "sha512-2ZPCc+uNbjV5ERJr+aKSPRwZgKd2z11x0EgLvb1PURmUrn9QNRXFqje0Ldq454PfAVyaJYyrDvvIKSFP4NnBog==", - "requires": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - }, - "dependencies": { - "globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", - "requires": { - "type-fest": "^0.8.1" - } - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" - }, - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" - } - } - }, - "@ethersproject/bignumber": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.1.1.tgz", - "integrity": "sha512-AVz5iqz7+70RIqoQTznsdJ6DOVBYciNlvO+AlQmPTB6ofCvoihI9bQdr6wljsX+d5W7Yc4nyvQvP4JMzg0Agig==", - "requires": { - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/logger": "^5.1.0", - "bn.js": "^4.4.0" - } - }, - "@ethersproject/bytes": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.1.0.tgz", - "integrity": "sha512-sGTxb+LVjFxJcJeUswAIK6ncgOrh3D8c192iEJd7mLr95V6du119rRfYT/b87WPkZ5I3gRBUYIYXtdgCWACe8g==", - "requires": { - "@ethersproject/logger": "^5.1.0" - } - }, - "@ethersproject/constants": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.1.0.tgz", - "integrity": "sha512-0/SuHrxc8R8k+JiLmJymxHJbojUDWBQqO+b+XFdwaP0jGzqC09YDy/CAlSZB6qHsBifY8X3I89HcK/oMqxRdBw==", - "requires": { - "@ethersproject/bignumber": "^5.1.0" - } - }, - "@ethersproject/logger": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.1.0.tgz", - "integrity": "sha512-wtUaD1lBX10HBXjjKV9VHCBnTdUaKQnQ2XSET1ezglqLdPdllNOIlLfhyCRqXm5xwcjExVI5ETokOYfjPtaAlw==" - }, - "@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "requires": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" - } - } - }, - "@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==" - }, - "@nodelib/fs.scandir": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", - "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==", - "requires": { - "@nodelib/fs.stat": "2.0.4", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz", - "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==" - }, - "@nodelib/fs.walk": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz", - "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==", - "requires": { - "@nodelib/fs.scandir": "2.1.4", - "fastq": "^1.6.0" - } - }, - "@open-rpc/client-js": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/@open-rpc/client-js/-/client-js-1.6.3.tgz", - "integrity": "sha512-KNlYB258FgMUopHUXqPAU4JZMAO/8HnGN7LcL/mXnwH/Qcd0GAMVwLLIXc5d9BBqtmDox8wxxAXGBCajRhyczA==", - "requires": { - "isomorphic-fetch": "^3.0.0", - "isomorphic-ws": "^4.0.1", - "strict-event-emitter-types": "^2.0.0", - "ws": "^7.0.0" - } - }, - "@sindresorhus/is": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.0.1.tgz", - "integrity": "sha512-Qm9hBEBu18wt1PO2flE7LPb30BHMQt1eQgbV76YntdNk73XZGpn3izvGTYxbGgzXKgbCjiia0uxTd3aTNQrY/g==" - }, - "@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==", - "requires": { - "defer-to-connect": "^2.0.0" - } - }, - "@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", - "requires": { - "@types/node": "*" - } - }, - "@types/body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==", - "requires": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "@types/cacheable-request": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", - "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", - "requires": { - "@types/http-cache-semantics": "*", - "@types/keyv": "*", - "@types/node": "*", - "@types/responselike": "*" - } - }, - "@types/chai": { - "version": "4.2.16", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.16.tgz", - "integrity": "sha512-vI5iOAsez9+roLS3M3+Xx7w+WRuDtSmF8bQkrbcIJ2sC1PcDgVoA0WGpa+bIrJ+y8zqY2oi//fUctkxtIcXJCw==" - }, - "@types/connect": { - "version": "3.4.34", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz", - "integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==", - "requires": { - "@types/node": "*" - } - }, - "@types/eccrypto": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/eccrypto/-/eccrypto-1.1.2.tgz", - "integrity": "sha512-qmB/iGIoqDdCMHAcJiOKI4ZBI1Z3kBQGYQCkgNP/Z9ge5w/EVx5uxQYkGOFpllm6l2N/B3qXcn9vjqXGaV1vRQ==", - "requires": { - "@types/expect": "^1.20.4", - "@types/node": "*" - } - }, - "@types/elliptic": { - "version": "6.4.12", - "resolved": "https://registry.npmjs.org/@types/elliptic/-/elliptic-6.4.12.tgz", - "integrity": "sha512-gP1KsqoouLJGH6IJa28x7PXb3cRqh83X8HCLezd2dF+XcAIMKYv53KV+9Zn6QA561E120uOqZBQ+Jy/cl+fviw==", - "requires": { - "@types/bn.js": "*" - } - }, - "@types/eslint": { - "version": "7.2.10", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.10.tgz", - "integrity": "sha512-kUEPnMKrqbtpCq/KTaGFFKAcz6Ethm2EjCoKIDaCmfRBWLbFuTcOJfTlorwbnboXBzahqWLgUp1BQeKHiJzPUQ==", - "requires": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "@types/eslint-scope": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.0.tgz", - "integrity": "sha512-O/ql2+rrCUe2W2rs7wMR+GqPRcgB6UiqN5RhrR5xruFlY7l9YLMn0ZkDzjoHLeiFkR8MCQZVudUuuvQ2BLC9Qw==", - "requires": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "@types/estree": { - "version": "0.0.47", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.47.tgz", - "integrity": "sha512-c5ciR06jK8u9BstrmJyO97m+klJrrhCf9u3rLu3DEAJBirxRqSCvDQoYKmxuYwQI5SZChAWu+tq9oVlGRuzPAg==" - }, - "@types/expect": { - "version": "1.20.4", - "resolved": "https://registry.npmjs.org/@types/expect/-/expect-1.20.4.tgz", - "integrity": "sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg==" - }, - "@types/express": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.11.tgz", - "integrity": "sha512-no+R6rW60JEc59977wIxreQVsIEOAYwgCqldrA/vkpCnbD7MqTefO97lmoBe4WE0F156bC4uLSP1XHDOySnChg==", - "requires": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.18", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "@types/express-serve-static-core": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.19.tgz", - "integrity": "sha512-DJOSHzX7pCiSElWaGR8kCprwibCB/3yW6vcT8VG3P0SJjnv19gnWG/AZMfM60Xj/YJIp/YCaDHyvzsFVeniARA==", - "requires": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*" - } - }, - "@types/http-cache-semantics": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", - "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" - }, - "@types/humanize-duration": { - "version": "3.18.1", - "resolved": "https://registry.npmjs.org/@types/humanize-duration/-/humanize-duration-3.18.1.tgz", - "integrity": "sha512-MUgbY3CF7hg/a/jogixmAufLjJBQT7WEf8Q+kYJkOc47ytngg1IuZobCngdTjAgY83JWEogippge5O5fplaQlw==" - }, - "@types/json-schema": { - "version": "7.0.7", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", - "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==" - }, - "@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=" - }, - "@types/keyv": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.2.tgz", - "integrity": "sha512-/FvAK2p4jQOaJ6CGDHJTqZcUtbZe820qIeTg7o0Shg7drB4JHeL+V/dhSaly7NXx6u8eSee+r7coT+yuJEvDLg==", - "requires": { - "@types/node": "*" - } - }, - "@types/mime": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", - "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" - }, - "@types/mocha": { - "version": "5.2.7", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", - "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==" - }, - "@types/node": { - "version": "14.14.41", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.41.tgz", - "integrity": "sha512-dueRKfaJL4RTtSa7bWeTK1M+VH+Gns73oCgzvYfHZywRCoPSd8EkXBL0mZ9unPTveBn+D9phZBaxuzpwjWkW0g==" - }, - "@types/normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==" - }, - "@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" - }, - "@types/pbkdf2": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", - "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", - "requires": { - "@types/node": "*" - } - }, - "@types/qs": { - "version": "6.9.6", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.6.tgz", - "integrity": "sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA==" - }, - "@types/range-parser": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", - "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==" - }, - "@types/responselike": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", - "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", - "requires": { - "@types/node": "*" - } - }, - "@types/secp256k1": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.2.tgz", - "integrity": "sha512-QMg+9v0bbNJ2peLuHRWxzmy0HRJIG6gFZNhaRSp7S3ggSbCCxiqQB2/ybvhXyhHOCequpNkrx7OavNhrWOsW0A==", - "requires": { - "@types/node": "*" - } - }, - "@types/serve-static": { - "version": "1.13.9", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.9.tgz", - "integrity": "sha512-ZFqF6qa48XsPdjXV5Gsz0Zqmux2PerNd3a/ktL45mHpa19cuMi/cL8tcxdAx497yRh+QtYPuofjT9oWw9P7nkA==", - "requires": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "@typescript-eslint/eslint-plugin": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.22.0.tgz", - "integrity": "sha512-U8SP9VOs275iDXaL08Ln1Fa/wLXfj5aTr/1c0t0j6CdbOnxh+TruXu1p4I0NAvdPBQgoPjHsgKn28mOi0FzfoA==", - "requires": { - "@typescript-eslint/experimental-utils": "4.22.0", - "@typescript-eslint/scope-manager": "4.22.0", - "debug": "^4.1.1", - "functional-red-black-tree": "^1.0.1", - "lodash": "^4.17.15", - "regexpp": "^3.0.0", - "semver": "^7.3.2", - "tsutils": "^3.17.1" - } - }, - "@typescript-eslint/experimental-utils": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.22.0.tgz", - "integrity": "sha512-xJXHHl6TuAxB5AWiVrGhvbGL8/hbiCQ8FiWwObO3r0fnvBdrbWEDy1hlvGQOAWc6qsCWuWMKdVWlLAEMpxnddg==", - "requires": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/scope-manager": "4.22.0", - "@typescript-eslint/types": "4.22.0", - "@typescript-eslint/typescript-estree": "4.22.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^2.0.0" - } - }, - "@typescript-eslint/parser": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.22.0.tgz", - "integrity": "sha512-z/bGdBJJZJN76nvAY9DkJANYgK3nlRstRRi74WHm3jjgf2I8AglrSY+6l7ogxOmn55YJ6oKZCLLy+6PW70z15Q==", - "requires": { - "@typescript-eslint/scope-manager": "4.22.0", - "@typescript-eslint/types": "4.22.0", - "@typescript-eslint/typescript-estree": "4.22.0", - "debug": "^4.1.1" - } - }, - "@typescript-eslint/scope-manager": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.22.0.tgz", - "integrity": "sha512-OcCO7LTdk6ukawUM40wo61WdeoA7NM/zaoq1/2cs13M7GyiF+T4rxuA4xM+6LeHWjWbss7hkGXjFDRcKD4O04Q==", - "requires": { - "@typescript-eslint/types": "4.22.0", - "@typescript-eslint/visitor-keys": "4.22.0" - } - }, - "@typescript-eslint/types": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.22.0.tgz", - "integrity": "sha512-sW/BiXmmyMqDPO2kpOhSy2Py5w6KvRRsKZnV0c4+0nr4GIcedJwXAq+RHNK4lLVEZAJYFltnnk1tJSlbeS9lYA==" - }, - "@typescript-eslint/typescript-estree": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.22.0.tgz", - "integrity": "sha512-TkIFeu5JEeSs5ze/4NID+PIcVjgoU3cUQUIZnH3Sb1cEn1lBo7StSV5bwPuJQuoxKXlzAObjYTilOEKRuhR5yg==", - "requires": { - "@typescript-eslint/types": "4.22.0", - "@typescript-eslint/visitor-keys": "4.22.0", - "debug": "^4.1.1", - "globby": "^11.0.1", - "is-glob": "^4.0.1", - "semver": "^7.3.2", - "tsutils": "^3.17.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.22.0.tgz", - "integrity": "sha512-nnMu4F+s4o0sll6cBSsTeVsT4cwxB7zECK3dFxzEjPBii9xLpq4yqqsy/FU5zMfan6G60DKZSCXAa3sHJZrcYw==", - "requires": { - "@typescript-eslint/types": "4.22.0", - "eslint-visitor-keys": "^2.0.0" - } - }, - "@webassemblyjs/ast": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.0.tgz", - "integrity": "sha512-kX2W49LWsbthrmIRMbQZuQDhGtjyqXfEmmHyEi4XWnSZtPmxY0+3anPIzsnRb45VH/J55zlOfWvZuY47aJZTJg==", - "requires": { - "@webassemblyjs/helper-numbers": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.0.tgz", - "integrity": "sha512-Q/aVYs/VnPDVYvsCBL/gSgwmfjeCb4LW8+TMrO3cSzJImgv8lxxEPM2JA5jMrivE7LSz3V+PFqtMbls3m1exDA==" - }, - "@webassemblyjs/helper-api-error": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.0.tgz", - "integrity": "sha512-baT/va95eXiXb2QflSx95QGT5ClzWpGaa8L7JnJbgzoYeaA27FCvuBXU758l+KXWRndEmUXjP0Q5fibhavIn8w==" - }, - "@webassemblyjs/helper-buffer": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.0.tgz", - "integrity": "sha512-u9HPBEl4DS+vA8qLQdEQ6N/eJQ7gT7aNvMIo8AAWvAl/xMrcOSiI2M0MAnMCy3jIFke7bEee/JwdX1nUpCtdyA==" - }, - "@webassemblyjs/helper-numbers": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.0.tgz", - "integrity": "sha512-DhRQKelIj01s5IgdsOJMKLppI+4zpmcMQ3XboFPLwCpSNH6Hqo1ritgHgD0nqHeSYqofA6aBN/NmXuGjM1jEfQ==", - "requires": { - "@webassemblyjs/floating-point-hex-parser": "1.11.0", - "@webassemblyjs/helper-api-error": "1.11.0", - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.0.tgz", - "integrity": "sha512-MbmhvxXExm542tWREgSFnOVo07fDpsBJg3sIl6fSp9xuu75eGz5lz31q7wTLffwL3Za7XNRCMZy210+tnsUSEA==" - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.0.tgz", - "integrity": "sha512-3Eb88hcbfY/FCukrg6i3EH8H2UsD7x8Vy47iVJrP967A9JGqgBVL9aH71SETPx1JrGsOUVLo0c7vMCN22ytJew==", - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-buffer": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/wasm-gen": "1.11.0" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.0.tgz", - "integrity": "sha512-KXzOqpcYQwAfeQ6WbF6HXo+0udBNmw0iXDmEK5sFlmQdmND+tr773Ti8/5T/M6Tl/413ArSJErATd8In3B+WBA==", - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.0.tgz", - "integrity": "sha512-aqbsHa1mSQAbeeNcl38un6qVY++hh8OpCOzxhixSYgbRfNWcxJNJQwe2rezK9XEcssJbbWIkblaJRwGMS9zp+g==", - "requires": { - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/utf8": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.0.tgz", - "integrity": "sha512-A/lclGxH6SpSLSyFowMzO/+aDEPU4hvEiooCMXQPcQFPPJaYcPQNKGOCLUySJsYJ4trbpr+Fs08n4jelkVTGVw==" - }, - "@webassemblyjs/wasm-edit": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.0.tgz", - "integrity": "sha512-JHQ0damXy0G6J9ucyKVXO2j08JVJ2ntkdJlq1UTiUrIgfGMmA7Ik5VdC/L8hBK46kVJgujkBIoMtT8yVr+yVOQ==", - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-buffer": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/helper-wasm-section": "1.11.0", - "@webassemblyjs/wasm-gen": "1.11.0", - "@webassemblyjs/wasm-opt": "1.11.0", - "@webassemblyjs/wasm-parser": "1.11.0", - "@webassemblyjs/wast-printer": "1.11.0" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.0.tgz", - "integrity": "sha512-BEUv1aj0WptCZ9kIS30th5ILASUnAPEvE3tVMTrItnZRT9tXCLW2LEXT8ezLw59rqPP9klh9LPmpU+WmRQmCPQ==", - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/ieee754": "1.11.0", - "@webassemblyjs/leb128": "1.11.0", - "@webassemblyjs/utf8": "1.11.0" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.0.tgz", - "integrity": "sha512-tHUSP5F4ywyh3hZ0+fDQuWxKx3mJiPeFufg+9gwTpYp324mPCQgnuVKwzLTZVqj0duRDovnPaZqDwoyhIO8kYg==", - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-buffer": "1.11.0", - "@webassemblyjs/wasm-gen": "1.11.0", - "@webassemblyjs/wasm-parser": "1.11.0" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.0.tgz", - "integrity": "sha512-6L285Sgu9gphrcpDXINvm0M9BskznnzJTE7gYkjDbxET28shDqp27wpruyx3C2S/dvEwiigBwLA1cz7lNUi0kw==", - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-api-error": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/ieee754": "1.11.0", - "@webassemblyjs/leb128": "1.11.0", - "@webassemblyjs/utf8": "1.11.0" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.0.tgz", - "integrity": "sha512-Fg5OX46pRdTgB7rKIUojkh9vXaVN6sGYCnEiJN1GYkb0RPwShZXp6KTDqmoMdQPKhcroOXh3fEzmkWmCYaKYhQ==", - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@xtuc/long": "4.2.2" - } - }, - "@webpack-cli/configtest": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.0.2.tgz", - "integrity": "sha512-3OBzV2fBGZ5TBfdW50cha1lHDVf9vlvRXnjpVbJBa20pSZQaSkMJZiwA8V2vD9ogyeXn8nU5s5A6mHyf5jhMzA==" - }, - "@webpack-cli/info": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.2.3.tgz", - "integrity": "sha512-lLek3/T7u40lTqzCGpC6CAbY6+vXhdhmwFRxZLMnRm6/sIF/7qMpT8MocXCRQfz0JAh63wpbXLMnsQ5162WS7Q==", - "requires": { - "envinfo": "^7.7.3" - } - }, - "@webpack-cli/serve": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.3.1.tgz", - "integrity": "sha512-0qXvpeYO6vaNoRBI52/UsbcaBydJCggoBBnIo/ovQQdn6fug0BgwsjorV1hVS7fMqGVTZGcVxv8334gjmbj5hw==" - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" - }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" - }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" - }, - "acorn": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.1.1.tgz", - "integrity": "sha512-xYiIVjNuqtKXMxlRMDc6mZUhXehod4a3gbZ1qRlM7icK4EbxUFNLhWoPblCvFtB2Y9CIqHP3CF/rdxLItaQv8g==" - }, - "acorn-jsx": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", - "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==" - }, - "aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==" - }, - "ansi-align": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", - "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", - "requires": { - "string-width": "^3.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==" - }, - "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==", - "requires": { - "type-fest": "^0.21.3" - }, - "dependencies": { - "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==" - } - } - }, - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "append-transform": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", - "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", - "requires": { - "default-require-extensions": "^3.0.0" - } - }, - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=" - }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "array-differ": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-2.1.0.tgz", - "integrity": "sha512-KbUpJgx909ZscOc/7CLATBFam7P1Z1QRQInvgT0UztM9Q72aGKCunKASAl7WNW0tnPmPyEMeMhdsfWhfmW037w==" - }, - "array-filter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz", - "integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=" - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==" - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" - }, - "asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - } - }, - "assert": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-2.0.0.tgz", - "integrity": "sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A==", - "requires": { - "es6-object-assign": "^1.1.0", - "is-nan": "^1.2.1", - "object-is": "^1.0.1", - "util": "^0.12.0" - } - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==" - }, - "astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==" - }, - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "requires": { - "lodash": "^4.17.14" - } - }, - "available-typed-arrays": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz", - "integrity": "sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ==", - "requires": { - "array-filter": "^1.0.0" - } - }, - "axios": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", - "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", - "requires": { - "follow-redirects": "^1.10.0" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "base-x": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz", - "integrity": "sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bip66": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", - "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", - "optional": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "blakejs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", - "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" - }, - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "boxen": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", - "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", - "requires": { - "ansi-align": "^3.0.0", - "camelcase": "^5.3.1", - "chalk": "^3.0.0", - "cli-boxes": "^2.2.0", - "string-width": "^4.1.0", - "term-size": "^2.1.0", - "type-fest": "^0.8.1", - "widest-line": "^3.1.0" - }, - "dependencies": { - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" - } - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "requires": { - "fill-range": "^7.0.1" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", - "requires": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - } - } - }, - "browserify-sign": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", - "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - } - } - }, - "browserslist": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.4.tgz", - "integrity": "sha512-d7rCxYV8I9kj41RH8UKYnvDYCRENUlHRgyXy/Rhr/1BaeLGfiCptEdFE8MIrvGfWbBFNjVYx76SQWvNX1j+/cQ==", - "requires": { - "caniuse-lite": "^1.0.30001208", - "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.712", - "escalade": "^3.1.1", - "node-releases": "^1.1.71" - } - }, - "bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", - "requires": { - "base-x": "^3.0.2" - } - }, - "bs58check": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", - "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", - "requires": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" - } - }, - "buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=" - }, - "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==" - }, - "cacheable-request": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", - "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", - "requires": { - "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" - }, - "dependencies": { - "normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==" - } - } - }, - "caching-transform": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", - "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", - "requires": { - "hasha": "^5.0.0", - "make-dir": "^3.0.0", - "package-hash": "^4.0.0", - "write-file-atomic": "^3.0.0" - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" - }, - "caniuse-lite": { - "version": "1.0.30001214", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001214.tgz", - "integrity": "sha512-O2/SCpuaU3eASWVaesQirZv1MSjUNOvmugaD8zNSJqw6Vv5SGwoOpA9LJs3pNPfM745nxqPvfZY3MQKY4AKHYg==" - }, - "chai": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", - "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=" - }, - "chokidar": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", - "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.3.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" - } - }, - "chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==" - }, - "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==" - }, - "cli-boxes": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", - "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==" - }, - "cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "requires": { - "restore-cursor": "^3.1.0" - } - }, - "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==", - "requires": { - "slice-ansi": "^3.0.0", - "string-width": "^4.2.0" - }, - "dependencies": { - "slice-ansi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", - "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - } - } - } - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "requires": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - } - }, - "clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "requires": { - "mimic-response": "^1.0.0" - } - }, - "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==", - "requires": { - "color-name": "~1.1.4" - } - }, - "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==" - }, - "colorette": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", - "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==" - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "comment-parser": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.1.2.tgz", - "integrity": "sha512-AOdq0i8ghZudnYv8RUnHrhTgafUGs61Rdz9jemU5x2lnZwAWyOq7vySo626K59e1fVKH1xSRorJwPVRLSWOoAQ==" - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" - }, - "compare-versions": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz", - "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "concurrently": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-6.0.2.tgz", - "integrity": "sha512-u+1Q0dJG5BidgUTpz9CU16yoHTt/oApFDQ3mbvHwSDgMjU7aGqy0q8ZQyaZyaNxdwRKTD872Ux3Twc6//sWA+Q==", - "requires": { - "chalk": "^4.1.0", - "date-fns": "^2.16.1", - "lodash": "^4.17.21", - "read-pkg": "^5.2.0", - "rxjs": "^6.6.3", - "spawn-command": "^0.0.2-1", - "supports-color": "^8.1.0", - "tree-kill": "^1.2.2", - "yargs": "^16.2.0" - }, - "dependencies": { - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "configstore": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", - "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", - "requires": { - "dot-prop": "^5.2.0", - "graceful-fs": "^4.1.2", - "make-dir": "^3.0.0", - "unique-string": "^2.0.0", - "write-file-atomic": "^3.0.0", - "xdg-basedir": "^4.0.0" - } - }, - "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "requires": { - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "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==" - } - } - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cosmiconfig": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", - "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==", - "requires": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - } - }, - "create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==" - }, - "date-fns": { - "version": "2.21.1", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.21.1.tgz", - "integrity": "sha512-m1WR0xGiC6j6jNFAyW4Nvh4WxAi4JF4w9jRJwSI8nBmNcyZXPcP9VUQG+6gHQXAmqaGEKDKhOqAtENDC941UkA==" - }, - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "requires": { - "ms": "2.1.2" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" - }, - "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==", - "requires": { - "mimic-response": "^3.1.0" - }, - "dependencies": { - "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==" - } - } - }, - "dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=" - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "requires": { - "type-detect": "^4.0.0" - } - }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" - }, - "default-require-extensions": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", - "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==", - "requires": { - "strip-bom": "^4.0.0" - } - }, - "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==" - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "requires": { - "object-keys": "^1.0.12" - } - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "requires": { - "path-type": "^4.0.0" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "requires": { - "esutils": "^2.0.2" - } - }, - "dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "requires": { - "is-obj": "^2.0.0" - }, - "dependencies": { - "is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==" - } - } - }, - "drbg.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", - "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", - "optional": true, - "requires": { - "browserify-aes": "^1.0.6", - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4" - } - }, - "duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" - }, - "eccrypto": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/eccrypto/-/eccrypto-1.1.6.tgz", - "integrity": "sha512-d78ivVEzu7Tn0ZphUUaL43+jVPKTMPFGtmgtz1D0LrFn7cY3K8CdrvibuLz2AAkHBLKZtR8DMbB2ukRYFk987A==", - "requires": { - "acorn": "7.1.1", - "elliptic": "6.5.4", - "es6-promise": "4.2.8", - "nan": "2.14.0", - "secp256k1": "3.7.1" - }, - "dependencies": { - "acorn": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", - "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==" - }, - "secp256k1": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.7.1.tgz", - "integrity": "sha512-1cf8sbnRreXrQFdH6qsg2H71Xw91fCCS9Yp021GnUNJzWJS/py96fS4lHbnTnouLp08Xj6jBoBB6V78Tdbdu5g==", - "optional": true, - "requires": { - "bindings": "^1.5.0", - "bip66": "^1.1.5", - "bn.js": "^4.11.8", - "create-hash": "^1.2.0", - "drbg.js": "^1.0.1", - "elliptic": "^6.4.1", - "nan": "^2.14.0", - "safe-buffer": "^5.1.2" - } - } - } - }, - "electron-to-chromium": { - "version": "1.3.719", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.719.tgz", - "integrity": "sha512-heM78GKSqrIzO9Oz0/y22nTBN7bqSP1Pla2SyU9DiSnQD+Ea9SyyN5RWWlgqsqeBLNDkSlE9J9EHFmdMPzxB/g==" - }, - "elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "requires": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "email-addresses": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-3.1.0.tgz", - "integrity": "sha512-k0/r7GrWVL32kZlGwfPNgB2Y/mMXVTq/decgLczm/j34whdaspNrZO8CnXPf1laaHxI6ptUlsnAxN+UAPw+fzg==" - }, - "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==" - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" - }, - "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==", - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.0.tgz", - "integrity": "sha512-Sl3KRpJA8OpprrtaIswVki3cWPiPKxXuFxJXBp+zNb6s6VwNWwFRUdtmzd2ReUut8n+sCPx7QCtQ7w5wfJhSgQ==", - "requires": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - } - }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "requires": { - "ansi-colors": "^4.1.1" - } - }, - "envinfo": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", - "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==" - }, - "errno": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", - "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", - "requires": { - "prr": "~1.0.1" - } - }, - "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==", - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0.tgz", - "integrity": "sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw==", - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "is-callable": "^1.2.3", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.2", - "is-string": "^1.0.5", - "object-inspect": "^1.9.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.0" - } - }, - "es-module-lexer": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.4.1.tgz", - "integrity": "sha512-ooYciCUtfw6/d2w56UVeqHPcoCFAiJdz5XOkYpv/Txl1HMUozpXjz/2RIQgqwKdXNDPSF1W7mJCFse3G+HDyAA==" - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==" - }, - "es6-object-assign": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", - "integrity": "sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw=" - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" - }, - "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==" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "eslint": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.24.0.tgz", - "integrity": "sha512-k9gaHeHiFmGCDQ2rEfvULlSLruz6tgfA8DEn+rY9/oYPFFTlz55mM/Q/Rij1b2Y42jwZiK3lXvNTw6w6TXzcKQ==", - "requires": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash": "^4.17.21", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.4", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "requires": { - "@babel/highlight": "^7.10.4" - } - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" - } - } - }, - "eslint-config-prettier": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.2.0.tgz", - "integrity": "sha512-dWV9EVeSo2qodOPi1iBYU/x6F6diHv8uujxbxr77xExs3zTAlNXvVZKiyLsQGNz7yPV2K49JY5WjPzNIuDc2Bw==" - }, - "eslint-plugin-jsdoc": { - "version": "32.3.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-32.3.0.tgz", - "integrity": "sha512-zyx7kajDK+tqS1bHuY5sapkad8P8KT0vdd/lE55j47VPG2MeenSYuIY/M/Pvmzq5g0+3JB+P3BJGUXmHxtuKPQ==", - "requires": { - "comment-parser": "1.1.2", - "debug": "^4.3.1", - "jsdoctypeparser": "^9.0.0", - "lodash": "^4.17.20", - "regextras": "^0.7.1", - "semver": "^7.3.4", - "spdx-expression-parse": "^3.0.1" - } - }, - "eslint-plugin-prefer-arrow": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-prefer-arrow/-/eslint-plugin-prefer-arrow-1.2.3.tgz", - "integrity": "sha512-J9I5PKCOJretVuiZRGvPQxCbllxGAV/viI20JO3LYblAodofBxyMnZAJ+WGeClHgANnSJberTNoFWWjrWKBuXQ==" - }, - "eslint-plugin-prettier": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.0.tgz", - "integrity": "sha512-UDK6rJT6INSfcOo545jiaOwB701uAIt2/dR7WnFQoGCVl1/EMqdANBmwUaqqQ45aXprsTGzSa39LI1PyuRBxxw==", - "requires": { - "prettier-linter-helpers": "^1.0.0" - } - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "requires": { - "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" - } - } - }, - "eslint-visitor-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", - "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==" - }, - "espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "requires": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "dependencies": { - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" - }, - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" - } - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "requires": { - "estraverse": "^5.1.0" - }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==" - } - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "requires": { - "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==" - } - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" - }, - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", - "requires": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==" - }, - "fast-glob": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", - "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", - "merge2": "^1.3.0", - "micromatch": "^4.0.2", - "picomatch": "^2.2.1" - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" - }, - "fastest-levenshtein": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", - "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==" - }, - "fastq": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", - "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==", - "requires": { - "reusify": "^1.0.4" - } - }, - "figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "requires": { - "flat-cache": "^3.0.4" - } - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "optional": true - }, - "filename-reserved-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-1.0.0.tgz", - "integrity": "sha1-5hz4BfDeHJhFZ9A4bcXfUO5a9+Q=" - }, - "filenamify": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-1.2.1.tgz", - "integrity": "sha1-qfL/0RxQO+0wABUCknI3jx8TZaU=", - "requires": { - "filename-reserved-regex": "^1.0.0", - "strip-outer": "^1.0.0", - "trim-repeated": "^1.0.0" - } - }, - "filenamify-url": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/filenamify-url/-/filenamify-url-1.0.0.tgz", - "integrity": "sha1-syvYExnvWGO3MHi+1Q9GpPeXX1A=", - "requires": { - "filenamify": "^1.0.0", - "humanize-url": "^1.0.0" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-cache-dir": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", - "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", - "requires": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "find-versions": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-4.0.0.tgz", - "integrity": "sha512-wgpWy002tA+wgmO27buH/9KzyEOQnKsG/R0yrcjPT9BOFm0zRBVQbZ95nRGXWMywS8YR5knRbpohio0bcJABxQ==", - "requires": { - "semver-regex": "^3.1.2" - } - }, - "flat": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", - "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", - "requires": { - "is-buffer": "~2.0.3" - } - }, - "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", - "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==" - }, - "follow-redirects": { - "version": "1.13.3", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.3.tgz", - "integrity": "sha512-DUgl6+HDzB0iEptNQEXLx/KhTmDb8tZUHSeLqpnjpknR70H0nC2t9N73BK6fN4hOvJ84pKlIQVQ4k5FFlBedKA==" - }, - "foreach": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" - }, - "foreground-child": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", - "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", - "requires": { - "cross-spawn": "^7.0.0", - "signal-exit": "^3.0.2" - } - }, - "fromentries": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", - "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==" - }, - "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==", - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" - }, - "gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" - }, - "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==" - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=" - }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "get-own-enumerable-property-symbols": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", - "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" - }, - "get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==" - }, - "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==", - "requires": { - "pump": "^3.0.0" - } - }, - "gh-pages": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-3.1.0.tgz", - "integrity": "sha512-3b1rly9kuf3/dXsT8+ZxP0UhNLOo1CItj+3e31yUVcaph/yDsJ9RzD7JOw5o5zpBTJVQLlJAASNkUfepi9fe2w==", - "requires": { - "async": "^2.6.1", - "commander": "^2.18.0", - "email-addresses": "^3.0.1", - "filenamify-url": "^1.0.0", - "find-cache-dir": "^3.3.1", - "fs-extra": "^8.1.0", - "globby": "^6.1.0" - }, - "dependencies": { - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "requires": { - "array-uniq": "^1.0.1" - } - }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - } - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "requires": { - "is-glob": "^4.0.1" - } - }, - "glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" - }, - "global-dirs": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.1.0.tgz", - "integrity": "sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==", - "requires": { - "ini": "1.3.7" - } - }, - "globals": { - "version": "13.8.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.8.0.tgz", - "integrity": "sha512-rHtdA6+PDBIjeEvA91rpqzEvk/k3/i7EeNQiryiWuJH0Hw9cpyJMAt2jtbAwUaRdhD+573X4vWw6IcjKPasi9Q==", - "requires": { - "type-fest": "^0.20.2" - }, - "dependencies": { - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==" - } - } - }, - "globby": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz", - "integrity": "sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==", - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - } - }, - "google-protobuf": { - "version": "3.15.8", - "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.15.8.tgz", - "integrity": "sha512-2jtfdqTaSxk0cuBJBtTTWsot4WtR9RVr2rXg7x7OoqiuOKopPrwXpM1G4dXIkLcUNRh3RKzz76C8IOkksZSeOw==" - }, - "got": { - "version": "11.8.2", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.2.tgz", - "integrity": "sha512-D0QywKgIe30ODs+fm8wMZiAcZjypcCodPNuMz5H9Mny7RJ+IjJ10BdmGW7OM7fHXP+O7r6ZwapQ/YQmMSvB0UQ==", - "requires": { - "@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.1", - "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" - } - }, - "graceful-fs": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==" - }, - "handlebars": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", - "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", - "requires": { - "minimist": "^1.2.5", - "neo-async": "^2.6.0", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4", - "wordwrap": "^1.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" - }, - "has-yarn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", - "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==" - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "hasha": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", - "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", - "requires": { - "is-stream": "^2.0.0", - "type-fest": "^0.8.0" - }, - "dependencies": { - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" - } - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "highlight.js": { - "version": "10.7.2", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.2.tgz", - "integrity": "sha512-oFLl873u4usRM9K63j4ME9u3etNF0PLiJhSQ8rdfuL51Wn3zkD6drf9ZW0dOzjnZI22YYG24z30JcmfCZjMgYg==" - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "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==" - }, - "html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" - }, - "http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" - }, - "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==", - "requires": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.0.0" - } - }, - "human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==" - }, - "humanize-duration": { - "version": "3.25.2", - "resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.25.2.tgz", - "integrity": "sha512-zSerjahuzBazDaE8skjMI7Xmrt/EirvW5cDsXgysx8tYIjcgCMnI5Y5985y3LxYeLah9L5cQY3WEw1k7GRWbfg==" - }, - "humanize-url": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/humanize-url/-/humanize-url-1.0.1.tgz", - "integrity": "sha1-9KuZ4NKIF0yk4eUEB8VfuuRk7/8=", - "requires": { - "normalize-url": "^1.0.0", - "strip-url-auth": "^1.0.0" - } - }, - "husky": { - "version": "4.3.8", - "resolved": "https://registry.npmjs.org/husky/-/husky-4.3.8.tgz", - "integrity": "sha512-LCqqsB0PzJQ/AlCgfrfzRe3e3+NvmefAdKQhRYpxS4u6clblBoDdzzvHi8fmxKRzvMxPY/1WZWzomPZww0Anow==", - "requires": { - "chalk": "^4.0.0", - "ci-info": "^2.0.0", - "compare-versions": "^3.6.0", - "cosmiconfig": "^7.0.0", - "find-versions": "^4.0.0", - "opencollective-postinstall": "^2.0.2", - "pkg-dir": "^5.0.0", - "please-upgrade-node": "^3.2.0", - "slash": "^3.0.0", - "which-pm-runs": "^1.0.0" - }, - "dependencies": { - "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==", - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "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==", - "requires": { - "p-locate": "^5.0.0" - } - }, - "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==", - "requires": { - "p-limit": "^3.0.2" - } - }, - "pkg-dir": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", - "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", - "requires": { - "find-up": "^5.0.0" - } - } - } - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" - }, - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==" - }, - "ignore-by-default": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=" - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "import-lazy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", - "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=" - }, - "import-local": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", - "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", - "requires": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" - }, - "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==" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ini": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", - "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==" - }, - "interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==" - }, - "is-arguments": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", - "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==", - "requires": { - "call-bind": "^1.0.0" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" - }, - "is-bigint": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.1.tgz", - "integrity": "sha512-J0ELF4yHFxHy0cmSxZuheDOz2luOdVvqjwmEcj8H/L1JHeuEDSDbeRP+Dk9kFVk5RTFzbucJ2Kb9F7ixY2QaCg==" - }, - "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==", - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-boolean-object": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.0.tgz", - "integrity": "sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA==", - "requires": { - "call-bind": "^1.0.0" - } - }, - "is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==" - }, - "is-callable": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", - "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==" - }, - "is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "requires": { - "ci-info": "^2.0.0" - } - }, - "is-core-module": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", - "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", - "requires": { - "has": "^1.0.3" - } - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==" - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" - }, - "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==" - }, - "is-generator-function": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.8.tgz", - "integrity": "sha512-2Omr/twNtufVZFr1GhxjOMFPAj2sjc/dKaIqBhvo4qciXfJmITGH6ZGd8eZYNHza8t1y0e01AuqRhJwfWp26WQ==" - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-installed-globally": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", - "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", - "requires": { - "global-dirs": "^2.0.1", - "is-path-inside": "^3.0.1" - } - }, - "is-nan": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", - "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - } - }, - "is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==" - }, - "is-npm": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", - "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==" - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" - }, - "is-number-object": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz", - "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==" - }, - "is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" - }, - "is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==" - }, - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "requires": { - "isobject": "^3.0.1" - } - }, - "is-regex": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", - "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", - "requires": { - "call-bind": "^1.0.2", - "has-symbols": "^1.0.1" - } - }, - "is-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=" - }, - "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" - }, - "is-string": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", - "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==" - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typed-array": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.5.tgz", - "integrity": "sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug==", - "requires": { - "available-typed-arrays": "^1.0.2", - "call-bind": "^1.0.2", - "es-abstract": "^1.18.0-next.2", - "foreach": "^2.0.5", - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" - }, - "is-yarn-global": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", - "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - }, - "isomorphic-fetch": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", - "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", - "requires": { - "node-fetch": "^2.6.1", - "whatwg-fetch": "^3.4.1" - } - }, - "isomorphic-ws": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", - "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==" - }, - "istanbul-lib-coverage": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", - "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==" - }, - "istanbul-lib-hook": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", - "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", - "requires": { - "append-transform": "^2.0.0" - } - }, - "istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", - "requires": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } - } - }, - "istanbul-lib-processinfo": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz", - "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==", - "requires": { - "archy": "^1.0.0", - "cross-spawn": "^7.0.0", - "istanbul-lib-coverage": "^3.0.0-alpha.1", - "make-dir": "^3.0.0", - "p-map": "^3.0.0", - "rimraf": "^3.0.0", - "uuid": "^3.3.3" - }, - "dependencies": { - "p-map": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" - }, - "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==", - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "requires": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - } - }, - "istanbul-lib-source-maps": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", - "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - } - }, - "istanbul-reports": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", - "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", - "requires": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - } - }, - "jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - } - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbi": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/jsbi/-/jsbi-3.1.4.tgz", - "integrity": "sha512-52QRRFSsi9impURE8ZUbzAMCLjPm4THO7H2fcuIvaaeFTbSysvkodbQQXIVsNgq/ypDbq6dJiuGKL0vZ/i9hUg==" - }, - "jsdoctypeparser": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/jsdoctypeparser/-/jsdoctypeparser-9.0.0.tgz", - "integrity": "sha512-jrTA2jJIL6/DAEILBEh2/w9QxCuwmvNXIry39Ay/HVfhE3o2yVV0U44blYkqdHA/OKloJEqvJy0xU+GSdE2SIw==" - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" - }, - "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==" - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" - }, - "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==" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=" - }, - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "requires": { - "minimist": "^1.2.5" - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "keccak": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.1.tgz", - "integrity": "sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA==", - "requires": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - } - }, - "key-encoder": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/key-encoder/-/key-encoder-2.0.3.tgz", - "integrity": "sha512-fgBtpAGIr/Fy5/+ZLQZIPPhsZEcbSlYu/Wu96tNDFNSjSACw5lEIOFeaVdQ/iwrb8oxjlWi6wmWdH76hV6GZjg==", - "requires": { - "@types/elliptic": "^6.4.9", - "asn1.js": "^5.0.1", - "bn.js": "^4.11.8", - "elliptic": "^6.4.1" - } - }, - "keyv": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.3.tgz", - "integrity": "sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA==", - "requires": { - "json-buffer": "3.0.1" - } - }, - "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==" - }, - "latest-version": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", - "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", - "requires": { - "package-json": "^6.3.0" - } - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=" - }, - "lint-staged": { - "version": "10.5.4", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-10.5.4.tgz", - "integrity": "sha512-EechC3DdFic/TdOPgj/RB3FicqE6932LTHCUm0Y2fsD9KGlLB+RwJl2q1IYBIvEsKzDOgn0D4gll+YxG5RsrKg==", - "requires": { - "chalk": "^4.1.0", - "cli-truncate": "^2.1.0", - "commander": "^6.2.0", - "cosmiconfig": "^7.0.0", - "debug": "^4.2.0", - "dedent": "^0.7.0", - "enquirer": "^2.3.6", - "execa": "^4.1.0", - "listr2": "^3.2.2", - "log-symbols": "^4.0.0", - "micromatch": "^4.0.2", - "normalize-path": "^3.0.0", - "please-upgrade-node": "^3.2.0", - "string-argv": "0.3.1", - "stringify-object": "^3.3.0" - }, - "dependencies": { - "commander": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", - "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==" - } - } - }, - "listr2": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.7.1.tgz", - "integrity": "sha512-cNd368GTrk8351/ov/IV+BSwyf9sJRgI0UIvfORonCZA1u9UHAtAlqSEv9dgafoQIA1CgB3nu4No79pJtK2LHw==", - "requires": { - "chalk": "^4.1.0", - "cli-truncate": "^2.1.0", - "figures": "^3.2.0", - "indent-string": "^4.0.0", - "log-update": "^4.0.0", - "p-map": "^4.0.0", - "rxjs": "^6.6.7", - "through": "^2.3.8", - "wrap-ansi": "^7.0.0" - } - }, - "loader-runner": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", - "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==" - }, - "loader-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", - "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "requires": { - "p-locate": "^4.1.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=" - }, - "lodash.flattendeep": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=" - }, - "lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=" - }, - "log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "requires": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - } - }, - "log-update": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", - "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", - "requires": { - "ansi-escapes": "^4.3.0", - "cli-cursor": "^3.1.0", - "slice-ansi": "^4.0.0", - "wrap-ansi": "^6.2.0" - }, - "dependencies": { - "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - } - } - }, - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" - }, - "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==", - "requires": { - "yallist": "^4.0.0" - } - }, - "lunr": { - "version": "2.3.9", - "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", - "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==" - }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "requires": { - "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } - } - }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" - }, - "marked": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-1.0.0.tgz", - "integrity": "sha512-Wo+L1pWTVibfrSr+TTtMuiMfNzmZWiOPeO7rZsQUY5bgsxpHesBEcIWJloWVTFnrMXnf/TL30eTFSGJddmQAng==" - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "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" - } - }, - "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==" - }, - "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==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" - }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - } - }, - "mime-db": { - "version": "1.47.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", - "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==" - }, - "mime-types": { - "version": "2.1.30", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", - "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", - "requires": { - "mime-db": "1.47.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" - }, - "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, - "mkdirp": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz", - "integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==", - "requires": { - "minimist": "^1.2.5" - } - }, - "mocha": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.3.tgz", - "integrity": "sha512-0R/3FvjIGH3eEuG17ccFPk117XL2rWxatr81a57D+r/x2uTYZRbdZ4oVidEUMh2W2TJDa7MdAb12Lm2/qrKajg==", - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "2.2.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.4", - "ms": "2.1.1", - "node-environment-flags": "1.0.5", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "dependencies": { - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==" - }, - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "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==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.0.0" - } - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", - "requires": { - "chalk": "^2.0.1" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "requires": { - "has-flag": "^3.0.0" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - }, - "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } - }, - "mri": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.1.6.tgz", - "integrity": "sha512-oi1b3MfbyGa7FJMP9GmLTttni5JoICpYBRlq+x5V16fZbLsnL9N3wFqqIm/nIG43FjUFkFh9Epzp/kzUGUnJxQ==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "multimatch": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-3.0.0.tgz", - "integrity": "sha512-22foS/gqQfANZ3o+W7ST2x25ueHDVNWl/b9OlGcLpy/iKxjCpvcNCM51YCenUi7Mt/jAjjqv8JwZRs8YP5sRjA==", - "requires": { - "array-differ": "^2.0.3", - "array-union": "^1.0.2", - "arrify": "^1.0.1", - "minimatch": "^3.0.4" - }, - "dependencies": { - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "requires": { - "array-uniq": "^1.0.1" - } - } - } - }, - "nan": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" - }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" - }, - "node-addon-api": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" - }, - "node-environment-flags": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", - "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==", - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" - }, - "node-gyp-build": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", - "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==" - }, - "node-preload": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", - "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", - "requires": { - "process-on-spawn": "^1.0.0" - } - }, - "node-releases": { - "version": "1.1.71", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz", - "integrity": "sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==" - }, - "nodemon": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.7.tgz", - "integrity": "sha512-XHzK69Awgnec9UzHr1kc8EomQh4sjTQ8oRf8TsGrSmHDx9/UmiGG9E/mM3BuTfNeFwdNBvrqQq/RHL0xIeyFOA==", - "requires": { - "chokidar": "^3.2.2", - "debug": "^3.2.6", - "ignore-by-default": "^1.0.1", - "minimatch": "^3.0.4", - "pstree.remy": "^1.1.7", - "semver": "^5.7.1", - "supports-color": "^5.5.0", - "touch": "^3.1.0", - "undefsafe": "^2.0.3", - "update-notifier": "^4.1.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "nopt": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", - "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", - "requires": { - "abbrev": "1" - } - }, - "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==", - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" - }, - "normalize-url": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", - "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", - "requires": { - "object-assign": "^4.0.1", - "prepend-http": "^1.0.0", - "query-string": "^4.1.0", - "sort-keys": "^1.0.0" - } - }, - "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==", - "requires": { - "path-key": "^3.0.0" - } - }, - "nyc": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", - "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", - "requires": { - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "caching-transform": "^4.0.0", - "convert-source-map": "^1.7.0", - "decamelize": "^1.2.0", - "find-cache-dir": "^3.2.0", - "find-up": "^4.1.0", - "foreground-child": "^2.0.0", - "get-package-type": "^0.1.0", - "glob": "^7.1.6", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-hook": "^3.0.0", - "istanbul-lib-instrument": "^4.0.0", - "istanbul-lib-processinfo": "^2.0.2", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "make-dir": "^3.0.0", - "node-preload": "^0.2.1", - "p-map": "^3.0.0", - "process-on-spawn": "^1.0.0", - "resolve-from": "^5.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "spawn-wrap": "^2.0.0", - "test-exclude": "^6.0.0", - "yargs": "^15.0.2" - }, - "dependencies": { - "cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "p-map": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" - }, - "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "requires": { - "ansi-regex": "^5.0.0" - } - }, - "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" - }, - "yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "requires": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - } - }, - "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "object-inspect": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.2.tgz", - "integrity": "sha512-gz58rdPpadwztRrPjZE9DZLOABUpTGdcANUgOwBFO1C+HZZhePoP83M65WGDmbpwFYJSWqavbl4SgDn4k8RYTA==" - }, - "object-is": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", - "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" - }, - "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz", - "integrity": "sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "opencollective-postinstall": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz", - "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==" - }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - } - }, - "p-cancelable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==" - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "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==", - "requires": { - "p-limit": "^2.2.0" - }, - "dependencies": { - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - } - } - }, - "p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "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==" - }, - "package-hash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", - "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", - "requires": { - "graceful-fs": "^4.1.15", - "hasha": "^5.0.0", - "lodash.flattendeep": "^4.4.0", - "release-zalgo": "^1.0.0" - } - }, - "package-json": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", - "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", - "requires": { - "got": "^9.6.0", - "registry-auth-token": "^4.0.0", - "registry-url": "^5.0.0", - "semver": "^6.2.0" - }, - "dependencies": { - "@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==" - }, - "@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", - "requires": { - "defer-to-connect": "^1.0.1" - } - }, - "cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", - "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" - }, - "dependencies": { - "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==", - "requires": { - "pump": "^3.0.0" - } - }, - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" - } - } - }, - "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "requires": { - "mimic-response": "^1.0.0" - } - }, - "defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==" - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - }, - "got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", - "requires": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" - } - }, - "json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" - }, - "keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", - "requires": { - "json-buffer": "3.0.0" - } - }, - "lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" - }, - "normalize-url": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", - "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==" - }, - "p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==" - }, - "responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", - "requires": { - "lowercase-keys": "^1.0.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } - } - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", - "requires": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "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==", - "requires": { - "@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" - } - }, - "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==" - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" - }, - "pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==" - }, - "pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "picomatch": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", - "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==" - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "requires": { - "find-up": "^4.0.0" - } - }, - "please-upgrade-node": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", - "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", - "requires": { - "semver-compare": "^1.0.0" - } - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" - }, - "prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" - }, - "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==" - }, - "prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "requires": { - "fast-diff": "^1.1.2" - } - }, - "pretty-quick": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-1.11.1.tgz", - "integrity": "sha512-kSXCkcETfak7EQXz6WOkCeCqpbC4GIzrN/vaneTGMP/fAtD8NerA9bPhCUqHAks1geo7biZNl5uEMPceeneLuA==", - "requires": { - "chalk": "^2.3.0", - "execa": "^0.8.0", - "find-up": "^2.1.0", - "ignore": "^3.3.7", - "mri": "^1.1.0", - "multimatch": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "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==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "execa": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.8.0.tgz", - "integrity": "sha1-2NdrvBtVIX7RkP1t1J08d07PyNo=", - "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "requires": { - "locate-path": "^2.0.0" - } - }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "ignore": { - "version": "3.3.10", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", - "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==" - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "requires": { - "path-key": "^2.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" - } - } - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" - }, - "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==" - }, - "process-on-spawn": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", - "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", - "requires": { - "fromentries": "^1.2.0" - } - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" - }, - "pstree.remy": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", - "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "pupa": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", - "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", - "requires": { - "escape-goat": "^2.0.0" - } - }, - "query-string": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", - "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", - "requires": { - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - } - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" - }, - "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==" - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" - } - } - }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - } - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", - "requires": { - "picomatch": "^2.2.1" - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "requires": { - "resolve": "^1.1.6" - } - }, - "reflect-metadata": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", - "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" - }, - "regexpp": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", - "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==" - }, - "regextras": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/regextras/-/regextras-0.7.1.tgz", - "integrity": "sha512-9YXf6xtW+qzQ+hcMQXx95MOvfqXFgsKDZodX3qZB0x2n5Z94ioetIITsBtvJbiOyxa/6s9AtyweBLCdPmPko/w==" - }, - "registry-auth-token": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", - "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", - "requires": { - "rc": "^1.2.8" - } - }, - "registry-url": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", - "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", - "requires": { - "rc": "^1.2.8" - } - }, - "release-zalgo": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", - "requires": { - "es6-error": "^4.0.1" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" - }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" - }, - "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", - "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - } - }, - "resolve-alpn": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.1.2.tgz", - "integrity": "sha512-8OyfzhAtA32LVUsJSke3auIyINcwdh5l3cvYKdKO0nvsYSKuiLfTM5i78PJswFPT8y6cPW+L1v6/hE95chcpDA==" - }, - "resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "requires": { - "resolve-from": "^5.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" - } - } - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" - }, - "responselike": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", - "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", - "requires": { - "lowercase-keys": "^2.0.0" - } - }, - "restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "requires": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - } - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "requires": { - "glob": "^7.1.3" - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "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==", - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "requires": { - "tslib": "^1.9.0" - } - }, - "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==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "schema-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", - "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", - "requires": { - "@types/json-schema": "^7.0.6", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - }, - "scrypt-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" - }, - "secp256k1": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz", - "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==", - "requires": { - "elliptic": "^6.5.2", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - } - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "requires": { - "lru-cache": "^6.0.0" - } - }, - "semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=" - }, - "semver-diff": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", - "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", - "requires": { - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } - } - }, - "semver-regex": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-3.1.2.tgz", - "integrity": "sha512-bXWyL6EAKOJa81XG1OZ/Yyuq+oT0b2YLlxx7c+mrdYPaPbnj6WgVULXhinMIeZGufuUBu/eVRqXEhiv4imfwxA==" - }, - "serialize-javascript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", - "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", - "requires": { - "randombytes": "^2.1.0" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "requires": { - "kind-of": "^6.0.2" - } - }, - "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==", - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" - }, - "shelljs": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz", - "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==", - "requires": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - } - }, - "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" - }, - "slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - } - }, - "sort-keys": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", - "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", - "requires": { - "is-plain-obj": "^1.0.0" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "spawn-command": { - "version": "0.0.2-1", - "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", - "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=" - }, - "spawn-wrap": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", - "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", - "requires": { - "foreground-child": "^2.0.0", - "is-windows": "^1.0.2", - "make-dir": "^3.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "which": "^2.0.1" - }, - "dependencies": { - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==" - }, - "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==", - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz", - "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==" - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "stream-browserify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", - "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", - "requires": { - "inherits": "~2.0.4", - "readable-stream": "^3.5.0" - } - }, - "stream-http": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz", - "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==", - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "xtend": "^4.0.2" - } - }, - "strict-event-emitter-types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strict-event-emitter-types/-/strict-event-emitter-types-2.0.0.tgz", - "integrity": "sha512-Nk/brWYpD85WlOgzw5h173aci0Teyv8YdIAEtV+N88nDB0dLlazZyJMIsN6eo1/AR61l+p6CJTG1JIyFaoNEEA==" - }, - "strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" - }, - "string-argv": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", - "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==" - }, - "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "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==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "stringify-object": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", - "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", - "requires": { - "get-own-enumerable-property-symbols": "^3.0.0", - "is-obj": "^1.0.1", - "is-regexp": "^1.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "requires": { - "ansi-regex": "^5.0.0" - } - }, - "strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" - }, - "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" - }, - "strip-outer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", - "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", - "requires": { - "escape-string-regexp": "^1.0.2" - } - }, - "strip-url-auth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-url-auth/-/strip-url-auth-1.0.1.tgz", - "integrity": "sha1-IrD6OkE4WzO+PzMVUbu4N/oM164=" - }, - "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==", - "requires": { - "has-flag": "^4.0.0" - } - }, - "table": { - "version": "6.3.2", - "resolved": "https://registry.npmjs.org/table/-/table-6.3.2.tgz", - "integrity": "sha512-I9/Ca6Huf2oxFag7crD0DhA+arIdfLtWunSn0NIXSzjtUlDgIBGVZY7SsMkNPNT3Psd/z4gza0nuEpmra9eRbg==", - "requires": { - "ajv": "^8.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "lodash.clonedeep": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.0" - }, - "dependencies": { - "ajv": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.1.0.tgz", - "integrity": "sha512-B/Sk2Ix7A36fs/ZkuGLIR86EdjbgR6fsAcbx9lOP/QBSXujDNbVmIS/U4Itz5k8fPFDeVZl/zQ/gJW4Jrq6XjQ==", - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - } - } - }, - "tapable": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", - "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==" - }, - "term-size": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", - "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==" - }, - "terser": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.6.1.tgz", - "integrity": "sha512-yv9YLFQQ+3ZqgWCUk+pvNJwgUTdlIxUk1WTN+RnaFJe2L7ipG2csPT0ra2XRm7Cs8cxN7QXmK1rFzEwYEQkzXw==", - "requires": { - "commander": "^2.20.0", - "source-map": "~0.7.2", - "source-map-support": "~0.5.19" - }, - "dependencies": { - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" - } - } - }, - "terser-webpack-plugin": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.1.tgz", - "integrity": "sha512-5XNNXZiR8YO6X6KhSGXfY0QrGrCRlSwAEjIIrlRQR4W8nP69TaJUlh3bkuac6zzgspiGPfKEHcY295MMVExl5Q==", - "requires": { - "jest-worker": "^26.6.2", - "p-limit": "^3.1.0", - "schema-utils": "^3.0.0", - "serialize-javascript": "^5.0.1", - "source-map": "^0.6.1", - "terser": "^5.5.1" - } - }, - "test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "requires": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" - }, - "to-readable-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==" - }, - "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==", - "requires": { - "is-number": "^7.0.0" - } - }, - "touch": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", - "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", - "requires": { - "nopt": "~1.0.10" - } - }, - "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==" - }, - "trim-repeated": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", - "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=", - "requires": { - "escape-string-regexp": "^1.0.2" - } - }, - "ts-loader": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-8.1.0.tgz", - "integrity": "sha512-YiQipGGAFj2zBfqLhp28yUvPP9jUGqHxRzrGYuc82Z2wM27YIHbElXiaZDc93c3x0mz4zvBmS6q/DgExpdj37A==", - "requires": { - "chalk": "^4.1.0", - "enhanced-resolve": "^4.0.0", - "loader-utils": "^2.0.0", - "micromatch": "^4.0.0", - "semver": "^7.3.4" - }, - "dependencies": { - "enhanced-resolve": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz", - "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==", - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==" - } - } - }, - "ts-node": { - "version": "8.10.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz", - "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==", - "requires": { - "arg": "^4.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "source-map-support": "^0.5.17", - "yn": "3.1.1" - }, - "dependencies": { - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" - } - } - }, - "ts-protoc-gen": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/ts-protoc-gen/-/ts-protoc-gen-0.10.0.tgz", - "integrity": "sha512-EEbgDWNHK3CvcNhmib94I4HMO23qLddjLRdXW8EUE11VJxbi3n5J0l2DiX/L1pijOaPTkbEoRK+zQinKgKGqsw==", - "requires": { - "google-protobuf": "^3.6.1" - } - }, - "ts-results": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ts-results/-/ts-results-3.2.1.tgz", - "integrity": "sha512-cMvWPLvxM39fSQgSHRT2d+dwQfpK+ttfj5FpPuXum9m/pm6iDmgsirpWXp/3/ErmZqx1x+rAhJi/33NQqCCM3Q==" - }, - "tsconfig-paths": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", - "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", - "requires": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.0", - "strip-bom": "^3.0.0" - }, - "dependencies": { - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "requires": { - "minimist": "^1.2.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" - } - } - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "tslint": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz", - "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==", - "requires": { - "@babel/code-frame": "^7.0.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.3.0", - "commander": "^2.12.1", - "diff": "^4.0.1", - "glob": "^7.1.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.3", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.13.0", - "tsutils": "^2.29.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "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==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "requires": { - "tslib": "^1.8.1" - } - } - } - }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "requires": { - "tslib": "^1.8.1" - } - }, - "tweetnacl-ts": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl-ts/-/tweetnacl-ts-1.0.3.tgz", - "integrity": "sha512-C5I/dWf6xjAXaCDlf84T4HvozU/8ycAlq5WRllF1hAeeq5390tfXD+bNas5bhEV0HMSOx8bsQYpLjPl8wfnEeQ==", - "requires": { - "tslib": "^1" - } - }, - "tweetnacl-util": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", - "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==" - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" - }, - "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==" - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "typedjson": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/typedjson/-/typedjson-1.7.0.tgz", - "integrity": "sha512-MnRgQLwtEcdHqQG0FkT8ebpBG53Wgr/axYRbiD2WL5NcYx8Z2AoCpXvtTfLnuPqOBKG/9JpXq0O/nl2m4wqJYw==", - "requires": { - "tslib": "^2.0.1" - }, - "dependencies": { - "tslib": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", - "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" - } - } - }, - "typedoc": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.17.8.tgz", - "integrity": "sha512-/OyrHCJ8jtzu+QZ+771YaxQ9s4g5Z3XsQE3Ma7q+BL392xxBn4UMvvCdVnqKC2T/dz03/VXSLVKOP3lHmDdc/w==", - "requires": { - "fs-extra": "^8.1.0", - "handlebars": "^4.7.6", - "highlight.js": "^10.0.0", - "lodash": "^4.17.15", - "lunr": "^2.3.8", - "marked": "1.0.0", - "minimatch": "^3.0.0", - "progress": "^2.0.3", - "shelljs": "^0.8.4", - "typedoc-default-themes": "^0.10.2" - } - }, - "typedoc-default-themes": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/typedoc-default-themes/-/typedoc-default-themes-0.10.2.tgz", - "integrity": "sha512-zo09yRj+xwLFE3hyhJeVHWRSPuKEIAsFK5r2u47KL/HBKqpwdUSanoaz5L34IKiSATFrjG5ywmIu98hPVMfxZg==", - "requires": { - "lunr": "^2.3.8" - } - }, - "typescript": { - "version": "3.9.9", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.9.tgz", - "integrity": "sha512-kdMjTiekY+z/ubJCATUPlRDl39vXYiMV9iyeMuEuXZh2we6zz80uovNN2WlAxmmdE/Z/YQe+EbOEXB5RHEED3w==" - }, - "uglify-js": { - "version": "3.13.4", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.4.tgz", - "integrity": "sha512-kv7fCkIXyQIilD5/yQy8O+uagsYIOt5cZvs890W40/e/rvjMSzJw81o9Bg0tkURxzZBROtDQhW2LFjOGoK3RZw==", - "optional": true - }, - "unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - } - }, - "undefsafe": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz", - "integrity": "sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==", - "requires": { - "debug": "^2.2.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "unique-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "requires": { - "crypto-random-string": "^2.0.0" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "update-notifier": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", - "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==", - "requires": { - "boxen": "^4.2.0", - "chalk": "^3.0.0", - "configstore": "^5.0.1", - "has-yarn": "^2.1.0", - "import-lazy": "^2.1.0", - "is-ci": "^2.0.0", - "is-installed-globally": "^0.3.1", - "is-npm": "^4.0.0", - "is-yarn-global": "^0.3.0", - "latest-version": "^5.0.0", - "pupa": "^2.0.1", - "semver-diff": "^3.1.1", - "xdg-basedir": "^4.0.0" - }, - "dependencies": { - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "requires": { - "punycode": "^2.1.0" - } - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" - } - } - }, - "url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", - "requires": { - "prepend-http": "^2.0.0" - }, - "dependencies": { - "prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" - } - } - }, - "util": { - "version": "0.12.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.3.tgz", - "integrity": "sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog==", - "requires": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "safe-buffer": "^5.1.2", - "which-typed-array": "^1.1.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" - }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==" - }, - "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==", - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "watchpack": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.1.1.tgz", - "integrity": "sha512-Oo7LXCmc1eE1AjyuSBmtC3+Wy4HcV8PxWh2kP6fOl8yTlNS7r0K9l1ao2lrrUza7V39Y3D/BbJgY8VeSlc5JKw==", - "requires": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - } - }, - "webpack": { - "version": "5.35.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.35.0.tgz", - "integrity": "sha512-au3gu55yYF/h6NXFr0KZPZAYxS6Nlc595BzYPke8n0CSff5WXcoixtjh5LC/8mXunkRKxhymhXmBY0+kEbR6jg==", - "requires": { - "@types/eslint-scope": "^3.7.0", - "@types/estree": "^0.0.47", - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/wasm-edit": "1.11.0", - "@webassemblyjs/wasm-parser": "1.11.0", - "acorn": "^8.0.4", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.8.0", - "es-module-lexer": "^0.4.0", - "eslint-scope": "^5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.4", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.0.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.1", - "watchpack": "^2.0.0", - "webpack-sources": "^2.1.1" - } - }, - "webpack-cli": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.6.0.tgz", - "integrity": "sha512-9YV+qTcGMjQFiY7Nb1kmnupvb1x40lfpj8pwdO/bom+sQiP4OBMKjHq29YQrlDWDPZO9r/qWaRRywKaRDKqBTA==", - "requires": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^1.0.2", - "@webpack-cli/info": "^1.2.3", - "@webpack-cli/serve": "^1.3.1", - "colorette": "^1.2.1", - "commander": "^7.0.0", - "enquirer": "^2.3.6", - "execa": "^5.0.0", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^2.2.0", - "rechoir": "^0.7.0", - "v8-compile-cache": "^2.2.0", - "webpack-merge": "^5.7.3" - }, - "dependencies": { - "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==" - }, - "execa": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.0.0.tgz", - "integrity": "sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==", - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - } - }, - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==" - }, - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==" - }, - "interpret": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", - "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==" - }, - "rechoir": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.0.tgz", - "integrity": "sha512-ADsDEH2bvbjltXEP+hTIAmeFekTFK0V2BTxMkok6qILyAJEXV0AFfoWcAq4yfll5VdIMd/RVXq0lR+wQi5ZU3Q==", - "requires": { - "resolve": "^1.9.0" - } - } - } - }, - "webpack-merge": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.7.3.tgz", - "integrity": "sha512-6/JUQv0ELQ1igjGDzHkXbVDRxkfA57Zw7PfiupdLFJYrgFqY5ZP8xxbpp2lU3EPwYx89ht5Z/aDkD40hFCm5AA==", - "requires": { - "clone-deep": "^4.0.1", - "wildcard": "^2.0.0" - } - }, - "webpack-node-externals": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/webpack-node-externals/-/webpack-node-externals-2.5.2.tgz", - "integrity": "sha512-aHdl/y2N7PW2Sx7K+r3AxpJO+aDMcYzMQd60Qxefq3+EwhewSbTBqNumOsCE1JsCUNoyfGj5465N0sSf6hc/5w==" - }, - "webpack-sources": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.2.0.tgz", - "integrity": "sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w==", - "requires": { - "source-list-map": "^2.0.1", - "source-map": "^0.6.1" - } - }, - "whatwg-fetch": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", - "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==" - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "requires": { - "isexe": "^2.0.0" - } - }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" - }, - "which-pm-runs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", - "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=" - }, - "which-typed-array": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.4.tgz", - "integrity": "sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA==", - "requires": { - "available-typed-arrays": "^1.0.2", - "call-bind": "^1.0.0", - "es-abstract": "^1.18.0-next.1", - "foreach": "^2.0.5", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.1", - "is-typed-array": "^1.1.3" - } - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "widest-line": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", - "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", - "requires": { - "string-width": "^4.0.0" - } - }, - "wildcard": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", - "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==" - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" - }, - "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==", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "ws": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz", - "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==" - }, - "xdg-basedir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", - "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "requires": { - "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" - } - }, - "yargs-parser": { - "version": "20.2.7", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz", - "integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==" - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "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==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - }, - "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } - }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" - }, - "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==" - } - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "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==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" - }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" - }, - "dotenv": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", - "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-core-module": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", - "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", - "requires": { - "has": "^1.0.3" - } - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "requires": { - "minimist": "^1.2.5" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "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==" - }, - "prettier": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz", - "integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==" - }, - "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", - "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - }, - "ts-node": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.0.0.tgz", - "integrity": "sha512-ROWeOIUvfFbPZkoDis0L/55Fk+6gFQNZwwKPLinacRl6tsxstTF1DbAcLKkovwnpKMVvOMHP1TIbnwXwtLg1gg==", - "requires": { - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "source-map-support": "^0.5.17", - "yn": "3.1.1" - } - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "tslint": { - "version": "5.20.1", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.20.1.tgz", - "integrity": "sha512-EcMxhzCFt8k+/UP5r8waCf/lzmeSyVlqxqMEDQE7rWYiQky8KpIBz1JAoYXfROHrPZ1XXd43q8yQnULOLiBRQg==", - "requires": { - "@babel/code-frame": "^7.0.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.3.0", - "commander": "^2.12.1", - "diff": "^4.0.1", - "glob": "^7.1.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.8.0", - "tsutils": "^2.29.0" - } - }, - "tslint-config-prettier": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz", - "integrity": "sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==" - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "requires": { - "tslib": "^1.8.1" - } - }, - "typescript": { - "version": "3.9.10", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", - "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==" - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" - } + "casper-js-sdk": "2.2.0" } }, "casper-js-sdk": { - "version": "file:../../casper-js-sdk", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/casper-js-sdk/-/casper-js-sdk-2.2.0.tgz", + "integrity": "sha512-VU2GxGHt++68IR+n2h+UiZnrwBnNVkQKAJ1RWSv3A+zqHZwTZahMF+NO5pz43xwrDBG+sET2vu8JqJ4JJ7AsnQ==", "requires": { "@ethersproject/bignumber": "^5.0.8", "@ethersproject/bytes": "^5.0.5", @@ -7114,5077 +443,791 @@ "tweetnacl-util": "^0.15.0", "typedjson": "^1.6.0-rc2", "webpack": "^5.24.3" + } + }, + "chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==" + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "colorette": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==" + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "drbg.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", + "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", + "optional": true, + "requires": { + "browserify-aes": "^1.0.6", + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4" + } + }, + "eccrypto": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/eccrypto/-/eccrypto-1.1.6.tgz", + "integrity": "sha512-d78ivVEzu7Tn0ZphUUaL43+jVPKTMPFGtmgtz1D0LrFn7cY3K8CdrvibuLz2AAkHBLKZtR8DMbB2ukRYFk987A==", + "requires": { + "acorn": "7.1.1", + "elliptic": "6.5.4", + "es6-promise": "4.2.8", + "nan": "2.14.0", + "secp256k1": "3.7.1" + } + }, + "electron-to-chromium": { + "version": "1.3.784", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.784.tgz", + "integrity": "sha512-JTPxdUibkefeomWNaYs8lI/x/Zb4cOhZWX+d7kpzsNKzUd07pNuo/AcHeNJ/qgEchxM1IAxda9aaGUhKN/poOg==" + }, + "elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "requires": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "enhanced-resolve": { + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz", + "integrity": "sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==", + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + } + }, + "es-module-lexer": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.7.1.tgz", + "integrity": "sha512-MgtWFl5No+4S3TmhDmCz2ObFGm6lEpTnzbQi+Dd+pw4mlTIZTmM2iAs5gRlmx5zS9luzobCSBSI90JM/1/JgOw==" + }, + "es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, + "eslint-plugin-prettier": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.0.tgz", + "integrity": "sha512-UDK6rJT6INSfcOo545jiaOwB701uAIt2/dR7WnFQoGCVl1/EMqdANBmwUaqqQ45aXprsTGzSa39LI1PyuRBxxw==", + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "requires": { + "estraverse": "^5.2.0" }, "dependencies": { - "@babel/code-frame": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", - "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", - "requires": { - "@babel/highlight": "^7.12.13" - } - }, - "@babel/compat-data": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.13.15.tgz", - "integrity": "sha512-ltnibHKR1VnrU4ymHyQ/CXtNXI6yZC0oJThyW78Hft8XndANwi+9H+UIklBDraIjFEJzw8wmcM427oDd9KS5wA==" - }, - "@babel/core": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.16.tgz", - "integrity": "sha512-sXHpixBiWWFti0AV2Zq7avpTasr6sIAu7Y396c608541qAU2ui4a193m0KSQmfPSKFZLnQ3cvlKDOm3XkuXm3Q==", - "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.13.16", - "@babel/helper-compilation-targets": "^7.13.16", - "@babel/helper-module-transforms": "^7.13.14", - "@babel/helpers": "^7.13.16", - "@babel/parser": "^7.13.16", - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.15", - "@babel/types": "^7.13.16", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", - "semver": "^6.3.0", - "source-map": "^0.5.0" - }, - "dependencies": {} - }, - "@babel/helper-compilation-targets": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz", - "integrity": "sha512-3gmkYIrpqsLlieFwjkGgLaSHmhnvlAYzZLlYVjlW+QwI+1zE17kGxuJGmIqDQdYp56XdmGeD+Bswx0UTyG18xA==", - "requires": { - "@babel/compat-data": "^7.13.15", - "@babel/helper-validator-option": "^7.12.17", - "browserslist": "^4.14.5", - "semver": "^6.3.0" - }, - "dependencies": {} - }, - "@babel/helper-function-name": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", - "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", - "requires": { - "@babel/helper-get-function-arity": "^7.12.13", - "@babel/template": "^7.12.13", - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", - "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", - "requires": { - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz", - "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==", - "requires": { - "@babel/types": "^7.13.12" - } - }, - "@babel/helper-module-imports": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz", - "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==", - "requires": { - "@babel/types": "^7.13.12" - } - }, - "@babel/helper-module-transforms": { - "version": "7.13.14", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.13.14.tgz", - "integrity": "sha512-QuU/OJ0iAOSIatyVZmfqB0lbkVP0kDRiKj34xy+QNsnVZi/PA6BoSoreeqnxxa9EHFAIL0R9XOaAR/G9WlIy5g==", - "requires": { - "@babel/helper-module-imports": "^7.13.12", - "@babel/helper-replace-supers": "^7.13.12", - "@babel/helper-simple-access": "^7.13.12", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/helper-validator-identifier": "^7.12.11", - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.13", - "@babel/types": "^7.13.14" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", - "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", - "requires": { - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-replace-supers": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz", - "integrity": "sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw==", - "requires": { - "@babel/helper-member-expression-to-functions": "^7.13.12", - "@babel/helper-optimise-call-expression": "^7.12.13", - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.12" - } - }, - "@babel/helper-simple-access": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz", - "integrity": "sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==", - "requires": { - "@babel/types": "^7.13.12" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", - "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", - "requires": { - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==" - }, - "@babel/helper-validator-option": { - "version": "7.12.17", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz", - "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==" - }, - "@babel/helpers": { - "version": "7.13.17", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.13.17.tgz", - "integrity": "sha512-Eal4Gce4kGijo1/TGJdqp3WuhllaMLSrW6XcL0ulyUAQOuxHcCafZE8KHg9857gcTehsm/v7RcOx2+jp0Ryjsg==", - "requires": { - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.17", - "@babel/types": "^7.13.17" - } - }, - "@babel/highlight": { - "version": "7.13.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.10.tgz", - "integrity": "sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg==", - "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": {} - }, - "@babel/parser": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.16.tgz", - "integrity": "sha512-6bAg36mCwuqLO0hbR+z7PHuqWiCeP7Dzg73OpQwsAB1Eb8HnGEz5xYBzCfbu+YjoaJsJs+qheDxVAuqbt3ILEw==" - }, - "@babel/template": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", - "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", - "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/parser": "^7.12.13", - "@babel/types": "^7.12.13" - } - }, - "@babel/traverse": { - "version": "7.13.17", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.17.tgz", - "integrity": "sha512-BMnZn0R+X6ayqm3C3To7o1j7Q020gWdqdyP50KEoVqaCO2c/Im7sYZSmVgvefp8TTMQ+9CtwuBp0Z1CZ8V3Pvg==", - "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.13.16", - "@babel/helper-function-name": "^7.12.13", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/parser": "^7.13.16", - "@babel/types": "^7.13.17", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "dependencies": {} - }, - "@babel/types": { - "version": "7.13.17", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.17.tgz", - "integrity": "sha512-RawydLgxbOPDlTLJNtoIypwdmAy//uQIzlKt2+iBiJaRlVuI6QLUxVAyWGNfOzp8Yu4L4lLIacoCyTNtpb4wiA==", - "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "to-fast-properties": "^2.0.0" - } - }, - "@discoveryjs/json-ext": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz", - "integrity": "sha512-HyYEUDeIj5rRQU2Hk5HTB2uHsbRQpF70nvMhVzi+VJR0X+xNEhjPui4/kBf3VeH/wqD28PT4sVOm8qqLjBrSZg==" - }, - "@eslint/eslintrc": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.0.tgz", - "integrity": "sha512-2ZPCc+uNbjV5ERJr+aKSPRwZgKd2z11x0EgLvb1PURmUrn9QNRXFqje0Ldq454PfAVyaJYyrDvvIKSFP4NnBog==", - "requires": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - }, - "dependencies": {} - }, - "@ethersproject/bignumber": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.1.1.tgz", - "integrity": "sha512-AVz5iqz7+70RIqoQTznsdJ6DOVBYciNlvO+AlQmPTB6ofCvoihI9bQdr6wljsX+d5W7Yc4nyvQvP4JMzg0Agig==", - "requires": { - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/logger": "^5.1.0", - "bn.js": "^4.4.0" - } - }, - "@ethersproject/bytes": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.1.0.tgz", - "integrity": "sha512-sGTxb+LVjFxJcJeUswAIK6ncgOrh3D8c192iEJd7mLr95V6du119rRfYT/b87WPkZ5I3gRBUYIYXtdgCWACe8g==", + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==" + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" + }, + "ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "requires": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + }, + "dependencies": { + "secp256k1": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz", + "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==", "requires": { - "@ethersproject/logger": "^5.1.0" + "elliptic": "^6.5.2", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" } - }, - "@ethersproject/constants": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.1.0.tgz", - "integrity": "sha512-0/SuHrxc8R8k+JiLmJymxHJbojUDWBQqO+b+XFdwaP0jGzqC09YDy/CAlSZB6qHsBifY8X3I89HcK/oMqxRdBw==", - "requires": { - "@ethersproject/bignumber": "^5.1.0" - } - }, - "@ethersproject/logger": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.1.0.tgz", - "integrity": "sha512-wtUaD1lBX10HBXjjKV9VHCBnTdUaKQnQ2XSET1ezglqLdPdllNOIlLfhyCRqXm5xwcjExVI5ETokOYfjPtaAlw==" - }, - "@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "requires": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "dependencies": {} - }, - "@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==" - }, - "@nodelib/fs.scandir": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", - "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==", - "requires": { - "@nodelib/fs.stat": "2.0.4", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz", - "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==" - }, - "@nodelib/fs.walk": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz", - "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==", - "requires": { - "@nodelib/fs.scandir": "2.1.4", - "fastq": "^1.6.0" - } - }, - "@open-rpc/client-js": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/@open-rpc/client-js/-/client-js-1.6.3.tgz", - "integrity": "sha512-KNlYB258FgMUopHUXqPAU4JZMAO/8HnGN7LcL/mXnwH/Qcd0GAMVwLLIXc5d9BBqtmDox8wxxAXGBCajRhyczA==", - "requires": { - "isomorphic-fetch": "^3.0.0", - "isomorphic-ws": "^4.0.1", - "strict-event-emitter-types": "^2.0.0", - "ws": "^7.0.0" - } - }, - "@sindresorhus/is": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.0.1.tgz", - "integrity": "sha512-Qm9hBEBu18wt1PO2flE7LPb30BHMQt1eQgbV76YntdNk73XZGpn3izvGTYxbGgzXKgbCjiia0uxTd3aTNQrY/g==" - }, - "@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==", - "requires": { - "defer-to-connect": "^2.0.0" - } - }, - "@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", - "requires": { - "@types/node": "*" - } - }, - "@types/body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==", - "requires": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "@types/cacheable-request": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", - "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", - "requires": { - "@types/http-cache-semantics": "*", - "@types/keyv": "*", - "@types/node": "*", - "@types/responselike": "*" - } - }, - "@types/chai": { - "version": "4.2.16", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.16.tgz", - "integrity": "sha512-vI5iOAsez9+roLS3M3+Xx7w+WRuDtSmF8bQkrbcIJ2sC1PcDgVoA0WGpa+bIrJ+y8zqY2oi//fUctkxtIcXJCw==" - }, - "@types/connect": { - "version": "3.4.34", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz", - "integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==", - "requires": { - "@types/node": "*" - } - }, - "@types/eccrypto": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/eccrypto/-/eccrypto-1.1.2.tgz", - "integrity": "sha512-qmB/iGIoqDdCMHAcJiOKI4ZBI1Z3kBQGYQCkgNP/Z9ge5w/EVx5uxQYkGOFpllm6l2N/B3qXcn9vjqXGaV1vRQ==", - "requires": { - "@types/expect": "^1.20.4", - "@types/node": "*" - } - }, - "@types/elliptic": { - "version": "6.4.12", - "resolved": "https://registry.npmjs.org/@types/elliptic/-/elliptic-6.4.12.tgz", - "integrity": "sha512-gP1KsqoouLJGH6IJa28x7PXb3cRqh83X8HCLezd2dF+XcAIMKYv53KV+9Zn6QA561E120uOqZBQ+Jy/cl+fviw==", - "requires": { - "@types/bn.js": "*" - } - }, - "@types/eslint": { - "version": "7.2.10", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.10.tgz", - "integrity": "sha512-kUEPnMKrqbtpCq/KTaGFFKAcz6Ethm2EjCoKIDaCmfRBWLbFuTcOJfTlorwbnboXBzahqWLgUp1BQeKHiJzPUQ==", - "requires": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "@types/eslint-scope": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.0.tgz", - "integrity": "sha512-O/ql2+rrCUe2W2rs7wMR+GqPRcgB6UiqN5RhrR5xruFlY7l9YLMn0ZkDzjoHLeiFkR8MCQZVudUuuvQ2BLC9Qw==", - "requires": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "@types/estree": { - "version": "0.0.47", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.47.tgz", - "integrity": "sha512-c5ciR06jK8u9BstrmJyO97m+klJrrhCf9u3rLu3DEAJBirxRqSCvDQoYKmxuYwQI5SZChAWu+tq9oVlGRuzPAg==" - }, - "@types/expect": { - "version": "1.20.4", - "resolved": "https://registry.npmjs.org/@types/expect/-/expect-1.20.4.tgz", - "integrity": "sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg==" - }, - "@types/express": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.11.tgz", - "integrity": "sha512-no+R6rW60JEc59977wIxreQVsIEOAYwgCqldrA/vkpCnbD7MqTefO97lmoBe4WE0F156bC4uLSP1XHDOySnChg==", - "requires": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.18", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "@types/express-serve-static-core": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.19.tgz", - "integrity": "sha512-DJOSHzX7pCiSElWaGR8kCprwibCB/3yW6vcT8VG3P0SJjnv19gnWG/AZMfM60Xj/YJIp/YCaDHyvzsFVeniARA==", - "requires": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*" - } - }, - "@types/http-cache-semantics": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", - "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" - }, - "@types/humanize-duration": { - "version": "3.18.1", - "resolved": "https://registry.npmjs.org/@types/humanize-duration/-/humanize-duration-3.18.1.tgz", - "integrity": "sha512-MUgbY3CF7hg/a/jogixmAufLjJBQT7WEf8Q+kYJkOc47ytngg1IuZobCngdTjAgY83JWEogippge5O5fplaQlw==" - }, - "@types/json-schema": { - "version": "7.0.7", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", - "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==" - }, - "@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=" - }, - "@types/keyv": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.2.tgz", - "integrity": "sha512-/FvAK2p4jQOaJ6CGDHJTqZcUtbZe820qIeTg7o0Shg7drB4JHeL+V/dhSaly7NXx6u8eSee+r7coT+yuJEvDLg==", - "requires": { - "@types/node": "*" - } - }, - "@types/mime": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", - "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" - }, - "@types/mocha": { - "version": "5.2.7", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", - "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==" - }, - "@types/node": { - "version": "14.14.41", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.41.tgz", - "integrity": "sha512-dueRKfaJL4RTtSa7bWeTK1M+VH+Gns73oCgzvYfHZywRCoPSd8EkXBL0mZ9unPTveBn+D9phZBaxuzpwjWkW0g==" - }, - "@types/normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==" - }, - "@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" - }, - "@types/pbkdf2": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", - "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", - "requires": { - "@types/node": "*" - } - }, - "@types/qs": { - "version": "6.9.6", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.6.tgz", - "integrity": "sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA==" - }, - "@types/range-parser": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", - "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==" - }, - "@types/responselike": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", - "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", - "requires": { - "@types/node": "*" - } - }, - "@types/secp256k1": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.2.tgz", - "integrity": "sha512-QMg+9v0bbNJ2peLuHRWxzmy0HRJIG6gFZNhaRSp7S3ggSbCCxiqQB2/ybvhXyhHOCequpNkrx7OavNhrWOsW0A==", - "requires": { - "@types/node": "*" - } - }, - "@types/serve-static": { - "version": "1.13.9", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.9.tgz", - "integrity": "sha512-ZFqF6qa48XsPdjXV5Gsz0Zqmux2PerNd3a/ktL45mHpa19cuMi/cL8tcxdAx497yRh+QtYPuofjT9oWw9P7nkA==", - "requires": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "@typescript-eslint/eslint-plugin": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.22.0.tgz", - "integrity": "sha512-U8SP9VOs275iDXaL08Ln1Fa/wLXfj5aTr/1c0t0j6CdbOnxh+TruXu1p4I0NAvdPBQgoPjHsgKn28mOi0FzfoA==", - "requires": { - "@typescript-eslint/experimental-utils": "4.22.0", - "@typescript-eslint/scope-manager": "4.22.0", - "debug": "^4.1.1", - "functional-red-black-tree": "^1.0.1", - "lodash": "^4.17.15", - "regexpp": "^3.0.0", - "semver": "^7.3.2", - "tsutils": "^3.17.1" - } - }, - "@typescript-eslint/experimental-utils": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.22.0.tgz", - "integrity": "sha512-xJXHHl6TuAxB5AWiVrGhvbGL8/hbiCQ8FiWwObO3r0fnvBdrbWEDy1hlvGQOAWc6qsCWuWMKdVWlLAEMpxnddg==", - "requires": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/scope-manager": "4.22.0", - "@typescript-eslint/types": "4.22.0", - "@typescript-eslint/typescript-estree": "4.22.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^2.0.0" - } - }, - "@typescript-eslint/parser": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.22.0.tgz", - "integrity": "sha512-z/bGdBJJZJN76nvAY9DkJANYgK3nlRstRRi74WHm3jjgf2I8AglrSY+6l7ogxOmn55YJ6oKZCLLy+6PW70z15Q==", - "requires": { - "@typescript-eslint/scope-manager": "4.22.0", - "@typescript-eslint/types": "4.22.0", - "@typescript-eslint/typescript-estree": "4.22.0", - "debug": "^4.1.1" - } - }, - "@typescript-eslint/scope-manager": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.22.0.tgz", - "integrity": "sha512-OcCO7LTdk6ukawUM40wo61WdeoA7NM/zaoq1/2cs13M7GyiF+T4rxuA4xM+6LeHWjWbss7hkGXjFDRcKD4O04Q==", - "requires": { - "@typescript-eslint/types": "4.22.0", - "@typescript-eslint/visitor-keys": "4.22.0" - } - }, - "@typescript-eslint/types": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.22.0.tgz", - "integrity": "sha512-sW/BiXmmyMqDPO2kpOhSy2Py5w6KvRRsKZnV0c4+0nr4GIcedJwXAq+RHNK4lLVEZAJYFltnnk1tJSlbeS9lYA==" - }, - "@typescript-eslint/typescript-estree": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.22.0.tgz", - "integrity": "sha512-TkIFeu5JEeSs5ze/4NID+PIcVjgoU3cUQUIZnH3Sb1cEn1lBo7StSV5bwPuJQuoxKXlzAObjYTilOEKRuhR5yg==", - "requires": { - "@typescript-eslint/types": "4.22.0", - "@typescript-eslint/visitor-keys": "4.22.0", - "debug": "^4.1.1", - "globby": "^11.0.1", - "is-glob": "^4.0.1", - "semver": "^7.3.2", - "tsutils": "^3.17.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.22.0.tgz", - "integrity": "sha512-nnMu4F+s4o0sll6cBSsTeVsT4cwxB7zECK3dFxzEjPBii9xLpq4yqqsy/FU5zMfan6G60DKZSCXAa3sHJZrcYw==", - "requires": { - "@typescript-eslint/types": "4.22.0", - "eslint-visitor-keys": "^2.0.0" - } - }, - "@webassemblyjs/ast": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.0.tgz", - "integrity": "sha512-kX2W49LWsbthrmIRMbQZuQDhGtjyqXfEmmHyEi4XWnSZtPmxY0+3anPIzsnRb45VH/J55zlOfWvZuY47aJZTJg==", - "requires": { - "@webassemblyjs/helper-numbers": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.0.tgz", - "integrity": "sha512-Q/aVYs/VnPDVYvsCBL/gSgwmfjeCb4LW8+TMrO3cSzJImgv8lxxEPM2JA5jMrivE7LSz3V+PFqtMbls3m1exDA==" - }, - "@webassemblyjs/helper-api-error": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.0.tgz", - "integrity": "sha512-baT/va95eXiXb2QflSx95QGT5ClzWpGaa8L7JnJbgzoYeaA27FCvuBXU758l+KXWRndEmUXjP0Q5fibhavIn8w==" - }, - "@webassemblyjs/helper-buffer": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.0.tgz", - "integrity": "sha512-u9HPBEl4DS+vA8qLQdEQ6N/eJQ7gT7aNvMIo8AAWvAl/xMrcOSiI2M0MAnMCy3jIFke7bEee/JwdX1nUpCtdyA==" - }, - "@webassemblyjs/helper-numbers": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.0.tgz", - "integrity": "sha512-DhRQKelIj01s5IgdsOJMKLppI+4zpmcMQ3XboFPLwCpSNH6Hqo1ritgHgD0nqHeSYqofA6aBN/NmXuGjM1jEfQ==", - "requires": { - "@webassemblyjs/floating-point-hex-parser": "1.11.0", - "@webassemblyjs/helper-api-error": "1.11.0", - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.0.tgz", - "integrity": "sha512-MbmhvxXExm542tWREgSFnOVo07fDpsBJg3sIl6fSp9xuu75eGz5lz31q7wTLffwL3Za7XNRCMZy210+tnsUSEA==" - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.0.tgz", - "integrity": "sha512-3Eb88hcbfY/FCukrg6i3EH8H2UsD7x8Vy47iVJrP967A9JGqgBVL9aH71SETPx1JrGsOUVLo0c7vMCN22ytJew==", - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-buffer": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/wasm-gen": "1.11.0" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.0.tgz", - "integrity": "sha512-KXzOqpcYQwAfeQ6WbF6HXo+0udBNmw0iXDmEK5sFlmQdmND+tr773Ti8/5T/M6Tl/413ArSJErATd8In3B+WBA==", - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.0.tgz", - "integrity": "sha512-aqbsHa1mSQAbeeNcl38un6qVY++hh8OpCOzxhixSYgbRfNWcxJNJQwe2rezK9XEcssJbbWIkblaJRwGMS9zp+g==", - "requires": { - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/utf8": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.0.tgz", - "integrity": "sha512-A/lclGxH6SpSLSyFowMzO/+aDEPU4hvEiooCMXQPcQFPPJaYcPQNKGOCLUySJsYJ4trbpr+Fs08n4jelkVTGVw==" - }, - "@webassemblyjs/wasm-edit": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.0.tgz", - "integrity": "sha512-JHQ0damXy0G6J9ucyKVXO2j08JVJ2ntkdJlq1UTiUrIgfGMmA7Ik5VdC/L8hBK46kVJgujkBIoMtT8yVr+yVOQ==", - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-buffer": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/helper-wasm-section": "1.11.0", - "@webassemblyjs/wasm-gen": "1.11.0", - "@webassemblyjs/wasm-opt": "1.11.0", - "@webassemblyjs/wasm-parser": "1.11.0", - "@webassemblyjs/wast-printer": "1.11.0" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.0.tgz", - "integrity": "sha512-BEUv1aj0WptCZ9kIS30th5ILASUnAPEvE3tVMTrItnZRT9tXCLW2LEXT8ezLw59rqPP9klh9LPmpU+WmRQmCPQ==", - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/ieee754": "1.11.0", - "@webassemblyjs/leb128": "1.11.0", - "@webassemblyjs/utf8": "1.11.0" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.0.tgz", - "integrity": "sha512-tHUSP5F4ywyh3hZ0+fDQuWxKx3mJiPeFufg+9gwTpYp324mPCQgnuVKwzLTZVqj0duRDovnPaZqDwoyhIO8kYg==", - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-buffer": "1.11.0", - "@webassemblyjs/wasm-gen": "1.11.0", - "@webassemblyjs/wasm-parser": "1.11.0" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.0.tgz", - "integrity": "sha512-6L285Sgu9gphrcpDXINvm0M9BskznnzJTE7gYkjDbxET28shDqp27wpruyx3C2S/dvEwiigBwLA1cz7lNUi0kw==", - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-api-error": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/ieee754": "1.11.0", - "@webassemblyjs/leb128": "1.11.0", - "@webassemblyjs/utf8": "1.11.0" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.0.tgz", - "integrity": "sha512-Fg5OX46pRdTgB7rKIUojkh9vXaVN6sGYCnEiJN1GYkb0RPwShZXp6KTDqmoMdQPKhcroOXh3fEzmkWmCYaKYhQ==", - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@xtuc/long": "4.2.2" - } - }, - "@webpack-cli/configtest": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.0.2.tgz", - "integrity": "sha512-3OBzV2fBGZ5TBfdW50cha1lHDVf9vlvRXnjpVbJBa20pSZQaSkMJZiwA8V2vD9ogyeXn8nU5s5A6mHyf5jhMzA==" - }, - "@webpack-cli/info": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.2.3.tgz", - "integrity": "sha512-lLek3/T7u40lTqzCGpC6CAbY6+vXhdhmwFRxZLMnRm6/sIF/7qMpT8MocXCRQfz0JAh63wpbXLMnsQ5162WS7Q==", - "requires": { - "envinfo": "^7.7.3" - } - }, - "@webpack-cli/serve": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.3.1.tgz", - "integrity": "sha512-0qXvpeYO6vaNoRBI52/UsbcaBydJCggoBBnIo/ovQQdn6fug0BgwsjorV1hVS7fMqGVTZGcVxv8334gjmbj5hw==" - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" - }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" - }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" - }, - "acorn": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.1.1.tgz", - "integrity": "sha512-xYiIVjNuqtKXMxlRMDc6mZUhXehod4a3gbZ1qRlM7icK4EbxUFNLhWoPblCvFtB2Y9CIqHP3CF/rdxLItaQv8g==" - }, - "acorn-jsx": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", - "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==" - }, - "aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==" - }, - "ansi-align": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", - "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", - "requires": { - "string-width": "^3.0.0" - }, - "dependencies": {} - }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==" - }, - "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==", - "requires": { - "type-fest": "^0.21.3" - }, - "dependencies": {} - }, - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "append-transform": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", - "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", - "requires": { - "default-require-extensions": "^3.0.0" - } - }, - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=" - }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "array-differ": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-2.1.0.tgz", - "integrity": "sha512-KbUpJgx909ZscOc/7CLATBFam7P1Z1QRQInvgT0UztM9Q72aGKCunKASAl7WNW0tnPmPyEMeMhdsfWhfmW037w==" - }, - "array-filter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz", - "integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=" - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==" - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" - }, - "asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - } - }, - "assert": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-2.0.0.tgz", - "integrity": "sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A==", - "requires": { - "es6-object-assign": "^1.1.0", - "is-nan": "^1.2.1", - "object-is": "^1.0.1", - "util": "^0.12.0" - } - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==" - }, - "astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==" - }, - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "requires": { - "lodash": "^4.17.14" - } - }, - "available-typed-arrays": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz", - "integrity": "sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ==", - "requires": { - "array-filter": "^1.0.0" - } - }, - "axios": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", - "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", - "requires": { - "follow-redirects": "^1.10.0" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "base-x": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz", - "integrity": "sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bip66": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", - "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", - "optional": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "blakejs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", - "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" - }, - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "boxen": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", - "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", - "requires": { - "ansi-align": "^3.0.0", - "camelcase": "^5.3.1", - "chalk": "^3.0.0", - "cli-boxes": "^2.2.0", - "string-width": "^4.1.0", - "term-size": "^2.1.0", - "type-fest": "^0.8.1", - "widest-line": "^3.1.0" - }, - "dependencies": {} - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "requires": { - "fill-range": "^7.0.1" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", - "requires": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - }, - "dependencies": {} - }, - "browserify-sign": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", - "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": {} - }, - "browserslist": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.4.tgz", - "integrity": "sha512-d7rCxYV8I9kj41RH8UKYnvDYCRENUlHRgyXy/Rhr/1BaeLGfiCptEdFE8MIrvGfWbBFNjVYx76SQWvNX1j+/cQ==", - "requires": { - "caniuse-lite": "^1.0.30001208", - "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.712", - "escalade": "^3.1.1", - "node-releases": "^1.1.71" - } - }, - "bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", - "requires": { - "base-x": "^3.0.2" - } - }, - "bs58check": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", - "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", - "requires": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" - } - }, - "buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=" - }, - "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==" - }, - "cacheable-request": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", - "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", - "requires": { - "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" - }, - "dependencies": {} - }, - "caching-transform": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", - "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", - "requires": { - "hasha": "^5.0.0", - "make-dir": "^3.0.0", - "package-hash": "^4.0.0", - "write-file-atomic": "^3.0.0" - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" - }, - "caniuse-lite": { - "version": "1.0.30001214", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001214.tgz", - "integrity": "sha512-O2/SCpuaU3eASWVaesQirZv1MSjUNOvmugaD8zNSJqw6Vv5SGwoOpA9LJs3pNPfM745nxqPvfZY3MQKY4AKHYg==" - }, - "chai": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", - "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=" - }, - "chokidar": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", - "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.3.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" - } - }, - "chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==" - }, - "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==" - }, - "cli-boxes": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", - "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==" - }, - "cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "requires": { - "restore-cursor": "^3.1.0" - } - }, - "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==", - "requires": { - "slice-ansi": "^3.0.0", - "string-width": "^4.2.0" - }, - "dependencies": {} - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "requires": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - } - }, - "clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "requires": { - "mimic-response": "^1.0.0" - } - }, - "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==", - "requires": { - "color-name": "~1.1.4" - } - }, - "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==" - }, - "colorette": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", - "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==" - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "comment-parser": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.1.2.tgz", - "integrity": "sha512-AOdq0i8ghZudnYv8RUnHrhTgafUGs61Rdz9jemU5x2lnZwAWyOq7vySo626K59e1fVKH1xSRorJwPVRLSWOoAQ==" - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" - }, - "compare-versions": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz", - "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "concurrently": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-6.0.2.tgz", - "integrity": "sha512-u+1Q0dJG5BidgUTpz9CU16yoHTt/oApFDQ3mbvHwSDgMjU7aGqy0q8ZQyaZyaNxdwRKTD872Ux3Twc6//sWA+Q==", - "requires": { - "chalk": "^4.1.0", - "date-fns": "^2.16.1", - "lodash": "^4.17.21", - "read-pkg": "^5.2.0", - "rxjs": "^6.6.3", - "spawn-command": "^0.0.2-1", - "supports-color": "^8.1.0", - "tree-kill": "^1.2.2", - "yargs": "^16.2.0" - }, - "dependencies": {} - }, - "configstore": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", - "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", - "requires": { - "dot-prop": "^5.2.0", - "graceful-fs": "^4.1.2", - "make-dir": "^3.0.0", - "unique-string": "^2.0.0", - "write-file-atomic": "^3.0.0", - "xdg-basedir": "^4.0.0" - } - }, - "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "requires": { - "safe-buffer": "~5.1.1" - }, - "dependencies": {} - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cosmiconfig": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", - "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==", - "requires": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - } - }, - "create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==" - }, - "date-fns": { - "version": "2.21.1", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.21.1.tgz", - "integrity": "sha512-m1WR0xGiC6j6jNFAyW4Nvh4WxAi4JF4w9jRJwSI8nBmNcyZXPcP9VUQG+6gHQXAmqaGEKDKhOqAtENDC941UkA==" - }, - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "requires": { - "ms": "2.1.2" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" - }, - "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==", - "requires": { - "mimic-response": "^3.1.0" - }, - "dependencies": {} - }, - "dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=" - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "requires": { - "type-detect": "^4.0.0" - } - }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" - }, - "default-require-extensions": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", - "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==", - "requires": { - "strip-bom": "^4.0.0" - } - }, - "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==" - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "requires": { - "object-keys": "^1.0.12" - } - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "requires": { - "path-type": "^4.0.0" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "requires": { - "esutils": "^2.0.2" - } - }, - "dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "requires": { - "is-obj": "^2.0.0" - }, - "dependencies": {} - }, - "drbg.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", - "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", - "optional": true, - "requires": { - "browserify-aes": "^1.0.6", - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4" - } - }, - "duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" - }, - "eccrypto": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/eccrypto/-/eccrypto-1.1.6.tgz", - "integrity": "sha512-d78ivVEzu7Tn0ZphUUaL43+jVPKTMPFGtmgtz1D0LrFn7cY3K8CdrvibuLz2AAkHBLKZtR8DMbB2ukRYFk987A==", - "requires": { - "acorn": "7.1.1", - "elliptic": "6.5.4", - "es6-promise": "4.2.8", - "nan": "2.14.0", - "secp256k1": "3.7.1" - }, - "dependencies": {} - }, - "electron-to-chromium": { - "version": "1.3.719", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.719.tgz", - "integrity": "sha512-heM78GKSqrIzO9Oz0/y22nTBN7bqSP1Pla2SyU9DiSnQD+Ea9SyyN5RWWlgqsqeBLNDkSlE9J9EHFmdMPzxB/g==" - }, - "elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "requires": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "email-addresses": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-3.1.0.tgz", - "integrity": "sha512-k0/r7GrWVL32kZlGwfPNgB2Y/mMXVTq/decgLczm/j34whdaspNrZO8CnXPf1laaHxI6ptUlsnAxN+UAPw+fzg==" - }, - "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==" - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" - }, - "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==", - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.0.tgz", - "integrity": "sha512-Sl3KRpJA8OpprrtaIswVki3cWPiPKxXuFxJXBp+zNb6s6VwNWwFRUdtmzd2ReUut8n+sCPx7QCtQ7w5wfJhSgQ==", - "requires": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - } - }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "requires": { - "ansi-colors": "^4.1.1" - } - }, - "envinfo": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", - "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==" - }, - "errno": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", - "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", - "requires": { - "prr": "~1.0.1" - } - }, - "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==", - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0.tgz", - "integrity": "sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw==", - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "is-callable": "^1.2.3", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.2", - "is-string": "^1.0.5", - "object-inspect": "^1.9.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.0" - } - }, - "es-module-lexer": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.4.1.tgz", - "integrity": "sha512-ooYciCUtfw6/d2w56UVeqHPcoCFAiJdz5XOkYpv/Txl1HMUozpXjz/2RIQgqwKdXNDPSF1W7mJCFse3G+HDyAA==" - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==" - }, - "es6-object-assign": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", - "integrity": "sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw=" - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" - }, - "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==" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "eslint": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.24.0.tgz", - "integrity": "sha512-k9gaHeHiFmGCDQ2rEfvULlSLruz6tgfA8DEn+rY9/oYPFFTlz55mM/Q/Rij1b2Y42jwZiK3lXvNTw6w6TXzcKQ==", - "requires": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash": "^4.17.21", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.4", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": {} - }, - "eslint-config-prettier": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.2.0.tgz", - "integrity": "sha512-dWV9EVeSo2qodOPi1iBYU/x6F6diHv8uujxbxr77xExs3zTAlNXvVZKiyLsQGNz7yPV2K49JY5WjPzNIuDc2Bw==" - }, - "eslint-plugin-jsdoc": { - "version": "32.3.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-32.3.0.tgz", - "integrity": "sha512-zyx7kajDK+tqS1bHuY5sapkad8P8KT0vdd/lE55j47VPG2MeenSYuIY/M/Pvmzq5g0+3JB+P3BJGUXmHxtuKPQ==", - "requires": { - "comment-parser": "1.1.2", - "debug": "^4.3.1", - "jsdoctypeparser": "^9.0.0", - "lodash": "^4.17.20", - "regextras": "^0.7.1", - "semver": "^7.3.4", - "spdx-expression-parse": "^3.0.1" - } - }, - "eslint-plugin-prefer-arrow": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-prefer-arrow/-/eslint-plugin-prefer-arrow-1.2.3.tgz", - "integrity": "sha512-J9I5PKCOJretVuiZRGvPQxCbllxGAV/viI20JO3LYblAodofBxyMnZAJ+WGeClHgANnSJberTNoFWWjrWKBuXQ==" - }, - "eslint-plugin-prettier": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.0.tgz", - "integrity": "sha512-UDK6rJT6INSfcOo545jiaOwB701uAIt2/dR7WnFQoGCVl1/EMqdANBmwUaqqQ45aXprsTGzSa39LI1PyuRBxxw==", - "requires": { - "prettier-linter-helpers": "^1.0.0" - } - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "requires": { - "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": {} - }, - "eslint-visitor-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", - "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==" - }, - "espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "requires": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "dependencies": {} - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "requires": { - "estraverse": "^5.1.0" - }, - "dependencies": {} - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "requires": { - "estraverse": "^5.2.0" - }, - "dependencies": {} - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" - }, - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", - "requires": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==" - }, - "fast-glob": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", - "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", - "merge2": "^1.3.0", - "micromatch": "^4.0.2", - "picomatch": "^2.2.1" - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" - }, - "fastest-levenshtein": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", - "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==" - }, - "fastq": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", - "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==", - "requires": { - "reusify": "^1.0.4" - } - }, - "figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "requires": { - "flat-cache": "^3.0.4" - } - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "optional": true - }, - "filename-reserved-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-1.0.0.tgz", - "integrity": "sha1-5hz4BfDeHJhFZ9A4bcXfUO5a9+Q=" - }, - "filenamify": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-1.2.1.tgz", - "integrity": "sha1-qfL/0RxQO+0wABUCknI3jx8TZaU=", - "requires": { - "filename-reserved-regex": "^1.0.0", - "strip-outer": "^1.0.0", - "trim-repeated": "^1.0.0" - } - }, - "filenamify-url": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/filenamify-url/-/filenamify-url-1.0.0.tgz", - "integrity": "sha1-syvYExnvWGO3MHi+1Q9GpPeXX1A=", - "requires": { - "filenamify": "^1.0.0", - "humanize-url": "^1.0.0" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-cache-dir": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", - "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", - "requires": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "find-versions": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-4.0.0.tgz", - "integrity": "sha512-wgpWy002tA+wgmO27buH/9KzyEOQnKsG/R0yrcjPT9BOFm0zRBVQbZ95nRGXWMywS8YR5knRbpohio0bcJABxQ==", - "requires": { - "semver-regex": "^3.1.2" - } - }, - "flat": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", - "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", - "requires": { - "is-buffer": "~2.0.3" - } - }, - "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", - "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==" - }, - "follow-redirects": { - "version": "1.13.3", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.3.tgz", - "integrity": "sha512-DUgl6+HDzB0iEptNQEXLx/KhTmDb8tZUHSeLqpnjpknR70H0nC2t9N73BK6fN4hOvJ84pKlIQVQ4k5FFlBedKA==" - }, - "foreach": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" - }, - "foreground-child": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", - "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", - "requires": { - "cross-spawn": "^7.0.0", - "signal-exit": "^3.0.2" - } - }, - "fromentries": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", - "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==" - }, - "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==", - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" - }, - "gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" - }, - "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==" - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=" - }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "get-own-enumerable-property-symbols": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", - "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" - }, - "get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==" - }, - "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==", - "requires": { - "pump": "^3.0.0" - } - }, - "gh-pages": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-3.1.0.tgz", - "integrity": "sha512-3b1rly9kuf3/dXsT8+ZxP0UhNLOo1CItj+3e31yUVcaph/yDsJ9RzD7JOw5o5zpBTJVQLlJAASNkUfepi9fe2w==", - "requires": { - "async": "^2.6.1", - "commander": "^2.18.0", - "email-addresses": "^3.0.1", - "filenamify-url": "^1.0.0", - "find-cache-dir": "^3.3.1", - "fs-extra": "^8.1.0", - "globby": "^6.1.0" - }, - "dependencies": {} - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "requires": { - "is-glob": "^4.0.1" - } - }, - "glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" - }, - "global-dirs": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.1.0.tgz", - "integrity": "sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==", - "requires": { - "ini": "1.3.7" - } - }, - "globals": { - "version": "13.8.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.8.0.tgz", - "integrity": "sha512-rHtdA6+PDBIjeEvA91rpqzEvk/k3/i7EeNQiryiWuJH0Hw9cpyJMAt2jtbAwUaRdhD+573X4vWw6IcjKPasi9Q==", - "requires": { - "type-fest": "^0.20.2" - }, - "dependencies": {} - }, - "globby": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz", - "integrity": "sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==", - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - } - }, - "google-protobuf": { - "version": "3.15.8", - "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.15.8.tgz", - "integrity": "sha512-2jtfdqTaSxk0cuBJBtTTWsot4WtR9RVr2rXg7x7OoqiuOKopPrwXpM1G4dXIkLcUNRh3RKzz76C8IOkksZSeOw==" - }, - "got": { - "version": "11.8.2", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.2.tgz", - "integrity": "sha512-D0QywKgIe30ODs+fm8wMZiAcZjypcCodPNuMz5H9Mny7RJ+IjJ10BdmGW7OM7fHXP+O7r6ZwapQ/YQmMSvB0UQ==", - "requires": { - "@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.1", - "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" - } - }, - "graceful-fs": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==" - }, - "handlebars": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", - "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", - "requires": { - "minimist": "^1.2.5", - "neo-async": "^2.6.0", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4", - "wordwrap": "^1.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" - }, - "has-yarn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", - "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==" - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "hasha": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", - "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", - "requires": { - "is-stream": "^2.0.0", - "type-fest": "^0.8.0" - }, - "dependencies": {} - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "highlight.js": { - "version": "10.7.2", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.2.tgz", - "integrity": "sha512-oFLl873u4usRM9K63j4ME9u3etNF0PLiJhSQ8rdfuL51Wn3zkD6drf9ZW0dOzjnZI22YYG24z30JcmfCZjMgYg==" - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "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==" - }, - "html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" - }, - "http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" - }, - "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==", - "requires": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.0.0" - } - }, - "human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==" - }, - "humanize-duration": { - "version": "3.25.2", - "resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.25.2.tgz", - "integrity": "sha512-zSerjahuzBazDaE8skjMI7Xmrt/EirvW5cDsXgysx8tYIjcgCMnI5Y5985y3LxYeLah9L5cQY3WEw1k7GRWbfg==" - }, - "humanize-url": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/humanize-url/-/humanize-url-1.0.1.tgz", - "integrity": "sha1-9KuZ4NKIF0yk4eUEB8VfuuRk7/8=", - "requires": { - "normalize-url": "^1.0.0", - "strip-url-auth": "^1.0.0" - } - }, - "husky": { - "version": "4.3.8", - "resolved": "https://registry.npmjs.org/husky/-/husky-4.3.8.tgz", - "integrity": "sha512-LCqqsB0PzJQ/AlCgfrfzRe3e3+NvmefAdKQhRYpxS4u6clblBoDdzzvHi8fmxKRzvMxPY/1WZWzomPZww0Anow==", - "requires": { - "chalk": "^4.0.0", - "ci-info": "^2.0.0", - "compare-versions": "^3.6.0", - "cosmiconfig": "^7.0.0", - "find-versions": "^4.0.0", - "opencollective-postinstall": "^2.0.2", - "pkg-dir": "^5.0.0", - "please-upgrade-node": "^3.2.0", - "slash": "^3.0.0", - "which-pm-runs": "^1.0.0" - }, - "dependencies": {} - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" - }, - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==" - }, - "ignore-by-default": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=" - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "import-lazy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", - "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=" - }, - "import-local": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", - "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", - "requires": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" - }, - "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==" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ini": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", - "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==" - }, - "interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==" - }, - "is-arguments": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", - "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==", - "requires": { - "call-bind": "^1.0.0" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" - }, - "is-bigint": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.1.tgz", - "integrity": "sha512-J0ELF4yHFxHy0cmSxZuheDOz2luOdVvqjwmEcj8H/L1JHeuEDSDbeRP+Dk9kFVk5RTFzbucJ2Kb9F7ixY2QaCg==" - }, - "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==", - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-boolean-object": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.0.tgz", - "integrity": "sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA==", - "requires": { - "call-bind": "^1.0.0" - } - }, - "is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==" - }, - "is-callable": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", - "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==" - }, - "is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "requires": { - "ci-info": "^2.0.0" - } - }, - "is-core-module": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", - "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", - "requires": { - "has": "^1.0.3" - } - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==" - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" - }, - "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==" - }, - "is-generator-function": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.8.tgz", - "integrity": "sha512-2Omr/twNtufVZFr1GhxjOMFPAj2sjc/dKaIqBhvo4qciXfJmITGH6ZGd8eZYNHza8t1y0e01AuqRhJwfWp26WQ==" - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-installed-globally": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", - "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", - "requires": { - "global-dirs": "^2.0.1", - "is-path-inside": "^3.0.1" - } - }, - "is-nan": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", - "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - } - }, - "is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==" - }, - "is-npm": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", - "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==" - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" - }, - "is-number-object": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz", - "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==" - }, - "is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" - }, - "is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==" - }, - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "requires": { - "isobject": "^3.0.1" - } - }, - "is-regex": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", - "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", - "requires": { - "call-bind": "^1.0.2", - "has-symbols": "^1.0.1" - } - }, - "is-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=" - }, - "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" - }, - "is-string": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", - "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==" - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typed-array": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.5.tgz", - "integrity": "sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug==", - "requires": { - "available-typed-arrays": "^1.0.2", - "call-bind": "^1.0.2", - "es-abstract": "^1.18.0-next.2", - "foreach": "^2.0.5", - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" - }, - "is-yarn-global": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", - "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - }, - "isomorphic-fetch": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", - "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", - "requires": { - "node-fetch": "^2.6.1", - "whatwg-fetch": "^3.4.1" - } - }, - "isomorphic-ws": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", - "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==" - }, - "istanbul-lib-coverage": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", - "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==" - }, - "istanbul-lib-hook": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", - "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", - "requires": { - "append-transform": "^2.0.0" - } - }, - "istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", - "requires": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - }, - "dependencies": {} - }, - "istanbul-lib-processinfo": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz", - "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==", - "requires": { - "archy": "^1.0.0", - "cross-spawn": "^7.0.0", - "istanbul-lib-coverage": "^3.0.0-alpha.1", - "make-dir": "^3.0.0", - "p-map": "^3.0.0", - "rimraf": "^3.0.0", - "uuid": "^3.3.3" - }, - "dependencies": {} - }, - "istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "requires": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - } - }, - "istanbul-lib-source-maps": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", - "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - } - }, - "istanbul-reports": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", - "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", - "requires": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - } - }, - "jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - } - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbi": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/jsbi/-/jsbi-3.1.4.tgz", - "integrity": "sha512-52QRRFSsi9impURE8ZUbzAMCLjPm4THO7H2fcuIvaaeFTbSysvkodbQQXIVsNgq/ypDbq6dJiuGKL0vZ/i9hUg==" - }, - "jsdoctypeparser": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/jsdoctypeparser/-/jsdoctypeparser-9.0.0.tgz", - "integrity": "sha512-jrTA2jJIL6/DAEILBEh2/w9QxCuwmvNXIry39Ay/HVfhE3o2yVV0U44blYkqdHA/OKloJEqvJy0xU+GSdE2SIw==" - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" - }, - "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==" - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" - }, - "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==" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=" - }, - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "requires": { - "minimist": "^1.2.5" - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "keccak": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.1.tgz", - "integrity": "sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA==", - "requires": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - } - }, - "key-encoder": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/key-encoder/-/key-encoder-2.0.3.tgz", - "integrity": "sha512-fgBtpAGIr/Fy5/+ZLQZIPPhsZEcbSlYu/Wu96tNDFNSjSACw5lEIOFeaVdQ/iwrb8oxjlWi6wmWdH76hV6GZjg==", - "requires": { - "@types/elliptic": "^6.4.9", - "asn1.js": "^5.0.1", - "bn.js": "^4.11.8", - "elliptic": "^6.4.1" - } - }, - "keyv": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.3.tgz", - "integrity": "sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA==", - "requires": { - "json-buffer": "3.0.1" - } - }, - "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==" - }, - "latest-version": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", - "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", - "requires": { - "package-json": "^6.3.0" - } - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=" - }, - "lint-staged": { - "version": "10.5.4", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-10.5.4.tgz", - "integrity": "sha512-EechC3DdFic/TdOPgj/RB3FicqE6932LTHCUm0Y2fsD9KGlLB+RwJl2q1IYBIvEsKzDOgn0D4gll+YxG5RsrKg==", - "requires": { - "chalk": "^4.1.0", - "cli-truncate": "^2.1.0", - "commander": "^6.2.0", - "cosmiconfig": "^7.0.0", - "debug": "^4.2.0", - "dedent": "^0.7.0", - "enquirer": "^2.3.6", - "execa": "^4.1.0", - "listr2": "^3.2.2", - "log-symbols": "^4.0.0", - "micromatch": "^4.0.2", - "normalize-path": "^3.0.0", - "please-upgrade-node": "^3.2.0", - "string-argv": "0.3.1", - "stringify-object": "^3.3.0" - }, - "dependencies": {} - }, - "listr2": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.7.1.tgz", - "integrity": "sha512-cNd368GTrk8351/ov/IV+BSwyf9sJRgI0UIvfORonCZA1u9UHAtAlqSEv9dgafoQIA1CgB3nu4No79pJtK2LHw==", - "requires": { - "chalk": "^4.1.0", - "cli-truncate": "^2.1.0", - "figures": "^3.2.0", - "indent-string": "^4.0.0", - "log-update": "^4.0.0", - "p-map": "^4.0.0", - "rxjs": "^6.6.7", - "through": "^2.3.8", - "wrap-ansi": "^7.0.0" - } - }, - "loader-runner": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", - "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==" - }, - "loader-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", - "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "requires": { - "p-locate": "^4.1.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=" - }, - "lodash.flattendeep": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=" - }, - "lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=" - }, - "log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "requires": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - } - }, - "log-update": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", - "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", - "requires": { - "ansi-escapes": "^4.3.0", - "cli-cursor": "^3.1.0", - "slice-ansi": "^4.0.0", - "wrap-ansi": "^6.2.0" - }, - "dependencies": {} - }, - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" - }, - "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==", - "requires": { - "yallist": "^4.0.0" - } - }, - "lunr": { - "version": "2.3.9", - "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", - "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==" - }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "requires": { - "semver": "^6.0.0" - }, - "dependencies": {} - }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" - }, - "marked": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-1.0.0.tgz", - "integrity": "sha512-Wo+L1pWTVibfrSr+TTtMuiMfNzmZWiOPeO7rZsQUY5bgsxpHesBEcIWJloWVTFnrMXnf/TL30eTFSGJddmQAng==" - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "dependencies": {} - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" - }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - } - }, - "mime-db": { - "version": "1.47.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", - "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==" - }, - "mime-types": { - "version": "2.1.30", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", - "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", - "requires": { - "mime-db": "1.47.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" - }, - "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, - "mkdirp": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz", - "integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==", - "requires": { - "minimist": "^1.2.5" - } - }, - "mocha": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.3.tgz", - "integrity": "sha512-0R/3FvjIGH3eEuG17ccFPk117XL2rWxatr81a57D+r/x2uTYZRbdZ4oVidEUMh2W2TJDa7MdAb12Lm2/qrKajg==", - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "2.2.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.4", - "ms": "2.1.1", - "node-environment-flags": "1.0.5", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "dependencies": {} - }, - "mri": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.1.6.tgz", - "integrity": "sha512-oi1b3MfbyGa7FJMP9GmLTttni5JoICpYBRlq+x5V16fZbLsnL9N3wFqqIm/nIG43FjUFkFh9Epzp/kzUGUnJxQ==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "multimatch": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-3.0.0.tgz", - "integrity": "sha512-22foS/gqQfANZ3o+W7ST2x25ueHDVNWl/b9OlGcLpy/iKxjCpvcNCM51YCenUi7Mt/jAjjqv8JwZRs8YP5sRjA==", - "requires": { - "array-differ": "^2.0.3", - "array-union": "^1.0.2", - "arrify": "^1.0.1", - "minimatch": "^3.0.4" - }, - "dependencies": {} - }, - "nan": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" - }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" - }, - "node-addon-api": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" - }, - "node-environment-flags": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", - "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==", - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": {} - }, - "node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" - }, - "node-gyp-build": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", - "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==" - }, - "node-preload": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", - "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", - "requires": { - "process-on-spawn": "^1.0.0" - } - }, - "node-releases": { - "version": "1.1.71", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz", - "integrity": "sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==" - }, - "nodemon": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.7.tgz", - "integrity": "sha512-XHzK69Awgnec9UzHr1kc8EomQh4sjTQ8oRf8TsGrSmHDx9/UmiGG9E/mM3BuTfNeFwdNBvrqQq/RHL0xIeyFOA==", - "requires": { - "chokidar": "^3.2.2", - "debug": "^3.2.6", - "ignore-by-default": "^1.0.1", - "minimatch": "^3.0.4", - "pstree.remy": "^1.1.7", - "semver": "^5.7.1", - "supports-color": "^5.5.0", - "touch": "^3.1.0", - "undefsafe": "^2.0.3", - "update-notifier": "^4.1.0" - }, - "dependencies": {} - }, - "nopt": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", - "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", - "requires": { - "abbrev": "1" - } - }, - "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==", - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - }, - "dependencies": {} - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" - }, - "normalize-url": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", - "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", - "requires": { - "object-assign": "^4.0.1", - "prepend-http": "^1.0.0", - "query-string": "^4.1.0", - "sort-keys": "^1.0.0" - } - }, - "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==", - "requires": { - "path-key": "^3.0.0" - } - }, - "nyc": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", - "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", - "requires": { - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "caching-transform": "^4.0.0", - "convert-source-map": "^1.7.0", - "decamelize": "^1.2.0", - "find-cache-dir": "^3.2.0", - "find-up": "^4.1.0", - "foreground-child": "^2.0.0", - "get-package-type": "^0.1.0", - "glob": "^7.1.6", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-hook": "^3.0.0", - "istanbul-lib-instrument": "^4.0.0", - "istanbul-lib-processinfo": "^2.0.2", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "make-dir": "^3.0.0", - "node-preload": "^0.2.1", - "p-map": "^3.0.0", - "process-on-spawn": "^1.0.0", - "resolve-from": "^5.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "spawn-wrap": "^2.0.0", - "test-exclude": "^6.0.0", - "yargs": "^15.0.2" - }, - "dependencies": {} - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "object-inspect": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.2.tgz", - "integrity": "sha512-gz58rdPpadwztRrPjZE9DZLOABUpTGdcANUgOwBFO1C+HZZhePoP83M65WGDmbpwFYJSWqavbl4SgDn4k8RYTA==" - }, - "object-is": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", - "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" - }, - "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz", - "integrity": "sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "opencollective-postinstall": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz", - "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==" - }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - } - }, - "p-cancelable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==" - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "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==", - "requires": { - "p-limit": "^2.2.0" - }, - "dependencies": {} - }, - "p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "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==" - }, - "package-hash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", - "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", - "requires": { - "graceful-fs": "^4.1.15", - "hasha": "^5.0.0", - "lodash.flattendeep": "^4.4.0", - "release-zalgo": "^1.0.0" - } - }, - "package-json": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", - "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", - "requires": { - "got": "^9.6.0", - "registry-auth-token": "^4.0.0", - "registry-url": "^5.0.0", - "semver": "^6.2.0" - }, - "dependencies": {} - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", - "requires": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "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==", - "requires": { - "@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" - } - }, - "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==" - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" - }, - "pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==" - }, - "pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "picomatch": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", - "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==" - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "requires": { - "find-up": "^4.0.0" - } - }, - "please-upgrade-node": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", - "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", - "requires": { - "semver-compare": "^1.0.0" - } - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" - }, - "prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" - }, - "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==" - }, - "prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "requires": { - "fast-diff": "^1.1.2" - } - }, - "pretty-quick": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-1.11.1.tgz", - "integrity": "sha512-kSXCkcETfak7EQXz6WOkCeCqpbC4GIzrN/vaneTGMP/fAtD8NerA9bPhCUqHAks1geo7biZNl5uEMPceeneLuA==", - "requires": { - "chalk": "^2.3.0", - "execa": "^0.8.0", - "find-up": "^2.1.0", - "ignore": "^3.3.7", - "mri": "^1.1.0", - "multimatch": "^3.0.0" - }, - "dependencies": {} - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" - }, - "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==" - }, - "process-on-spawn": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", - "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", - "requires": { - "fromentries": "^1.2.0" - } - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" - }, - "pstree.remy": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", - "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "pupa": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", - "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", - "requires": { - "escape-goat": "^2.0.0" - } - }, - "query-string": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", - "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", - "requires": { - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - } - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" - }, - "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==" - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": {} - }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - } - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", - "requires": { - "picomatch": "^2.2.1" - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "requires": { - "resolve": "^1.1.6" - } - }, - "reflect-metadata": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", - "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" - }, - "regexpp": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", - "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==" - }, - "regextras": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/regextras/-/regextras-0.7.1.tgz", - "integrity": "sha512-9YXf6xtW+qzQ+hcMQXx95MOvfqXFgsKDZodX3qZB0x2n5Z94ioetIITsBtvJbiOyxa/6s9AtyweBLCdPmPko/w==" - }, - "registry-auth-token": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", - "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", - "requires": { - "rc": "^1.2.8" - } - }, - "registry-url": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", - "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", - "requires": { - "rc": "^1.2.8" - } - }, - "release-zalgo": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", - "requires": { - "es6-error": "^4.0.1" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" - }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" - }, - "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", - "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - } - }, - "resolve-alpn": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.1.2.tgz", - "integrity": "sha512-8OyfzhAtA32LVUsJSke3auIyINcwdh5l3cvYKdKO0nvsYSKuiLfTM5i78PJswFPT8y6cPW+L1v6/hE95chcpDA==" - }, - "resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "requires": { - "resolve-from": "^5.0.0" - }, - "dependencies": {} - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" - }, - "responselike": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", - "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", - "requires": { - "lowercase-keys": "^2.0.0" - } - }, - "restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "requires": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - } - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "requires": { - "glob": "^7.1.3" - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "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==", - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "requires": { - "tslib": "^1.9.0" - } - }, - "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==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "schema-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", - "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", - "requires": { - "@types/json-schema": "^7.0.6", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - }, - "scrypt-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" - }, - "secp256k1": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz", - "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==", - "requires": { - "elliptic": "^6.5.2", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - } - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "requires": { - "lru-cache": "^6.0.0" - } - }, - "semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=" - }, - "semver-diff": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", - "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", - "requires": { - "semver": "^6.3.0" - }, - "dependencies": {} - }, - "semver-regex": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-3.1.2.tgz", - "integrity": "sha512-bXWyL6EAKOJa81XG1OZ/Yyuq+oT0b2YLlxx7c+mrdYPaPbnj6WgVULXhinMIeZGufuUBu/eVRqXEhiv4imfwxA==" - }, - "serialize-javascript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", - "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", - "requires": { - "randombytes": "^2.1.0" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "requires": { - "kind-of": "^6.0.2" - } - }, - "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==", - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" - }, - "shelljs": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz", - "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==", - "requires": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - } - }, - "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" - }, - "slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - } - }, - "sort-keys": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", - "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", - "requires": { - "is-plain-obj": "^1.0.0" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" - }, + } + } + }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==" + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "optional": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" + }, + "graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "humanize-duration": { + "version": "3.27.0", + "resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.27.0.tgz", + "integrity": "sha512-qLo/08cNc3Tb0uD7jK0jAcU5cnqCM0n568918E7R2XhMr/+7F37p4EY062W/stg7tmzvknNn9b/1+UhVRzsYrQ==" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "isomorphic-fetch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", + "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", + "requires": { + "node-fetch": "^2.6.1", + "whatwg-fetch": "^3.4.1" + } + }, + "isomorphic-ws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", + "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==" + }, + "jest-worker": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.0.6.tgz", + "integrity": "sha512-qupxcj/dRuA3xHPMUd40gr2EaAurFbkwzOh7wfPaeE9id7hyjURRQoqNfHifHK3XjJU6YJJUQKILGUnwGPEOCA==", + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + } + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "keccak": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.1.tgz", + "integrity": "sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA==", + "requires": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + } + }, + "key-encoder": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/key-encoder/-/key-encoder-2.0.3.tgz", + "integrity": "sha512-fgBtpAGIr/Fy5/+ZLQZIPPhsZEcbSlYu/Wu96tNDFNSjSACw5lEIOFeaVdQ/iwrb8oxjlWi6wmWdH76hV6GZjg==", + "requires": { + "@types/elliptic": "^6.4.9", + "asn1.js": "^5.0.1", + "bn.js": "^4.11.8", + "elliptic": "^6.4.1" + } + }, + "loader-runner": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", + "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==" + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "mime-db": { + "version": "1.48.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", + "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==" + }, + "mime-types": { + "version": "2.1.31", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", + "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", + "requires": { + "mime-db": "1.48.0" + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" + }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + }, + "node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" + }, + "node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" + }, + "node-gyp-build": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", + "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==" + }, + "node-releases": { + "version": "1.1.73", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz", + "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "requires": { + "fast-diff": "^1.1.2" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "reflect-metadata": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", + "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "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==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "schema-utils": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", + "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + }, + "scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" + }, + "secp256k1": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.7.1.tgz", + "integrity": "sha512-1cf8sbnRreXrQFdH6qsg2H71Xw91fCCS9Yp021GnUNJzWJS/py96fS4lHbnTnouLp08Xj6jBoBB6V78Tdbdu5g==", + "optional": true, + "requires": { + "bindings": "^1.5.0", + "bip66": "^1.1.5", + "bn.js": "^4.11.8", + "create-hash": "^1.2.0", + "drbg.js": "^1.0.1", + "elliptic": "^6.4.1", + "nan": "^2.14.0", + "safe-buffer": "^5.1.2" + } + }, + "serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "requires": { + "randombytes": "^2.1.0" + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "strict-event-emitter-types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strict-event-emitter-types/-/strict-event-emitter-types-2.0.0.tgz", + "integrity": "sha512-Nk/brWYpD85WlOgzw5h173aci0Teyv8YdIAEtV+N88nDB0dLlazZyJMIsN6eo1/AR61l+p6CJTG1JIyFaoNEEA==" + }, + "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==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "tapable": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", + "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==" + }, + "terser": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.7.1.tgz", + "integrity": "sha512-b3e+d5JbHAe/JSjwsC3Zn55wsBIM7AsHLjKxT31kGCldgbpFePaFo+PiddtO6uwRZWRw7sPXmAN8dTW61xmnSg==", + "requires": { + "commander": "^2.20.0", + "source-map": "~0.7.2", + "source-map-support": "~0.5.19" + }, + "dependencies": { "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "spawn-command": { - "version": "0.0.2-1", - "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", - "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=" - }, - "spawn-wrap": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", - "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", - "requires": { - "foreground-child": "^2.0.0", - "is-windows": "^1.0.2", - "make-dir": "^3.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "which": "^2.0.1" - }, - "dependencies": {} - }, - "spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==" - }, - "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==", - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz", - "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==" - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "stream-browserify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", - "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", - "requires": { - "inherits": "~2.0.4", - "readable-stream": "^3.5.0" - } - }, - "stream-http": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz", - "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==", - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "xtend": "^4.0.2" - } - }, - "strict-event-emitter-types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strict-event-emitter-types/-/strict-event-emitter-types-2.0.0.tgz", - "integrity": "sha512-Nk/brWYpD85WlOgzw5h173aci0Teyv8YdIAEtV+N88nDB0dLlazZyJMIsN6eo1/AR61l+p6CJTG1JIyFaoNEEA==" - }, - "strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" - }, - "string-argv": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", - "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==" - }, - "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "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==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "stringify-object": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", - "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", - "requires": { - "get-own-enumerable-property-symbols": "^3.0.0", - "is-obj": "^1.0.1", - "is-regexp": "^1.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "requires": { - "ansi-regex": "^5.0.0" - } - }, - "strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" - }, - "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" - }, - "strip-outer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", - "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", - "requires": { - "escape-string-regexp": "^1.0.2" - } - }, - "strip-url-auth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-url-auth/-/strip-url-auth-1.0.1.tgz", - "integrity": "sha1-IrD6OkE4WzO+PzMVUbu4N/oM164=" - }, - "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==", - "requires": { - "has-flag": "^4.0.0" - } - }, - "table": { - "version": "6.3.2", - "resolved": "https://registry.npmjs.org/table/-/table-6.3.2.tgz", - "integrity": "sha512-I9/Ca6Huf2oxFag7crD0DhA+arIdfLtWunSn0NIXSzjtUlDgIBGVZY7SsMkNPNT3Psd/z4gza0nuEpmra9eRbg==", - "requires": { - "ajv": "^8.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "lodash.clonedeep": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.0" - }, - "dependencies": {} - }, - "tapable": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", - "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==" - }, - "term-size": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", - "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==" - }, - "terser": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.6.1.tgz", - "integrity": "sha512-yv9YLFQQ+3ZqgWCUk+pvNJwgUTdlIxUk1WTN+RnaFJe2L7ipG2csPT0ra2XRm7Cs8cxN7QXmK1rFzEwYEQkzXw==", - "requires": { - "commander": "^2.20.0", - "source-map": "~0.7.2", - "source-map-support": "~0.5.19" - }, - "dependencies": {} - }, - "terser-webpack-plugin": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.1.tgz", - "integrity": "sha512-5XNNXZiR8YO6X6KhSGXfY0QrGrCRlSwAEjIIrlRQR4W8nP69TaJUlh3bkuac6zzgspiGPfKEHcY295MMVExl5Q==", - "requires": { - "jest-worker": "^26.6.2", - "p-limit": "^3.1.0", - "schema-utils": "^3.0.0", - "serialize-javascript": "^5.0.1", - "source-map": "^0.6.1", - "terser": "^5.5.1" - } - }, - "test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "requires": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" - }, - "to-readable-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==" - }, - "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==", - "requires": { - "is-number": "^7.0.0" - } - }, - "touch": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", - "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", - "requires": { - "nopt": "~1.0.10" - } - }, - "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==" - }, - "trim-repeated": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", - "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=", - "requires": { - "escape-string-regexp": "^1.0.2" - } - }, - "ts-loader": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-8.1.0.tgz", - "integrity": "sha512-YiQipGGAFj2zBfqLhp28yUvPP9jUGqHxRzrGYuc82Z2wM27YIHbElXiaZDc93c3x0mz4zvBmS6q/DgExpdj37A==", - "requires": { - "chalk": "^4.1.0", - "enhanced-resolve": "^4.0.0", - "loader-utils": "^2.0.0", - "micromatch": "^4.0.0", - "semver": "^7.3.4" - }, - "dependencies": {} - }, - "ts-node": { - "version": "8.10.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz", - "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==", - "requires": { - "arg": "^4.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "source-map-support": "^0.5.17", - "yn": "3.1.1" - }, - "dependencies": {} - }, - "ts-protoc-gen": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/ts-protoc-gen/-/ts-protoc-gen-0.10.0.tgz", - "integrity": "sha512-EEbgDWNHK3CvcNhmib94I4HMO23qLddjLRdXW8EUE11VJxbi3n5J0l2DiX/L1pijOaPTkbEoRK+zQinKgKGqsw==", - "requires": { - "google-protobuf": "^3.6.1" - } - }, - "ts-results": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ts-results/-/ts-results-3.2.1.tgz", - "integrity": "sha512-cMvWPLvxM39fSQgSHRT2d+dwQfpK+ttfj5FpPuXum9m/pm6iDmgsirpWXp/3/ErmZqx1x+rAhJi/33NQqCCM3Q==" - }, - "tsconfig-paths": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", - "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", - "requires": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.0", - "strip-bom": "^3.0.0" - }, - "dependencies": {} - }, + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" + } + } + }, + "terser-webpack-plugin": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.4.tgz", + "integrity": "sha512-C2WkFwstHDhVEmsmlCxrXUtVklS+Ir1A7twrYzrDrQQOIMOaVAYykaoo/Aq1K0QRkMoY2hhvDQY1cm4jnIMFwA==", + "requires": { + "jest-worker": "^27.0.2", + "p-limit": "^3.1.0", + "schema-utils": "^3.0.0", + "serialize-javascript": "^6.0.0", + "source-map": "^0.6.1", + "terser": "^5.7.0" + } + }, + "ts-results": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ts-results/-/ts-results-3.3.0.tgz", + "integrity": "sha512-FWqxGX2NHp5oCyaMd96o2y2uMQmSu8Dey6kvyuFdRJ2AzfmWo3kWa4UsPlCGlfQ/qu03m09ZZtppMoY8EMHuiA==" + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "tweetnacl-ts": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl-ts/-/tweetnacl-ts-1.0.3.tgz", + "integrity": "sha512-C5I/dWf6xjAXaCDlf84T4HvozU/8ycAlq5WRllF1hAeeq5390tfXD+bNas5bhEV0HMSOx8bsQYpLjPl8wfnEeQ==", + "requires": { + "tslib": "^1" + } + }, + "tweetnacl-util": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", + "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==" + }, + "typedjson": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/typedjson/-/typedjson-1.7.0.tgz", + "integrity": "sha512-MnRgQLwtEcdHqQG0FkT8ebpBG53Wgr/axYRbiD2WL5NcYx8Z2AoCpXvtTfLnuPqOBKG/9JpXq0O/nl2m4wqJYw==", + "requires": { + "tslib": "^2.0.1" + }, + "dependencies": { "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "tslint": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz", - "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==", - "requires": { - "@babel/code-frame": "^7.0.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.3.0", - "commander": "^2.12.1", - "diff": "^4.0.1", - "glob": "^7.1.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.3", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.13.0", - "tsutils": "^2.29.0" - }, - "dependencies": {} - }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "requires": { - "tslib": "^1.8.1" - } - }, - "tweetnacl-ts": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl-ts/-/tweetnacl-ts-1.0.3.tgz", - "integrity": "sha512-C5I/dWf6xjAXaCDlf84T4HvozU/8ycAlq5WRllF1hAeeq5390tfXD+bNas5bhEV0HMSOx8bsQYpLjPl8wfnEeQ==", - "requires": { - "tslib": "^1" - } - }, - "tweetnacl-util": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", - "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==" - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" - }, - "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==" - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "typedjson": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/typedjson/-/typedjson-1.7.0.tgz", - "integrity": "sha512-MnRgQLwtEcdHqQG0FkT8ebpBG53Wgr/axYRbiD2WL5NcYx8Z2AoCpXvtTfLnuPqOBKG/9JpXq0O/nl2m4wqJYw==", - "requires": { - "tslib": "^2.0.1" - }, - "dependencies": {} - }, - "typedoc": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.17.8.tgz", - "integrity": "sha512-/OyrHCJ8jtzu+QZ+771YaxQ9s4g5Z3XsQE3Ma7q+BL392xxBn4UMvvCdVnqKC2T/dz03/VXSLVKOP3lHmDdc/w==", - "requires": { - "fs-extra": "^8.1.0", - "handlebars": "^4.7.6", - "highlight.js": "^10.0.0", - "lodash": "^4.17.15", - "lunr": "^2.3.8", - "marked": "1.0.0", - "minimatch": "^3.0.0", - "progress": "^2.0.3", - "shelljs": "^0.8.4", - "typedoc-default-themes": "^0.10.2" - } - }, - "typedoc-default-themes": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/typedoc-default-themes/-/typedoc-default-themes-0.10.2.tgz", - "integrity": "sha512-zo09yRj+xwLFE3hyhJeVHWRSPuKEIAsFK5r2u47KL/HBKqpwdUSanoaz5L34IKiSATFrjG5ywmIu98hPVMfxZg==", - "requires": { - "lunr": "^2.3.8" - } - }, - "typescript": { - "version": "3.9.9", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.9.tgz", - "integrity": "sha512-kdMjTiekY+z/ubJCATUPlRDl39vXYiMV9iyeMuEuXZh2we6zz80uovNN2WlAxmmdE/Z/YQe+EbOEXB5RHEED3w==" - }, - "uglify-js": { - "version": "3.13.4", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.4.tgz", - "integrity": "sha512-kv7fCkIXyQIilD5/yQy8O+uagsYIOt5cZvs890W40/e/rvjMSzJw81o9Bg0tkURxzZBROtDQhW2LFjOGoK3RZw==", - "optional": true - }, - "unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - } - }, - "undefsafe": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz", - "integrity": "sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==", - "requires": { - "debug": "^2.2.0" - }, - "dependencies": {} - }, - "unique-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "requires": { - "crypto-random-string": "^2.0.0" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "update-notifier": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", - "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==", - "requires": { - "boxen": "^4.2.0", - "chalk": "^3.0.0", - "configstore": "^5.0.1", - "has-yarn": "^2.1.0", - "import-lazy": "^2.1.0", - "is-ci": "^2.0.0", - "is-installed-globally": "^0.3.1", - "is-npm": "^4.0.0", - "is-yarn-global": "^0.3.0", - "latest-version": "^5.0.0", - "pupa": "^2.0.1", - "semver-diff": "^3.1.1", - "xdg-basedir": "^4.0.0" - }, - "dependencies": {} - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "requires": { - "punycode": "^2.1.0" - } - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": {} - }, - "url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", - "requires": { - "prepend-http": "^2.0.0" - }, - "dependencies": {} - }, - "util": { - "version": "0.12.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.3.tgz", - "integrity": "sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog==", - "requires": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "safe-buffer": "^5.1.2", - "which-typed-array": "^1.1.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" - }, - "v8-compile-cache": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==" - }, - "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==", - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "watchpack": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.1.1.tgz", - "integrity": "sha512-Oo7LXCmc1eE1AjyuSBmtC3+Wy4HcV8PxWh2kP6fOl8yTlNS7r0K9l1ao2lrrUza7V39Y3D/BbJgY8VeSlc5JKw==", - "requires": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - } - }, - "webpack": { - "version": "5.35.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.35.0.tgz", - "integrity": "sha512-au3gu55yYF/h6NXFr0KZPZAYxS6Nlc595BzYPke8n0CSff5WXcoixtjh5LC/8mXunkRKxhymhXmBY0+kEbR6jg==", - "requires": { - "@types/eslint-scope": "^3.7.0", - "@types/estree": "^0.0.47", - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/wasm-edit": "1.11.0", - "@webassemblyjs/wasm-parser": "1.11.0", - "acorn": "^8.0.4", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.8.0", - "es-module-lexer": "^0.4.0", - "eslint-scope": "^5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.4", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.0.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.1", - "watchpack": "^2.0.0", - "webpack-sources": "^2.1.1" - } - }, - "webpack-cli": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.6.0.tgz", - "integrity": "sha512-9YV+qTcGMjQFiY7Nb1kmnupvb1x40lfpj8pwdO/bom+sQiP4OBMKjHq29YQrlDWDPZO9r/qWaRRywKaRDKqBTA==", - "requires": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^1.0.2", - "@webpack-cli/info": "^1.2.3", - "@webpack-cli/serve": "^1.3.1", - "colorette": "^1.2.1", - "commander": "^7.0.0", - "enquirer": "^2.3.6", - "execa": "^5.0.0", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^2.2.0", - "rechoir": "^0.7.0", - "v8-compile-cache": "^2.2.0", - "webpack-merge": "^5.7.3" - }, - "dependencies": {} - }, - "webpack-merge": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.7.3.tgz", - "integrity": "sha512-6/JUQv0ELQ1igjGDzHkXbVDRxkfA57Zw7PfiupdLFJYrgFqY5ZP8xxbpp2lU3EPwYx89ht5Z/aDkD40hFCm5AA==", - "requires": { - "clone-deep": "^4.0.1", - "wildcard": "^2.0.0" - } - }, - "webpack-node-externals": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/webpack-node-externals/-/webpack-node-externals-2.5.2.tgz", - "integrity": "sha512-aHdl/y2N7PW2Sx7K+r3AxpJO+aDMcYzMQd60Qxefq3+EwhewSbTBqNumOsCE1JsCUNoyfGj5465N0sSf6hc/5w==" - }, - "webpack-sources": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.2.0.tgz", - "integrity": "sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w==", - "requires": { - "source-list-map": "^2.0.1", - "source-map": "^0.6.1" - } - }, - "whatwg-fetch": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", - "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==" - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "requires": { - "isexe": "^2.0.0" - } - }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" - }, - "which-pm-runs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", - "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=" - }, - "which-typed-array": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.4.tgz", - "integrity": "sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA==", - "requires": { - "available-typed-arrays": "^1.0.2", - "call-bind": "^1.0.0", - "es-abstract": "^1.18.0-next.1", - "foreach": "^2.0.5", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.1", - "is-typed-array": "^1.1.3" - } - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": {} - }, - "widest-line": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", - "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", - "requires": { - "string-width": "^4.0.0" - } - }, - "wildcard": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", - "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==" - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" - }, - "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==", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "ws": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz", - "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==" - }, - "xdg-basedir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", - "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "requires": { - "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" - } - }, - "yargs-parser": { - "version": "20.2.7", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz", - "integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==" - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - }, - "dependencies": {} - }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" - }, - "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==" + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" + } + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "requires": { + "punycode": "^2.1.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "watchpack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.2.0.tgz", + "integrity": "sha512-up4YAn/XHgZHIxFBVCdlMiWDj6WaLKpwVeGQk2I5thdYxF/KmF0aaz6TfJZ/hfl1h/XlcDr7k1KH7ThDagpFaA==", + "requires": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + } + }, + "webpack": { + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.46.0.tgz", + "integrity": "sha512-qxD0t/KTedJbpcXUmvMxY5PUvXDbF8LsThCzqomeGaDlCA6k998D8yYVwZMvO8sSM3BTEOaD4uzFniwpHaTIJw==", + "requires": { + "@types/eslint-scope": "^3.7.0", + "@types/estree": "^0.0.50", + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/wasm-edit": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "acorn": "^8.4.1", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.8.0", + "es-module-lexer": "^0.7.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.4", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.1.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.1.3", + "watchpack": "^2.2.0", + "webpack-sources": "^2.3.1" + }, + "dependencies": { + "acorn": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", + "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==" } } + }, + "webpack-sources": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.1.tgz", + "integrity": "sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA==", + "requires": { + "source-list-map": "^2.0.1", + "source-map": "^0.6.1" + } + }, + "whatwg-fetch": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", + "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "ws": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz", + "integrity": "sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==" + }, + "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==" } } } From 38a45971bd3cb12247d60a678a695ada66e5b4b7 Mon Sep 17 00:00:00 2001 From: Maciej Zielinski Date: Thu, 22 Jul 2021 14:34:33 +0200 Subject: [PATCH 50/98] Groupe label fix --- .gitignore | 1 + Cargo.toml | 1 - Makefile | 3 +- cep47-logic/Cargo.toml | 2 +- cep47-test/Cargo.toml | 16 - cep47-test/src/cep47.rs | 256 - cep47-test/src/contract_tests.rs | 389 - cep47-test/src/lib.rs | 5 - cep47-test/wasm/dragons-nft.wasm | Bin 492201 -> 0 bytes cep47/Cargo.toml | 6 +- cep47/src/lib.rs | 18 +- dragons-nft-scripts/package-lock.json | 13337 +++--------------------- dragons-nft-scripts/src/index.js | 19 +- dragons-nft-tests/src/cep47.rs | 10 +- dragons-nft/Cargo.toml | 4 +- dragons-nft/src/main.rs | 2 +- 16 files changed, 1225 insertions(+), 12844 deletions(-) delete mode 100644 cep47-test/Cargo.toml delete mode 100644 cep47-test/src/cep47.rs delete mode 100644 cep47-test/src/contract_tests.rs delete mode 100644 cep47-test/src/lib.rs delete mode 100755 cep47-test/wasm/dragons-nft.wasm diff --git a/.gitignore b/.gitignore index e9bcfca..1d85916 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ target Cargo.lock dragons-nft-tests/wasm/*.wasm node_modules +cep47-test \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 2e926cf..4186153 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,6 @@ members = [ "cep47", "cep47-logic", - "cep47-test", "dragons-nft", "dragons-nft-tests" ] diff --git a/Makefile b/Makefile index 0bea48a..4680782 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,6 @@ build-contract: cargo build --release -p dragons-nft --target wasm32-unknown-unknown test-only: - cargo test -p cep47-test cargo test -p cep47-logic cargo test -p dragons-nft-tests @@ -16,7 +15,7 @@ copy-wasm-file-to-test: test: build-contract copy-wasm-file-to-test test-only clippy: - echo 1 + cargo clippy --all-targets --all -- -A clippy::ptr_arg check-lint: clippy cargo fmt --all -- --check diff --git a/cep47-logic/Cargo.toml b/cep47-logic/Cargo.toml index ae619e8..d50bd36 100644 --- a/cep47-logic/Cargo.toml +++ b/cep47-logic/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Maciej Zielinski "] edition = "2018" [dependencies] -casper-types = "1.2.0" +casper-types = "1.2.1" [dev-dependencies] rand = "0.7.3" diff --git a/cep47-test/Cargo.toml b/cep47-test/Cargo.toml deleted file mode 100644 index 0d2c06e..0000000 --- a/cep47-test/Cargo.toml +++ /dev/null @@ -1,16 +0,0 @@ -[package] -name = "cep47-test" -version = "0.1.0" -authors = ["astro019 "] -edition = "2018" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -casper-contract = "1.2.0" -casper-types = "1.2.0" -casper-engine-test-support = "1.2.0" -maplit = "1.0.2" - -[features] -default = ["casper-contract/std", "casper-types/std", "casper-contract/test-support"] diff --git a/cep47-test/src/cep47.rs b/cep47-test/src/cep47.rs deleted file mode 100644 index bb9d749..0000000 --- a/cep47-test/src/cep47.rs +++ /dev/null @@ -1,256 +0,0 @@ -use std::collections::BTreeMap; - -use casper_engine_test_support::{Code, Hash, SessionBuilder, TestContext, TestContextBuilder}; -use casper_types::{ - account::AccountHash, bytesrepr::FromBytes, runtime_args, CLTyped, PublicKey, RuntimeArgs, - SecretKey, URef, U256, U512, -}; - -pub type TokenId = String; -pub type Meta = BTreeMap; - -pub const CONTRACT_KEY_SUFFIX: &str = "_contract"; -pub const CONTRACT_HASH_KEY_SUFFIX: &str = "_contract_hash"; -pub const CONTRACT_NAME_KEY: &str = "name"; -pub const CONTRACT_SYMBOL_KEY: &str = "symbol"; -pub const CONTRACT_META_KEY: &str = "meta"; -pub const CONTRACT_TOTAL_SUPPLY_KEY: &str = "total_supply"; - -pub struct Sender(pub AccountHash); - -pub struct TestConfig { - pub context: TestContext, - pub contract_hash: Hash, - pub contract_key: String, - pub accounts: Vec, -} - -pub trait CEP47TestContract { - fn config(&self) -> &TestConfig; - fn config_mut(&mut self) -> &mut TestConfig; - - fn deploy(token_name: &str, token_symbol: &str, token_meta: Meta, wasm: &str) -> TestConfig { - let admin: PublicKey = SecretKey::ed25519_from_bytes([1u8; 32]).unwrap().into(); - let ali: PublicKey = SecretKey::ed25519_from_bytes([3u8; 32]).unwrap().into(); - let bob: PublicKey = SecretKey::ed25519_from_bytes([5u8; 32]).unwrap().into(); - let mut context = TestContextBuilder::new() - .with_public_key(admin.clone(), U512::from(500_000_000_000_000_000u64)) - .with_public_key(ali.clone(), U512::from(500_000_000_000_000_000u64)) - .with_public_key(bob.clone(), U512::from(500_000_000_000_000_000u64)) - .build(); - let session_code = Code::from(wasm); - let session_args = runtime_args! { - "token_name" => token_name, - "token_symbol" => token_symbol, - "token_meta" => token_meta - }; - let session = SessionBuilder::new(session_code, session_args) - .with_address(admin.to_account_hash()) - .with_authorization_keys(&[admin.to_account_hash()]) - .build(); - context.run(session); - let contract_hash = context - .query( - admin.to_account_hash(), - &[format!("{}{}", token_name, CONTRACT_HASH_KEY_SUFFIX)], - ) - .unwrap() - .into_t() - .unwrap(); - let contract_key = format!("{}{}", token_name, CONTRACT_KEY_SUFFIX); - - TestConfig { - context, - contract_hash, - contract_key, - accounts: vec![admin, ali, bob], - } - } - - fn call(&mut self, sender: Sender, method: &str, args: RuntimeArgs) { - let Sender(address) = sender; - let code = Code::Hash(self.config().contract_hash, method.to_string()); - let session = SessionBuilder::new(code, args) - .with_address(address) - .with_authorization_keys(&[address]) - .build(); - self.config_mut().context.run(session); - } - - fn query_contract(&self, name: &str) -> Option { - match self.config().context.query( - self.config().accounts.first().unwrap().to_account_hash(), - &[self.config().contract_key.clone(), name.to_string()], - ) { - Err(_) => None, - Ok(maybe_value) => { - let value = maybe_value - .into_t() - .unwrap_or_else(|_| panic!("{} is not expected type.", name)); - Some(value) - } - } - } - - fn name(&self) -> String { - self.query_contract(CONTRACT_NAME_KEY).unwrap() - } - - fn symbol(&self) -> String { - self.query_contract(CONTRACT_SYMBOL_KEY).unwrap() - } - - fn meta(&self) -> Meta { - self.query_contract(CONTRACT_META_KEY).unwrap() - } - - fn total_supply(&self) -> U256 { - self.query_contract(CONTRACT_TOTAL_SUPPLY_KEY) - .unwrap_or_default() - } - - fn owner_of(&self, token_id: &TokenId) -> Option { - self.query_contract(owner_key(&token_id).as_str()) - } - - fn balance_of(&self, owner: PublicKey) -> U256 { - self.query_contract(balance_key(&owner.to_account_hash()).as_str()) - .unwrap_or_default() - } - - fn tokens(&self, owner: PublicKey) -> Vec { - self.query_contract::>(token_key(&owner.to_account_hash()).as_str()) - .unwrap_or_default() - } - - fn token_meta(&self, token_id: TokenId) -> Option { - self.query_contract(meta_key(&token_id).as_str()) - } - - fn token_uref(&self, token_id: &TokenId) -> Option { - self.query_contract(test_uref_key(&token_id).as_str()) - } - - fn mint_one(&mut self, recipient: PublicKey, token_meta: Meta, sender: Sender) { - self.call( - sender, - "mint_one", - runtime_args! { - "recipient" => recipient, - "token_meta" => token_meta - }, - ); - } - - fn mint_copies(&mut self, recipient: PublicKey, token_meta: Meta, count: U256, sender: Sender) { - self.call( - sender, - "mint_copies", - runtime_args! { - "recipient" => recipient, - "token_meta" => token_meta, - "count" => count - }, - ); - } - - fn mint_many(&mut self, recipient: PublicKey, token_metas: Vec, sender: Sender) { - self.call( - sender, - "mint_many", - runtime_args! { - "recipient" => recipient, - "token_metas" => token_metas - }, - ); - } - - fn burn_many(&mut self, owner: PublicKey, token_ids: Vec, sender: Sender) { - self.call( - sender, - "burn_many", - runtime_args! { - "owner" => owner, - "token_ids" => token_ids - }, - ); - } - - fn burn_one(&mut self, owner: PublicKey, token_id: TokenId, sender: Sender) { - self.call( - sender, - "burn_one", - runtime_args! { - "owner" => owner, - "token_id" => token_id - }, - ); - } - - fn transfer_token( - &mut self, - owner: PublicKey, - recipient: PublicKey, - token_id: TokenId, - sender: Sender, - ) { - self.call( - sender, - "transfer_token", - runtime_args! { - "sender" => owner, - "recipient" => recipient, - "token_id" => token_id - }, - ); - } - - fn transfer_many_tokens( - &mut self, - owner: PublicKey, - recipient: PublicKey, - token_ids: Vec, - sender: Sender, - ) { - self.call( - sender, - "transfer_many_tokens", - runtime_args! { - "sender" => owner, - "recipient" => recipient, - "token_ids" => token_ids - }, - ); - } - - fn transfer_all_tokens(&mut self, owner: PublicKey, recipient: PublicKey, sender: Sender) { - self.call( - sender, - "transfer_all_tokens", - runtime_args! { - "sender" => owner, - "recipient" => recipient - }, - ); - } -} - -fn balance_key(account: &AccountHash) -> String { - format!("balances_{}", account) -} - -fn owner_key(token_id: &TokenId) -> String { - format!("owners_{}", token_id) -} - -fn meta_key(token_id: &TokenId) -> String { - format!("metas_{}", token_id) -} - -fn token_key(account: &AccountHash) -> String { - format!("tokens_{}", account) -} - -fn test_uref_key(token_id: &TokenId) -> String { - format!("turef_{}", token_id) -} diff --git a/cep47-test/src/contract_tests.rs b/cep47-test/src/contract_tests.rs deleted file mode 100644 index ba15923..0000000 --- a/cep47-test/src/contract_tests.rs +++ /dev/null @@ -1,389 +0,0 @@ -use crate::cep47::{CEP47TestContract, Meta, Sender, TestConfig, TokenId}; -use casper_types::U256; -use maplit::btreemap; - -pub struct CasperCEP47Contract { - config: TestConfig, -} - -impl CEP47TestContract for CasperCEP47Contract { - fn config(&self) -> &TestConfig { - &self.config - } - - fn config_mut(&mut self) -> &mut TestConfig { - &mut self.config - } -} - -impl CasperCEP47Contract { - fn new() -> Self { - let config = Self::deploy( - "CasperNFT", - "CNFT", - btreemap! {"origin".to_string() => "fire".to_string()}, - "dragons-nft.wasm", - ); - Self { config } - } -} - -mod meta { - use super::Meta; - use maplit::btreemap; - - pub fn red_dragon() -> Meta { - btreemap! { - "color".to_string() => "red".to_string() - } - } - - pub fn blue_dragon() -> Meta { - btreemap! { - "color".to_string() => "blue".to_string() - } - } - - pub fn black_dragon() -> Meta { - btreemap! { - "color".to_string() => "black".to_string() - } - } - - pub fn gold_dragon() -> Meta { - btreemap! { - "color".to_string() => "gold".to_string() - } - } -} - -#[test] -fn test_deploy() { - let contract = CasperCEP47Contract::new(); - - assert_eq!(contract.name(), "CasperNFT"); - assert_eq!(contract.symbol(), "CNFT"); - assert_eq!( - contract.meta(), - btreemap! {"origin".to_string() => "fire".to_string()} - ); - assert_eq!(contract.total_supply(), U256::zero()); -} - -#[test] -fn test_token_meta() { - let mut contract = CasperCEP47Contract::new(); - let ali = contract.config().accounts.get(1).unwrap().clone(); - let token_meta = meta::red_dragon(); - contract.mint_one( - ali.clone(), - token_meta.clone(), - Sender( - contract - .config() - .accounts - .first() - .unwrap() - .clone() - .to_account_hash(), - ), - ); - - let ali_tokens: Vec = contract.tokens(ali.clone()); - let ali_token_meta = contract.token_meta(ali_tokens[0].clone()); - - assert_eq!(ali_token_meta, Some(token_meta)); -} - -#[test] -fn test_mint_one() { - let mut contract = CasperCEP47Contract::new(); - let ali = contract.config().accounts.get(1).unwrap().clone(); - let token_meta = meta::red_dragon(); - contract.mint_one( - ali.clone(), - token_meta, - Sender( - contract - .config() - .accounts - .first() - .unwrap() - .clone() - .to_account_hash(), - ), - ); - - let ali_tokens: Vec = contract.tokens(ali.clone()); - - assert_eq!(contract.total_supply(), U256::one()); - assert_eq!(contract.balance_of(ali.clone()), U256::one()); - assert_eq!(U256::from(ali_tokens.len() as u64), U256::one()); - assert_eq!(contract.owner_of(&ali_tokens[0]), Some(ali.clone())); -} - -#[test] -fn test_mint_copies() { - let mut contract = CasperCEP47Contract::new(); - let ali = contract.config().accounts.get(1).unwrap().clone(); - let token_meta = meta::gold_dragon(); - contract.mint_copies( - ali.clone(), - token_meta, - U256::from(3), - Sender( - contract - .config() - .accounts - .first() - .unwrap() - .clone() - .to_account_hash(), - ), - ); - - let ali_tokens: Vec = contract.tokens(ali.clone()); - - assert_eq!(contract.total_supply(), U256::from(3)); - assert_eq!(contract.balance_of(ali.clone()), U256::from(3)); - assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(3)); - assert_eq!(contract.owner_of(&ali_tokens[0]), Some(ali.clone())); - assert_eq!(contract.owner_of(&ali_tokens[1]), Some(ali.clone())); - assert_eq!(contract.owner_of(&ali_tokens[2]), Some(ali.clone())); -} - -#[test] -fn test_mint_many() { - let mut contract = CasperCEP47Contract::new(); - let ali = contract.config().accounts.get(1).unwrap().clone(); - let token_metas: Vec = vec![meta::gold_dragon(), meta::red_dragon()]; - contract.mint_many( - ali.clone(), - token_metas, - Sender( - contract - .config() - .accounts - .first() - .unwrap() - .clone() - .to_account_hash(), - ), - ); - - let ali_tokens: Vec = contract.tokens(ali.clone()); - - assert_eq!(contract.total_supply(), U256::from(2)); - assert_eq!(contract.balance_of(ali.clone()), U256::from(2)); - assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(2)); - assert_eq!(contract.owner_of(&ali_tokens[0]), Some(ali.clone())); - assert_eq!(contract.owner_of(&ali_tokens[1]), Some(ali.clone())); -} - -#[test] -fn test_burn_many() { - let mut contract = CasperCEP47Contract::new(); - let ali = contract.config().accounts.get(1).unwrap().clone(); - let token_metas: Vec = vec![ - meta::gold_dragon(), - meta::blue_dragon(), - meta::black_dragon(), - meta::red_dragon(), - ]; - contract.mint_many( - ali.clone(), - token_metas, - Sender( - contract - .config() - .accounts - .first() - .unwrap() - .clone() - .to_account_hash(), - ), - ); - - let mut ali_tokens: Vec = contract.tokens(ali.clone()); - - assert_eq!(contract.total_supply(), U256::from(4)); - assert_eq!(contract.balance_of(ali.clone()), U256::from(4)); - assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(4)); - - contract.burn_many( - ali.clone(), - vec![ - ali_tokens.first().unwrap().clone(), - ali_tokens.last().unwrap().clone(), - ], - Sender( - contract - .config() - .accounts - .first() - .unwrap() - .clone() - .to_account_hash(), - ), - ); - assert_eq!(contract.total_supply(), U256::from(2)); - assert_eq!(contract.balance_of(ali.clone()), U256::from(2)); - - ali_tokens = contract.tokens(ali.clone()); - assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(2)); -} - -#[test] -fn test_burn_one() { - let mut contract = CasperCEP47Contract::new(); - let ali = contract.config().accounts.get(1).unwrap().clone(); - let token_metas: Vec = vec![meta::gold_dragon(), meta::red_dragon()]; - contract.mint_many( - ali.clone(), - token_metas, - Sender( - contract - .config() - .accounts - .first() - .unwrap() - .clone() - .to_account_hash(), - ), - ); - - let mut ali_tokens: Vec = contract.tokens(ali.clone()); - - assert_eq!(contract.total_supply(), U256::from(2)); - assert_eq!(contract.balance_of(ali.clone()), U256::from(2)); - assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(2)); - - contract.burn_one( - ali.clone(), - ali_tokens.first().unwrap().clone(), - Sender( - contract - .config() - .accounts - .first() - .unwrap() - .clone() - .to_account_hash(), - ), - ); - assert_eq!(contract.total_supply(), U256::from(1)); - assert_eq!(contract.balance_of(ali.clone()), U256::from(1)); - - ali_tokens = contract.tokens(ali.clone()); - assert_eq!(U256::from(ali_tokens.len() as u64), U256::from(1)); -} - -#[test] -fn test_transfer_token() { - let mut contract = CasperCEP47Contract::new(); - let ali = contract.config().accounts.get(1).unwrap().clone(); - let bob = contract.config().accounts.get(2).unwrap().clone(); - let token_metas: Vec = vec![meta::gold_dragon(), meta::blue_dragon()]; - contract.mint_many( - ali.clone(), - token_metas, - Sender( - contract - .config() - .accounts - .first() - .unwrap() - .clone() - .to_account_hash(), - ), - ); - let ali_tokens: Vec = contract.tokens(ali.clone()); - contract.transfer_token( - ali.clone(), - bob.clone(), - ali_tokens[1].clone(), - Sender(ali.clone().to_account_hash()), - ); - - assert_eq!(contract.balance_of(ali.clone()), U256::from(1)); - assert_eq!(contract.balance_of(bob.clone()), U256::from(1)); - assert_eq!(contract.total_supply(), U256::from(2)); - assert_eq!(contract.owner_of(&ali_tokens[0]), Some(ali.clone())); - assert_eq!(contract.owner_of(&ali_tokens[1]), Some(bob.clone())); -} - -#[test] -fn test_transfer_many_tokens() { - let mut contract = CasperCEP47Contract::new(); - let ali = contract.config().accounts.get(1).unwrap().clone(); - let bob = contract.config().accounts.get(2).unwrap().clone(); - let token_metas: Vec = vec![ - meta::gold_dragon(), - meta::black_dragon(), - meta::black_dragon(), - ]; - contract.mint_many( - ali.clone(), - token_metas, - Sender( - contract - .config() - .accounts - .first() - .unwrap() - .clone() - .to_account_hash(), - ), - ); - let ali_tokens: Vec = contract.tokens(ali.clone()); - contract.transfer_many_tokens( - ali.clone(), - bob.clone(), - ali_tokens[..2].to_vec(), - Sender(ali.clone().to_account_hash()), - ); - - assert_eq!(contract.balance_of(ali.clone()), U256::from(1)); - assert_eq!(contract.balance_of(bob.clone()), U256::from(2)); - assert_eq!(contract.total_supply(), U256::from(3)); - assert_eq!(contract.owner_of(&ali_tokens[0]), Some(bob.clone())); - assert_eq!(contract.owner_of(&ali_tokens[1]), Some(bob.clone())); - assert_eq!(contract.owner_of(&ali_tokens[2]), Some(ali.clone())); -} - -#[test] -fn test_transfer_all_tokens() { - let mut contract = CasperCEP47Contract::new(); - let ali = contract.config().accounts.get(1).unwrap().clone(); - let bob = contract.config().accounts.get(2).unwrap().clone(); - let token_metas: Vec = vec![meta::gold_dragon(), meta::blue_dragon()]; - contract.mint_many( - ali.clone(), - token_metas, - Sender( - contract - .config() - .accounts - .first() - .unwrap() - .clone() - .to_account_hash(), - ), - ); - let ali_tokens: Vec = contract.tokens(ali.clone()); - assert_eq!(contract.balance_of(ali.clone()), U256::from(2)); - assert_eq!(contract.balance_of(bob.clone()), U256::from(0)); - assert_eq!(contract.owner_of(&ali_tokens[0]), Some(ali.clone())); - assert_eq!(contract.owner_of(&ali_tokens[1]), Some(ali.clone())); - - contract.transfer_all_tokens( - ali.clone(), - bob.clone(), - Sender(ali.clone().to_account_hash()), - ); - assert_eq!(contract.balance_of(ali.clone()), U256::from(0)); - assert_eq!(contract.balance_of(bob.clone()), U256::from(2)); - assert_eq!(contract.total_supply(), U256::from(2)); - assert_eq!(contract.owner_of(&ali_tokens[0]), Some(bob.clone())); - assert_eq!(contract.owner_of(&ali_tokens[1]), Some(bob.clone())); -} diff --git a/cep47-test/src/lib.rs b/cep47-test/src/lib.rs deleted file mode 100644 index f86f3b0..0000000 --- a/cep47-test/src/lib.rs +++ /dev/null @@ -1,5 +0,0 @@ -#[cfg(test)] -pub mod cep47; - -#[cfg(test)] -pub mod contract_tests; diff --git a/cep47-test/wasm/dragons-nft.wasm b/cep47-test/wasm/dragons-nft.wasm deleted file mode 100755 index d014f8991192441c709ade9bf51c33d704ae5fcc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 492201 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