diff --git a/blog/news-and-updates/2024-08-28-update.mdx b/blog/news-and-updates/2024-08-28-update.mdx new file mode 100644 index 0000000000..ac7c2cffd7 --- /dev/null +++ b/blog/news-and-updates/2024-08-28-update.mdx @@ -0,0 +1,50 @@ +--- +title: Developer weekly update August 28, 2024 +description: This week, we're excited to talk about the upcoming Beryllium milestone, a new episode of NNS explained, and a new release of the `ic-siwe` package. +tags: [Devs] +image: /img/blog/dev-update-blog-aug-28.jpg +--- + +# Developer weekly update August 28, 2024 + +![August 28 2024](../../static/img/blog/dev-update-blog-aug-28.jpg) + +Hello developers, and welcome to this week's developer weekly update! This week, we're excited to talk about the upcoming Beryllium milestone, a new episode of NNS explained, and a new release of the `ic-siwe` package. Let's get started! + +## Beryllium milestone + +The Beryllium roadmap milestone is nearing completion and is expected to be released in early October! This milestone is focused on providing canister developer improvements and operation simplifications. Exciting features included in this milestone include: + +- Canister logging: Read and write canister runtime logs. + +- Canister snapshots: Rollback to previous snapshots to fix errors and recover data. + +- Canister lifecycle hooks: Canisters can receive notifications from ICP regarding lifecycle updates, such as low canister balance. + +- Actionable error messages and backtraces: Create a standard for response and error codes for better service composability. + +- Standardized canister response codes: Enhance error codes by providing actionable items and documentation explaining how to resolve errors. + +You can read the full details of this milestone on the [ICP roadmap](https://internetcomputer.org/roadmap#Developer%20Experience-Beryllium).  + +## ic-siwe v0.1.0 + +The `ic-siwe` package enables developers to provide users with the option to login to an application with their Ethereum wallet. The latest release of `ic-siwe` introduces security improvements and reliability. Release notes include: + +- Breaking changes to the `prepare_login` and `login` functions. + +- Improved security through a nonce-based implementation and validated signature expiration. + +- Proper cleanup of SIWE messages through added logic to remove failed login attempts and prevent stale data.  + +[Learn more on the developer forum](https://forum.dfinity.org/t/announcing-ic-siwe-v0-1-0-security-fixes-making-nonce-required/34410). + +## New episode: NNS explained + +A new episode of the NNS explained series has been released! In this episode, [Verifying NNS Dapp Proposals](https://www.youtube.com/watch?v=J-aJFJ_4zIw), you can learn how to build the NNS dapp locally, obtain the proposed Wasm module hash included in a proposal, then verify that the proposed hash matches the hash of the NNS dapp you built and tested locally. + +You can learn more about the NNS explained series on the [developer forum](https://forum.dfinity.org/t/announcement-nns-explained-youtube-series/32337/12). + +That'll wrap up this week. Tune back in next week for more developer updates! + +-DFINITY \ No newline at end of file diff --git a/blog/news-and-updates/2024-09-04-update.mdx b/blog/news-and-updates/2024-09-04-update.mdx new file mode 100644 index 0000000000..cac23b031d --- /dev/null +++ b/blog/news-and-updates/2024-09-04-update.mdx @@ -0,0 +1,58 @@ +--- +title: Developer weekly update September 4, 2024 +description: In this week's update, we're excited to talk about the most recent update to the NNS, highlight an update on the community project Nauts World, and ask for your feedback regarding API changes for public and private neurons.  +tags: [Devs] +image: /img/blog/dev-update-blog-sept-4.jpg +--- + +# Developer weekly update September 4, 2024 + +![September 4 2024](../../static/img/blog/dev-update-blog-sept-4.jpg) + +Hello developers, and welcome to this week's developer weekly update! In this week's update, we're excited to talk about the most recent update to the NNS, highlight an update on the community project Nauts World, and ask for your feedback regarding API changes for public and private neurons. Let's get started! + +## August 30, 2024 NNS updates + +On August 30, 2024, the following updates were proposed for three of the NNS canisters: + +- **Cycles minting canister**: Added more log visibility support, initialized `average_icp_xdr_conversion_rate`, and added support for `wasm_memory_threshold`. + +- **Governance canister**: Backfilled Neurons Fund data, removed `SetDefaultFollowees`, `SetSnsTokenSwapOpenTimeWindow`, and `OpenSnsTokenSwap` proposal types, disabled `UpdateAllowedPrincipals` proposal type, and added functionality where deprecated `*_pb` methods now fail. + +- **Genesis token canister**: Did not include any new features or fixes, but was updated as a general maintenance procedure. + +You can read more about these updates and verify the code for each by checking out the [forum post](https://forum.dfinity.org/t/nns-updates-2024-08-30/34620) with all the details. + +## Nauts World update + +A new season is starting at Nauts World! Nauts World is a collectible-based game featuring characters known as Nauts that players can mint, trade, and sell. There is exciting new functionality coming to Nauts World soon, including: + +- Mobile game: Nauts World will soon have an accompanying mobile game that will provide players a way to strengthen their arsenal of Nauts.  + +- NFT utility: Players can redeem a 3D printed variant of their Nauts NFT once certain criteria are met. + +- Game lore: Stories about the character's clans will be released to help improve world building and character development. + +- Nauts World staking sector will be released. + +Want to learn more? Read the full update on the [developer forum](https://forum.dfinity.org/t/nauts-world-season-update/34644/1). + +## Request for feedback: API changes for public and private neurons + +A request for comments has been opened on the forum regarding changes to the API for public and private neurons. These changes would include breaking changes, and your feedback is appreciated in helping to finalize the decisions regarding these changes.  + +Breaking changes would alter how an app reads neurons that do not belong to the caller, i.e., the caller is not a controller or hotkey of the neuron. Specifically, the fields `recent_ballots` and `joined_community_fund_timestmap_seconds` would not work, and would require a new field called `visibility` to properly interpret the values of either of these fields. + +Non-breaking changes include: + +- Allowing neurons to utilize the new `visibility` field. + +- Allow public neurons to be read without special privileges through changes to the `list_neurons` method. + +- Known Neurons will always be public. + +You can read the full details of these API changes and leave your feedback on the [developer forum](https://forum.dfinity.org/t/request-for-comments-api-changes-for-public-private-neurons/33360/1). + +That'll wrap up this week. Tune back in next week for more developer updates! + +-DFINITY \ No newline at end of file diff --git a/blog/news-and-updates/individual-spotlight-staff-researcher.mdx b/blog/news-and-updates/individual-spotlight-staff-researcher.mdx new file mode 100644 index 0000000000..f7515bcb6a --- /dev/null +++ b/blog/news-and-updates/individual-spotlight-staff-researcher.mdx @@ -0,0 +1,70 @@ +--- +title: Individual spotlight - Staff researcher +description: In today's interview, we're chatting with Thomas from the Systems & Research team. +tags: [Individual spotlight] +image: /img/blog/indv-spotlight-6.jpg +--- + +![Product manager spotlight](../../static/img/blog/indv-spotlight-6.jpg) + +**Hello everyone, and welcome back to the individual spotlight series! In today's interview, we're chatting with Thomas from the Systems & Research team. Thomas is the research lead for multiple different engineering teams, and has worked on various important projects like the Bitcoin integration, the cycles ledger, and chain-key tokens. We're excited to learn more about Thomas' unique role at DFINITY and his perspective of the various different initiatives and features of ICP! + +**To kick things off, how is the role of a staff researcher different from other roles in the organization?** + +*Each researcher has the role of “research lead” for at least one engineering team. I’m the research lead for three teams: IC Integrations, SDK, and the Cross-Chain team, so I get to work on various different projects, such as the exchange rate canister (owned by the IC Integrations team), the recently released cycles ledger (SDK team), and everything related to Bitcoin, Ethereum, and chain-key tokens (cross-chain team).* + +**What responsibilities do you have as a staff researcher?** + +*As a staff researcher, one of my primary tasks is to lead and support bigger projects and features with a potentially large impact for the Internet Computer and DFINITY. A good example is the Bitcoin integration project, which was a significant cross-team effort to enable the creation of Bitcoin smart contracts on the Internet Computer. This integration is further the foundation of ckBTC, our first chain-key token.* + +**You’ve contributed to several of the different Chain Fusion projects, such as the Bitcoin integration and ckERC20 tokens. What was your role in the Bitcoin integration project?** + +*As the research lead for this feature, I was responsible for the technical specification. It was also my task to review the implementation to ensure that it conformed to the design. Of course, this was an iterative process, requiring many discussions with other researchers and the teams driving the implementation, and the design changed significantly throughout this process.* + +**What was your biggest learning or takeaway from working on the Bitcoin integration?** + +*Our Bitcoin integration is quite unique. Do you know any other smart contract on any blockchain that has a state size of nearly 100 GiB? I think the way Bitcoin blocks are ingested is unique too. Whenever you build something that has never been done before, there are many unknowns, which makes planning and estimating the required effort challenging. Maybe the biggest learning is that the challenges in such endeavors should never be underestimated—but this project also nicely showed that DFINITY has fantastic teams with the skill required to pull off such endeavors!* + +**Were there any challenges or hurdles that the team had to overcome during the Bitcoin integration?** + +*There were many challenges, small and large. One of the main challenges was to reach agreement across all involved teams and management about numerous important design decisions. For example, what information about the Bitcoin blockchain is stored? How many Bitcoin addresses can canisters have? Is the Bitcoin code part of the replica code, or does it run in a canister? And many more. Not surprisingly, many discussions were required, but in the end we converged on a fairly nice architecture, in my opinion.* + +**Let's talk about the ckERC20 project, that enabled ERC-20 tokens to be deployed on ICP as chain-key tokens. How was your role in this project different from your role in the Bitcoin integration project?** + +*It was actually quite different because, unlike in the Bitcoin integration project, the cross-chain team had already worked out a good design. So my focus was more on reviewing the specification and the implementation to make sure that they are consistent.* + +**You were also a contributor to the cycles ledger project that we did a [Project Spotlight](/blog/features/cycles-ledger) post on a few months ago. What has the community feedback been on the cycles ledger since launch?** + +*Before the launch, we were frequently asked when the cycles ledger would finally be ready. After the launch, there were a few positive comments, but that was it. I’d like to believe that the developers in our community are now happily using it, and we don’t hear anything because everything works as it should. But it is a good question. Maybe we should do a survey to figure out if the cycles ledger really lives up to the developers’ expectations.* + +**To switch gears a bit, let's chat about what projects you are currently working on.** + +*I currently work on multiple projects. In the future, we want to charge for query calls as well; that’s why we’re looking into accurately accumulating query statistics from replicas in a subnet. The challenge here is that the individual replicas are not trustworthy and may report completely wrong numbers!* + +*Of course, I’m also involved in current cross-chain activities. My main focus in that domain is currently the switch to a simpler know-your-token (KYT) mechanism for ckBTC. The new mechanism will result in lower KYT fees and reduce the risk of “false positives” where bitcoins get quarantined because of (overly) restrictive KYT rules.* + +*I’m also working on exposing recent Bitcoin blocks through the Bitcoin canister, which will help all projects that require more information about the Bitcoin blockchain state than balances and unspent outputs. This includes all projects that work with meta protocols such as Ordinals, BRC-20, and so on.* + +**Those are all exciting initiatives! We're excited to see each of those projects complete and available for our developers to use. Looking at the ICP roadmap, are there any other items from your team you are excited about?** + +*As far as the cross-chain team is concerned, I’m excited about all the work items that will make our Bitcoin integration more useful and accessible to developers. I also hope that our work on chain-key tokens will help grow our DeFi ecosystem.* + +*The SDK team has many cool roadmap items as well, which will help improve developer experience. For example, the work to provide more actionable information to developers, such as well-defined error codes and backtraces, is important to write correct canister code. I also like the `dfx` extensions feature as it makes it possible to reduce `dfx` to its core functionality while providing a flexible mechanism to integrate additional (DFINITY-made or third-party) functionality into `dfx`.* + +**What about roadmap items from other teams—are there any you're keeping an eye on?** + +*I’m excited about all features that bring substantial enhancements to the Internet Computer across all layers. For example, starting at the networking layer, I think having a synchronous message submission endpoint will be a nice feature for developers. Improving throughput on the consensus layer by only including hashes in blocks instead of large payloads is another roadmap item that I think will help the Internet Computer significantly, in particular once we start to see larger loads on the subnets. The roadmap item to support multiple terabytes of replicated storage is important for canisters that require a large state, for example, a canister that stores the full Bitcoin blockchain, a feature that has been requested numerous times!* + +**What advice would you give a new developer getting started on ICP?** + +*The Internet Computer has so many unique features, like HTTPS outcalls, code that can execute on a timer, whole frontends being served by canisters, and many more. I would advise a new developer to try out whatever feature he or she finds most interesting. Luckily, we have great documentation now, which should help anybody get started quickly!* + +**Are there any community projects or tools that you’ve been using recently?** + +*I don’t use any community project that is directly related to things that I’m working on. However, I do use some community tools for work, for example, OpenChat, and I try out various community projects privately. I think it’s definitely worthwhile to check out what our community is building.* + +**To wrap things up, what’s your favorite thing about ICP?** + +*I've used the word “unique” several times before, but its many unique features set the Internet Computer far apart from virtually any other blockchain project. My favorite thing about the Internet Computer is that it has the necessary features to build decentralized applications that can have a substantial impact in the real world.* + +**Thanks again, Thomas, for chatting with us and providing such great insight into several projects, especially the Bitcoin integration and cross-chain team initiatives! Be sure to tune in next time for another individual spotlight interview!** \ No newline at end of file diff --git a/docs/developer-docs/backend/rust/counter.mdx b/docs/developer-docs/backend/rust/counter.mdx index a5537e7d66..bfddc269a1 100644 --- a/docs/developer-docs/backend/rust/counter.mdx +++ b/docs/developer-docs/backend/rust/counter.mdx @@ -49,55 +49,54 @@ Now that you have the files in place for your Rust dapp, you can replace the tem To replace the default dapp, open the template `src/rust_counter_backend/src/lib.rs` file in a text editor and delete the existing content. Then, copy and paste this code into the file: ```rust title="src/rust_counter_backend/src/lib.rs" -use std::cell::RefCell; use candid::types::number::Nat; +use ic_cdk::{query, update}; +use std::cell::RefCell; thread_local! { -    static COUNTER: RefCell = RefCell::new(Nat::from(0)); + static COUNTER: RefCell = RefCell::new(Nat::from(0 as u32)); } /// Get the value of the counter. -#[ic_cdk_macros::query] +#[query] fn get() -> Nat { -    COUNTER.with(|counter| (*counter.borrow()).clone()) + COUNTER.with(|counter| counter.borrow().clone()) } /// Set the value of the counter. -#[ic_cdk_macros::update] +#[update] fn set(n: Nat) { -    // COUNTER.replace(n);  // requires #![feature(local_key_cell_methods)] -    COUNTER.with(|count| *count.borrow_mut() = n); + COUNTER.with(|counter| *counter.borrow_mut() = n); } -/// Increment the value of the counter. -#[ic_cdk_macros::update] +#[update] fn increment() { -    COUNTER.with(|counter| *counter.borrow_mut() += 1); + COUNTER.with(|counter| *counter.borrow_mut() += 1 as u32); } #[cfg(test)] mod tests { -    use super::*; - -    #[test] -    fn test_get_set() { -        let expected = Nat::from(42); -        set(expected.clone()); -        assert_eq!(get(), expected); -    } - -    #[test] -    fn test_init() { -        assert_eq!(get(), Nat::from(0)); -    } - -    #[test] -    fn test_inc() { -        for i in 1..10 { -            inc(); -            assert_eq!(get(), Nat::from(i)); -        } -    } + use super::*; + + #[test] + fn test_get_set() { + let expected = Nat::from(42 as u32); + set(expected.clone()); + assert_eq!(get(), expected); + } + + #[test] + fn test_init() { + assert_eq!(get(), Nat::from(0 as u32)); + } + + #[test] + fn test_inc() { + for i in 1..10 { + increment(); + assert_eq!(get(), Nat::from(i as u32)); + } + } } ``` @@ -137,8 +136,8 @@ edition = "2021" crate-type = ["cdylib"] [dependencies] -candid = "0.8.2" -ic-cdk = "0.7.0" +candid = "0.10" +ic-cdk = "0.13" serde = { version = "1.0", features = ["derive"] } ic-cdk-macros = "0.8.0" ``` diff --git a/docs/developer-docs/backend/rust/intercanister.mdx b/docs/developer-docs/backend/rust/intercanister.mdx index e611b3e55c..3068125950 100644 --- a/docs/developer-docs/backend/rust/intercanister.mdx +++ b/docs/developer-docs/backend/rust/intercanister.mdx @@ -83,7 +83,7 @@ async fn publish(counter: Counter) { } ``` -In this code, you can see two inter-canister update calls: `fn subscribe(subscriber: Subscriber)` and `async fn publish(counter: Counter)`. The first method allows for the publisher canister to make a call to the subscriber canister and subscribe to topics. The second method allows the publisher canister to publish information on a topic in the subscriber canister. +In this code, you can see two inter-canister update calls: `fn subscribe(subscriber: Subscriber)` and `async fn publish(counter: Counter)`. The first method allows for the subscriber canister to make a call to the publisher canister and subscribe to topics. The second method allows the publisher canister to publish information on a topic in the subscriber canister. ```rust title="src/subscriber/src/lib.rs" use candid::{CandidType, Principal}; @@ -154,7 +154,7 @@ dfx deploy First, let's subscribe to a topic. For example, to subscribe to the "Apples" topic, use the command: ```bash -dfx canister call subscriber init '("Apples")' +dfx canister call subscriber setup_subscribe '(principal "", "Apples")' ``` Then, to publish a record to the "Apples" topic, use the command: @@ -166,11 +166,11 @@ dfx canister call publisher publish '(record { "topic" = "Apples"; "value" = 2 } Then, you can query and receive the subscription record value with the command: ```bash -dfx canister call subscriber getCount +dfx canister call subscriber get_count ``` The output should resemble the following: ```bash -(2 : nat) -``` \ No newline at end of file +(2 : nat64) +``` diff --git a/docs/developer-docs/backend/rust/rust-limitations.mdx b/docs/developer-docs/backend/rust/rust-limitations.mdx new file mode 100644 index 0000000000..b03050052d --- /dev/null +++ b/docs/developer-docs/backend/rust/rust-limitations.mdx @@ -0,0 +1,71 @@ +--- +keywords: [intermediate, rust, tutorial, limitations on wasm, rust wasm, rust limitations] +--- + +import { MarkdownChipRow } from "/src/components/Chip/MarkdownChipRow"; + +# Rust limitations on Wasm + + + +## Overview + +WebAssembly (Wasm) is a binary code format and does not provide network access, a filesystem, or other functionalities other than pure computation. Anything function that needs to communicate outside of the Wasm module must use an IC API. This guide details limitations imposed by Wasm on canisters written in Rust. + +## Wasm limitations + +- You cannot create threads. Instead, use [`ic_cdk::spawn`](https://docs.rs/ic-cdk/0.16.0/ic_cdk/fn.spawn.html). +- You cannot sleep. Instead, use [`ic_cdk_timers`](https://docs.rs/ic-cdk-timers/latest/ic_cdk_timers/). +- You cannot use `Instant`. Instead, use [`ic_cdk::api::time`](https://docs.rs/ic-cdk/0.16.0/ic_cdk/api/fn.time.html). +- You cannot access environment variables with `std::env::var`, but you can embed compile-time environment variables with the `env!` macro. + +## Crate limitations + +Most crates work on ICP, but anything that performs input/output will not. Typically, it is fine to use a crate that performs input/output as long as you don't call the function that executes it. If you try to deploy a canister that uses this workflow, ICP will return an error about importing a function from `"env"`. + +Crates that specifically have a Wasm mode usually do not work as expected, as they usually have a special mode for executing in the browser and will perform their functionality using JavaScript functions instead, which don’t exist on ICP. If you try to deploy a canister that uses this workflow, ICP will return an error about importing a function named `__wbindgen_describe`. + +One example is the `getrandom` crate, which usually pulled in from another dependency. If you tried to import `uuid` with the `v4` feature, it refuses to compile into Wasm, but if you enable its Wasm mode, it just gives you a different error, because it’s trying to use JavaScript. + +Instead, `getrandom` allows you to create your own random function with the `register_custom_getrandom!` macro. The following boilerplate will eliminate the error and allow other crates to fetch randomness like usual: + +```rust +thread_local! { +// A global random number generator, seeded when the canister is initialized +static RNG: RefCell> = RefCell::new(None); +} +#[init] +fn init() { + init_rng(); +} +// Static variables are cleared on upgrade, so also initialize it on post-upgrade +#[post_upgrade] +fn post_upgrade() { + init_rng(); +} +// Randomness on the IC is async, and the custom getrandom function can't be async, +// so we seed an RNG instead of always calling raw_rand directly +fn init_rng() { + // raw_rand is technically an inter-canister call, and you can't make those from lifecycle functions like #[init], + // so we schedule an immediate timer to make the call instead + ic_cdk_timers::set_timer(Duration::ZERO, || ic_cdk::spawn(async { + let (seed,) = ic_cdk::api::management_canister::main::raw_rand().await.unwrap(); + // StdRng is from the `rand` crate. It makes for a good default but any RNG implementation would work + RNG.with(|rng| *rng.borrow_mut() = Some(StdRng::from_seed(seed.try_into().unwrap()))); + })); +} +register_custom_getrandom!(custom_getrandom); +fn custom_getrandom(buf: &mut [u8]) -> Result<(), getrandom::Error> { + RNG.with(|rng| rng.borrow_mut().as_mut().unwrap().fill_bytes(buf)); + Ok(()) + + +``` + +Crates in the category [`no-std`](https://crates.io/categories/no-std) should typically work as expected. + +Additional crate limitations include: + +- You cannot use `tokio`, use [`ic_cdk::spawn`](https://docs.rs/ic-cdk/0.16.0/ic_cdk/fn.spawn.html). +- You cannot use crates that make or serve HTTP requests. Instead, use [HTTP outcalls](/docs/current/developer-docs/smart-contracts/advanced-features/https-outcalls/https-outcalls-overview) or the [gateway API](/docs/current/references/http-gateway-protocol-spec/). + diff --git a/docs/developer-docs/backend/rust/searching-records.mdx b/docs/developer-docs/backend/rust/searching-records.mdx index bc0d49d2d4..445f392afc 100644 --- a/docs/developer-docs/backend/rust/searching-records.mdx +++ b/docs/developer-docs/backend/rust/searching-records.mdx @@ -66,13 +66,8 @@ Then, open the template `src/rust_profile_backend/src/lib.rs` file in a text edi The next step is to add a Rust program that implements the `getSelf`, `update`, `get`, and `search` functions. To do this, copy and paste this code into the `src/rust_profile_backend/src/lib.rs` file. ```rust title="src/rust_profile_backend/src/lib.rs" -use ic_cdk::{ -    export::{ -        candid::{CandidType, Deserialize}, -        Principal, -    }, -    query, update, -}; +use candid::{CandidType, Deserialize, Principal}; +use ic_cdk::{query, update}; use std::cell::RefCell; use std::collections::BTreeMap; @@ -126,6 +121,31 @@ fn update(profile: Profile) {         profile_store.borrow_mut().insert(principal_id, profile);     }); } + +#[query] +fn search(search_parameter: String) -> Option { + PROFILE_STORE.with(|profile_store| { + let profiles = profile_store.borrow(); + + for (_, profile) in profiles.iter() { + if profile.name.contains(&search_parameter) + || profile.description.contains(&search_parameter) + { + return Some(profile.clone()); + } + + if profile + .keywords + .iter() + .any(|keyword| keyword.contains(&search_parameter)) + { + return Some(profile.clone()); + } + } + + None + }) +} ``` Save your changes and close the file to continue. diff --git a/docs/developer-docs/daos/_attachments/copy-subaccount.png b/docs/developer-docs/daos/_attachments/copy-subaccount.png new file mode 100644 index 0000000000..3935607827 Binary files /dev/null and b/docs/developer-docs/daos/_attachments/copy-subaccount.png differ diff --git a/docs/developer-docs/daos/_attachments/ledger-1.webp b/docs/developer-docs/daos/_attachments/ledger-1.webp new file mode 100644 index 0000000000..464faecc82 Binary files /dev/null and b/docs/developer-docs/daos/_attachments/ledger-1.webp differ diff --git a/docs/developer-docs/daos/_attachments/ledger-2.webp b/docs/developer-docs/daos/_attachments/ledger-2.webp new file mode 100644 index 0000000000..7003eddbbb Binary files /dev/null and b/docs/developer-docs/daos/_attachments/ledger-2.webp differ diff --git a/docs/developer-docs/daos/_attachments/ledger-3.webp b/docs/developer-docs/daos/_attachments/ledger-3.webp new file mode 100644 index 0000000000..7b429bf23e Binary files /dev/null and b/docs/developer-docs/daos/_attachments/ledger-3.webp differ diff --git a/docs/developer-docs/daos/_attachments/ledger-4.webp b/docs/developer-docs/daos/_attachments/ledger-4.webp new file mode 100644 index 0000000000..fdb8a6917f Binary files /dev/null and b/docs/developer-docs/daos/_attachments/ledger-4.webp differ diff --git a/docs/developer-docs/daos/_attachments/ledger-5.webp b/docs/developer-docs/daos/_attachments/ledger-5.webp new file mode 100644 index 0000000000..f616cad6da Binary files /dev/null and b/docs/developer-docs/daos/_attachments/ledger-5.webp differ diff --git a/docs/developer-docs/daos/_attachments/ledger-6.webp b/docs/developer-docs/daos/_attachments/ledger-6.webp new file mode 100644 index 0000000000..49d45e0441 Binary files /dev/null and b/docs/developer-docs/daos/_attachments/ledger-6.webp differ diff --git a/docs/developer-docs/daos/_attachments/ledger-7.webp b/docs/developer-docs/daos/_attachments/ledger-7.webp new file mode 100644 index 0000000000..74435ca351 Binary files /dev/null and b/docs/developer-docs/daos/_attachments/ledger-7.webp differ diff --git a/docs/developer-docs/daos/_attachments/ledger-8.webp b/docs/developer-docs/daos/_attachments/ledger-8.webp new file mode 100644 index 0000000000..725efa362a Binary files /dev/null and b/docs/developer-docs/daos/_attachments/ledger-8.webp differ diff --git a/docs/developer-docs/daos/_attachments/ledger-9.webp b/docs/developer-docs/daos/_attachments/ledger-9.webp new file mode 100644 index 0000000000..79cc43912c Binary files /dev/null and b/docs/developer-docs/daos/_attachments/ledger-9.webp differ diff --git a/docs/developer-docs/daos/nns/neurons-fund.mdx b/docs/developer-docs/daos/nns/concepts/neurons-fund.mdx similarity index 98% rename from docs/developer-docs/daos/nns/neurons-fund.mdx rename to docs/developer-docs/daos/nns/concepts/neurons-fund.mdx index 48398bcf7c..d29cd52e01 100644 --- a/docs/developer-docs/daos/nns/neurons-fund.mdx +++ b/docs/developer-docs/daos/nns/concepts/neurons-fund.mdx @@ -1,5 +1,5 @@ --- -keywords: [intermediate, governance, concept, nns] +keywords: [intermediate, governance, concept, nns, neurons fund, neurons, NF] --- diff --git a/docs/developer-docs/daos/nns/proposal-voting.mdx b/docs/developer-docs/daos/nns/concepts/neurons/becoming-a-known-neuron.mdx similarity index 56% rename from docs/developer-docs/daos/nns/proposal-voting.mdx rename to docs/developer-docs/daos/nns/concepts/neurons/becoming-a-known-neuron.mdx index 399e4fcbfc..0a41f3e1d2 100644 --- a/docs/developer-docs/daos/nns/proposal-voting.mdx +++ b/docs/developer-docs/daos/nns/concepts/neurons/becoming-a-known-neuron.mdx @@ -1,102 +1,77 @@ --- -keywords: [intermediate, governance, concept, nns] +keywords: [advanced, governance, tutorial, nns, known neurons, named neurons, neurons] --- import { MarkdownChipRow } from "/src/components/Chip/MarkdownChipRow"; +import '/src/components/CenterImages/center.scss'; -# Voting on proposals +# Registering a known neuron - + ## Overview -The NNS DAO is an open governance system where anyone can become a participant by [staking some ICP in a neuron](https://internetcomputer.org/docs/current/developer-docs/daos/nns/nns-app-quickstart#stake-icp-utility-tokens-in-a-neuron) and locking the tokens for at least 6 months. Locking tokens for a period of time is known as the neuron's dissolve delay. - -## Finding proposals and discussions - -You can see all the NNS proposals on the [Internet Computer dashboard](https://dashboard.internetcomputer.org/governance) or on the [NNS dapp](https://nns.ic0.app/). Voters can freely discuss proposals anywhere they like. A lot of NNS proposals are discussed on the [developer forum](https://forum.dfinity.org/c/roadmap/29). - -## Direct voting -When a user has an eligible neuron and would like to vote on an open proposal, one option is to directly vote to adopt or reject the proposal. Currently, the most user-friendly way to first find and [vote on open proposals](/docs/current/developer-docs/daos/nns/nns-app-quickstart#vote-on-proposals) is via the NNS Frontend dapp: https://nns.ic0.app/. - -## Liquid democracy (following) -Users may not have the time or knowledge to participate in all voting decisions. Therefore, instead of directly voting on proposals, neuron holders may choose to delegate their vote to other neurons that they trust with certain decisions. This concept of delegating the right to vote to other neurons, who then effectively vote with more voting power, is called **liquid democracy**. In the NNS DAO, this is also called **following**, as a neuron follows the decision of some other neurons. - -### How to follow a neuron -Concretely, proposals are grouped into different [**proposal topics**](./proposal-voting.mdx#proposal-topics-and-types) and following is done on a per-topic basis. Learn how you can set up your neuron to [follow a group of other neurons](/docs/current/developer-docs/daos/nns/nns-app-quickstart#neuron-following). +A know neuron has a name and optionally a short description. +A known neuron can be registered in the NNS governance via a proposal, officially storing its name and description +within the NNS. This information can be used by other neurons to find known neurons and [follow](/docs/current/developer-docs/daos/nns/concepts/neurons/neuron-following) them. -### How to find neurons to follow -In order for a neuron to follow others, there need to be some neurons that actively vote and can be followed. +To become a known neuron in the NNS DAO, you first need to create a neuron, then submit an NNS proposal to register as a known neuron. After the proposal is accepted and your neuron is registered, it will be visible to all NNS users when they set up their own neuron following. -There are two ways neurons to follow can be found and set: -* A user with an actively voting neuron who is offering to be followed can communicate their neuron ID to others, for example on the forum or their website. Other neurons can then [follow them](https://internetcomputer.org/docs/current/developer-docs/daos/nns/nns-app-quickstart#step-5-enter-a-neuron-id-to-follow-or-select-a-group-of-neurons-from-the-menu-provided) using this neuron ID. -* A user with an actively voting neuron who is offering to be followed can register a **known neuron**, also called a **named neuron**, in the NNS governance canister. Neurons who would like to follow others can see a list of all registered neurons with their name and optionally a short description, and can then select one of them to follow (without having to remember an ID). +It can be useful for known neuron candidates to be an (unregistered) actively voting neuron for a while before registering a neuron. During this time, the neuron holder can get familiar with voting and start becoming an expert in a topic. They can also share their neuron ID for others to follow them. In this way, by the time that they register the neuron as a known neuron, there is already some evidence of their voting behavior that NNS participants can base their decision on. Moreover, to convince the NNS DAO to accept a new known neuron, it can be useful for known neuron candidates to present themselves to the community outside the governance context, for example, on the forum or social media. -## How to become a known neuron -To become a known neuron in the NNS DAO, you first need to create a neuron and then submit an NNS proposal to register the known neuron in the NNS governance. -A know neuron has a name and optionally a short description. -After registering the known neuron, it will be visible to all NNS DAO users when they set up their following. -It can be useful for known neuron candidates to be an (unregistered) acvitely voting neuron for a while before registering the neuron. -During this time, the neuron holder can get familiar with voting and start becoming an expert in a topic. They can also alread share their neuron ID for others to follow them. -In this way, by the time that they register the neuron as a known neuron, there is already some evidence of their behavior as voters that NNS voters can base their decision on. -Moreover, to convince the NNS DAO to accept a new known neuron, it can be useful for known neuron candidates to present themselves to the community outside the governance context, for example on the forum or social media. - -### Create a neuron -There are multiple options to create and set up a neuron that is then registered as a know neuron. -A known neuron can be operated by an individual person or an organization where one person controls the neuron -or it can be operated by a group of people. +## Create a neuron +There are multiple options to create and set up a neuron that can then be registered as a know neuron. +A known neuron can be operated by an individual person, or an organization where either one person controls the neuron or it is operated by a group of people. Depending on this, different neuron creation options might be more suitable. -#### Create a neuron controlled by one party +### Create a neuron controlled by one party If you would like to create a known neuron that is operated by one party that knows the neuron's controlling key and can change the neuron, you can use one of the following options: -* [Create the neuron on the NNS dapp](/docs/current/developer-docs/daos/nns/nns-app-quickstart#stake-icp-utility-tokens-in-a-neuron). +* [Create the neuron on the NNS dapp](/docs/current/developer-docs/daos/nns/using-the-nns-dapp/nns-app-quickstart#stake-icp-utility-tokens-in-a-neuron). * [Create the neuron on the NNS dapp that is controlled by a hardware ledger wallet](https://support.dfinity.org/hc/en-us/articles/8760495850900-How-do-I-use-my-Ledger-Nano-with-the-Internet-Computer) * [Create the neuron via the quill command line tool](https://support.dfinity.org/hc/en-us/articles/4408752586260-What-is-Quill). :::info -If there are multiple people involved in a know neuron's voting decision, the known neuron can be set up to follow their individual neurons - on the topics that it should vote on. -However, for a neuron which is created this way, the **person who created the neuron has the controlling key**. -This person can modify the neuron and, in particular, can also vote in the name of the neuron without taking the input of others into account. +If there are multiple people involved in a known neuron's voting decision, the known neuron can be set up to follow their individual neurons on the topics that it should vote on. +However, for a neuron that is created this way, the **person who created the neuron has the controlling key**. +This person can modify the neuron and, in particular, can also vote using the neuron without taking the input of others into account. This can be suitable for individuals who operate a known neuron, or for organizations where one person is trusted with this task. - ::: -#### Create a community neuron +### Create a community neuron Additional information on how to create a community neuron will be added soon! -### Start voting and present your neuron to the community +## Start voting and present your neuron to the community Once you have created a neuron, you can start voting with it and also share context about how you voted and why with the community. You can already share your neuron ID with others so that they can follow you on certain topics. -When you are familiar with voting and soon ready to register a know neuron, you can prepare for this step. A known neuron needs a name and a description. Often, the owners of known neurons use the description part to present themselves to the community. - There are no rules that a known neuron must follow regarding if it presents itself to the community or not, but it can make sense for neuron owners to present themselves before submitting the proposal to register themselves as a known neuron. This can serve as a way for promoting the neuron and explaining the motivation behind it. This can, for example, be done with a forum post or by sharing information on social media, such as OpenChat or X. -It might be useful to share the following information with the community, so that followers can make well-informed decisions regarding who to follow for which topic: -* **Who you are**: Name of the person or group and their relationship to the ICP. You may want to argue why the people behind the neuron have a long-term interest in the wellbeing of the ICP and are, therefore, motivated to make good voting decisions. -* **Neuron control**: Who controls the neuron? Does it have a single controller or can it only be changed by a group of people? + +This might be useful so that followers can make well-informed decisions regarding who to follow for which topic: + +* **Who you are**: Name of the person or group and their relationship to the ICP. You may want to argue why the people behind the neuron have a long-term interest in the wellbeing of the ICP and are motivated to make good voting decisions. +* **Neuron control**: Who controls the neuron? Does it have a single controller or can it be changed by a group of people? * **Covered topics**: A description of what topics the known neuron will vote on. Does the neuron commit to always vote on these topics? Since following is done based on proposal topics, this is relevant information for followers. Usually, neurons would want to follow other neurons that always vote on a given topic in order not to miss out on [voting rewards](./staking-voting-rewards.mdx). * **Depth of reviews**: A description of how the known neuron plans to verify proposals. To which depth will it review the code or the content of the proposal and how is this done? * **Following setting**: For the topics where the know neuron does not vote directly, who does the neuron follow? * **Voting principles**: What are the principles according to which you plan to vote? -* **Link to the neuron ID / proposal**: If you already created the neuron, you may want to provide its ID or even link to a dashboard where it can be inspected. The same holds for the proposal to register it as a know neuron in the case where the proposal was already made. +* **Link to the neuron ID / proposal**: If you already created the neuron, you may want to provide its ID or even link to a dashboard where it can be inspected. The same holds for the proposal to register it as a known neuron in the case where the proposal was already made. :::info -There are no rules regarding how a known neuron has to vote. However, due to the above reasons, it might be useful for known neurons to **focus on fewer topics and commit to always vote on those** rather than trying to cover a lot of topics and vote less reliably. For example, they could become experts on some proposal topics. If a known neuron commits to always vote on a certain topic, it might be more likely that others follow the neuron on this topic as the followers want to make sure they are not missing out on rewards. - +It might be useful for known neurons to **focus on fewer topics and commit to always vote on those** rather than trying to cover a lot of topics and vote less reliably. For example, they could become experts on some proposal topics. If a known neuron commits to always vote on a certain topic, it might be more likely that others follow the neuron on this topic as the followers want to make sure they are not missing out on rewards. ::: -### Register the known neuron +## Register the known neuron To register a neuron as a know neuron, you need to submit a NNS proposal. The proposal can be submitted by any neuron that has at least 10 ICP staked. For simplicity, we assume in the following example that the neuron to be registered was created on the NNS dapp and that the same neuron is used to submit the proposal. -**1. Download and install `dfx`** -It is not possible to submit proposals through the NNS dapp. Therefore, you must use a command line tool called `dfx`.`dfx` is only natively supported on Mac and Linux, but it can be installed on Windows using WSL. +- ### Step 1: Download and install `dfx` + +It is not possible to submit proposals through the NNS dapp. Therefore, you must use a command line tool called `dfx`.`dfx` is only natively supported on Mac and Linux, but it can be installed on Windows using WSL. To install `dfx`, follow the [installation instructions](/docs/current/developer-docs/getting-started/install/#installing-dfx). @@ -109,11 +84,12 @@ sh -ci "$(curl -fsSL https://internetcomputer.org/install.sh)" If you are using a machine running Apple silicon, you will need to have [Rosetta](https://support.apple.com/en-us/HT211861) installed. You can install Rosetta by running `softwareupdate --install-rosetta` in your terminal. -**2. Add your `dfx` principal as a hotkey to your neuron** +- ### Step 2: Add your `dfx` principal as a hotkey to your neuron + Your neuron is controlled by a **principal ID**, which is an identity on ICP. However, you want to be able to submit proposals from the command line on your computer in this neuron's name. For this, you can register the principal that you have on your computer as a -[**hot key**](/docs/current/developer-docs/daos/nns/neuron-management#neuron-attributes) +[**hot key**](/docs/current/developer-docs/daos/nns/concepts/neurons/neuron-management#neuron-attributes) of the neuron. Hot keys have the permission to vote and submit proposals for the neuron. Run `dfx identity get-principal` to get the principal ID that corresponds to your current [developer identity](/docs/current/developer-docs/getting-started/accounts). The following steps will refer to this as your "dfx principal". @@ -125,7 +101,7 @@ and press confirm. Your dfx principal should appear under “Hotkeys”. You can now control your neuron from the local terminal. -**3. Submit the proposal** +- ### Step 3: Submit the proposal To submit the proposal, you need the neuron ID of the neuron to be registered as a known neuron, a name for the known neuron, and a short description. You find your neuron ID in the NNS dapp at the top right of the NNS dashboard page for your neuron. diff --git a/docs/developer-docs/daos/nns/concepts/neurons/neuron-following.mdx b/docs/developer-docs/daos/nns/concepts/neurons/neuron-following.mdx new file mode 100644 index 0000000000..cf0f160a53 --- /dev/null +++ b/docs/developer-docs/daos/nns/concepts/neurons/neuron-following.mdx @@ -0,0 +1,65 @@ +--- +keywords: [beginner, governance, concept, nns, following, neuron following, neurons] +--- + +import { MarkdownChipRow } from "/src/components/Chip/MarkdownChipRow"; +import '/src/components/CenterImages/center.scss'; + +# Following + + + +## Overview +Users may not have the time or knowledge to participate in all voting decisions. +Therefore, instead of directly voting on proposals, neuron holders may choose to delegate their vote to other neurons that they trust with certain decisions. +This concept, where a neuron follows the decisions of some other neurons, is called **following** in the NNS DAO. +The delegation of the voting rights to others, who then effectively vote with more voting power, is also called **liquid democracy**. + +For an explanation video regarding how following works and more information how following can be set on the NNS dapp, +refer to [configuring neuron following](/docs/current/developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-following-other-neurons). +## Following rules +A neuron can be configured to vote automatically by following the voting decision made by a group of other neurons, +called **followees**. +Proposals are grouped into different [**proposal topics**](/docs/current/developer-docs/daos/nns/concepts/proposals/proposal-topics) and following is done on a per-topic basis. + +Each neuron can follow at most 15 other neurons for each proposal topic. +A neuron will only cast a "Yes"-vote if **more than half** of the neurons within the followee-group voted Yes. +A neuron will only cast a "No"-vote if **at least half** of the neurons within the followee-group voted No. + +:::caution +Your neuron will follow when there are **enough votes to make a decision whether it is a ADOPT or REJECT**. +For example, if you follow 10 neurons on a topic: + +- Your neuron only votes to adopt if at least 6 out of the 10 neurons vote to adopt. + +- Your neuron only votes to reject a proposal if at least 5 out of the 10 reject the proposal. + +- If less than 5 neurons (out of your 10 followed) vote at all, your neuron will not cast any vote. + +This should be considered when choosing to follow multiple neurons on a topic. +It might be better to follow fewer neurons, and it can be more beneficial to follow an odd number of + neurons than an even number. +::: + +## Following "catch-all" +In addition to setting following for individual topics, neurons may also define a catch-all follow rule which is triggered for proposals with topics for which no other explicit follow rule has been defined. +However, the catch-all follow rule does not include the proposal topics **SNS & neurons' fund** and **governance**. + +:::caution +The catch-all follow rule is only applied for proposal topics with no other explicit choice. For example, let's assume neuron A follows neuron B for the catch-all and neuron C on the topic subnet management. If B votes on a subnet management proposal but C does not, no vote will be cast for A. + +The catch-all follow rule does not apply for SNS & neurons' fund or governance proposals. +For example, if neuron A follows neuron B for the catch-all and B votes on a governance proposal, no vote will be cast for A. If neuron A intends to also follow B on such decisions, the user has to explicitly choose to also follow B on the governance topic. +::: + +It is in each neuron's interest to follow other neurons that support the best interests of the network and their own economic interests. + +## How to follow a neuron +To learn more about how to set up your neuron to follow a group of other neurons on the NNS dapp, refer to [NNS dapp quickstart for following](/docs/current/developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-following-other-neurons). + +### How to find neurons to follow +In order for a neuron to follow others, there needs to be some neurons that actively vote and can be followed. + +There are two ways neurons to follow can be found and set: +* A user with an actively voting neuron who is offering to be followed can communicate their neuron ID to others, for example on the forum or their website. Other neurons can then [follow them](https://internetcomputer.org/docs/current/developer-docs/daos/nns/using-the-nns-dapp/nns-app-quickstart#step-5-enter-a-neuron-id-to-follow-or-select-a-group-of-neurons-from-the-menu-provided) using this neuron ID. +* A user with an actively voting neuron who is offering to be followed can register a **known neuron**, also called a **named neuron**, in the NNS governance canister. Neurons who would like to follow others can see a list of all registered neurons with their name and optionally a short description, and can then select one of them to follow (without having to remember an ID). diff --git a/docs/developer-docs/daos/nns/neuron-management.mdx b/docs/developer-docs/daos/nns/concepts/neurons/neuron-management.mdx similarity index 51% rename from docs/developer-docs/daos/nns/neuron-management.mdx rename to docs/developer-docs/daos/nns/concepts/neurons/neuron-management.mdx index dff74f6bba..1deff0c8bd 100644 --- a/docs/developer-docs/daos/nns/neuron-management.mdx +++ b/docs/developer-docs/daos/nns/concepts/neurons/neuron-management.mdx @@ -1,48 +1,106 @@ --- -keywords: [intermediate, governance, concept, nns] +keywords: [advanced, governance, concept, nns, neurons, neuron management, managing a neuron] --- import { MarkdownChipRow } from "/src/components/Chip/MarkdownChipRow"; # Neuron management - + -## Overview -This page describes the technical APIs used to manage neurons on the NNS. -If you are building a project that offers neuron staking or custody support, this page is particularly useful. +## Who should read this page +This page describes all of the operations that you can perform on a neuron and their associated APIs. + +This page is for you if you want to learn the technical details about neuron operations, or if you want to integrate with the NNS, for example, if you build a project that offers neuron staking or custody support. + +Tutorials for users who want to interact with the NNS using the [NNS dapp](https://nns.ic0.app) frontend are available in the [NNS dapp quickguide](/docs/current/developer-docs/daos/nns/using-the-nns-dapp/nns-app-quickstart). +## Overview View the most up-to-date [`candid` definition for the NNS governance canister](https://github.com/dfinity/ic/blob/master/rs/nns/governance/canister/governance.did). -This page will focus on the neuron interactions and explain some of the relevant definitions from this Candid file. +This page will explain some of the relevant definitions from this Candid file. To keep up to date with new NNS release proposals from DFINITY, you can subscribe to [this forum thread](https://forum.dfinity.org/t/nns-updates-aggregation-thread/23551). -## Neuron attributes -Before explaining how to modify a neuron, it is important to understand the most important parts of a neuron. -Every user can stake ICP utility tokens into a neuron and participate in the NNS DAO with this neuron. +## Neuron and NeuronInfo + +Find a high level overview of the most important neuron concepts in the [Neuron overview](/docs/current/developer-docs/daos/nns/concepts/neurons/neuron-overview). +Below are details about the [`Neuron` record](https://github.com/dfinity/ic/blob/173d06185f77265d97bc363d266ce79410f6b914/rs/nns/governance/canister/governance.did#L363C1-L386C3) +including all neuron attributes. This represents a full neuron with all details. + +* `id : opt NeuronId;`: A unique ID identifying the neuron. This is a number that is randomly chosen by the governance canister when a neuron is created. + +* `account : blob;`: The neuron's account on the ledger. This corresponds to a subaccount of the NNS governance canister so that the tokens are locked and can only be transferred by dissolving the neuron. + +* `controller : opt principal;`: The principal controlling the neuron. This principal has the permissions to read the neuron and perform any operations on the neuron. + +* `hot_keys : vec principal;`: A list of principals that have limited permissions on the neuron. This can be used for example to use more accessible but less secure keys for everyday operations. Hotkey principals can read the neuron as well as vote with it, which includes both direct voting and changing following. + +* `cached_neuron_stake_e8s : nat64;`: The amount of staked ICP tokens, measured in fractions of 10E-8 of an ICP token. + +* `neuron_fees_e8s : nat64;`: The amount of ICP that this neuron has forfeited due to making proposals that were rejected or from using the 'manage neurons through proposals' functionality. This value must be smaller than `neuron_stake_e8s`. When a neuron is disbursed, these ICP are burned. + +* `created_timestamp_seconds : nat64;`: The timestamp, in seconds from the Unix epoch, when the neuron was created. + +* `dissolve_state : opt DissolveState; type DissolveState = variant { DissolveDelaySeconds : nat64; WhenDissolvedTimestampSeconds : nat64; };`: The timer that defines how long the tokens in this neuron are locked for. When the neuron is dissolving, i.e., the timer is running down, this this stores the timestamp at which the neuron becomes dissolved `WhenDissolvedTimestampSeconds`. When the neuron is non-dissolving, `DissolveDelaySeconds` stores how much time, in seconds, is left until the neuron is dissolved when the dissolve timer is turned on again. +A neuron is dissolved if `WhenDissolvedTimestampSeconds` is in the past or if `DissolveDelaySeconds` is zero. + +* `aging_since_timestamp_seconds : nat64;`: The timestamp, in seconds from the Unix epoch, when this neuron last entered the non-dissolving state and has started aging. This value is +meaningless when the neuron is dissolving and has age zero. The canonical value of this field for a dissolving neuron is `u64::MAX`. + +* `followees : vec record { int32; Followees }; type Followees = record { followees : vec NeuronId };`: The followees of a neuron, that is the group of neurons that this neuron follows. They are expressed as maps from proposal topics (expressed by integers) to a list of followees for this particular topic. + +* `recent_ballots : vec BallotInfo;`: Information about how this neuron voted in the recent past. + +* `maturity_e8s_equivalent : nat64;`: The accumulated unstaked maturity of the neuron, in e8s equivalent. + +* `staked_maturity_e8s_equivalent : opt nat64;`: The accumulated staked maturity of the neuron, in e8s equivalent. Staked maturity becomes unstaked maturity once the neuron is dissolved. -* **Neuron ID**: Each neuron has an identity selected by NNS governance at neuron creation. -* **Account**: Each neuron has an associated account on the ICP ledger where the locked ICP balance resides. This account is owned by the NNS governance canister and therefore a user cannot move staked tokens. -* **Controller**: The principal that controls the neuron and which cannot be changed. A principal corresponds to the public key of a public-private key pair and anyone with possession of the corresponding private key will have full control of the neuron. Therefore, the private key of the controller principal should be kept very secure. A principal can control many neurons. -* **Hot Keys**: In addition to the controller, a neuron can have hot keys. Hot keys are defined by a list of principal ID and can be used to perform actions with limited privileges, namely voting, following (see below), and reading the full information about the neuron. +* `auto_stake_maturity : opt bool;`: If set and true the maturity rewarded to this neuron for voting will be automatically staked and will contribute to the neuron's voting power. -* **Dissolve delay & dissolve state**: The tokens in a neuron are locked for a specified duration, called the _dissolve delay_. This can be thought of like a kitchen timer that can only be turned in one direction. It can be arbitrarily increased, but only reduced by turning on the countdown and waiting for the time to pass. A neuron must have a dissolve delay of at least 6 months to be eligible to vote. - * A neuron can be _non-dissolving_ which means that the timer is stopped and the neuron's dissolve delay remains the same. - * A neuron can be _dissolving_ which means that the timer is decreasing the neuron's dissolve delay as time passes. - * Once the timer has counted down, a neuron is _dissolved_ and the ICP tokens can be unstaked again. -* **Age**: Every non-dissolving neuron has an age, which denotes how long it has been in the non-dissolving state. -A neuron's voting power increases as its age increases. A neuron's voting power also increases if its controller increases its dissolve delay. +* `spawn_at_timestamp_seconds : opt nat64;`: This is used if for neurons that were created to spawn maturity into a neuron. It denotes the timestamp, in seconds from the Unix epoch, at which this + neuron's maturity is replaced by newly minted ICP. -* **Maturity**: When neurons vote, over time the NNS increases their maturity to reward them. Maturity can be converted into ICP by spawning (see below). +* `visibility : opt int32;`: The visibility defines how much information about this neuron is publicly accessible, i.e., visible to those who are neither the controller nor + have hot-key privileges to this neuron. Visibility can be public, private, or undefined. + For public neurons, the full neuron is accessible to everyone, for private neurons only a part of the `NeuronInfo` (see below) is visible, excluding the recent_ballots` + and `joined_community_fund_timestamp_seconds`. -### Getting information about a neuron +* `known_neuron_data : opt KnownNeuronData; message KnownNeuronData { string name = 1; optional string description = 2; }`: A neuron can be registered as a **known neuron** via proposal so that it can be followed by others. +Known neurons have extra information, a name and optionally a description. + +* `joined_community_fund_timestamp_seconds : opt nat64;`: Timestamp when this neuron joined the community fund. + +* `transfer : opt NeuronStakeTransfer;`: The record of the transfer that was made to create this neuron. + +* `kyc_verified : bool;`: This is a field indicating whether genesis neurons have been KYC verified. `false` if this is a genesis neurons that has not been KYC verified. + +* `not_for_profit : bool;`: Whether this neuron is "Not for profit", making it dissolvable by voting on a manage neuron proposal. + +* `neuron_type : opt int32;`: The type of a neuron, identifying seed neurons and Early Contributor Token (ECT) neurons. + + +In addition to this neuron record, `NeuronInfo` provides the most important information about a neuron. +Refer to the `candid` file for the [`NeuronInfo` record](https://github.com/dfinity/ic/blob/173d06185f77265d97bc363d266ce79410f6b914/rs/nns/governance/canister/governance.did#L408). + + +## Getting information about a neuron Before diving deeper into how a neuron can be created and modified, let's first understand how to get information about a user's existing neurons. -This can be done by using the following API on the NNS governance canister. +### Neuron visibility +A neuron can be private or public. +* For public neurons, everyone can view the full neuron. This includes the full `NeuronInfo` which can be viewed as a summary of the most important information. +* For private neurons: + * Everyone can view the fields in `NeuronInfo`, except for `recent_ballots` and `joined_community_fund_timestamp_seconds`. + * Principals who control the neuron or are a hotkey of the neuron can view the full neuron. This includes the full `NeuronInfo`. + +### APIs +A user can request information about a list of neurons using this API: ``` list_neurons : (ListNeurons) -> (ListNeuronsResponse) query; type ListNeurons = record { + include_public_neurons_in_full_neurons : opt bool; neuron_ids : vec nat64; + include_empty_neurons_readable_by_caller : opt bool; include_neurons_readable_by_caller : bool; }; @@ -51,13 +109,15 @@ type ListNeuronsResponse = record { full_neurons : vec Neuron; }; ``` -By using this API, a user can request information about a list of neurons. - The user can define which neurons to get information from by defining a list of neuron IDs in the argument `neuron_ids`. -In addition, if the argument `include_neurons_readable_by_caller` is set to true, the neurons who the user is authorized to read are also included (i.e., the neurons for which the user is a controller or hot key). +Additionally: +* If the argument `include_neurons_readable_by_caller` is set to true, the neurons who the user is authorized to read are also included (i.e., the neurons for which the user is a controller or hotkey). +* If the argument `include_empty_neurons_readable_by_caller` is set to true, the empty neurons readable by the caller are also included. Neurons are empty if they have 0 stake, 0 maturity, and 0 staked maturity. This field only has an effect when `include_neurons_readable_by_caller` is true. If a neuron is explicitly requested to be returned by including it in the `neuron_ids` field, then the neuron will be included in the response regardless of this value. If this fields is not provided, it defaults to true for backwards compatibility. -The answer to such a query is defined by `ListNeuronsResponse`. First, it contains a map that points for each neuron that was requested to the corresponding `NeuronInfo` (assuming the neuron exists). This is the public information about a [neuron and the exact definition](https://github.com/dfinity/ic/blob/7184d168d44f3ba27f750285a0fba43a0c56190a/rs/nns/governance/src/gen/ic_nns_governance.pb.v1.rs#L50). -In addition, for each requested neuron that exists and for which the calling user is authorized to read the full neuron (controller or hot key), the full neuron is returned. +The answer to such a query is defined by `ListNeuronsResponse`: +* First, it contains a map that points for each neuron that was requested to the corresponding `NeuronInfo` (assuming the neuron exists). For neurons that are public or for which the calling user is the controller or a hotkey, this includes the full `NeuronInfo`. For other private neurons `recent_ballots` and `joined_community_fund_timestamp_seconds` are redacted. +* For each requested neuron that exists and for which the calling user is a controller or hotkey, the full neuron is returned. +* If the argument `include_public_neurons_in_full_neurons` is set to true, for each requested public neuron, the full neuron is returned. ## Interacting with neurons All neuron modifications go through the following API on the NNS governance canister. This includes everything in a neuron's lifetime such as the neuron's creation, modifications and voting, and unstaking the ICP tokens. @@ -68,10 +128,18 @@ type ManageNeuron = record { neuron_id_or_subaccount : opt NeuronIdOrSubaccount; }; ``` +:::info +For most of the workflows detailed below, you can also use the [ICP Rosetta API](/docs/current/developer-docs/defi/rosetta/icp_rosetta/construction_api/staking/). -You can also use the [ICP Rosetta API](/docs/current/developer-docs/defi/rosetta/icp_rosetta/construction_api/staking/) for this workflow. +::: ### Creating a neuron and topping it up + +Each neuron's stake is stored on a subaccount of the governance canister on the ICP ledger. +The following diagram provides a simplified view of the workflow for creating a neuron and the relationship between the neuron and its ledger account. + +![neuron dissolve](../../../_attachments/distribute-neurons-diagram.png) + Staking ICP utility tokens in a neuron involves three steps: 1. Compute the neuron's address on the ledger, where the staked tokens will be held. This corresponds to a subaccount of the NNS governance canister. 2. Send ICP utility tokens to the neuron's address computed in (1). @@ -79,27 +147,28 @@ Staking ICP utility tokens in a neuron involves three steps: Let us go through these steps in more detail. -**Compute the neuron's address** +#### Step 1: Compute the neuron's address To compute the neuron's address in the first step, proceed as follows. -a) Learn the principal that should control the neuron and choose a nonce. The nonce is used to allow the same principal to control multiple neurons and does not need to be kept secret. +1. Learn the principal that should control the neuron and choose a nonce. The nonce is used to allow the same principal to control multiple neurons and does not need to be kept secret. -b) Computed the subaccount based on the two inputs from (a). View for example the method [`compute_neuron_staking_subaccount_bytes`](https://github.com/dfinity/ic/blob/master/rs/nervous_system/common/src/ledger.rs) which computes the subaccount given a controller principal and a nonce. +2. Compute the subaccount based on the two inputs from (1). View for example the method +[`compute_neuron_staking_subaccount_bytes`](https://github.com/dfinity/ic/blob/master/rs/nervous_system/common/src/ledger.rs) which computes the subaccount given a controller principal and a nonce. -c) Compute the final account identifier on the ledger (that gives you the address) using the computed subaccount from (b) and the principal ID of the NNS governance canister. View for example the method [`neuron_subaccount`](https://github.com/dfinity/ic/blob/master/rs/nns/governance/src/governance.rs) which computes the account based on a given subaccount and with the NNS governance principal ID `GOVERNANCE_CANISTER_ID`. +3. Compute the final account identifier on the ledger (that gives you the address) using the computed subaccount from (2) and the principal ID of the NNS governance canister. View for example the method [`neuron_subaccount`](https://github.com/dfinity/ic/blob/master/rs/nns/governance/src/governance.rs) which computes the account based on a given subaccount and with the NNS governance principal ID `GOVERNANCE_CANISTER_ID`. For the above steps, make sure you are using an up-to-date version of this code in your application. -:::info +:::caution It is of utmost importance to ensure that the address is computed correctly in the first step and remembered so that it can be reused in the second step. If this fails, funds could be sent to a dead account and be unrecoverable. It is recommended to test the corresponding code thoroughly. ::: -**Send ICP to the neuron's account** +#### Step 2: Send ICP to the neuron's account After having computed the neuron's address, make a transfer to this address. For this, view the [relevant `candid` interface of the ICP ledger](https://github.com/dfinity/ic/blob/846886223adf11f86b70b5f19c345b3fe6f33fed/rs/rosetta-api/icp_ledger/ledger.did#L432C5-L432C13) which contains the following details for a transfer. ``` @@ -115,14 +184,12 @@ type TransferArgs = record { to: AccountIdentifier; created_at_time: opt TimeStamp; }; - -}; ``` To make a transfer to the correct account, choose the `memo` equal to your chosen nonce (from Step (1a)). To stake a neuron, the `amount` must be at least 1 ICP. Set the `fee` to the standard fee of the ICP ledger canister, which is 10000 e8s. You can make the transfer from any `from_subaccount` account that you control. For the `to` account, use the account that you have computed in Step (1). -**Claim the neuron** +#### Step 3: Claim the neuron As a third step, claim the neuron using the following `ManageNeuron` command. ``` @@ -136,6 +203,7 @@ The `controller` is the principal controller chosen in Step (1a) that will contr _Required permissions:_ Anyone can make this call and claim a neuron for the specified controller. **Topping up a neuron** + Topping up an existing neuron with more tokens is called _refreshing_ a neuron and works similarly to claiming a neuron. 1. Send additional ICP utility tokens to the (existing) neuron's address. 2. Refresh the neuron on the NNS governance canister, which tells the governance canister that the transfer in (1) happened, upon which the NNS governance will update the neuron's stake. @@ -151,8 +219,6 @@ When `ClaimOrRefreshNeuronFromAccount` is used, the NNS governance canister will _Required permissions:_ Anyone can make this call and top up a neuron, even if they do not have any permissions on the neuron. No matter who makes the call to the governance canister, its controller is set by the arguments as mentioned above. -You can also use the [ICP Rosetta API](/docs/current/developer-docs/defi/rosetta/icp_rosetta/construction_api/staking/) for this workflow. - ### Managing permissions of a neuron Every neuron has a controller that cannot be changed and may have hot keys. Hot keys are defined by a list of principal ID and can be used to perform actions with limited privileges, namely voting and following. To manage these permissions, a neuron's controller can add and remove hot keys using the neuron command `Configure` with the `Operation` `AddHotKey` and `RemoveHotKey`, respectively. @@ -176,8 +242,15 @@ For adding a hot key, the principal `new_hot_key` to add needs to be provided an _Required permissions:_ Only a neuron's controller can add and remove hot keys. -You can also use the [ICP Rosetta API](/docs/current/developer-docs/defi/rosetta/icp_rosetta/construction_api/staking/) for this workflow. +### Set a neuron's visibility +To set a neuron's visibility, use the following configuration: +``` +type SetVisibility = record { visibility : opt int32 }; +``` +The input determines the new visibility that the neuron should have, which can either be private (encoded as 1) or public (encoded as 2). +_Required permissions:_ +Only a neuron's controller can set the visibility. ### Modifying a neuron's state Recall from the section _Neuron attributes_, that a neuron has a dissolve delay and can be non-dissolving, dissolving, or dissolved. @@ -213,55 +286,13 @@ In both cases, the dissolve delay can only be increased but never decreased. _Required permissions:_ Only a neuron's controller can start or stop dissolving a neuron or increase its dissolve delay. -You can also use the [ICP Rosetta API](/docs/current/developer-docs/defi/rosetta/icp_rosetta/construction_api/staking/) for this workflow. - - -### Spawning a neuron's rewards -When a neuron's maturity has risen above a threshold, one can spawn a portion of the maturity. In a first step, this creates a new neuron in a special spawning state containing the spawned maturity. After 7 days, the maturity is replaced with newly minted ICP, taking some [maturity modulation function](https://wiki.internetcomputer.org/wiki/Maturity_modulation#:~:text=The%20maturity%20modulation%20function%20introduces,NNS%20neurons%20and%20SNS%20neurons.) into account. In the end, the new neuron will be dissolved and have these ICP as stake - which can then be disbursed to any account. -The new neuron can remain controlled by the same principal as the parent neuron, or be assigned to a new principal. - -The following command spawns a neuron. -``` -type Spawn = record { - percentage_to_spawn : opt nat32; - new_controller : opt principal; - nonce : opt nat64; -}; -``` -Specify by `percentage_to_spawn` the portion of the maturity that should be spawn into a neuron in percentage. This should be a value between 1 and 100 (inclusive). -If the spawned neurons should have a different controller than the parent neuron (from which you spawn the maturity), you can optionally define a different controlling principal by `new_controller`. Otherwise, the spawned neuron will have the same controller as the parent neuron. -Similarly to claiming a neuron (see above), you need to specify the new neuron's ledger address and choose a nonce for this in the last argument `nonce`. -Based on this nonce and the controlling principal, the neuron's address is uniquely defined (see section _Compute the neuron's address_). -If no nonce is provided, the governance canister chooses a random one. - -_Required permissions:_ -Only a neuron's controller can spawn maturity from a neuron. - -You can also use the [ICP Rosetta API](/docs/current/developer-docs/defi/rosetta/icp_rosetta/construction_api/staking/) for this workflow. - - - -### Disbursing / unstaking a neuron -When a neuron is dissolved, i.e., its dissolve delay is zero, the neuron's controlling principal can instruct it to _disburse_ the neuron’s stake. -This means that the staked ICP balance is transferred to a specified ledger account and is liquid again. -The following command can be used to disburse a neuron. -``` -type Disburse = record { - to_account : opt AccountIdentifier; - amount : opt Amount; -}; -``` -The command takes as argument the ledger account `to_account` to which the ICP tokens should be transferred to and the amount `amount` that should be disbursed. The latter allows to only disburse a portion of a neuron's stake. - -_Required permissions:_ -Only a neuron's controller can disburse a neuron. - ### Voting with a neuron A neuron represents a participant of the NNS DAO and can participate in governance. Concretely, a neuron can submit proposals or vote on them if its dissolve delay is at least 6 months. A neuron can either directly vote to adopt or reject a given proposal or it can _follow_ other neurons for certain decisions - which will automatically cast a ballot for the neuron if enough of the followees voted. **Vote directly** + To vote directly, first find out what proposals can be voted on and then find the ID of the proposal you want to vote on. The following are the relevant NNS governance API and record that can also be found in the candid file. ``` @@ -287,8 +318,6 @@ The `vote` represents if the neuron should adopt or reject the proposal. As can be found [here](https://github.com/dfinity/ic/blob/720c78843f20246bf4e5c15f703923bd316c19de/rs/nns/governance/proto/ic_nns_governance/pb/v1/governance.proto#L427), 1 corresponds to a yes-vote and hence to adopt the proposal and 2 corresponds to a no-vote and thus to reject the proposal. `proposal` is the proposal ID of the proposal that the neuron votes on. -You can also use the [ICP Rosetta API](/docs/current/developer-docs/defi/rosetta/icp_rosetta/construction_api/voting/) for this workflow. - **Set a neuron's following** In case that a neuron's owner lacks the time or expertise to vote on some proposals, a neuron can be configured to vote automatically by following other neurons on a topic-by-topic basis. @@ -296,7 +325,7 @@ For any valid topic, a list of followees can be specified, and the neuron will f There are two topics that are excluded from the catch-all: `Governance` and `SNS & Neuron's Fund`. :::info -It is important to understand that a neuron's vote is only cast if the majority of the followed neurons agree on a decision. Find [here](/docs/current/developer-docs/daos/nns/nns-app-quickstart#neuron-following) more information and examples regarding the following-rules. +It is important to understand that a neuron's vote is only cast if the majority of the followed neurons agree on a decision. [View more information](/docs/current/developer-docs/daos/nns/using-the-nns-dapp/nns-app-quickstart#neuron-following) and examples regarding the following rules. ::: @@ -315,14 +344,98 @@ The second argument `followees` defines a list of neuron IDs whose decision will _Required permissions:_ Voting and setting following can be done by a neuron's controller or a neuron's hot key. -You can also use the [ICP Rosetta API](/docs/current/developer-docs/defi/rosetta/icp_rosetta/construction_api/voting/) for this workflow. +### Handling a neuron's maturity +Recall from the [neuron overview](/docs/current/developer-docs/daos/nns/concepts/neurons/neuron-overview) that when a neuron votes it gets rewards in the form of maturity. +The maturity can either be unstaked, meaning that it can be spawned and converted into ICP at any point, or it can be staked, +meaning that it is viewed as part of the neuron's stake and contributes to the voting power, but it is locked until the neuron is dissolved. + +#### Spawn a neuron + +When a neuron's maturity has risen above a threshold, one can spawn a portion of the maturity. In a first step, this creates a new neuron in a special spawning state containing the spawned maturity. After 7 days, the maturity is replaced with newly minted ICP, taking some [maturity modulation function](https://wiki.internetcomputer.org/wiki/Maturity_modulation#:~:text=The%20maturity%20modulation%20function%20introduces,NNS%20neurons%20and%20SNS%20neurons.) into account. In the end, the new neuron will be dissolved and have these ICP as stake, which can then be disbursed to any account. +The new neuron can remain controlled by the same principal as the parent neuron, or be assigned to a new principal. + +The following command spawns a neuron: +``` +type Spawn = record { + percentage_to_spawn : opt nat32; + new_controller : opt principal; + nonce : opt nat64; +}; +``` +Specify by `percentage_to_spawn` the portion of the maturity that should be spawn into a neuron in percentage. This should be a value between 1 and 100 (inclusive). +If the spawned neurons should have a different controller than the parent neuron (from which you spawn the maturity), you can optionally define a different controlling principal by `new_controller`. Otherwise, the spawned neuron will have the same controller as the parent neuron. +Similarly to claiming a neuron (see above), you need to specify the new neuron's ledger address and choose a nonce for this in the last argument `nonce`. +Based on this nonce and the controlling principal, the neuron's address is uniquely defined (see section _Compute the neuron's address_). +If no nonce is provided, the governance canister chooses a random one. + +_Required permissions:_ +Only a neuron's controller can spawn maturity from a neuron. + +#### Merge maturity + +This method allows a neuron controller to merge the (unstaked) maturity of a neuron into the neuron's stake. +The caller can choose a percentage of maturity to merge. + +``` +type MergeMaturity = record { + percentage_to_merge : nat32 +}; +``` + +_Required permissions:_ +Only a neuron's controller can merge maturity. + +#### Stake maturity + +This method allows a neuron controller to stake some of the currently existing (unstaked) maturity of a neuron, moving some of it to the staked maturity. The caller can choose a percentage of maturity to merge. +``` +type StakeMaturity = record { + percentage_to_stake : opt nat32 +}; +``` +_Required permissions:_ +Only a neuron's controller can stake maturity. + +#### Change auto-stake maturity + +This method allows a neuron controller to change the auto-stake maturity setting for a neuron. +``` +type ChangeAutoStakeMaturity = record { + requested_setting_for_auto_stake_maturity : bool; +}; +``` +The input provides the boolean value to which the auto-stake flag will be set to. +If set to `true`, auto-stake maturity causes all the maturity generated by voting rewards to be automatically moved to staked maturity. + +_Required permissions:_ +Only a neuron's controller can change the auto-stake settings. + +### Disbursing / unstaking a neuron +When a neuron is dissolved, i.e., its dissolve delay is zero, the neuron's controlling principal can instruct it to _disburse_ the neuron’s stake. This means that the staked ICP balance is transferred to a specified ledger account and is liquid again. + +The following command can be used to disburse a neuron: + +``` +type Disburse = record { + to_account : opt AccountIdentifier; + amount : opt Amount; +}; +``` +The command takes as argument for the ledger account `to_account` to which the ICP tokens should be transferred to and the amount `amount` that should be disbursed. The latter allows only a portion of a neuron's stake to be disbursed. + +_Required permissions:_ +Only a neuron's controller can disburse a neuron. +### Splitting and merging neurons +If you have multiple neurons, you can split and merge them for reorganization. + +#### Split a neuron -### Splitting a neuron A neuron can be split in two neurons, for example to set different dissolve delays. A user can choose how much of the neuron's stake should be split into a new neuron. -The new neuron will inherit the parent neuron's hot keys and followees. -Note that the maturity is not affected and the new neuron will start with no maturity. +The staked and unstaked maturity also split proportionally. +The new neuron will inherit the parent neuron's settings, such as the hotkeys and followees. + ``` type Split = record { @@ -334,3 +447,22 @@ new neuron. _Required permissions:_ Only a neuron's controller can split a neuron. + +#### Merge two neurons + +If you have two neurons, you can merge one, called the source neuron, into another, called the target neuron. + +The source neuron's stake, maturity, and age are moved into the target. Any fees for the source neuron are burned before the transfer occurs. The dissolve delay of the target neuron is the greater of the dissolve delay of the two, while the source remains unchanged. + +Two neurons can only be merged if they are both non-dissolving. If you wish to merge other neurons, you can first use `stop_dissolving`, increase their dissolve delay, and then merge them. + +The neuron for which you make this call is the target neuron and you provide the source neuron as an argument of your call. + +``` +type Merge = record { + source_neuron_id : opt NeuronId +}; +``` + +_Required permissions:_ +Only a neuron's controller can split a neuron. \ No newline at end of file diff --git a/docs/developer-docs/daos/nns/concepts/neurons/neuron-overview.mdx b/docs/developer-docs/daos/nns/concepts/neurons/neuron-overview.mdx new file mode 100644 index 0000000000..1d7c52d6b8 --- /dev/null +++ b/docs/developer-docs/daos/nns/concepts/neurons/neuron-overview.mdx @@ -0,0 +1,86 @@ +--- +keywords: [beginner, governance, concept, overview, nns, neurons, neuron overview, what is a neuron] +--- + +import { MarkdownChipRow } from "/src/components/Chip/MarkdownChipRow"; + +# What is a neuron? + + + +In order to participate in the network's governance and receive voting rewards, ICP tokens must first +be staked in a **neuron**. + +Neurons represent governance participants. Each neuron has its own identifier and +several attributes. + +Once a neuron is locked for more than six months, it gains the ability +both to submit proposals and to vote on them. Voting in turn generates +voting rewards, based on how active a neuron is in voting on proposals. +If you vote on every open proposal, you gain the maximum reward. + +A neuron can also **follow** other neurons, which causes it to +automatically vote the same way as the majority of the neurons that it +follows. + +## Why staking matters + +Staking is a way of allowing those who support the Internet Computer to +decide what happens next with the network. + +It is possible for proposals to pass with only a +majority among 3% of the total voting power, meaning that proposals +stand a chance even if large entities abstain and the majority of the +network does not vote. + + +## Key concepts + +It is important to understand a few key concepts of a neuron. +Every user can stake ICP utility tokens into a neuron and participate in the NNS DAO. + +### Neuron ID and account +Each neuron has a **neuron ID**, which is an identity selected by the NNS when the neuron is created. +In addition, each neuron has an associated **account** on the ICP ledger where the locked ICP balance resides. This account is owned by the NNS governance canister, and therefore a user cannot move staked tokens. + +### Neuron permissions +The **controller** is a principal that controls the neuron and which cannot be changed. A principal corresponds to the public key of a public-private key pair, and anyone with possession of the corresponding private key will have full control of the neuron. Therefore, the private key of the controller principal should be kept very secure. A principal can control many neurons. + +In addition to the controller, a neuron can have **hotkeys**. Hotkeys are defined by a list of principal ID and can be used to perform actions with limited privileges, namely voting, following (see below), and reading the full information about the neuron. + +### Voting power +The NNS is a stake-based governance system, so the main factor for how much **voting power** a neuron has is its stake. In addition, the voting power depends on two more factors. + +* **Dissolve delay & dissolve state**: The tokens in a neuron are locked for a specified duration called the **dissolve delay**. This can be thought of like a kitchen timer that can only be turned in one direction. It can be arbitrarily increased, but only reduced by turning on the countdown and waiting for the time to pass. A neuron must have a dissolve delay of at least 6 months to be eligible to vote. + * A neuron can be _non-dissolving_ which means that the timer is stopped and the neuron's dissolve delay remains the same. + * A neuron can be _dissolving_ which means that the timer is decreasing the neuron's dissolve delay as time passes. + * Once the timer has counted down, a neuron is _dissolved_ and the ICP tokens can be unstaked again. This is called **disbursing** a neuron. +* **Age**: Every non-dissolving neuron has an age, which denotes how long it has been in the non-dissolving state. + +The main idea is that a neuron who has tokens locked for longer or has been around for longer has more voting power as it is more committed to the long term interest of the Internet Computer. + +Based on these factors, a neuron's voting power can be determined: +* Principally, by its stake. 1 ICP = the power of 1 vote. +* Next, by its dissolve delay. 6 months grants a 1.06x voting power bonus, and 8 years grants 2x. All other durations scale linearly between. +* Lastly, by its age. 4 years grants a 1.25x bonus, multiplicative with any other bonuses. All other durations between 0 seconds and 4 years scale linearly between. + +This means that the maximum voting power of 2.5 votes per ICP staked is only achievable by locking up your neuron for 8 years, and leaving it in that locked up state for 4 years. At that time, you will have the most +voting power for the stake committed. + +To better understand how these factors influence a neuron's voting power and rewards over time, you can simulate some behaviors with the [NNS neuron sandbox](https://klgza-cqaaa-aaaak-qcz5a-cai.icp0.io/). + +### Maturity +When neurons vote, directly or through following, the **maturity** of a neuron increases as it collects voting rewards. +Each day the network rewards participants by allocating to every voting neuron a portion of the total reward, based both on its voting power at the time proposals were made, and the number of proposals it voted on. +There are different things that a neuron holder can do with maturity: +* Maturity can be liquidated by **spawning**. This is a process that can be started at any time and will then take seven days. In the end, a **maturity modulation** is applied and new ICP tokens are minted that can be freely used. +* Maturity can be staked into **staked maturity** into the neuron. Staked maturity is viewed as part of the neuron's stake and contributes to the neuron's voting power. But, similarly to the neuron's stake, it is also locked until the neuron is dissolved. When a neuron dissolves, its staked maturity is converted back to normal un-staked maturity. +* Maturity can be **auto-staked**. In order to not have to regularly perform the previous action, a neuron can also choose to auto-stake its maturity. This means that all new maturity will automatically be added to the staked maturity. + +For more details on voting rewards and spawn maturity, refer to [voting rewards](/docs/current/developer-docs/daos/nns/concepts/neurons/staking-voting-rewards). + +### Neuron visibility +A neuron can be **public** or **private**. +If a neuron is private, only its controller and the hotkeys can read the full neuron. Other parties cannot access all the information about the neuron. +In particular, they cannot access the neuron's ballot. If a neuron is public, anyone can read the full neuron. +All [known neurons](/docs/current/developer-docs/daos/nns/concepts/neurons/becoming-a-known-neuron) are public. diff --git a/docs/developer-docs/daos/nns/staking-voting-rewards.mdx b/docs/developer-docs/daos/nns/concepts/neurons/staking-voting-rewards.mdx similarity index 53% rename from docs/developer-docs/daos/nns/staking-voting-rewards.mdx rename to docs/developer-docs/daos/nns/concepts/neurons/staking-voting-rewards.mdx index af4bf19271..b5fb91194e 100644 --- a/docs/developer-docs/daos/nns/staking-voting-rewards.mdx +++ b/docs/developer-docs/daos/nns/concepts/neurons/staking-voting-rewards.mdx @@ -1,80 +1,20 @@ --- -keywords: [beginner, governance, concept, nns] +keywords: [intermediate, governance, concept, nns, voting, voting rewards, rewards] --- import { MarkdownChipRow } from "/src/components/Chip/MarkdownChipRow"; -# Staking and voting rewards +# Rewards and maturity - + ## Overview -Stakeholders gain voting power and can earn voting rewards by staking their ICP tokens. +Stakeholders gain voting power and can earn voting rewards by staking their ICP tokens in neurons and participating in governance. -The Internet Computer is a decentralized computer whose evolution is decided by its stakeholders through voting. This means decision impacting the future of the Internet Computer are made by people vested in the outcome. In return for participation in governance, the Internet Computer Procotol provides voting rewards. Voters can vote actively, or they can use a form liquid democracy to automatically follow other voters. - -## Key concepts - -### Neurons - -To become vested and obtain voting power, ICP tokens must first -be staked, and then locked up for a length of time greater than 6 -months to, at most, 8 years. - -Just as tokens are held in a user's account, stake is held in a special -account called a "neuron". Each neuron has its own identifier, and -several attributes relating to its stake. These include: - -* The length of time it is locked for (the "dissolve delay"). -* Whether it is currently dissolving. -* How much reward it has accrued as a result of voting on proposals (the "maturity"). - -Once a neuron is locked for more than six months, it gains the ability -both to submit proposals and to vote on them. Voting in turn generates -voting rewards, based on how active a neuron is in voting on proposals. -If you vote on every open proposal, you gain the maximum reward. - -A neuron can also "follow" other neurons, which causes it to -automatically vote the same as the majority of the neurons that it -follows. - -### Voting power - -The voting power of a locked neuron is determined by several factors: - -* Principally, by its stake. 1 ICP = the power of 1 vote. -* Next, by its lock up duration, or dissolve delay. 6 months grants a 1.06x voting power bonus, and 8 years grants 2x. All other durations scale linearly between. -* Lastly, by its age, or length of time spent locked up without dissolving. 4 years grants a 1.25x bonus, multiplicative with any other bonuses. All other durations between 0 seconds and 4 years scale linearly between. - -This means that the maximum voting power, of 2.5 votes per ICP staked, -is only achievable by locking up your neuron for 8 years, and leaving it -in that locked up state for 4 years. At that time you will have the most -voting power for the stake committed. - -### Maturity - -Maturity of a neuron increases as it collects voting rewards. Each day -the network rewards participants by allocating to every voting neuron a -portion of the total reward, based both on its voting power at the time -proposals were made, and the number of proposals it voted on. - -For those who wish to compound gained maturity in their neuron, the most -natural activity is to "stake maturity" on a regular basis. -If you wish to liquidate maturity gained, you can use it to produce liquid ICP. - -## Why staking matters - -Staking is a way of allowing those who support the Internet Computer to -decide what happens next with the platform. - -When the Internet Computer first launched, all proposals required a -majority vote to pass. Gradually, however, this is changing. After an -update it is now possible for proposals to pass with only a -majority among 3% of the total voting power, meaning that proposals -stand a chance even if large entities abstain and the majority of the -network does not vote. - -## Voting rewards +The Internet Computer is a decentralized platform whose evolution is decided by its stakeholders through voting. +This means decisions impacting the future of the Internet Computer are made by people vested in the outcome. +In return for participation in governance, ICP provides voting rewards. +Voters can vote actively, or they can use a form of liquid democracy to automatically follow other voters. Voting rewards are an important aspect of neurons and can be compounded to increase your total voting power. So to better understand staking and reward, it may be helpful to look at @@ -109,7 +49,7 @@ following factors: * Amount of ICP and maturity staked. * Length of dissolve delay. -* "Age" of the neuron (time spent in a non-dissolving state). +* Age of the neuron (time spent in a non-dissolving state). * Number of eligible proposals the neuron has voted on. These values are combined to calculate the total voting power of a neuron. It is computed as follows: @@ -151,7 +91,52 @@ If the five proposals the neuron voted on had a reward weight of two, it would have a `weight_of_proposal_votes = 5 * 2`, while the `weight_of_all_proposals = 5 * 2 + 5 * 1`, therefore it would receive `(5 * 2) / (5 * 1 + 5 * 2) = 66%` of the rewards for which it is eligible that day. -### Inflationary and deflationary mechanisms +## Spawning & maturity modulation +Voting rewards are collected by neurons in the form of maturity. +As explained in the [neuron overview](/docs/current/developer-docs/daos/nns/concepts/neurons/neuron-overview), maturity can then either be staked or spawned. + +### Background and goal +Maturity is an attribute of a neuron; it is not a tradable asset. The decentralized governance of the Internet Computer can change the treatment of maturity at any time. +To generate income from maturity, a user needs to trigger a non-deterministic process, which is burning maturity to create new ICP via spawning a neuron. +The maturity modulation function introduces uncertainty in the creation of tokens from maturity. + +### Spawning maturity via the maturity modulation function +The user triggers spawn maturity. A new neuron will be immediately spawned; however, this newly spawned neuron will have no ICP at start, only maturity. +Spawned neurons will have a dissolve delay of 7 days and will be set to dissolving at the time of spawning. After 7 days when the neuron is dissolved, the amount of ICP, modulated by the function introduced below, will be minted from the neuron's maturity and be available to the user. + +### Description of the maturity modulation function + +At the day of modulation, for each of the last 29 days, a 30-day moving average ICP/cycles conversion rate is determined, which is displayed on the Internet Computer dashboard. These are labeled `a1` through `a29`, where `a1` denotes the average rate on the previous day, `a2` denotes the rate 2 days ago and so on. The 30-day moving average conversion rates are used because they exhibit less variance than day-to-day conversion rates. + +Then, compute the relative 7-day return for each of the last 4 weeks. Thus: +* `w1 = (a1 - a8) / a8`, +* `w2 = (a8 - a15) / a15`, +* `w3 = (a15 - a22) / a22`, +* `w4 = (a22 - a29) / a29`. + +* The values w1, w2, w3, and w4 are bounded from -0.05 to 0.05 by clipping values to the limits of this range, i.e., capping by 0.05 and flooring by -0.05. +* Take the average `w = (w1 + w2 + w3 + w4) / 4`. +* The resulting value w is a number between -5% and 5% that determines modulation. +* The maturity amount x is converted to x * (1+w) units of ICP. + +The maturity modulation function is updated once a day. + +### Example +On Feb 1, 2022, the modulation function is 0.73% which is the average of the relative weekly returns w1 = -4.59%, w2 =-0.63%, w3=5.00%, w4 = 3.13%. +If a user disburses on that day (day of transfer) 100 maturity, then this will result in 100.73 ICP. + +### Motivation and Analysis + +Evidently, this process introduces a certain amount of uncertainty for the conversion from maturity to ICP. However this uncertainty is limited in two ways: +* The modulation value w is between -5% and +5%: This implies that, e.g., 100 maturity will be converted into an ICP amount in the range of 95 and 105. This kind of volatility is well in the range of daily conversion rate fluctuations of ICP. +* The modulation value w is calculated at the day of modulation as `w = (w1+ w2+ w3 + w4) / 4`. At the day of initiation (7 days prior), the user can already determine `(w2+ w3 + w4)/4`. The missing value w1 can affect the modulation value at most by 1.25% (5%/4) up or down. + +The modulation value can change by at most 2.5% from one week to the next, as one week drops out of the window and +one week enters the calculation window. + +The modulation function gives an incentive for users to disburse maturity when the ICP/Cycles conversion rate has been increasing over time and to hold back when the ICP has been decreasing recently. For example if the ICP/Cycles conversion rate was monotonically increasing, then w1, w2, w3, w4 are positive and thus also w, incentivizing users to convert a maturity amount x to x * (1+w) units of ICP. + +## Inflationary and deflationary mechanisms Deflationary mechanisms: diff --git a/docs/developer-docs/daos/nns/concepts/proposal-requirements.mdx b/docs/developer-docs/daos/nns/concepts/proposal-requirements.mdx new file mode 100644 index 0000000000..0b0e27c337 --- /dev/null +++ b/docs/developer-docs/daos/nns/concepts/proposal-requirements.mdx @@ -0,0 +1,35 @@ +--- +keywords: [intermediate, governance, concept, nns] +--- + +import { MarkdownChipRow } from "/src/components/Chip/MarkdownChipRow"; + +# Neuron and proposal details + + + +## ICP tokens +ICP are native utility tokens that play three key roles in the network: + +* **Facilitating network governance**: ICP tokens can be locked to create neurons that participate in network governance by voting, through which they can earn economic rewards. + +* **Production of cycles for compute**: ICP provides a source store of value that can be converted into “cycles,” which power computation in the role of fuel that is burned when it is used. The NNS converts ICP to cycles at a variable rate, so chosen to ensure users of the network can always create new cycles at approximately constant cost concerning IMF SDR, such that the cost of acquiring fuel is predictable. + +* **Rewarding participants**: The network provides rewards to incentivize those playing important roles that enable the network to function, including a) the provision of “voting rewards” to those participating in governance, and b) the provision of “node provider rewards” to those operating the node machines that are hosting the network. + +## Ledger +The ICP ledger is hosted within the NNS and records all balances of ICP in the manner similar to a spreadsheet. Each row is called an “account,” which has two fields (i.e., there are two “columns”): + +* **Account identifier (bytes)**: A unique value that is derived from the identity of the “principal” that “controls” the account. Currently, the principal must either be (i) the owner of a public key pair, or (ii) a canister smart contract that is part of the NNS. Account identifiers are derived by hashing the concatenation of a domain separator, the principal ID, and the subaccount (or zeros if no subaccount is given). + +* **Balance**: The quantity of ICP assigned to the account. + +When the principal is a public key or Canister, they can apply the following operation to an account: + +* **Send**: Transfer a portion of the ICP balance to another account. If all the ICP is sent to another account, then the transfering account ceases to exist (i.e., is deleted from the ledger). + +Operations that require interaction between the ledger and the governance system (Neurons): + +* **Create neuron**: When the principal is a public key holder, they may lock a portion of their balance inside a new neuron. Technically, creating the neuron is done in two stages. First, transfer the ICP to be staked to an account of the governance canister (which corresponds to a new neuron — the details of the association are omitted here). Then notify the governance canister of the incoming transfer which updates its internal neuron bookkeeping. To move these ICP to a different account, such as back to the original account, where they can once again be controlled like a normal balance, the associated neuron must be fully dissolved and disbursed (destroyed). + +* **Refresh stake**: The stake of a neuron may be increased by transferring to its address/account in the ledger and notifying the governance canister of the incoming transfer. Refreshing the stake will change the maturity and age of the neuron prorated. For example, if the stake is doubled, the maturity and age will be halved, so spawning will yield the same amount and the age bonus will be the same as before (in absolute terms). diff --git a/docs/developer-docs/daos/nns/concepts/proposals/direct-voting.mdx b/docs/developer-docs/daos/nns/concepts/proposals/direct-voting.mdx new file mode 100644 index 0000000000..f38809424b --- /dev/null +++ b/docs/developer-docs/daos/nns/concepts/proposals/direct-voting.mdx @@ -0,0 +1,28 @@ +--- +keywords: [beginner, governance, concept, nns, voting, proposal voting] +--- + +import { MarkdownChipRow } from "/src/components/Chip/MarkdownChipRow"; +import '/src/components/CenterImages/center.scss'; + +# Voting + + + +## Overview +The NNS DAO is an open governance system where anyone can become a participant by [staking some ICP in a neuron](https://internetcomputer.org/docs/current/developer-docs/daos/nns/using-the-nns-dapp/nns-app-quickstart#stake-icp-utility-tokens-in-a-neuron). At least 1 ICP is required to create a neuron. + +Locking tokens for a period of time is known as the neuron's dissolve delay. If a neuron has more than 6 months dissolve delay, it is eligible to participate in voting. This means that it can both submit and vote on proposals. + + +## Finding proposals and discussions + +You can see all the NNS proposals on the [Internet Computer dashboard](https://dashboard.internetcomputer.org/governance) or on the [NNS dapp](https://nns.ic0.app/). Voters can freely discuss proposals anywhere they like. Many NNS proposals are discussed on the [developer forum](https://forum.dfinity.org/c/roadmap/29). + +## Direct voting +When a user has an eligible neuron and would like to vote on an open proposal, one option is to directly vote to adopt or reject the proposal. +Currently, the most user-friendly way to first find and [vote on open proposals](/docs/current/developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-voting-on-proposals) is via the + NNS dapp: https://nns.ic0.app/. + +For more information how a user can set up their neuron to delegate its voting power using liquid democracy, refer to +[following](/docs/current/developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-following-other-neurons). diff --git a/docs/developer-docs/daos/nns/concepts/proposals/proposal-overview.mdx b/docs/developer-docs/daos/nns/concepts/proposals/proposal-overview.mdx new file mode 100644 index 0000000000..8cf170b7ea --- /dev/null +++ b/docs/developer-docs/daos/nns/concepts/proposals/proposal-overview.mdx @@ -0,0 +1,80 @@ +--- +keywords: [intermediate, governance, concept, nns, proposals, nns proposals] +--- + +import { MarkdownChipRow } from "/src/components/Chip/MarkdownChipRow"; + +# Proposal lifecycle + + + +A proposal is a suggestion to evolve and update the Internet Computer protocol. NNS DAO participants can submit proposals, make suggestions on how the ICP should evolve, and vote on proposals that others have submitted. + +Based on the majority decision, a proposal is either adopted or rejected. If a proposal is adopted, it is automatically executed fully on-chain, without the need for manual intervention. + +While other blockchains take weeks or months to upgrade and typically require substantial manual work and coordination to do so, ICP upgrades itself every week (https://dashboard.internetcomputer.org/releases). Its ability to upgrade and iterate is a comparative "superpower." + + +## Proposal lifecycle + +A proposal's lifecycle starts when it is submitted by a governance participants. Then, other governance participants form a decision and vote on the proposal. Based on these votes, the governance canister derives a proposal decision, i.e., the proposal is either adopted or rejected. + +If the proposal is rejected, usually nothing happens. If the proposal is adopted, the agreed upon decision is automatically executed by the governance canister. + +### Proposal submission + +Any eligible neuron can make and submit a proposal. To avoid being inundated by useless proposals, a user submitting a proposal has to pay a fee of 10 ICP when submitting a proposal that they will receive back if the proposal is adopted, but not if the proposal is rejected. + +After a proposal is submitted, the proposal is created and stored in the governance canister. The governance canister computes and stores additional information with each proposal. + +Then, the governance canister looks at all neurons and creates an empty ballot for each eligible neuron that has a +dissolve delay of at least 6 months, storing the neuron's voting power in this moment. This means that at the time of the proposal's submission, a neuron snapshot is taken and all neurons can vote on the proposal with the voting power that they have at that moment. + +:::info +This results in the following, potentially unintuitive cases: +* If a neuron is created after a proposal was submitted, it is not eligible to vote on this proposal. +* If a neuron had a dissolve delay of less than 6 months when a proposal was submitted, it cannot vote on the proposal, even if the neuron's dissolve delay is increased again. +* If a neuron had a dissolve delay of 6 months when a proposal was submitted, it can vote on the proposal during the full voting period, even if by the time of voting the neuron's dissolve delay decreased slightly below 6 months. + +::: + +The sum of all of the neurons' voting powers determines the total voting power associated with a given proposal. In +addition to creating all ballots, when a new proposal is created, the proposer's ballot is set to a “Yes” vote. This reflects that the proposal already has the support of the user submitting it. + +Moreover, each proposal has an associated **voting period**, which determines the period of time over which votes for this proposal are accepted. + +For more information on how to submit a proposal, refer to [How to submit a proposal](/docs/current/developer-docs/daos/nns/concepts/proposals/proposal-submit). + +### Proposal decision +After a proposal is submitted and added to the governance canister, other users who control neurons can [vote on the +proposal](/docs/current/developer-docs/daos/nns/concepts/proposals/direct-voting). The governance canister stores a +neuron's choice in the empty ballot where the neuron's voting power has been recorded. In this way, the proposal always contains the information of the total voting power of "Yes" and "No" votes. + +A proposal can be decided in two ways: + +1. **Absolute majority before the voting period ends**: At any point, even before the voting period ends, if an absolute majority (more than half of the total voting power stored in the proposal) has voted "Yes", then the proposal is adopted, and if an absolute majority has voted "No", then the proposal is rejected. +2. **Simple majority at the voting period’s end**: When the voting period ends, if a simple majority (more than half of the cast votes) has voted "Yes" and the number of these "Yes"-votes constitute at least 3% of the total voting power, then the proposal is adopted. Otherwise, the proposal is rejected. + +### Wait-for-quiet +What also plays into this is an algorithm called **wait-for-quiet** that dynamically adjusts the deadline. The idea +of wait-for-quiet is to decide proposals quickly when all voters agree, but increase the time that neurons can vote +for proposals that are controversial. That means that the voting period can be dynamically increased, depending on the neurons’ votes. In particular, each time a proposal’s outcome is turned (either a "Yes"-majority is turned to a "No"-majority or vice versa), the proposal’s deadline is increased. Currently, a proposal's initial voting period is 4 days and can be increased by at most another 4 days. That is, the voting period that is taken into account for the above rules can be between 4 and 8 days, depending on the voting activity. + +### Proposal execution +Technically, a proposal defines a method on a canister that will be called if the proposal is adopted with [some parameters](./proposal-submit.mdx). + +When a proposal is adopted, the defined method on the specified canister is automatically called with the given parameters. This is done automatically by the governance canister and does not require any manual intervention. +A proposal's execution may be successful, in which case the proposal is labeled as `executed`, or it may fail, in which case the proposal is labeled as `failed`. + +When a proposal is rejected, most of the time nothing happens. In very few cases, some cleanup work is initiated. +Therefore, `rejected` is also a possible final proposal state. + +:::info +A proposal is adopted or rejected as soon as a decision can be made, which might be before the voting deadline. +To ensure that neurons can still take their time to vote and get rewards, neurons that vote after the proposals' decision but before the voting period's deadline still get rewards. +See [staking and voting rewards](../neurons/staking-voting-rewards.mdx) for more information on rewards. +::: + +### Reward distribution +After a proposal is in a final state of either executed, failed, or rejected, the governance canister will take it into account for the next reward round. +After the rewards are distributed, a proposal has been through the full lifecycle. The proposal's details may be emptied by the governance canister to save space. \ No newline at end of file diff --git a/docs/developer-docs/daos/nns/concepts/proposals/proposal-submit.mdx b/docs/developer-docs/daos/nns/concepts/proposals/proposal-submit.mdx new file mode 100644 index 0000000000..22798c4836 --- /dev/null +++ b/docs/developer-docs/daos/nns/concepts/proposals/proposal-submit.mdx @@ -0,0 +1,255 @@ +--- +keywords: [advanced, governance, concept, nns, proposals, submitting proposals, submit proposal] +--- + +import { MarkdownChipRow } from "/src/components/Chip/MarkdownChipRow"; + +# Submitting + + + +To submit a proposal, it is recommended to use a neuron that can be controlled with a command line tool. +This guide will show how this can be done using an example of a motion proposal. +You can find another example for how to submit a proposal on [registering a known neuron] +(/docs/current/developer-docs/daos/nns/concepts/neurons/becoming-a-known-neuron). + + +## How to submit a motion proposal +This section explains one way to submit NNS motion proposals by using a few command line tools and a self-custody neuron. + +### Background +To properly follow what is going on, there are a few high-level points worth highlighting: + +#### Only Neurons can submit NNS proposals + +Neurons with at least 10 ICP and 6 months of dissolve delay can submit NNS proposals. Therefore, the first step is to create such a neuron. + +#### The NNS governance canister accepts motion proposals + +The governance canister is a canister like any other, so it has a Candid file, it accepts messages, etc. This article describes a way where you can have your local computer send a message to the governance canister (signed on behalf of a neuron) that contains a motion proposal. + +### One-time setup +#### Install `dfx` + +* `dfx` is a command line tool that will be used to send messages from your machine to the NNS. +[Install `dfx`](https://internetcomputer.org/docs/current/developer-docs/getting-started/install/). +``` +$ dfx [OPTIONS] +``` + +#### Install `quill` + +* `quill` is a minimalist "governance toolkit". It is wrapper for crafting & sending messages to the NNS and manage one's neuron. [Install quill](https://github.com/dfinity/quill). + +This article will assume that you execute `quill` on your local machine by running: +``` +quill [OPTIONS] +``` + +#### Create a neuron via command line tools + +#### Create a `private.pem` (private/public keypair) and Ledger `account id`. + +Before you start, you need a private/public keypair. + +``` +quill generate --seed-file seed.txt --pem-file private.pem +``` + +When returned, your `account id` should look something like this: +`612ec300g9ec990da900d6ec45919e7d5dbb9fa0dd8e69c54d374df93aa28d57`. + +#### Link this private/public keypair to `dfx` so you can use it as an identity. + +In this case, the new identity is called "proposals". + +``` +dfx identity import proposals private.pem +``` + +If you see the message “creating identity: proposals” in the terminal, this means it worked. + +[Learn more about dfx identities](https://smartcontracts.org/docs/developers-guide/cli-reference/dfx-identity.html dfx identity). + +#### Send ICP to the previously created `account id`. + +You should send at least 10.001 in order to have enough ICP to create a neuron and pay for the ledger transaction fees. + +To send ICP to the account, all you need is to input the `account id` in your wallet of choice. + +#### Stake a neuron + +To stake a neuron using quill, run the following command: + +``` +// Craft a message to stake a neuron by choosing a 8-character $NAME and an $AMOUNT to stake +// Note: you need to stake at LEAST 10 ICP to send proposals as $AMOUNT +quill --pem-file private.pem neuron-stake --name $NAME --amount $AMOUNT > message.json + +// Send the message crafted above. +quill send message.json +``` + +You should see a message with a neuron ID staked. If successful, response will return `neuron ID: +9_218_890_096_040_352_708`. This means the neuron ID is `9218890096040352708`. + +#### Increase neuron dissolve to at least 6 months + +Time is measured in seconds on the NNS. One year in seconds equals 31557600 seconds. + +``` +// Craft message to increase dissolve delay of neuron to 1 year +quill --pem-file private.pem neuron-manage 9218890096040352708 --additional-dissolve-delay-seconds 31557600 > message.json + +//send message created above to the NNS +quill send message.json +``` + +### How to send a proposal + +This sections shows how to create a [motion proposal](https://dashboard.internetcomputer.org/proposal/42626). + +#### Craft a proposal in markdown + +The IC dashboard and the NNS frontend dapp both render markdown of the `summary` field. It is recommended to use standard markdown for your motion proposal. + +Below is an example of using markdown for a NNS motion proposal: + +```md +## Objective + +Service nervous systems (SNSs) are algorithmic DAOs that allow developers to create decentralized, token-based governance systems for their dapps. The proposed governance canister design is similar to the governance canister of the Network Nervous System (NNS) but simpler and more flexible, allowing each SNS community to choose the configurations according to their needs. This design is also presented and discussed in this forum: https://forum.dfinity.org/t/open-governance-canister-for-sns-design-proposal/10224 . + +## Background + +### Relation to the original SNS design & overall approach +DFINITY Foundation presented a first proposed [SNS design](https://www.youtube.com/watch?v=L4443aaAP5A) in October 2021. + +## Community conversation & Timeline +The NNS team is ready to work on this feature! +To get the design approved by the community, the following schedule was followed: + +* Jan 11-18th: Design discussion on the forum thread +* Jan 18th: Community conversation about the topic +* Jan 20th: Developer discussion on Discord +* today: motion proposal submission proposing the above design + +## What is being asked of: + +* Vote accept or reject on NNS Motion +* Participate in technical discussions as the motion moves forward +``` + +#### Send proposal via dfx + +Below is an example structure of sending an NNS motion proposal with placeholders `$TITLE`, `$MOTION_TEXT`,`$SUMMARY`, and`$NEURON_ID`. These are not variables and you need to replace them with real values directly within the command: + +`rrkah-fqaaa-aaaaa-aaaaq-cai` is the ID of the governance canister on the NNS so this command is sending a message to the `manage_neuron` method of the governance canister of the NNS. + +``` +dfx --identity proposals canister --network ic call rrkah-fqaaa-aaaaa-aaaaq-cai manage_neuron '(record {id = null; command=opt variant {MakeProposal=record {url=""; title=opt "$TITLE";action=opt variant {Motion=record {motion_text="$MOTION_TEXT"}}; summary=" + +$SUMMARY + +"}}; neuron_id_or_subaccount=opt variant {NeuronId=record {id=$NEURON_ID:nat64}}})' +``` + +Below is an example NNS motion proposal with`$TITLE`,`$MOTION_TEXT`,`$SUMMARY`, and`$NEURON_ID` filled out: + +``` +dfx --identity proposals canister --network ic call rrkah-fqaaa-aaaaa-aaaaq-cai manage_neuron '(record {id = null; command=opt variant {MakeProposal=record {url=""; title="Open Governance canister for SNS | Design proposal";action=opt variant {Motion=record {motion_text="Present design proposal for Open Governance canister"}}; summary=" + +## Objective + +Service nervous systems (SNSs) are algorithmic DAOs that allow developers to create decentralized, token-based governance systems for their dapps. The proposed governance canister design is similar to the governance canister of the Network Nervous System (NNS) but simpler and more flexible, allowing each SNS community to choose the configurations according to their needs. This design is also presented and discussed in this forum: https://forum.dfinity.org/t/open-governance-canister-for-sns-design-proposal/10224 . + +## Background + +### Relation to the original SNS design & overall approach +DFINITY Foundation presented a first proposed [SNS design](https://www.youtube.com/watch?v=L4443aaAP5A) in October 2021. + +## Community conversation & Timeline +The NNS team is ready to work on this feature! +To get the design approved by the community, the following schedule was followed: + +* Jan 11-18th: Design discussion on the forum thread +* Jan 18th: Community conversation about the topic +* Jan 20th: Developer discussion on Discord +* today: motion proposal submission proposing the above design + +## What is asked of the community: + +* Vote accept or reject on NNS Motion +* Participate in technical discussions as the motion moves forward + +"}}; neuron_id_or_subaccount=opt variant {NeuronId=record {id=9218890096040352708:nat64}}})' +``` + +#### Check dashboard to see proposal was successful + +If successful, `dfx` will return an output such as: + +``` +( + record { + 2_171_433_291 = opt variant { + 3_217_030_240 = record { + 2_744_746_248 = opt record { 23_515 = 42_626 : nat64 }; + } + }; + }, +) +``` + +In this example, `42_626` (or rather `42626`) is the ID of the proposal. Your proposal will have a different ID. + +You will be able to see the proposal at the URL `https://dashboard.internetcomputer.org/proposal/42626`. + +### Best practices for motion proposals + +#### Writing the proposal + +The proposal can accept any free form text. Below is a recommended starting template for anyone starting to think about how to write one: + +``` +# Example Motion Project Proposal + +## 1. Objective +Lorem Ipsum + +## 2. Background +Lorem Ipsum + +## 3. Why this is important +Lorem Ipsum + +## 4. Pros +Lorem Ipsum + +## 5. Cons +Lorem Ipsum + +## 6. Key milestones (if any) +Lorem Ipsum + +## 7. Discussion leads (if any) +Alice, Bob, etc... + +## 8. Security concerns (if any) +Lorem Ipsum + +## 11. What is asked of the community + +* Review comments, ask questions, give feedback + +* Vote accept or reject on NNS Motion + +Developer forum: https://forum.dfinity.org/t/long-term-r-d-tokenomics-proposal/9392/3 +``` + +#### Communicating the proposal + +Once the proposal is live, it will be open to voting for 4 days, and if there is a lot of contesting of votes, that deadline will be automatically extended up to an additional 4 days. + +Proposals typically require significant communication and promotion (like in any organization) to make sure enough people vote for it. It is very common for proposals to be promoted 'before' submission so its intended voters are aware of it. + diff --git a/docs/developer-docs/daos/nns/proposal-advanced.mdx b/docs/developer-docs/daos/nns/concepts/proposals/proposal-topics.mdx similarity index 55% rename from docs/developer-docs/daos/nns/proposal-advanced.mdx rename to docs/developer-docs/daos/nns/concepts/proposals/proposal-topics.mdx index 8edc1b5a66..ebf1ac1496 100644 --- a/docs/developer-docs/daos/nns/proposal-advanced.mdx +++ b/docs/developer-docs/daos/nns/concepts/proposals/proposal-topics.mdx @@ -1,14 +1,16 @@ --- -keywords: [intermediate, governance, concept, nns] +keywords: [advanced, governance, concept, nns, voting, proposals, proposal details, details about proposals] --- import { MarkdownChipRow } from "/src/components/Chip/MarkdownChipRow"; +import '/src/components/CenterImages/center.scss'; -# Proposal format +# Proposal details - + -## Overview + +## Proposal fields Each proposal submitted to the NNS has the following fields: @@ -18,7 +20,7 @@ Each proposal submitted to the NNS has the following fields: * **Proposer**: The ID of the neuron that submitted the proposal. When a proposal is submitted, a “charge” is placed on its balance in case it is rejected. The balance needs to be enough to pay the charge on all rejection(s). The NNS requires a neuron to have a dissolve delay of ≥ 6 months to vote, which also applies to submitting proposals. -* **Proposal type**: The type of the proposal determines the function that will process the proposal if it is adopted, and the type and structure of the parameters that will be passed to that function. The type also infers what topic a proposal belongs to, which is used for [following](./proposal-voting). +* **Proposal type**: The type of the proposal determines the function that will process the proposal if it is adopted, and the type and structure of the parameters that will be passed to that function. The type also infers what topic a proposal belongs to, which is used for [following](./direct-voting). * **Parameters**: The parameters that will be passed to the system function and invoked if the proposal is adopted, as determined by its type. When a proposal is submitted, the NNS checks these parameters. @@ -27,141 +29,53 @@ The NNS assigns a unique identity to each proposal that it receives. ## Proposal topics and types Each proposal has a **proposal type**, which determines what happens if the proposal is adopted or rejected. This defines which canister method is invoked with which arguments. -Each type of proposal belongs to a specific **proposal topic**. Topics are used for [following](https://internetcomputer.org/docs/current/developer-docs/daos/nns/nns-app-quickstart#neuron-following) and also determine some other details about how the proposal is processed. -For example, the voting period and the voting reward weight are defined per topic. +Each type of proposal belongs to a specific **proposal topic**. Topics are used for [following] +(/docs/current/developer-docs/daos/nns/concepts/neurons/neuron-following) and also determine some other details about +how the proposal is processed. For example, the voting period and the voting reward weight are defined per topic. We present the proposals grouped by their topics, with the corresponding proposal types that they contain. +For more information on what to consider when verifying the different kinds of proposals, please refer to [verifying proposals](/docs/current/developer-docs/daos/nns/concepts/proposals/proposal-topics). -### Topic: `NetworkCanisterManagement` -Installing and upgrading [**system canisters**](/docs/current/developer-docs/smart-contracts/advanced-features/system-canisters/) that belong to the network. -This includes the NNS DAO canisters, the ICP ledger canister, and other canisters on the system subnets such as Internet Identity (II), ckBTC, ckETH, ckERC20, and the Wasm version of the [SNS canisters](https://internetcomputer.org/docs/current/developer-docs/daos/sns/overview#sns-canisters) (governance, root, ledger, swap). +### Topic: `ProtocolCanisterManagement` +All proposals to manage [protocol canisters](/docs/current/developer-docs/smart-contracts/advanced-features/system-canisters/), which are considered part of the Internet Computer protocol and are essential for its proper functioning. +This includes the NNS DAO canisters, such as NNS governance, NNS root, the registry canister, and the ICP ledger +canister. -* `NnsCanisterUpgrade`: A proposal to upgrade an existing system canister. This proposal type is executed by the root canister. Beyond upgrading the Wasm module of the target canister, the proposal can also set the authorization information and the allocations. -* `NnsCanisterInstall`: A proposal to add a new canister to be installed and executed on the NNS subnet. The root canister, which controls all canisters on the NNS except for itself, handles this proposal type. The call also expects the Wasm module that shall be installed. -* `NnsRootUpgrade`: A proposal to upgrade the root canister on the NNS subnet. The proposal is processed by the Lifeline canister, which controls the root canister. The proposal updates the Wasm module. +* `InstallCode`: Install, reinstall or upgrade the code of a canister that is controlled by the NNS. +* `UpdateCanisterSettings`: Update the settings of a canister that is controlled by the NNS. +* `StopOrStartCanister`: Stop or start a canister that is controlled by the NNS. * `HardResetNnsRootToVersion`: Uninstall and install root with the Wasm provided in the function. If `InitArgs` are provided, they will be passed to the `canister_init` function of the Wasm provided. This function is meant as a 'break glass' mechanism for when an open call context in the root canister is preventing root or another canisters from upgrading. -* `StopOrStartNnsCanister`: Stop or start an NNS canister. Usually this is done as part of a canister upgrade, but this proposal offers the flexibility to just start or stop a canister if needed. - -The following proposal types are specific for SNS canisters: - -* `AddSnsWasm`: Add a new SNS canister Wasm to SNS-W. All SNS DAOs can then upgrade to new versions along the upgrade path defined in [SNS-W](https://internetcomputer.org/docs/current/developer-docs/daos/sns/overview#SNS-W). -* `InsertSnsWasmUpgradePathEntries`: Insert custom upgrade path entries into SNS-W for all SNSes, or for an SNS specified by its governance canister ID. - -The following proposal type is specific for the Bitcoin canister: -* `BitcoinSetConfig`: A proposal to set the configuration of the underlying Bitcoin Canister that powers the Bitcoin API. The configuration includes whether or not the Bitcoin Canister should sync new blocks from the network, whether the API is enabled, the fees to charge, etc. - -#### How to verify NNS core canister upgrades -If you are looking to verify NNS core canister upgrades apart from regularly checking open proposals, you might want to consider the following information for proposals submitted by the DFINITY foundation: - -* For updates to the NNS canisters, you can follow [this repository](https://github.com/dfinity/ic). More specifically, the following sub-directories are relevant: - -- `rs/rosetta-api/icp_ledger/src` -- `rs/rosetta-api/ledger_core` -- `rs/rosetta-api/ledger_canister_core` -- `rs/packages/icrc-ledger_types` -- `rs/registry/canister` -- `rs/nns/governance` -- `rs/rosetta-api/ledger_canister/ledger`, -- `rs/rosetta-api/icp_ledger/archive` -- `rs/nns/handlers/root/impl` -- `rs/nns/cmc` -- `rs/nns/handlers/lifeline`, -- `rs/nns/gtc` -- `rs/nns/identity` -- `rs/nns/nns-ui` -- `rs/nns/sns-wasm` - -* NNS core canister upgrade proposals are announced in [this forum thread](https://forum.dfinity.org/t/nns-updates-aggregation-thread/23551). -* You can find the instructions on how to verify that the Wasm in the proposal was indeed build from the provided `git commit` in the proposal's section "Wasm Verification" (see [this example proposal](https://dashboard.internetcomputer.org/proposal/129394)). - -#### How to verify ICP ledger canister upgrades -If you are looking to verify the ICP ledger suite, apart from regularly checking open proposals, you might want to consider the following information for proposals submitted by the DFINITY foundation: - -* For updates to the NNS canisters, you can follow [this repository](https://github.com/dfinity/ic). - -More specifically, the following sub-directories are relevant: -- `rs/rosetta-api/icp_ledger` is the directory for the ICP ledger - -#### How to verify ledger upgrades for ckBTC, ckETH, and ckERC20 -If you are looking to verify the ledger suite for ckBTC, ckETH or ckERC20 apart from regularly checking open proposals, you might want to consider the following information for proposals submitted by the DFINITY foundation: - -* For updates to the NNS canisters, you can follow [this repository](https://github.com/dfinity/ic). - -More specifically, the following sub-directories are relevant: -- `rs/rosetta-api/icrc1/ledger` for the ckBTC, ckETH, and ckERC20 ledgers, where `rs/rosetta-api/icrc1/ledger:ledger_canister` is the Wasm relevant for the ckBTC ledger and `rs/rosetta-api/icrc1/ledger:ledger_canister_u256.wasm` the Wasm for the ckETH and ckERC20 ledgers. - -* You can find the instructions on how to verify that the Wasm in the proposal was indeed build from the provided `git commit` in the proposal. - -#### How to verify ledger suite orchestrator canister upgrades -If you are looking to verify the ledger suite orchestrator, which manages all ledger suites of all ckERC20 tokens (e.g., the orchestrator can upgrade managed canisters or add new ckERC20 tokens, see the [README](https://github.com/dfinity/ic/blob/master/rs/ethereum/ledger-suite-orchestrator/README.adoc) for more details), the following sub-directories in the [IC repository](https://github.com/dfinity/ic) are relevant: -- `rs/ethereum/ledger-suite-orchestrator` -* You can find the instructions on how to verify that the Wasm in the proposal was indeed built from the provided `git commit` in the proposal. -#### How to verify Internet Identity upgrades +### Topic: `ServiceNervousSystemManagement` +All proposals to manage the canisters of service nervous systems (SNS), including upgrading relevant canisters and managing SNS framework canister Wasms through SNS-W. -If you are looking to verify [Internet Identity (II)](/docs/current/developer-docs/identity/internet-identity/overview) canister upgrades apart from regularly checking open proposals, you might want to consider the following information for proposals submitted by the DFINITY foundation: - -* For updates to the II canister, you can find the code in [the II repository](https://github.com/dfinity/internet-identity). -* Each proposal points to the relevant commit that was used. -* You can find the instructions on how to verify that the Wasm in the proposal was indeed build from the provided `git commit` in the proposal itself (see for example the section "Wasm Verification" in [this example proposal](https://dashboard.internetcomputer.org/proposal/129486)) and in the [Github release pages](https://github.com/dfinity/internet-identity/releases). - -#### How to verify SNS canister Wasm upgrades - -If you are looking to verify SNS canister Wasm upgrades apart from regularly checking open proposals, you might want to consider the following information for proposals submitted by the DFINITY foundation: - -* You can find the code for the SNS governance, SNS root, and SNS swap in [the SNS repository](https://github.com/dfinity/ic/tree/master/rs/sns). -The SNS also uses the ICRC ledger suite, which you can find in [the Rosetta repository](https://github.com/dfinity/ic/tree/master/rs/rosetta-api/icrc1). -* SNS upgrade proposals are announced in [this forum thread](https://forum.dfinity.org/t/sns-upgrade-aggregation-thread/24259). -* You can find the instructions on how to verify that the Wasm in the proposal was indeed build from the provided `git commit` in the proposal's section "Wasm Verification" (see [this example proposal](https://dashboard.internetcomputer.org/proposal/129633)). +* `InstallCode`, `UpdateCanisterSettings`, and `StopOrStartCanister` are the same as in topic +`ProtocolCanisterManagement` only targeting different canisters. +* `AddSnsWasm`: Add a new SNS canister Wasm to SNS-W. All SNS DAOs can then upgrade to new versions along the upgrade path defined in [SNS-W](/docs/current/developer-docs/daos/sns/overview#SNS-W). +* `InsertSnsWasmUpgradePathEntries`: Insert custom upgrade path entries into SNS-W for all SNSes, or for an SNS specified by its governance canister ID. -**How to verify Bitcoin canister upgrades** -If you are looking to verify Bitcoin canister upgrades apart from regularly checking open proposals, you might want to consider the following information: +### Topic: `ApplicationCanisterManagement` +All proposals to manage NNS-controlled canisters not covered by other topics (Protocol Canister Management or Service Nervous System Management). -* You can find the code for the Bitcoin canister in [the `bitcoin-canister` repository](https://github.com/dfinity/bitcoin-canister). -* These proposals are not expected to happen frequently, but rather when there are important updates to be applied to the Bitcoin canister. You can expect that a new release will be cut in preparation of an upgrade in the above repository. See this [example release](https://github.com/dfinity/bitcoin-canister/releases/tag/release%2F2024-04-26). -* There are 2 Bitcoin canisters, one following the Bitcoin testnet and one following the Bitcoin mainnet network. The proposals will be specific to one of these canisters. Typically, you can expect that the proposal to upgrade the Bitcoin testnet canister happens 1 week before the one to upgrade the Bitcoin mainnet canister. -* You can find the instructions on how to verify that the Wasm in the proposal was indeed built from the provided `git commit` in the proposal's section "How can I verify the Wasm hash of this canister?" (see [this example proposal](https://dashboard.internetcomputer.org/proposal/129499)). +* `InstallCode`, `UpdateCanisterSettings`, and `StopOrStartCanister` are the same as in topics +`ProtocolCanisterManagement` and `ServiceNervousSystemManagement` only targeting different canisters. -For more information about the Bitcoin canister, you can read the [Bitcoin canister documentation](https://github.com/dfinity/bitcoin-canister/blob/master/README.md). +The following proposal type is specific for the Bitcoin canister: +* `BitcoinSetConfig`: A proposal to set the configuration of the underlying Bitcoin canister that powers the Bitcoin API. The configuration includes whether or not the Bitcoin canister should sync new blocks from the network, whether the API is enabled, the fees to charge, etc. ### Topic: `IcOsVersionElection` -To upgrade the ICP protocol, the NNS DAO first elects new IC OS versions (the software that is run by ICP nodes), then in a second step, selected nodes can be upgraded to the previously elected IC OS versions. -This proposal type is for the first part, i.e., to elect new versions. - -This topic contains the following proposal types: - -* `ReviseElectedGuestosVersions`: A proposal to change the set of elected GuestOS versions. The version to elect (identified by the hash of the installation image) is added to the registry. Besides creating a record for that version, the proposal also appends that version to the list of elected versions that can be installed on nodes of a subnet. Only elected GuestOS versions can be deployed. -* `ReviseElectedHostosVersions`: A proposal to change the set of currently elected HostOS versions by electing a new version, and/or un-electing some priorly elected versions. HostOS versions are identified by the hash of the installation image. The version to elect is added to the registry, and the versions to un-elect are removed from the registry, ensuring that HostOS cannot upgrade to these versions anymore. - -#### How to verify Ic OS Version Election proposals -To upgrade the ICP protocol, the NNS DAO first elects new IC OS versions (the software run by ICP nodes), pre-approves the deployment of the new IC-OS versions, and then upgrades selected parts of the IC to these versions. The `IcOsVersionElection` proposal topic addresses the first part: electing new IC-OS versions. - -The topic includes the following proposal types: - -* `ReviseElectedGuestosVersions`: Proposes changes to the list of elected GuestOS versions. The proposal adds the version to the registry, identified by the Git revision of the installation image, along with the URLs of the upgrade image and the SHA-256 checksum of the image. Only elected GuestOS versions can be deployed. -* `ReviseElectedHostosVersions`: Similar to the GuestOS version proposal, this proposes changes to the list of elected HostOS versions. +To upgrade the ICP protocol, the NNS DAO first elects new IC OS versions (the software that is run by ICP nodes), then in a second step, selected nodes can be upgraded to the previously elected IC OS versions. This proposal type is for the first part, i.e., to elect new versions. HostOS is the hypervisor OS running on the IC node machine. Its main responsibilities include initializing and configuring the node machine hardware and passing it through to the GuestOS. The GuestOS, a VM running on the HostOS, contains the critical parts of the IC Protocol code, including the IC Replica, which runs the IC Canisters smart contracts. -**How to verify IC operating system version election proposals** - -To verify IC OS version election proposals, besides regularly checking open proposals, consider the following information for proposals submitted by the DFINITY foundation: - -* Each proposal submitted by the DFINITY foundation has a corresponding post on the forum (see [example](https://forum.dfinity.org/t/proposal-to-elect-new-release-rc-2024-05-01-23-01/30247)). Relevant posts can be found under the `Governance` category with the tags `replica` and `release`. -* The relevant code is available in [this repository](https://github.com/dfinity/ic). -* To verify that the code in the proposal is built from the specified `git commit`, follow the instructions in the [README file of the IC repository](https://github.com/dfinity/ic#verifying-releases). -* Each proposal summary includes instructions for verifying the proposal payload. See this [example](https://dashboard.internetcomputer.org/proposal/130083). These steps are tested on Ubuntu 22.04, which is the recommended operating system for the verification process. +This topic contains the following proposal types: -``` -# From https://github.com/dfinity/ic#verifying-releases -sudo apt-get install -y curl && curl --proto '=https' --tlsv1.2 -sSLO https://raw.githubusercontent.com/dfinity/ic/ec35ebd252d4ffb151d2cfceba3a86c4fb87c6d6/gitlab-ci/tools/repro-check.sh && chmod +x repro-check.sh && ./repro-check.sh -c ec35ebd252d4ffb151d2cfceba3a86c4fb87c6d6 -``` +* `ReviseElectedGuestosVersions`: A proposal to change the set of elected GuestOS versions. The version to elect is +added to the registry, identified by the Git revision of the installation image, along with the URLs of the upgrade image and the SHA-256 checksum of the image. Besides creating a record for that version, the proposal also appends that version to the list of elected versions that can be installed on nodes of a subnet. Only elected GuestOS versions can be deployed. +* `ReviseElectedHostosVersions`: A proposal to change the set of currently elected HostOS versions by electing a new version, and/or un-electing some previously elected versions. HostOS versions are identified by the hash of the installation image. The version to elect is added to the registry, and the versions to un-elect are removed from the registry, ensuring that HostOS cannot upgrade to these versions anymore. -* The reproducibility check script is versioned, cryptographically checksummed, and open-sourced, ensuring it cannot change post-submission. The proposal summary is immutable after submission. The upgrade image contents are cryptographically checksummed, and the checksum is included in the proposal payload and verified during the upgrade process. -* For GuestOS, DFINITY aims for a weekly release cycle, resulting in approximately one proposal per week plus additional feature builds. -* For HostOS, there is no fixed release cycle, but an upgrade is typically proposed every 3-6 months. ### Topic: `IcOsVersionDeployment` @@ -174,6 +88,8 @@ This topic includes the following proposal types: * `DeployGuestosToSomeApiBoundaryNodes`: Update the GuestOS version on a set of API Boundary Nodes. * `DeployGuestosToAllUnassignedNodes`: Update the GuestOS version on all unassigned nodes. + + ### Topic: `Governance` The are less technical proposals that administer governance. In contrast to other topics, this topic has reward weight 20. This means that participation in this topic is rewarded more. @@ -186,7 +102,7 @@ This topic includes the following proposal types: ### Topic: `SnsAndCommunityFund` -This topic includes proposals that concern [SNS DAO launches](/docs/current/developer-docs/daos/sns/launching/) and the [Neurons' Fund](./neurons-fund.mdx) (formerly called Community Fund). +This topic includes proposals that concern [SNS DAO launches](/docs/current/developer-docs/daos/sns/launching/) and the [Neurons' Fund](/docs/current/developer-docs/daos/nns/concepts/neurons-fund) (formerly called Community Fund). In contrast to other topics, this topic has reward weight 20. This means that participation in this topic is rewarded more. @@ -211,7 +127,7 @@ The following parameters can be changed: - **Maximum node provider rewards**: The maximum rewards to be distributed to node providers in a single distribution event (proposal). - **Transaction fee**: The transaction fee that must be paid for each ledger transaction. - **Maximum number of proposals to keep per topic**: The maximum number of proposals to keep, per topic. When the total number of proposals for a given topic is greater than this number, the oldest proposals that have reached a “final” state may be deleted to save space. -- **Neurons' Fund economics**: This includes all parameters related to the [Neurons' Fund](./neurons-fund.mdx): +- **Neurons' Fund economics**: This includes all parameters related to the [Neurons' Fund](/docs/current/developer-docs/daos/nns/concepts/neurons-fund): - `max_theoretical_neurons_fund_participation_amount_xdr`: A theoretical limit which should be smaller than any realistic amount of maturity that practically needs to be reserved from the Neurons' Fund for a given SNS swap. - `neurons_fund_matched_funding_curve_coefficients`: Defines a threshold specifying the shape of the matching function used by the Neurons' Fund to determine how much to contribute for a given direct participation amount. - `minimum_icp_xdr_rate` and `maximum_icp_xdr_rate` are respectively the minimum and maximum value of the ICP/XDR conversion rate used by the Neurons' Fund for converting XDR values into ICP. diff --git a/docs/developer-docs/daos/nns/concepts/proposals/verify-proposals.mdx b/docs/developer-docs/daos/nns/concepts/proposals/verify-proposals.mdx new file mode 100644 index 0000000000..a0749a53bd --- /dev/null +++ b/docs/developer-docs/daos/nns/concepts/proposals/verify-proposals.mdx @@ -0,0 +1,182 @@ +--- +keywords: [advanced, governance, tutorial, nns, voting, proposals, verifying proposals] +--- + +import { MarkdownChipRow } from "/src/components/Chip/MarkdownChipRow"; +import '/src/components/CenterImages/center.scss'; + +# Verifying proposals + + + +The decentralized nature of the NNS is one of the key factors of the Internet Computer's security - it ensures that there is no single point of failure. +Therefore, it is important that proposals are verified by as many governance participants as possible. +Each neuron verifying a proposal can define their own criteria for when a proposal should be adopted or rejected. This provides inputs that can be considered in this process. + +The community is encouraged to discuss proposals and their verification on the [developer forum](https://forum.dfinity.org/), using the category `Governance` with sub-category `NNS proposal discussion` and using the proposal’s topic as a tag. + +## Verify protocol canister management proposals +If you are looking to verify [protocol canister management proposals](/docs/current/developer-docs/daos/nns/concepts/proposals/proposal-topics#Topic:-`ProtocolCanisterManagement`), you +can refer to this video that explains the process on the example of an NNS governance canister upgrade: + + + +Apart from regularly checking open proposals, the following sections list some relevant information for +proposals submitted by the DFINITY foundation. + +### NNS canister upgrades +* For updates to the NNS canisters, you can follow [the IC repository](https://github.com/dfinity/ic). More specifically, the following sub-directories are relevant: + + - `rs/rosetta-api/icp_ledger/src` + - `rs/rosetta-api/ledger_core` + - `rs/rosetta-api/ledger_canister_core` + - `rs/packages/icrc-ledger_types` + - `rs/registry/canister` + - `rs/nns/governance` + - `rs/rosetta-api/ledger_canister/ledger`, + - `rs/rosetta-api/icp_ledger/archive` + - `rs/nns/handlers/root/impl` + - `rs/nns/cmc` + - `rs/nns/handlers/lifeline`, + - `rs/nns/gtc` + - `rs/nns/identity` + - `rs/nns/nns-ui` + - `rs/nns/sns-wasm` + +* NNS core canister upgrade proposals are announced [on the developer forum](https://forum.dfinity.org/t/nns-updates-aggregation-thread/23551). +* You can find the instructions on how to verify that the Wasm in the proposal was indeed build from the provided `git commit` in the proposal's section "Wasm Verification" (see [this example proposal](https://dashboard.internetcomputer.org/proposal/129394)). + +### ICP ledger suite upgrades +* For updates on the ICP ledger suite, you can follow [the IC repository](https://github.com/dfinity/ic). More specifically, the following sub-directories are relevant: + - `rs/rosetta-api/icp_ledger` is the directory for the ICP ledger + + +## Verify IC OS version election proposals + +If you are looking to verify [IC OS version election proposals](/docs/current/developer-docs/daos/nns/concepts/proposals/proposal-topics#Topic:-`IcOsVersionElection`), you +can refer to this video: + + + +You can also consider the following information for proposals submitted by the DFINITY foundation: + +* Each proposal submitted by the DFINITY foundation has a corresponding post on the forum (see [example](https://forum.dfinity.org/t/proposal-to-elect-new-release-rc-2024-05-01-23-01/30247)). Relevant posts can be found under the `Governance` category with the tags `replica` and `release`. +* The relevant code is available in [the IC repository](https://github.com/dfinity/ic). +* To verify that the code in the proposal is built from the specified `git commit`, follow the instructions in the [README file of the IC repository](https://github.com/dfinity/ic#verifying-releases). +* Each proposal summary includes instructions for verifying the proposal payload. See this [example](https://dashboard.internetcomputer.org/proposal/130083). These steps are tested on Ubuntu 22.04, which is the recommended operating system for the verification process. + +``` +# From https://github.com/dfinity/ic#verifying-releases +sudo apt-get install -y curl && curl --proto '=https' --tlsv1.2 -sSLO https://raw.githubusercontent.com/dfinity/ic/ec35ebd252d4ffb151d2cfceba3a86c4fb87c6d6/gitlab-ci/tools/repro-check.sh && chmod +x repro-check.sh && ./repro-check.sh -c ec35ebd252d4ffb151d2cfceba3a86c4fb87c6d6 +``` + +* The reproducibility check script is versioned, cryptographically checksummed, and open-sourced, ensuring it cannot change post-submission. The proposal summary is immutable after submission. The upgrade image contents are cryptographically checksummed, and the checksum is included in the proposal payload and verified during the upgrade process. +* For GuestOS, DFINITY aims for a weekly release cycle, resulting in approximately one proposal per week plus additional feature builds. +* For HostOS, there is no fixed release cycle, but an upgrade is typically proposed every 3-6 months. + + +## Verify participant management proposals +If you are looking to verify [participant management proposals](/docs/current/developer-docs/daos/nns/concepts/proposals/proposal-topics#Topic:-`ParticipantManagement`), +these are some steps you can consider for verification. + +### Add or remove node providers + +For proposals that add or remove node providers, you can check that: +* There is a proper forum introduction by the new node provider. +* Self-declaration and identity documents have been uploaded on the wiki. +* Hashes of the self-declaration and identity document match the hashes in the proposal. +* If this is a new region or community, there is an entry in the public Chamber of Commerce register (if Chamber +of Commerce number is provided). + +### Add or remove data centers +For proposals that add or remove data centers, you can: + * Check who submitted the proposal. This is typically only a new node provider. + * Perform an Internet search to verify whether this is a legitimate data center. + +## Verify node admin proposals +If you are looking to verify [node admin proposals](/docs/current/developer-docs/daos/nns/concepts/proposals/proposal-topics#Topic:-`NodeAdmin`), +these are some steps you can consider for verification. + +### Update node configuration +In such a proposal, a node provider sets the number of nodes and the `node_type` (Gen1, Gen2). +You can: +* Check these against the originally approved node allowance (whether that allowance was approved, and whether it matches the IC target topology using the [GitHub tooling](https://github.com/StephanusFischer/decentralization) + +### Add node operator +This proposal sets the allowance for a particular node provider in a specific data center. +You can perform the following checks: +* If it matches the IC target topology using the [GitHub tooling](https://github.com/StephanusFischer/decentralization). For example, such proposals should be rejected if the target topology has been reached. +* Whether the node `provider-id` and `data center-id` match with the previously submitted add node provider and add data center proposals. + +### Remove nodes from the network +This is a proposal to remove (unhealthy) nodes from the network. +You can: +* Check whether the nodes are indeed unassigned and not in a particular subnet. + + +## Verify subnet management proposals +If you are looking to verify [subnet management proposals](/docs/current/developer-docs/daos/nns/concepts/proposals/proposal-topics#Topic:-`SubnetManagement`), these are some steps you can consider for verification. + +### Node replacement proposals +You can: +* Check whether the nodes are replaced because they are dead/unhealthy, or replaced for other good reasons. + +### Other proposals of this topic +You can: +* Check whether the reasoning in the proposal makes sense with regard to which proposals need to be adopted in which order. + +## Verify service nervous system management proposals +If you are looking to verify [service nervous system management proposals](/docs/current/developer-docs/daos/nns/concepts/proposals/proposal-topics#Topic:-`ServiceNervousSystemManagement`), +you can refer to this video that explains the process using an example of an NNS proposal that elects a new SNS +governance Wasm: + + + + +Apart from regularly checking open proposals, here some relevant information for proposals submitted by the DFINITY foundation. + +* You can find the code for the SNS governance, SNS root, and SNS swap in [the SNS repository](https://github.com/dfinity/ic/tree/master/rs/sns). +The SNS also uses the ICRC ledger suite, which you can find in [the Rosetta repository](https://github.com/dfinity/ic/tree/master/rs/rosetta-api/icrc1). +* SNS upgrade proposals are announced in [this forum thread](https://forum.dfinity.org/t/sns-upgrade-aggregation-thread/24259). +* You can find the instructions on how to verify that the Wasm in the proposal was indeed build from the provided `git commit` in the proposal's section "Wasm Verification" (see [this example proposal](https://dashboard.internetcomputer.org/proposal/129633)). + + +## Verify application canister management proposals +If you are looking to verify [application canister management proposals](/docs/current/developer-docs/daos/nns/concepts/proposals/proposal-topics#Topic:-`ApplicationCanisterManagement`), you can refer to this video that explains the process on the example of an NNS frontend dapp upgrade proposal: + + + +Apart from regularly checking open proposals, the following sections list some relevant information for proposals submitted by the DFINITY foundation. + +### NNS frontend dapp upgrades +* For updates to the NNS frontend dapp, you can follow [the NNS dapp repository](https://github.com/dfinity/nns-dapp). + +### Ledger upgrades for ckBTC, ckETH, and ckERC20 + +* For updates to the NNS canisters, you can follow [the IC repository](https://github.com/dfinity/ic). More specifically, the following sub-directories are relevant: + - `rs/rosetta-api/icrc1/ledger` for the ckBTC, ckETH, and ckERC20 ledgers, where `rs/rosetta-api/icrc1/ledger:ledger_canister` is the Wasm relevant for the ckBTC ledger and `rs/rosetta-api/icrc1/ledger:ledger_canister_u256.wasm` the Wasm for the ckETH and ckERC20 ledgers. + +* You can find the instructions on how to verify that the Wasm in the proposal was indeed build from the provided `git commit` in the proposal. + +### Ledger suite orchestrator canister upgrades +The ledger suite orchestrator manages all ledger suites of all ckERC20 tokens. The orchestrator can +upgrade managed canisters or add new ckERC20 tokens. See the [README](https://github.com/dfinity/ic/blob/master/rs/ethereum/ledger-suite-orchestrator/README.adoc) for more details. + +* The following sub-directories in the [IC repository](https://github.com/dfinity/ic) are relevant: + - `rs/ethereum/ledger-suite-orchestrator` + +* You can find the instructions on how to verify that the Wasm in the proposal was indeed built from the provided `git commit` in the proposal. + +### Internet Identity upgrades +* For updates to the [Internet Identity (II)](/docs/current/developer-docs/identity/internet-identity/overview) canister, you can find the code in [the II repository](https://github.com/dfinity/internet-identity). +* Each proposal points to the relevant commit that was used. +* You can find the instructions on how to verify that the Wasm in the proposal was indeed build from the provided `git commit` in the proposal itself (see for example the section "Wasm Verification" in [this example proposal](https://dashboard.internetcomputer.org/proposal/129486)) and in the [GitHub release pages](https://github.com/dfinity/internet-identity/releases). + + +### Bitcoin canister upgrades +Please refer to the [Bitcoin canister documentation](https://github.com/dfinity/bitcoin-canister/blob/master/README.md) for more information about the Bitcoin canister. + +* You can find the code for the Bitcoin canister in [the `bitcoin-canister` repository](https://github.com/dfinity/bitcoin-canister). +* These proposals are not expected to happen frequently, but rather when there are important updates to be applied to the Bitcoin canister. You can expect that a new release will be cut in preparation of an upgrade in the above repository. See this [example release](https://github.com/dfinity/bitcoin-canister/releases/tag/release%2F2024-04-26). +* There are 2 Bitcoin canisters, one following the Bitcoin testnet and one following the Bitcoin mainnet network. The proposals will be specific to one of these canisters. Typically, you can expect that the proposal to upgrade the Bitcoin testnet canister happens 1 week before the one to upgrade the Bitcoin mainnet canister. +* You can find the instructions on how to verify that the Wasm in the proposal was indeed built from the provided `git commit` in the proposal's section "How can I verify the Wasm hash of this canister?" (see [this example proposal](https://dashboard.internetcomputer.org/proposal/129499)). diff --git a/docs/developer-docs/daos/nns/nns-app-quickstart.mdx b/docs/developer-docs/daos/nns/nns-app-quickstart.mdx deleted file mode 100644 index 610b18a9e8..0000000000 --- a/docs/developer-docs/daos/nns/nns-app-quickstart.mdx +++ /dev/null @@ -1,461 +0,0 @@ ---- -keywords: [beginner, governance, tutorial, nns] ---- - -import { MarkdownChipRow } from "/src/components/Chip/MarkdownChipRow"; -import '/src/components/CenterImages/center.scss'; - -# NNS quickstart - - - -## Overview -All changes to the configuration and behavior of the Internet Computer are controlled by an algorithmic governance system called the Network Nervous System (NNS). The NNS controls all aspects of the Internet Computer blockchain configuration and is responsible for performing many network management operations. For example, the Network Nervous System (NNS) is responsible for: - -- Upgrading the protocol and guest operating system software used by the nodes machines. -- Inducting new node providers and machines into the network. -- Creating new subnets to increase network capacity. -- Splitting subnets to balance network load. -- Configuring parameters that control how much must be paid by canisters for resource usage. -- De-activating under-performing nodes to protect the network. - -The requests for changes and updates to the network are submitted to the NNS in the form of **proposals**. The NNS decides to adopt or reject proposals based on voting activity by neuron holders. - -This guide will showcase how to interface with the NNS through the NNS dapp. You can interact with the NNS through other tools, such as [quill](/docs/current/developer-docs/developer-tools/cli-tools/quill-cli-reference/quill-parent) and [ic-js](https://github.com/dfinity/ic-js/tree/main/packages/nns). - -## What are neurons? - -For network participants to be able to vote on proposals, they need to lock up a stake of ICP utility tokens for a given period of time to create a representative called a **neuron**. - -Because neurons represent a stake of ICP utility tokens, they also represent an identity with a **ICP ledger account** and a principal that controls the account. - -Neurons provide the stability required for responsible governance of the Internet Computer by ensuring that the ICP utility tokens they represent cannot be exchanged for a specific period of time referred to as the **lock-up** period. - -The following diagram provides a simplified view of the workflow for creating a neuron and the relationship between the neuron and ledger canisters. - -![neuron dissolve](../_attachments/distribute-neurons-diagram.png) - -### Governance and voting rewards - -When a person or organization has ICP utility tokens locked up in a neuron, they can propose and vote on governance proposals. To encourage participation, neuron holders are also rewarded for voting in proportion to the number of ICP utility tokens they have locked up, the length of the lock-up period (dissolve delay), and the age of their neuron. - -### Unlocking the stake held by a neuron - -After network participants create a neuron, the locked balance of ICP utility tokens can only be unlocked by fully **dissolving** the neuron. -It's **dissolve delay** determines the time it takes for a neuron to be unlocked once it is but in the dissolving state. A dissolving neuron can always be put back int the non-dissolving state. When the dissolve timer reaches zero, the neuron owner or an authenticated custodian can dissolve the neuron and unlock the neuron's balance of ICP . - -The dissolved neuron ceases to exist and the stake of ICP utility tokens that the neuron represented is released to the appropriate ledger canister account. - -## Connect to the Internet Computer - -To connect to the Internet Computer using the Network Nervous System (NNS) dapp: - -- #### Step 1: Open a browser and navigate to the [Network Nervous System (NNS)](https://nns.ic0.app) dapp. - -![NNS dapp](../_attachments/nns1.png) - -- #### Step 2: Click **Login** to connect to [Internet Identity](https://identity.ic0.app). - -![Connect with Internet Identity](../_attachments/nns2.png) - -If you haven’t previously registered, you can click **Register with Internet Identity** to register. - -:::info -We strongly recommend you add multiple devices and authentication methods to your Internet Identity. For example, register multiple physical devices like your computer and phone with a security key and using the authentication options that those devices—and browsers running on them—support. -::: - -For more information about creating an Internet Identity, see [how to use Internet Identity](https://internetidentity.zendesk.com/hc/en-us/articles/15430677359124-How-Do-I-Create-an-Internet-Identity-on-My-Mobile-Device-). - -After you have registered, you can click **Login** to authenticate using your anchor and the authentication method—for example, a security key or fingerprint—you have registered. - -- #### Step 3: Click **Proceed** to access to the Network Nervous System (NNS) dapp. - -### Add an account - -Logging on using an Internet Identity creates a main account for you in the Internet Computer ledger. If your ICP utility tokens are associated with your developer identity; that is, the identity created by the SDK `dfx` command-line interface. Your main account displays 0.00 for your ICP utility token balance. For example: - -![nns app main](../_attachments/nns3.png) - -Before transferring any tokens, you can create one or more linked subaccounts or attach a hardware wallet to your account. - -To add an account for managing ICP utility tokens: - -- #### Step 1: On the default 'Tokens' tab, click 'ICP', then **Add Account**. - -![Add account](../_attachments/nns4.png) - -- #### Step 2: Select the type of account to add. - - - **New Account** creates a new subaccount linked to your Main account address in the ledger. - - - **New Account (Hardware Wallet)** adds a hardware wallet to your main account address in the ledger. - -![Select account](../_attachments/nns5.png) - -- #### Step 3: Click **New Account**, type an Account Name, then click **Create**. - -![new linked account](../_attachments/nns6.png) - -## Transfer ICP utility tokens between accounts - -### Using the CLI - -If you have selected self-custody for holding your ICP utility tokens and the tokens are associated with your developer identity instead of your registered Internet Identity, you need to transfer ICP utility tokens to your accounts if you want to manage them using the [Network Nervous System (NNS)](https://nns.ic0.app) dapp. - -To transfer ICP utility tokens controlled by your developer identity: - -- #### Step 1: Open a terminal shell on your local computer. - -- #### Step 2: Check that you are using an identity with control over the ledger account by running the following command: - -``` bash -dfx identity whoami -``` - -In most cases, you should see that you are currently using your `default` developer identity. For example: - -``` -default -``` - -- #### Step 3: View the textual representation of the principal for your current identity by running the following command: - -``` bash -dfx identity get-principal -``` - -This command displays output similar to the following: - -``` -tsqwz-udeik-5migd-ehrev-pvoqv-szx2g-akh5s-fkyqc-zy6q7-snav6-uqe -``` - -- #### Step 4: Check the current balance in the ledger account associated with your identity by running the following command: - -``` bash -dfx ledger --network ic balance -``` - -- #### Step 5: Transfer ICP utility tokens to your Main account or a linked subaccount you create by running a command similar to the following: - -``` bash -dfx ledger --network ic transfer --icp --memo -``` - -For example, assume you have the following accounts: - -![accounts](../_attachments/nns4.png) - -If you want to transfer one ICP utility token to the `Main` account, you can run the following command: - -``` -dfx ledger --network ic transfer dd81336dbfef5c5870e84b48405c7b229c07ad999fdcacb85b9b9850bd60766f --memo 12345 --icp 1 -``` - -If you also want to transfer one ICP utility token to the `pubs` account, you can run the following command: - -``` -dfx ledger --network ic transfer 183a04888eb20e73766f082bae01587830bd3cd912544f63fda515e9d77a96dc --icp 1 --memo 12346 -``` - -:::info -This example illustrates how to transfer ICP utility tokens to using a whole number with the `--icp` command-line option. -- You can also specify fractional units of ICP utility tokens—called **e8s**—using the `--e8s` option, either on its own or in conjunction with the `--icp` option. -- Alternatively, you can use the `--amount` to specify the number of ICP utility tokens to transfer with fractional units up to 8 decimal places, for example, as `5.00000025`. -::: - -The destination address can be an address in the ledger canister running on the Internet Computer network, an account you have added using the [Network Nervous System dapp](https://nns.ic0.app), or the address for a wallet you have on an exchange. - -If you transfer the ICP utility tokens to an account in the [Network Nervous System dapp](https://nns.ic0.app), you might need to refresh the browser to see the transaction reflected. - -For more information about using the `dfx ledger` command-line options, see [dfx ledger](/docs/current/developer-docs/developer-tools/cli-tools/cli-reference/dfx-ledger). - -### Using the NNS dapp - -- #### Step 1: On the default 'Tokens' tab, assure that The Internet Computer token has been selected, then click **Send** on the bottom of the window. - -![Send](../_attachments/nns4.png) - -- #### Step 2: In the 'Send' window, select your linked account or wallet for the source, then input the destination address and the amount of ICP to send. - -Transactions are charged a ledger fee, which is independent from NNS dapp and applies to any transaction. For ICP tokens, this fee is 0.0001 ICP. - -The maximum amount you can send is your token balance minus the ledger fee. The minimum amount you can send is 0.00000001 ICP. - -![Send ICP](../_attachments/nns7.png) - -- #### Step 3: Then select **Continue** to send the transaction. - -## Stake ICP utility tokens in a neuron - -After you transfer ICP utility tokens to the Network Nervous System dapp, you can use the Network Nervous System dapp to create and manage neurons, vote on proposals, and create canisters on the Internet Computer. - -Neurons are required to participate in governance and earn rewards. To create a neuron, you must lock up some number of ICP utility tokens for a period of time. The minimum stake required to create a neuron is one ICP utility token. You can configure the period of time the stake is locked from six months up to a maximum of eight years. - -To stake ICP utility tokens: - -- #### Step 1: In the NNS dapp, select **Neuron Staking** from the left navigation bar, then click **Stake Neurons** in the bottom of the window. - -![Neuron staking](../_attachments/nns8.png) - -- #### Step 2 : Select which wallet you'd like to use as the source, then type the number of ICP utility tokens to stake, then click **Create**. - -![Neuron staking](../_attachments/nns9.png) - -- #### Step 3: Set the dissolve delay for the neuron to control the length of time the stake is locked, then click **Update Delay**. - -For example: - -![dissolve delay](../_attachments/nns-dissolve.png) - -- #### Step 4: Click **Confirm and Set Delay** to confirm the lock up period. - -![neuron properties](../_attachments/nns-settings.png) - -## What you can do after creating a neuron - -After you have locked the stake and created a neuron, you can: - -- Start the dissolve delay timer by clicking **Start Unlock**. -- Increase the dissolve delay period by clicking **Increase Dissolve Delay**. -- Stop the dissolve delay after starting the unlock countdown by clicking **Lockup**. -- Increase the number of ICP utility tokens you have staked. - -## Starting and stopping the dissolve delay - -Creating a new neuron does not automatically start the dissolve delay timer. You must explicitly start the timer countdown by clicking **Start Unlock**. - -For example, if you set a dissolve delay of one year and want to immediately begin the countdown, you should click **Start Unlock** as part of the process of creating the neuron. If you change your mind and want to stop a current countdown in progress, you can click **Lockup**, After you click **Lockup** to stop the dissolve delay, you can click **Start Unlock** to resume the countdown without changing the existing dissolve delay period. If you want to continue a countdown already in progress but extend the lock up period, you can click **Increase Dissolve Delay** then select a longer dissolve delay. - -## Adding ICP utility tokens to an existing neuron - -After you create a neuron, you can increase the number of ICP utility tokens you have staked in that neuron to increase your voting power and rewards. For example, if you initially stake a small number of ICP utility tokens, then decide to purchase additional tokens, you have the option to create a new neuron or "top-up" your existing neuron. - -To increase the stake in an existing neuron: - -- #### Step 1: Follow the steps in [stake ICP utility tokens in a neuron](#stake-icp) to stake the original neuron using the [Network Nervous System (NNS)](https://nns.ic0.app) dapp. - -- #### Step 2: Look up the transaction in the Internet Computer Association [transaction dashboard](https://dashboard.internetcomputer.org/transactions) to get the neuron address. - -You can use the account identifier for your main ICP ledger account to search for your transactions. - -- #### Step 3: Return to the [Network Nervous System (NNS)](https://nns.ic0.app) dapp, then from the 'My Neuron Staking' window, click **New Transaction**. - -- #### Step 4: Paste the neuron address from the transaction dashboard into the **Destination** address field, then click **Continue**. - -- #### Step 5: Type the amount of ICP utility tokens you want to add to the specified neuron, then click **Continue**. - -![Increase stake](../_attachments/nns10.png) - -- #### Step 6: Verify the transaction details, then click **Send Now**. - -![Confirm increase stake](../_attachments/nns11.png) - -- #### Step 7: Once the transaction has completed, you will see the increased stake value. - -![Increased stake](../_attachments/nns12.png) - -## Disburse dissolved neurons into an account - -When the dissolve delay timer for a neuron reaches zero, you can disburse the neuron’s stake and transfer its locked ICP utility token balance to the ledger account you specify. - -To disburse a neuron and return its ICP utility tokens: - -- #### Step 1: From the NNS dapp, select 'My Neuron Staking', then click on an unlocked neuron that has reach the ended of its dissolve delay period. - -- #### Step 2: Click **Disburse**: - -- #### Step 3: Type an address or select an account to receive the ICP utility tokens. - -![select account](../_attachments/select-account.png) - -- #### Step 4: Verify the transaction information, then click **Confirm and Send**. - -## Neuron following -Neuron owners may find it hard to manually vote on every proposal submitted to the NNS. For example,neuron owners may not have the time or necessary expertise to evaluate each individual proposal. -The NNS uses a form of liquid democracy to address these challenges. -To aid in this, the NNS supports **neuron following **. -A neuron can be configured to vote automatically by following the voting decision made by a group of other neurons. -Following is done on the basis of topics, and a neuron can follow up to 15 neurons on each topic. - -### Following rules -A neuron can choose to follow the voting decision for different proposal topics like governance or subnet management. For example, if a neuron has been configured to follow a group's decision for governance proposals, if the group votes to adopt a governance proposal with more than half of the followees voting in favor of adoption, the neuron following that group will vote to approve the proposal as well. If the neuron has been configured to follow a group's decision for subnet management proposals and the group votes to reject a subnet management proposal with at least half of the followees voting to reject, the neuron following the group will vote to reject the proposal. - -:::caution -Your neuron will follow when there are enough votes to make a call (whether it is a ADOPT or REJECT). Your neuron will only cast a "Yes"-vote if **more than half** of the neurons within the group voted Yes. Your neuron will only cast a "No"-vote if **at least half** of the neurons within the group voted No. For example, if you follow 10 neurons on a topic: - -a. Your neuron only votes to adopt if at least 6 out of the 10 neurons vote to adopt. - -b. Your neuron only votes to reject a proposal if at least 5 out of the 10 reject the proposal. - -c. If less than 5 neurons (out of your 10 followed) vote at all, your neuron will not cast any vote. - -This should be considered when choosing to follow multiple neurons on a topic. -It might be better to follow fewer neurons, and it can be more beneficial to follow an odd number of neurons than an even number. -::: - -### Following "catch-all" -In addition to setting following for individual topics, neurons may also define a catch-all follow rule which is triggered for proposals with topics for which no other explicit follow rule has been defined. -However, the catch-all follow rule does not include SNS & neurons' fund or governance proposals. - -:::caution -The catch-all follow rule is only applied for proposal topics with no other explicit choice. For example, let's assume neuron A follows neuron B for the catch-all and neuron C on the topic subnet management. If B votes on a subnet management proposal but C does not, no vote will be cast for A. - -The catch-all follow rule does not apply for SNS & neurons' fund or governance proposals. -For example, if neuron A follows neuron B for the catch-all and B votes on a governance proposal, no vote will be cast for A. If neuron A intents to also follow B on such decisions, the user has to explicitly choose to also follow B on the governance topic. -::: - -It is in each neuron's interest to follow other neurons that support the best interests of the network and their own economic interests. - - - -To configure your neuron to follow the group of another neuron: - -- #### Step 1: From the NNS dapp, select 'Neuron Staking', then select the neuron that you'd like to set a following rule for. - -![NNS Neuron following 1](../_attachments/nns8.png) - -- #### Step 2: In the neuron's details, scroll down to the 'Following' section and select 'Follow Neurons'. - -![NNS Neuron following 2](../_attachments/nns13.png) - -- #### Step 3: Next, select a topic to follow. - -The topic refers to the different types of proposals; for example, the 'Governance' topic defines a following role for governanc-related proposals, while the 'Subnet Management' topic defines a following role for subnet management proposals. There is also a 'catch-all' rule that can be followed for all proposal types except for governance, SNS, and neurons' fund. - -For this example, select 'SNS & Neurons' Fund'. - -![NNS Neuron following 3](../_attachments/nns14.png) - -- #### Step 4: Select 'Add Followee'. - -![NNS Neuron following 4](../_attachments/nns15.png) - -- #### Step 5: Enter a Neuron ID to follow, or select a group of neurons from the menu provided. - -In this example, select 'DFINITY Foundation'. - -![NNS Neuron following 5](../_attachments/nns16.png) - -- #### Step 6: The window will now reflect the following configuration: - -![NNS Neuron following 6](../_attachments/nns17.png) - -The configuration will also now be shown in the neuron's details: - -![NNS Neuron following 7](../_attachments/nns18.png) - -## Spawn new neurons - -As you vote on proposals—either directly or by following the votes of other neurons—the maturity associated with your neuron increases, which in turn increases the rewards you earn for participating in governance. When the maturity for a locked stake reaches a minimum threshold of one ICP, you can spawn a new neuron. The spawn operation creates a new neuron that locks a new balance of ICP on the ledger. - -For example, if you have a neuron that contains 100 ICP utility tokens and it has a maturity of 10 percent, you can spawn a new neuron that contains approximately 10 new ICP tokens. For the neuron with 100 ICP tokens to reach the minimum threshold for spawning, its maturity would need to be greater than one percent. - -After you spawn a new neuron from an existing neuron, the maturity for the existing neuron falls to zero. - -To spawn new neurons from an existing neuron: - -- #### Step 1: From the NNS dapp, select 'Neuron Staking', then click the neuron that has reached the minimum maturity required to spawn a new neuron. - -- #### Step 2: Click **Spawn Neuron**. - - -## Vote on proposals - -Active participation in governance is an important factor in the long-term health of the Internet Computer. Voting on proposals is also an important factor in calculating the rewards you receive in return for locking up ICP utility tokens in neurons. - -However, voting directly on every proposal submitted to the NNS presents several challenges. For example, proposals might be submitted and require a vote when you are unavailable or propose changes that you lack the expertise to evaluate. To address these challenges, you can configure neurons to vote automatically to adopt or reject proposals by following the votes of a group of neurons. - -To maximize your rewards, you should vote on as many proposals as possible by following the active neuron holders who have interests aligned with your own. For example, you might follow the Internet Computer Association (ICA) on some topics such **SubnetManagement** and other neuron holders on topics such as **Governance**. - -You can choose the proposal types and proposal topics that you see and vote on either directly or by following other neuron stakeholders using filters in the Network Nervous System dapp. For example, if you want to review and vote on all proposals that involve network participants such as data center identities and node operators, but aren’t interested in viewing proposals related to the current market value of ICP, as measured by an International Monetary Fund (IMF) Special Drawing Right (SDR), you can select the **ParticipantManagement** topic filter and deselect the **ExchangeRate** topic filter. - -To manually vote on proposals: - -- #### Step 1: From the NNS dapp, select 'Vote' from the left navigation bar. - -![Proposals](../_attachments/nns19.png) - -- #### Step 2: Then, select which Nervous System you'd like to view proposals for. - -By default, the Internet Computer NNS proposals are shown, but other proposals for SNS's like OpenChat and Kinic are also available. - -- #### Step 3: Click on any proposals to view more information on it, such as the proposals summary, the type of proposals, the topic, and when the proposal's voting ends. - -![Proposal detail](../_attachments/nns20.png) - -:::info -For more information about voting and voting rewards, see the following articles: - -- [Earn substantial voting rewards by staking in the Network Nervous System](https://medium.com/dfinity/earn-substantial-voting-rewards-by-staking-in-the-network-nervous-system-7eb5cf988182) - -- [Understanding the Internet Computer’s Network Nervous System, neurons, and ICP utility tokens](https://medium.com/dfinity/understanding-the-internet-computers-network-nervous-system-neurons-and-icp-utility-tokens-730dab65cae8) - -- [Getting started on the Internet Computer’s Network Nervous System app and wallet](https://medium.com/dfinity/getting-started-on-the-internet-computers-network-nervous-system-app-wallet-61ecf111ea11) -::: - -## Submit a proposal - -Currently, you can only submit proposals to the network nervous system by using the SDK command-line interface (`dfx`) using calls to the `governance` canister. - -A separate command-line tool (`icx-nns`) for working with the `governance` canister is in development and this functionality will also be available in the [Network Nervous System (NNS)](https://nns.ic0.app) dapp soon. - -If you want to start submitting proposals right away, however, you can access a preliminary version of the `icx-nns` command-line tool by downloading a release from the [icx-nns](https://github.com/dfinity/icx-nns/releases) repository. - - -## SNS decentralization swaps - -You can participate in SNS decentralization swaps from the NNS dapp using the 'Launchpad' tab. An SNS is an advanced version of a decentralized autonomous organization, where the participants of the SNS can vote on proposals, such as a new feature, roadmap item, or allocation of SNS funds. - -You can learn more about SNS [here](https://internetcomputer.org/sns) - -To view current and past SNS decentralization swaps from the NNS dapp: - -- #### Step 1: From the NNS dapp, click **Launchpad** from the left navigation bar. - -![Launchpad](../_attachments/nns21.png) - -- #### Step 2: Select any SNS swap to view the details, such as the status, total participants, token supply, and when the swap ended. - -![SNS swap](../_attachments/nns22.png) - -## Deploying and managing canisters from the NNS dapp - -You must have **cycles** available to create and manage [canisters](/docs/current/concepts/glossary#canister), which are similar to smart contracts. The [Network Nervous System (NNS)](https://nns.ic0.app) dapp provides a convenient way for you to create and manage canisters by enabling you to convert ICP utility tokens into cycles and attach cycles to specific canister identifiers. - -To create a new canister: - -- #### Step 1: From the NNS dapp, click **Canisters**, then click **Create Canister** or **Link Canister**. - -![My canisters](../_attachments/nns23.png) - -- #### Step 2: If you select **Create Canister**, select the source account you'd like to use to create the canister. - -![Create a new canister](../_attachments/nns24.png) - -- #### Step 3: Then, enter the amount of ICP tokens and cycles to create the canister with. Then select **Review Canister Creation**. - -![Create a new canister](../_attachments/nns25.png) - -- #### Step 4: Review the ICP utility tokens to cycles details, then click **Confirm** to continue. - -After you click Confirm, you can review: -- The new canister identifier. -- The number of cycles available for the canister to use. -- The controlling principal that currently has full management rights for the new canister. - -:::info -To change the principal used as the controller of the canister, click **Change Controllers**. - -To add cycles to the canister, click **Add Cycles**. -::: - -- #### Step 5: To link a canister, input the canister's ID, then select **Confirm**. - -![Link canister](../_attachments/nns26.png) - -- #### Step 6: Return to the **Canisters** tab to see the canisters you have created. - -For example: - -![Canister list](../_attachments/nns27.png) diff --git a/docs/developer-docs/daos/nns/overview.mdx b/docs/developer-docs/daos/nns/overview.mdx index 7deda5d009..d127cd8f99 100644 --- a/docs/developer-docs/daos/nns/overview.mdx +++ b/docs/developer-docs/daos/nns/overview.mdx @@ -4,52 +4,50 @@ keywords: [beginner, governance, overview, nns] import { MarkdownChipRow } from "/src/components/Chip/MarkdownChipRow"; -# NNS overview +# Network Nervous System (NNS) -The NNS is the decentralized autonomous organization (DAO) that governs the Internet Computer Protocol. You can access the [on-chain frontend](https://nns.ic0.app/). +## Overview + -It is a fully on-chain, decentralized organization and is, for instance, responsible for making protocol-level upgrades to continuously improve the Internet Computer Protocol. +The Network Nervous System (NNS) is the fully on-chain decentralized autonomous organization (DAO) that governs the Internet Computer Protocol. +It is a stake-based, open governance system where everyone can participate by staking some ICP utility tokens. -It operates under a liquid democracy in which those who have [staked their ICP in a neuron vote](/docs/current/concepts/governance) on proposals that shape the development of the Internet Computer. +## The need for the NNS +The Internet Computer is run by independent node machines that run the Internet Computer protocol and are organized into different sub-groups, called subnets. +To ensure that the Internet Computer can evolve in terms of security, efficiency, and scale, decisions such as the following need to be made: +- Upgrading the protocol and guest operating system software used by the nodes machines, for cases such as added security or better performance. +- Inducting new node machines by new node providers into the network for more robustness. +- Creating new subnets to scale the Internet Computer's capacity. +- Splitting subnets to balance network load. -Some proposal examples include upgrading the protocol and software used by the node machines that host the network and creating new subnet blockchains to increase network capacity +The NNS ensures that all these decisions can be made in a decentralized and autonomous way. -A proposal passes based on either: -- **Absolute Majority** - At any point, even before the voting period ends, if an absolute majority (more than half of the total voting power) has voted "yes," then the proposal is adopted. If an absolute majority has voted "no," then the proposal is rejected. +## Neurons +On the Internet Computer, governance participants are called _neurons_. +Neurons are staked ICP tokens, so anyone can become a part of the NNS governance by staking ICP tokens in a neuron. +This is incentivized by voting rewards for neurons who participate in decision making. -- **Simple Majority** - When the voting period ends, if a simple majority (more than half of the cast votes) has voted "yes" and the number of these yes votes constitutes at least 3% of the total voting power, then the proposal is adopted. Otherwise, the proposal is rejected. +For a tutorial on how to stake tokens in a neuron, refer to [staking a neuron](/docs/current/developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-staking-a-neuron). +For more background information on neurons and voting rewards, refer to [neurons](/docs/current/developer-docs/daos/nns/concepts/neurons/neuron-overview). -For determining how long proposals are open for voting, the governance uses a so called "Wait-for-quiet" algorithm. This ensures that proposals are decided quickly if all voters agree, but have a longer voting period if they are controversial. Most proposals start with 4 days of voting period that can be extended up to 8 days. -Once a proposal is adopted, it is autonomously executed on-chain. - -While other blockchains take weeks or months to upgrade and typically require substantial manual work and coordination to do so, ICP upgrades itself every week (https://dashboard.internetcomputer.org/releases). Its ability to upgrade and iterate is a comparative "superpower." - -## Participation rewards -Network governance on the Internet Computer is incentivized through a system called "neurons". -ICP token holders can create a “neuron” by staking ICP up to eight years. - -When a user creates a neuron, the staked ICP can only be taken out of the neuron again by disbursing the neuron. Each neuron is configured with a “dissolve delay” that determines the minimum amount of time that you have to wait before you can unlock your staked ICP utility tokens. Once a neuron has been placed into “dissolving mode,” its dissolve delay falls over time, rather like a kitchen timer, until it reaches zero, whereupon its owner can perform a final disburse action to unlock the balance of ICP. - -Neurons with a longer dissolve delay have more voting power and get more rewards so that they are economically incentivized to vote in the best long-term interests of the network. - -The number of rewards that neuron receives derive from factors as the amount of staked tokens, the lockup period remaining (the “dissolve delay”), the neuron’s “age”, the proportion of possible votes it has participated in, and the sum of voting activity across all neurons, since the overall total rewards are capped and must be divided between voters. - -For more information on neurons, refer to the [What are Neurons section in the NNS quickstart](/docs/current/developer-docs/daos/nns/nns-app-quickstart). -For more information on staking rewards, refer to [Staking and Voting Rewards](/docs/current/developer-docs/daos/nns/staking-voting-rewards). ## Proposals -Participants submit proposals to the NNS. Refer to the proposal submission requirements and types at [proposal requirements](/docs/current/developer-docs/daos/nns/proposal-requirements). - -Proposals are adopted or rejected based on voting activity by “neurons” that network participants have created. - -## Participation - -Neurons can manually vote on all proposals. - -If they cannot manually vote on all proposals due to high submission volumes or a lack of expertise, neurons can delegate their vote, called _following_, for specific proposal topic. This ensures efficient decision-making without requiring constant manual input. - -Since the incentive to stake ICP in a neuron is high, it is difficult and exorbitantly expensive for an attacker to acquire a sufficiently large stake to gain significant influence. - -To participate, navigate to the [NNS app](https://nns.ic0.app/). \ No newline at end of file +Proposals are suggestion on how to evolve the Internet Computer, including decisions on how to update the protocol, organize node machines + into subnets, and update the rules of the NNS DAO itself. +Any neuron that has tokens staked for at least 6 months can submit and vote on proposals. + +On a high level, a proposal goes through the following lifecycle: + +1. **Proposal submission**: A neuron submits a proposal with a new suggestion to make a change to the network. +2. **Establish ballot roll**: The governance canister takes a snapshot and creates (empty) ballots for all eligible neurons. +3. **Voting**: All eligible neurons can cast their vote. This can either be done by a manual vote or by _following_, which is a mechanism for delegating the voting power to another neuron, also called liquid democracy. +4. **Proposal decision**: The proposal is decided based on either: + - **Absolute Majority** - At any point, even before the voting period ends, if an absolute majority (more than half of the total voting power) has voted "yes," then the proposal is adopted. If an absolute majority has voted "no," then the proposal is rejected. + - **Simple Majority** - When the voting period ends, if a simple majority (more than half of the cast votes) has voted "yes" and the number of these yes votes constitutes at least 3% of the total voting power, then the proposal is adopted. Otherwise, the proposal is rejected. +5. **Proposal execution**: If a proposal is adopted, the NNS DAO automatically and autonomously executes the proposals. For example, if the proposal decided to update the voting rules, the governance canister would automatically initiate an update of the smart contract that implements the NNS DAO which executes this decision. Compared to other DAOs, this has the advantage that no human action is needed for proposal execution, which removes a source of failure and inefficiency. + +For a tutorial on how to vote on a proposal, refer to [Voting on proposals](/docs/current/developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-voting-on-proposals) and for a tutorial on how to set following, refer to [Following](/docs/current/developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-following-other-neurons). +For more detailed information about proposals, including details of the lifecycle, how to submit proposals, and the precise type of proposals, refer to [Proposals](/docs/current/developer-docs/daos/nns/concepts/proposals/proposal-overview). +For more information about voting, the rules of following, and how to verify proposals, refer to [Voting](/docs/current/developer-docs/daos/nns/concepts/proposals/direct-voting). \ No newline at end of file diff --git a/docs/developer-docs/daos/nns/proposal-lifecycle.mdx b/docs/developer-docs/daos/nns/proposal-lifecycle.mdx deleted file mode 100644 index b07fc3ec6f..0000000000 --- a/docs/developer-docs/daos/nns/proposal-lifecycle.mdx +++ /dev/null @@ -1,74 +0,0 @@ ---- -keywords: [intermediate, governance, concept, nns] ---- - -import { MarkdownChipRow } from "/src/components/Chip/MarkdownChipRow"; - -# Proposal lifecycle - - - - -## Overview - -A proposal's lifecycle starts when it is submitted by a governance participants. Then other governance participants form a decision and vote on the proposal. Based on these votes, the governance canister derives a proposal decision, i.e., the proposal is either adopted or rejected. - -If the proposal is rejected, usually nothing happens. If the proposal is adopted, the agreed upon decision is automatically executed by the governance canister. - -## Proposal submission - -Any eligible neuron can make and submit a proposal. To avoid being inundated by useless proposals, a user submitting a proposal has to pay a fee of 10 ICP when submitting a proposal, that they will receive back if the proposal is adopted but not receive back if the proposal is rejected. - -After a proposal is submitted, the proposal is created and stored in the governance canister. The governance canister computes and stores additional information with each proposal. - -First, the governance canister looks at all neurons and creates an empty ballot for each eligible neuron that has a -dissolve delay of at least 6 months, storing the neuron's voting power in this moment. This means that at the time of the proposal's submission, a neuron snapshot is taken and all neurons can vote on the proposal with the voting power that they have at that moment. - -:::info -This results in the following, potentially unintuitive cases: -* If a neuron is created after a proposal was submitted, it is not eligible to vote on this proposal. -* If a neuron had a dissolve delay of less than 6 months when a proposal was submitted, it cannot vote on the proposal, even if the neuron's dissolve delay is increased again. -* If a neuron had a dissolve delay of 6 months when a proposal was submitted, it can vote on the proposal during the full voting period, even if by the time of voting the neuron's dissolve delay decreased slightly below 6 months. - -::: - -The sum of all of the neurons' voting powers determines the total voting power associated with a given proposal. -In addition to creating all ballots, when a new proposal is created, the proposer's ballot is set to a “Yes” vote. -This reflects that the proposal already has the support of the user submitting it. - -Moreover, each proposal has an associated **voting period**, which determines the period of time over which votes for - this proposal are accepted. - -### How to submit a proposal -To submit a proposal, it is recommended to use a neuron that can be controlled with a command line tool. -For example, you can review concrete instructions how to [submit a proposal of type `Motion`](https://wiki.internetcomputer.org/wiki/How-To:_Create_an_NNS_motion_proposal). - -## Proposal decision and wait-for-quiet -After a proposal is submitted and added to the governance canister, other users who control neurons can [vote on the proposal](./proposal-voting.mdx). -The governance canister stores a neuron's choice in the empty ballot where the neuron's voting power has been recorded. -In this way, the proposal always contains the information of the total voting power of "Yes" and "No" votes. - -A proposal can be decided in two ways: - -1. **Absolute majority before the voting period ends**: At any point, even before the voting period ends, if an absolute majority (more than half of the total voting power stored in the proposal) has voted "Yes", then the proposal is adopted, and if an absolute majority has voted "No", then the proposal is rejected. -2. **Simple majority at the voting period’s end**: When the voting period ends, if a simple majority (more than half of the cast votes) has voted "Yes" and the number of these "Yes"-votes constitute at least 3% of the total voting power, then the proposal is adopted. Otherwise, the proposal is rejected. - -What also plays into this is an algorithm called **wait-for-quiet** that dynamically adjusts the deadline. The idea of wait-for-quiet is to decide proposals quickly when all voters agree, but increase the time that neurons can vote for proposals that are controversial. That means that the voting period can be dynamically increased, depending -on the neurons’ votes. In particular, each time a proposal’s outcome is turned (either a "Yes"-majority is turned to a -"No"-majority or vice versa), the proposal’s deadline is increased. Currently, a proposal's initial voting period is 4 days and can be increased by at most another 4 days. That is, the voting period that is taken into account for the above rules can be between 4 and 8 days, depending on the voting activity. - -## Proposal execution -Technically, a proposal defines a method on a canister that will be called if the proposal is adopted with [some parameters](./proposal-advanced.mdx). - -When a proposal is adopted, the defined method on the specified canister is automatically called with the given parameters. This is done automatically by the governance canister and does not require any manual intervention. -A proposal's execution may be successful, in which case the proposal is labeled as `executed`, or it may fail, in which case the proposal is labeled as `failed`. - -When a proposal is rejected, most of the time nothing happens. In very few cases some cleanup work is initiated. -Therefore, `rejected` is also a possible final proposal state. - -:::info -A proposal is adopted or rejected as soon as a decision can be made, which might be before the voting deadline. -To ensure that neurons can still take their time to vote and get rewards, neurons that vote after the proposals' decision but before the voting period's deadline still get rewards. -See [staking and voting rewards](./staking-voting-rewards.mdx) for more information on rewards. -::: - diff --git a/docs/developer-docs/daos/nns/proposal-overview.mdx b/docs/developer-docs/daos/nns/proposal-overview.mdx deleted file mode 100644 index 36f66938d8..0000000000 --- a/docs/developer-docs/daos/nns/proposal-overview.mdx +++ /dev/null @@ -1,17 +0,0 @@ ---- -keywords: [intermediate, governance, concept, nns] ---- - -import { MarkdownChipRow } from "/src/components/Chip/MarkdownChipRow"; - -# Overview - - - -A proposal is a suggestion for a change to the Internet Computer protocol. The NNS is an open governance system where anyone can become a participant. NNS DAO participants can submit proposals, make suggestions on how the ICP should evolve, and vote on proposals that others have submitted. - -Based on the majority decision, a proposal is then adopted or rejected. If a proposal is adopted, it is automatically executed fully on-chain, without the need for manual intervention. - -More technically, to participate in the NNS governance, users can stake some ICP tokens in a neuron. At least 1 ICP are required to create a neuron. - -If a neuron has more than 6 months dissolve delay, it is eligible to participate in voting. This means that it can both submit and vote on proposals. \ No newline at end of file diff --git a/docs/developer-docs/daos/nns/proposal-requirements.mdx b/docs/developer-docs/daos/nns/proposal-requirements.mdx deleted file mode 100644 index cb413cb9e9..0000000000 --- a/docs/developer-docs/daos/nns/proposal-requirements.mdx +++ /dev/null @@ -1,206 +0,0 @@ ---- -keywords: [intermediate, governance, concept, nns] ---- - -import { MarkdownChipRow } from "/src/components/Chip/MarkdownChipRow"; - -# Neuron and proposal details - - - -## Overview - -Only [neurons](/docs/current/concepts/governance) with at least 10 ICP and 6 months of dissolve delay can submit proposals to the NNS. To learn more on how to submit a proposal, refer to the [how to create an NNS motion proposal](https://wiki.internetcomputer.org/wiki/How-To:_Create_an_NNS_motion_proposal). - -## Neurons - -Neurons have the following attributes: - -* **Identity (uint64)**: The general identity of the neuron object. When a neuron is configured to follow another neuron, this is the value that is used. This is a random 64-bit value selected by NNS governance at neuron creation. - -* **Account (bytes)**: The ledger account where the locked ICP balance resides. - -* **Controller (principal ID)**: The principal that actually controls the neuron. The principal must identify a public key pair, which acts as a “master key,” such that the corresponding secret key should be kept very secure. The principal might control many neurons. - -* **Hot Keys (list of principal ID)**: Keys that can be used to perform actions with limited privileges, such as voting, without exposing the secret key corresponding to the principal (e.g., could be a WebAuthn key). - -* **CreatedAt (timestamp)**: When the Neuron was created. - -* **AgingSince (timestamp)**: The timestamp corresponding to the time this neuron has started aging. This is either the creation time or the last time at which the neuron has stopped dissolving. This value is meaningless when the neuron is dissolving since a dissolving neuron always has an age of zero. - -* **DissolveState**: At any time, at most one of WhenDissolved and DissolveDelay are specified. - -* **WhenDissolved (timestamp)**: When the dissolve timer is running, this stores the timestamp in seconds from the Unix epoch, at which point the neuron becomes dissolved. At any time while the neuron is dissolving, the neuron owner may pause dissolving, in which case DissolveDelay will get assigned to WhenDissolved minus the timestamp when the action is taken. - -* **DissolveDelay (duration)**: When the dissolve timer is stopped, this stores how much time the dissolve timer will be started with. It can be eight years at most. At any time while in this state, the neuron owner may (re)start dissolving, in which case WhenDissolved will get assigned to the timestamp when the action is taken plus DissolveDelay. - -* **Maturity (positive number – percent)**: The maturity of a neuron, which determines its ability to spawn a new neuron and corresponding locked balance of newly minted ICP in expectation equal to this value in percent of the stake of the spawning neuron. When new neurons are created, their maturity is zero. When neurons vote, over time the NNS increases their maturity to reward them. - -* **Follow relationships (mapping from topic to list of followers)**: A neuron can be configured to vote automatically by following other neurons on a topic-by-topic basis. For any valid topic, a list of followers can be specified, and the neuron will follow the vote of a majority of the followers on a proposal with a type belonging to that topic. If a null topic is specified, this acts as a catch-all that enables the neuron to follow the vote of followees where a rule has not been specified. - -* **Recent votes**: A record of recent votes is maintained. This can provide a guide for those wishing to evaluate whether to follow a neuron or how their followers are voting. - -* **NotForProfit (boolean)**: Whether this neuron is “not for profit,” making it dissolvable by voting. - -The following attributes can be computed: - -* **Age (seconds)** (computed from AgingSince and current time): T he period that has elapsed since the neuron was created or last stopped dissolving. Conceptually, whenever a neuron starts dissolving, then its age is reset to zero and remains zero while it is dissolving. If a dissolving neuron has been turned off, the current time becomes the effective neuron creation date to calculate the age. -* **State (NON-DISSOLVING or DISSOLVING or DISSOLVED)** (computed from DissolveState and the current time): - - - Non-Dissolving: In this state, the neuron is non-dissolving with a specific DissolveDelay. It accrues age by the passage of time and it can vote if DissolveDelay is at least six months. The method `start_dissolving` can be called to transfer the neuron to the DISSOLVING state. The method `increase_dissolve_delay` can be used to increase the dissolve delay without affecting the state or the age of the neuron. - - Dissolving: In this state, the neuron’s effective dissolve delay decreases with time. While dissolving, the neuron’s age is considered zero. Eventually it will reach the DISSOLVED state. The method `stop_dissolving` can be called to transfer the neuron to the non-dissolving state, and the neuron will start aging again. The method `increase_dissolve_delay` can be used to increase the dissolve delay, but this will not stop the timer or affect the age of the neuron. - - Dissolved: In the dissolved state, the neuron’s stake can be disbursed using the disburse method. It cannot vote as its dissolve delay is considered to be zero. If the method `increase_dissolve_delay` is called in this state, the neuron will become non-dissolving with the specified dissolve delay and start aging again. Neuron holders have an incentive not to keep neurons in the dissolved state for a long time: if the holders want to make their tokens liquid, they disburse the neuron’s stake, and if they want to earn voting rewards, they increase the dissolve delay. If these incentives turn out to be insufficient, the NNS may decide to impose further restrictions on dissolved neurons. - -### Commands -The principal that controls a neuron may instruct it to perform some of these popular actions below. [View all possible actions](https://sourcegraph.com/github.com/dfinity/ic/-/blob/rs/nns/governance/proto/ic_nns_governance/pb/v1/governance.proto?L829). - -* **Start dissolving**: The dissolve delay is like a kitchen timer that can only be turned in one direction. It can be arbitrarily increased, but only reduced by turning on dissolve mode and counting down. The neuron can be instructed to start “dissolving.” When the neuron is dissolving, its dissolve delay falls over time until it is either stopped or reaches zero. A neuron cannot vote (or earn rewards for voting) when its dissolve delay falls below six months. Once the dissolve delay reaches zero, it stops falling and the controlling principal can instruct the neuron to disburse. - -* **Stop dissolving**: A neuron that is dissolving can be instructed to stop, whereupon its dissolve delay stops falling with time. - -* **Disburse**: When the dissolve delay of the neuron is 0, its controlling principal can instruct it to disburse the neuron’s stake. Its locked ICP balance is transferred to a specified new ledger account, and the neuron and its own ledger account disappear. - -* **Increase dissolve delay**: The dissolve delay of a neuron can be increased up to a maximum of eight years. - -* **Spawn**: When the maturity of a neuron has risen above a threshold, it can be instructed to spawn a new neuron. This creates a new neuron that locks a new balance of ICP on the ledger. The new neuron can remain controlled by the same principal as its parent, or be assigned to a new principal. When a neuron spawns a new neuron, its maturity is decreased by the amount that was spawned to the new neuron. - -* **Add hot key**: Add a new hot key that can be used to manage the neuron. This provides an alternative to using the principal’s cold key to manage the neuron, which might be onerous and difficult to keep secure, especially if it is used regularly. A hot key might be a WebAuthn key that is maintained inside a user device, such as a smartphone. - -* **Remove hot key**: Temove a hot key that has been previously assigned to the neuron. - -The following actions can be initiated using the principal or a hot key that has been configured: - -* **Vote**: Have the neuron vote to either adopt or reject a proposal with a specified ID. -* **Follow**: Add a rule that enables the neuron to vote automatically on proposals that belong to a specific topic, by specifying a group of followee neurons whose majority vote is followed. The configuration of such follow rules can be used to: - - Distribute control over voting power amongst multiple entities. - - Have a neuron vote automatically when its owner lacks time to evaluate newly submitted proposals. - - Have a neuron vote automatically when its own lacks the expertise to evaluate newly submitted proposals. - - For other purposes. - -A follow rule specifies a set of followers. Once a majority of the followers vote to adopt or reject a proposal belonging to the specified topic, the neuron votes the same way. If it becomes impossible for a majority of the followers to adopt (for example, because they are split 50–50 between adopt and reject), then the neuron votes to reject. If a rule is specified where the proposal topic is null, then it becomes a catch-all-follow rule, which will be used to vote automatically on proposals belonging to topics for which no specific rule has been specified. If the list of followers is empty, this effectively removes the following rule. - -## Proposal format - -Each proposal submitted to the NNS has the following fields: - -* **Summary**: Text providing a short description of the proposal, composed using a maximum of 280 bytes. - -* **URL**: The web address of additional content required to evaluate the proposal, specified using HTTPS. For example, the address might describe content supporting the assignment of a DCID (data center id) to a new data center. - -* **Proposer**: The ID of the neuron that submitted the proposal. When a proposal is submitted, a “charge” is placed on its balance in case it is rejected. The balance needs to be enough to pay the charge on (all) rejection(s). The NNS requires a neuron to have a dissolve delay of ≥ 6 months to vote, and which also applies to submitting proposals. - -* **Proposal Type**: The type of the proposal. This infers what topic it belongs to (e.g., #NodeAdmin), the system function that will process the proposal if it is adopted, and the type and structure of the parameters that will be passed to that function. - -* **Parameters**: The parameters that will be passed to the system function and invoked if the proposal is adopted, as determined by its type. When a proposal is submitted, the NNS checks these parameters. - -The NNS assigns a unique identity to each proposal that it receives. - -## Proposal topics - -Each type of proposal belongs to a specific “proposal topic,” such as “#NodeAdmin” or “#NetworkEconomics,” which determines details about how it will be processed. - -* **#NeuronManagement**: A special topic using which a neuron can be managed by the followees for this topic. Votes on this topic are not included in the voting history of the neuron. For proposals on this topic, only the neuron’s followers on the topic that the proposals pertain to are allowed to vote. Because the set of eligible voters for proposals on this topic is restricted, proposals on this topic have a shorter than normal voting period. -* **#NetworkEconomics**: Proposals that administer network economics; for example, determining what rewards should be paid to node operators. -* **#Governance**: All proposals that administer governance; for example, motions and the configuration of certain parameters. -* **#NodeAdmin**: All proposals that administer node machines including but not limited to upgrading or configuring the OS, upgrading or configuring the virtual machine framework, and upgrading or configuring the node replica software. -* **#ParticipantManagement**: All proposals that administer network participants; for example, granting and revoking DCIDs (data center identities) or NPIDs (node provider identities). -* **#SubnetManagement**: All proposals that administer network subnets; for example, creating new subnets, adding and removing subnet nodes, and splitting subnets. -* **#NetworkCanisterManagement**: Installing and upgrading “system” [[NNS Canisters|canisters]] that belong to the network; for example, upgrading the voting rules in the NNS DAO itself. -* **#NodeProviderRewards**: Topic for proposals to reward node providers. - -## Proposal types - -Each proposal is an instance of a specific “proposal type”, which determines what information it contains. For each type of proposal, the NNS maintains a corresponding system function, which it invokes whenever a proposal of that type is adopted. When a proposal is adopted by the NNS, it invokes the corresponding system function by drawing information from the proposal’s content to fill the parameters. - -* **ManageNeuron (#NeuronManagement, Restricted Voting)**: This type of proposal calls a major function on a specified target neuron. Only the followers of the target neuron may vote on these proposals. - -* **ManageNetworkEconomics (#NetworkEconomics)**: This is a single proposal type that can update one or several economic parameters: - - * **Reject cost**: The amount of ICP the proposer of a rejected proposal will be charged to prevent the spamming of frivolous proposals. - - * **Minimum neuron stake**: Set the minimum number of ICP required for the creation of a neuron. The same limit must also be respected when increasing the dissolve delay or changing the neuron state from dissolving to aging. - - * **Neuron management fee**: The cost in ICP per neuron management proposal. Here the NNS is doing work on behalf of a specific neuron, and a small fee will be applied to prevent overuse of this feature (i.e., spam). - - * **Minimum ICP/SDR rate**: To prevent mistakes, there is a lower bound for the ICP/SDR rate, managed by network economic proposals. - - * **Dissolve delay of spawned neurons**: The dissolve delay of a neuron spawned from the maturity of an existing neuron. - - * **Maximum node provider rewards**: The maximum rewards to be distributed to node providers in a single distribution event (proposal). - - * **Transaction fee**: The transaction fee that must be paid for each ledger transaction. - - * **Maximum number of proposals to keep per topic**: The maximum number of proposals to keep, per topic. When the total number of proposals for a given topic is greater than this number, the oldest proposals that have reached a “final” state may be deleted to save space. - -* **Motion (#Governance)**: A motion is a text that can be adopted or rejected. No code is executed when a motion is adopted. An adopted motion should guide the future strategy of the Internet Computer ecosystem. - -* **ApproveGenesisKYC (#KYC)**: When new neurons are created at Genesis, they have GenesisKYC=false. This restricts what actions they can perform. Specifically, they cannot spawn new neurons, and once their dissolve delays are zero, they cannot be disbursed and their balances unlocked to new accounts. This proposal sets GenesisKYC=true for batches of principals. -(Special note: The Genesis event disburses all ICP in the form of neurons, whose principals must be KYCed. Consequently, all neurons created after Genesis have GenesisKYC=true set automatically since they must have been derived from balances that have already been KYCed.) - -* **AddOrRemoveNodeProvider (#ParticipantManagement)**: Assign (or revoke) an identity to a node provider, associating key information regarding the legal person associated that should provide a way to uniquely identify it. - -* **RewardNodeProvider (#NodeProviderRewards)**: Propose to reward a Gen-1 node provider an amount of ICP as compensation for providing Gen-1 nodes to ICP. - -* **SetDefaultFollowees (#Governance)**: Specify the list of followers that a freshly created neuron should have. - -The following is a list of proposal types that call other NNS canisters: - -* **CreateSubnet (#SubnetManagement)**: Combine a specified set of nodes, typically drawn from data centers and operators in such a way as to guarantee their independence, into a new decentralized subnet. The execution of this external update first initiates a new instance of the distributed key generation protocol. The transcript of that protocol is written to a new subnet record in the registry, together with initial configuration information for the subnet, from where the nodes comprising the subnet pick it up. - -* **AddNodeToSubnet (#SubnetManagement)**: Add a new node to a subnet. The node cannot be currently assigned to a subnet. The execution of this proposal changes an existing subnet record to add a node. From the perspective of the NNS, this update is a simple update of the subnet record in the registry. - -* **InstallNetworkCanister (#NetworkCanisterManagement)**: A proposal to add a new canister to be installed and executed in the NNS subnetwork. The root canister, which controls all canisters on the NNS except for itself, handles this proposal type. The call also expects the Wasm module that be installed. - -* **UpgradeNetworkCanister (#NetworkCanisterManagement)**: A proposal to upgrade an existing canister in the NNS subnetwork. This proposal type is executed by the root canister. Beyond upgrading the Wasm module of the target canister, the proposal can also set the authorization information and the allocations. - -* **BlessReplicaVersion (#NodeAdmin)**: A proposal to bless a new version to which the replicas can be upgraded. The proposal registers a replica version (identified by the hash of the installation image) in the registry. Besides creating a record for that version, the proposal also appends that version to the list of “blessed versions” that can be installed on a subnet. By itself, this proposal does not affect any upgrade. (In the future, there will only be one blessed version of the replica software at any given time.) - -* **RecoverSubnet (#SubnetManagement)**: Update a subnet’s recovery CUP (used to recover subnets that have stalled). Nodes that find a recovery CUP for their subnet will load that CUP from the registry and restart the replica from that CUP. - -* **UpdateSubnetConfig (#SubnetManagement)**: Update a subnet’s configuration. This proposal updates the subnet record in the registry, with the changes being picked up by the nodes on the subnet when they reference the respective registry version. Subnet configuration comprises protocol parameters that must be consistent across the subnet (e.g., message sizes). - -* **AssignNPID (#ParticipantManagement)**: Assign an identity to a node operator associating key information regarding its ownership, the jurisdiction in which it is located, and other information. The node operator is stored as a record in the registry. It contains the remaining node allowance for that node operator, that is the number of nodes the node operator can still add to ICP. When an additional node is added by the node operator, the remaining allowance is decreased. - -* **RootUpgrade (#NetworkCanisterManagement)**: A proposal to upgrade the root canister in the NNS subnetwork. The proposal is processed by the Lifeline canister, which controls the root canister. The proposal updates the Wasm module as well as the authorization settings. - -* **SetICPSDR (#ExchangeRate)**: Instruct the NNS about the market value of 1 ICP as measured by an IMF SDR. This setting affects cycles pricing (as the value of cycles shall be constant concerning IMF SDRs). - -* **UpgradeSubnetToReplicaVersion (#SubnetManagement)**: Update the replica version running on a given subnet. The proposal changes the replica version that is used on the specified subnet. The version must be contained in the list of blessed replica versions. The upgrade is performed when the subnet creates the next regular CUP. - -* **ClearProvisionalWhitelist (#NetworkEconomics)**: Clears the provisional whitelist, which allows the listed principals to create canisters with cycles. The mechanism is only needed for bootstrap and testing and must be deactivated afterward. - -* **RemoveNodeFromSubnet (#SubnetManagement)**: Remove a node from a subnet. It then becomes available for reassignment. The execution of this proposal changes an existing subnet record to remove a node. From the perspective of the NNS, this update is a simple update of the subnet record in the registry. - -* **SetAuthorizedSubnetworks (#Governance)**: Informs the cycles minting canister that a certain principal is authorized to use certain subnetworks (from a list). Can also be used to set the “default” list of subnetworks that principals without special authorization are allowed to use. - -* **SetFirewallConfig (#SubnetManagement)**: Change the Firewall configuration in the registry (configures which boundary nodes subnet blockchain replicas will communicate with). - -* **UpdateNodeOperatorConfig (#NodeAdmin)**: Change a node operator’s allowance in the registry. - -* **StopOrStartNNSCanister (#NetworkCanisterManagement)**: Stop or start an NNS canister. - -## ICP tokens -ICP are native utility tokens that play three key roles in the network: - -* **Facilitating network governance**: ICP tokens can be locked to create neurons that participate in network governance by voting, through which they can earn economic rewards. - -* **Production of cycles for compute**: ICP provides a source store of value that can be converted into “cycles,” which power computation in the role of fuel that is burned when it is used. The NNS converts ICP to cycles at a variable rate, so chosen to ensure users of the network can always create new cycles at approximately constant cost concerning IMF SDR, such that the cost of acquiring fuel is predictable. - -* **Rewarding participants**: The network provides rewards to incentivize those playing important roles that enable the network to function, including a) the provision of “voting rewards” to those participating in governance, and b) the provision of “node provider rewards” to those operating the node machines that are hosting the network. - -## Ledger -The ICP ledger is hosted within the NNS and records all balances of ICP in the manner similar to a spreadsheet. Each row is called an “account,” which has two fields (i.e., there are two “columns”): - -* **Account identifier (bytes)**: A unique value that is derived from the identity of the “principal” that “controls” the account. Currently, the principal must either be (i) the owner of a public key pair, or (ii) a canister smart contract that is part of the NNS. Account identifiers are derived by hashing the concatenation of a domain separator, the principal ID, and the subaccount (or zeros if no subaccount is given). - -* **Balance**: The quantity of ICP assigned to the account. - -When the principal is a public key or Canister, they can apply the following operation to an account: - -* **Send**: Transfer a portion of the ICP balance to another account. If all the ICP is sent to another account, then the transfering account ceases to exist (i.e., is deleted from the ledger). - -Operations that require interaction between the ledger and the governance system (Neurons): - -* **Create neuron**: When the principal is a public key holder, they may lock a portion of their balance inside a new neuron. Technically, creating the neuron is done in two stages. First, transfer the ICP to be staked to an account of the governance canister (which corresponds to a new neuron — the details of the association are omitted here). Then notify the governance canister of the incoming transfer which updates its internal neuron bookkeeping. To move these ICP to a different account, such as back to the original account, where they can once again be controlled like a normal balance, the associated neuron must be fully dissolved and disbursed (destroyed). - -* **Refresh stake**: The stake of a neuron may be increased by transferring to its address/account in the ledger and notifying the governance canister of the incoming transfer. Refreshing the stake will change the maturity and age of the neuron prorated. For example, if the stake is doubled, the maturity and age will be halved, so spawning will yield the same amount and the age bonus will be the same as before (in absolute terms). diff --git a/docs/developer-docs/daos/nns/using-the-nns-dapp/nns-app-quickstart.mdx b/docs/developer-docs/daos/nns/using-the-nns-dapp/nns-app-quickstart.mdx new file mode 100644 index 0000000000..d776bf5c58 --- /dev/null +++ b/docs/developer-docs/daos/nns/using-the-nns-dapp/nns-app-quickstart.mdx @@ -0,0 +1,77 @@ +--- +keywords: [beginner, governance, tutorial, nns] +--- + +import { MarkdownChipRow } from "/src/components/Chip/MarkdownChipRow"; +import '/src/components/CenterImages/center.scss'; + +# Authentication + + + +## Overview + +There are different ways to interact with the NNS DAO to participate in governance. + +This guide will demonstrate how to interface with the NNS through the [NNS dapp](https://nns.ic0.app). +You can interact with the NNS through other tools, such as [quill](/docs/current/developer-docs/developer-tools/cli-tools/quill-cli-reference/quill-parent) +and [ic-js](https://github.com/dfinity/ic-js/tree/main/packages/nns). + +This section starts with a tutorial on how to connect and log in to the NNS dapp. +In the following pages, you will see how to use the NNS dapp to +[transfer tokens](/docs/current/developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-send-and-receive-tokens), +[stake tokens and set up a neuron](/docs/current/developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-staking-a-neuron), +and how to participate in voting either by [voting manually](/docs/current/developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-voting-on-proposals) + or by [following other neurons](/docs/current/developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-following-other-neurons). + + +## Connect to the NNS DAO using the NNS dapp + +To connect to the NNS using the Network Nervous System (NNS) dapp, follow these steps which are also explained in the first minutes of this video. + + +- #### Step 1: Open a browser and navigate to the [Network Nervous System (NNS)](https://nns.ic0.app) dapp. + +![NNS dapp](../../_attachments/nns1.png) + +- #### Step 2: Click **Login** to connect to [Internet Identity](https://identity.ic0.app). + +![Connect with Internet Identity](../../_attachments/nns2.png) + +If you haven’t previously registered, you can click **Register with Internet Identity** to register. + +:::info +We strongly recommend you add multiple devices and authentication methods to your Internet Identity. For example, register multiple physical devices like your computer and phone with a security key and using the authentication options that those devices—and browsers running on them—support. +::: + +For more information about creating an Internet Identity, see [how to use Internet Identity](https://internetidentity.zendesk.com/hc/en-us/articles/15430677359124-How-Do-I-Create-an-Internet-Identity-on-My-Mobile-Device-). + +After you have registered, you can click **Login** to authenticate using your anchor and the authentication method—for example, a security key or fingerprint—you have registered. + +- #### Step 3: Click **Proceed** to access to the Network Nervous System (NNS) dapp. + +## Add an account + +Logging on using an Internet Identity creates a main account for you in the Internet Computer ledger. If your ICP utility tokens are associated with your developer identity; that is, the identity created by the SDK `dfx` command-line interface. Your main account displays 0.00 for your ICP utility token balance. For example: + +![nns app main](../../_attachments/nns3.png) + +Before transferring any tokens, you can create one or more linked subaccounts or attach a hardware wallet to your account. + +To add an account for managing ICP utility tokens: + +- #### Step 1: On the default 'Tokens' tab, click 'ICP', then **Add Account**. + +![Add account](../../_attachments/nns4.png) + +- #### Step 2: Select the type of account to add. + + - **New Account** creates a new subaccount linked to your Main account address in the ledger. + + - **New Account (Hardware Wallet)** adds a hardware wallet to your main account address in the ledger. + +![Select account](../../_attachments/nns5.png) + +- #### Step 3: Click **New Account**, type an Account Name, then click **Create**. + +![new linked account](../../_attachments/nns6.png) \ No newline at end of file diff --git a/docs/developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-additional-features.mdx b/docs/developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-additional-features.mdx new file mode 100644 index 0000000000..ff2e47eb17 --- /dev/null +++ b/docs/developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-additional-features.mdx @@ -0,0 +1,73 @@ +--- +keywords: [beginner, governance, tutorial, nns] +--- + +import { MarkdownChipRow } from "/src/components/Chip/MarkdownChipRow"; +import '/src/components/CenterImages/center.scss'; +import { GlossaryTooltip } from "/src/components/Tooltip/GlossaryTooltip"; + +# Additional features + + + +## Overview +In addition to being the portal for interacting with the NNS DAO, the NNS dapp also provides access to the SNS DAOs, their launches, and allows users to manage canisters that they control. +This is a brief guide to some of these additional functionalities. + +## SNS decentralization swaps + +You can participate in SNS decentralization swaps from the NNS dapp using the 'Launchpad' tab. An SNS is an advanced version of a decentralized autonomous organization, where the participants of the SNS can vote on proposals, such as a new feature, roadmap item, or allocation of SNS funds. + +[Learn more about SNSs](https://internetcomputer.org/sns). + +To view current and past SNS decentralization swaps from the NNS dapp: + +- #### Step 1: From the NNS dapp, click **Launchpad** from the left navigation bar. + +![Launchpad](../../_attachments/nns21.png) + +- #### Step 2: Select any SNS swap to view the details, such as the status, total participants, token supply, and when the swap ended. + +![SNS swap](../../_attachments/nns22.png) + +## Deploying and managing canisters from the NNS dapp + +You must have **cycles** available to create and manage [canisters](/docs/current/concepts/glossary#canister). +The [NNS dapp](https://nns.ic0.app) provides a convenient way for you to create and manage canisters by enabling you to convert ICP utility tokens into cycles and attach cycles to specific canister identifiers. + +To create a new canister: + +- #### Step 1: From the NNS dapp, click **Canisters**, then click **Create Canister** or **Link Canister**. + +![My canisters](../../_attachments/nns23.png) + +- #### Step 2: If you select **Create Canister**, select the source account you'd like to use to create the canister. + +![Create a new canister](../../_attachments/nns24.png) + +- #### Step 3: Then, enter the amount of ICP tokens and cycles to create the canister with. Then select **Review Canister Creation**. + +![Create a new canister](../../_attachments/nns25.png) + +- #### Step 4: Review the ICP utility tokens to cycles details, then click **Confirm** to continue. + +After you click Confirm, you can review: +- The new canister identifier. +- The number of cycles available for the canister to use. +- The controlling principal that currently has full management rights for the new canister. + +:::info +To change the principal used as the controller of the canister, click **Change Controllers**. + +To add cycles to the canister, click **Add Cycles**. +::: + +- #### Step 5: To link a canister, input the canister's ID, then select **Confirm**. + +![Link canister](../../_attachments/nns26.png) + +- #### Step 6: Return to the **Canisters** tab to see the canisters you have created. + +For example: + +![Canister list](../../_attachments/nns27.png) diff --git a/docs/developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-advanced-neuron-operations.mdx b/docs/developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-advanced-neuron-operations.mdx new file mode 100644 index 0000000000..4ee772d880 --- /dev/null +++ b/docs/developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-advanced-neuron-operations.mdx @@ -0,0 +1,30 @@ +--- +keywords: [intermediate, governance, tutorial, nns] +--- + +import { MarkdownChipRow } from "/src/components/Chip/MarkdownChipRow"; +import '/src/components/CenterImages/center.scss'; + +# Spawn new neurons + + + +## Overview +Once you are a bit more familiar with the NNS, you might want to use the NNS dapp to perform additional neuron operations. + +For more background on neurons, including the concepts of voting rewards and what the different neuron operations do in details, +refer to the [Neurons overview](/docs/current/developer-docs/daos/nns/concepts/neurons/neuron-overview). + +## Spawn your voting rewards into a new neuron +As you vote on proposals, either directly or by following the votes of other neurons, the maturity associated with your neuron increases, which in turn increases the rewards you earn for participating in governance. +When the maturity for a locked stake reaches a minimum threshold of 1 ICP, you can spawn a new neuron. The spawn operation creates a new neuron that locks a new balance of ICP on the ledger. + +For example, if you have a neuron that contains 100 ICP utility tokens and it has a maturity of 10 percent, you can spawn a new neuron that contains approximately 10 new ICP tokens. For the neuron with 100 ICP tokens to reach the minimum threshold for spawning, its maturity would need to be greater than 1 percent. + +After you spawn a new neuron from an existing neuron, the maturity for the existing neuron falls to zero. + +To spawn new neurons from an existing neuron: + +- #### Step 1: From the NNS dapp, select 'Neuron Staking', then click the neuron that has reached the minimum maturity required to spawn a new neuron. + +- #### Step 2: Click **Spawn Neuron**. diff --git a/docs/developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-following-other-neurons.mdx b/docs/developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-following-other-neurons.mdx new file mode 100644 index 0000000000..c2487764a4 --- /dev/null +++ b/docs/developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-following-other-neurons.mdx @@ -0,0 +1,60 @@ +--- +keywords: [beginner, governance, tutorial, nns] +--- + +import { MarkdownChipRow } from "/src/components/Chip/MarkdownChipRow"; +import '/src/components/CenterImages/center.scss'; + +# Configuring neuron following + + + + + +## Overview +Neuron owners may find it hard to manually vote on every proposal submitted to the NNS. +For example, they may not have the time or necessary expertise to evaluate each individual proposal. +The NNS uses a form of liquid democracy to address these challenges called **following**. + +As it is in each neuron's interest to follow other neurons that support the best interests of the network and their +own, we recommend to study the precise rules of following as well as how you can find neurons to follow on +[Following](/docs/current/developer-docs/daos/nns/concepts/neurons/neuron-following). For information about how you +can become a neuron that can be followed, we refer to [Registering a known neuron](/docs/current/developer-docs/daos/nns/concepts/neurons/becoming-a-known-neuron). + +## Setting your neurons' following in the NNS dapp + +To configure your neuron to follow a group of another neurons: + +- #### Step 1: From the NNS dapp, select 'Neuron Staking', then select the neuron that you'd like to set a following rule for. + +![NNS Neuron following 1](../../_attachments/nns8.png) + +- #### Step 2: In the neuron's details, scroll down to the 'Following' section and select 'Follow Neurons'. + +![NNS Neuron following 2](../../_attachments/nns13.png) + +- #### Step 3: Next, select a topic to follow. + +The topic refers to the different types of proposals; for example, the 'Governance' topic defines a following role for governance-related proposals, while the 'Subnet Management' topic defines a following role for subnet management proposals. There is also a 'catch-all' rule that can be followed for all proposal types except for governance, SNS, and neurons' fund. + +For this example, select 'SNS & Neurons' Fund'. + +![NNS Neuron following 3](../../_attachments/nns14.png) + +- #### Step 4: Select 'Add Followee'. + +![NNS Neuron following 4](../../_attachments/nns15.png) + +- #### Step 5: Enter a Neuron ID to follow, or select a group of neurons from the menu provided. + +In this example, select 'DFINITY Foundation'. + +![NNS Neuron following 5](../../_attachments/nns16.png) + +- #### Step 6: The window will now reflect the following configuration: + +![NNS Neuron following 6](../../_attachments/nns17.png) + +The configuration will also now be shown in the neuron's details: + +![NNS Neuron following 7](../../_attachments/nns18.png) diff --git a/docs/developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-manage-quill-neurons.mdx b/docs/developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-manage-quill-neurons.mdx new file mode 100644 index 0000000000..b2d869a953 --- /dev/null +++ b/docs/developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-manage-quill-neurons.mdx @@ -0,0 +1,65 @@ +--- +keywords: [intermediate, governance, tutorial, nns] +--- + +import { MarkdownChipRow } from "/src/components/Chip/MarkdownChipRow"; +import '/src/components/CenterImages/center.scss'; + +# Accessing Neurons Created with Quill using the NNS Dapp and Ledger + + + + + +## Overview +You may have neurons controlled by a principal ID that was created using [quill](../../../../../../docs/current/developer-docs/developer-tools/cli-tools/quill-cli-reference/quill-parent). In this case, it may be inconvenient to manage your neurons through the terminal. If you know the seed phrase of this principal ID, you can use a Ledger hardware wallet to manage your neurons through the [NNS dapp](https://nns.ic0.app/). + +## How to access neurons controlled by a principal ID created with quill + +To follow this process, you may want to set up a new Ledger device. If you do, skip **step 1** and **step 2**. See warning message below for more information. + +- **Step 1**: Unlock your Ledger device and navigate to **Settings Manage device** > **Security** > **Reset device** + +![NNS Dapp Ledger 1](../../_attachments/ledger-1.webp) + +- **Step 2**: Type in your PIN to reset your Ledger device. + +:::caution +**Warning**: This process will reset the private key of your Ledger device. **You will no longer have access to digital assets you hold on this device.** + +While you can always regain access by resetting the device with its current seed phrase, you may want to use a new Ledger device to continue. In general, it is advised to securely store your seed phrase. +::: + +- **Step 3**: After your Ledger device has been successfully reset, navigate to **Restore from Recovery phrase**. + +![NNS Dapp Ledger 2](../../_attachments/ledger-2.webp) + +- **Step 4**: Select the number of words in your seed phrase, and enter the seed phrase of the principal ID that controls the neurons you would like to access. + +![NNS Dapp Ledger 3](../../_attachments/ledger-3.webp) + +- **Step 5**: Install the **Internet Computer** app on your Ledger device. + +![NNS Dapp Ledger 4](../../_attachments/ledger-4.webp) + +- **Step 6**: Go to the [NNS dapp](https://nns.ic0.app/) and Sign in with **Internet Identity**. + +- **Step 7**: Go to **Tokens** > **Internet Computer** > **+ Add Account** and select **New Account (Hardware Wallet)**. + +![NNS Dapp Ledger 5](../../_attachments/ledger-5.webp) + +- **Step 8**: While your Ledger device is connected to your computer, select your device from the popup to connect. + +![NNS Dapp Ledger 6](../../_attachments/ledger-6.webp) + +- **Step 9**: You can verify the principal ID and account ID, then click **Create**. + +![NNS Dapp Ledger 7](../../_attachments/ledger-7.webp) + +- **Step 10**: Select the ICP account you just created + +- **Step 11**: Click **Show Neurons** and approve the transaction on your Ledger device + +![NNS Dapp Ledger 8](../../_attachments/ledger-8.webp) + +- **Step 12**: Click **Add to NNS Dapp** to add your NNS Dapp principal ID as a hotkey to the neurons. This allows you to see and manage your neurons using the NNS Dapp. For all actions outside of voting and changing following, you will need to have your Ledger device connected and approve the action. \ No newline at end of file diff --git a/docs/developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-send-and-receive-tokens.mdx b/docs/developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-send-and-receive-tokens.mdx new file mode 100644 index 0000000000..aef2bc0e36 --- /dev/null +++ b/docs/developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-send-and-receive-tokens.mdx @@ -0,0 +1,123 @@ +--- +keywords: [beginner, governance, tutorial, nns] +--- + +import { MarkdownChipRow } from "/src/components/Chip/MarkdownChipRow"; +import '/src/components/CenterImages/center.scss'; + +# Receiving ICP tokens + + + +## Overview +When you log into the NNS dapp for the first time you will not yet have any ICP tokens in your wallet. +Therefore, you first might want transfer some tokens to the NNS dapp wallet. +This also the first step required for staking a neuron with the NNS dapp. + +## Get tokens from an exchange +If you already have ICP tokens on an exchange, you can transfer some of them to your NNS dapp account as explained in this video: + + +- #### Step 1: Open one of your accounts in the ICP wallet. + +![Send ICP](../../_attachments/copy-subaccount.png) + +- #### Step 2: Find the address to send the tokens to in the top right corner and can copy it by clicking on the symbol next to the number. + +- #### Step 3: Go to your exchange and send tokens to the address you just copied. + +Using this, you can send tokens from any exchange that supports sending ICP. +The tokens should be visible in your wallet within a few seconds or minutes. + +:::info +Not all exchanges support all features. It is advised to check with the exchange to be sure it supports the workflow described above. +::: + +## Get tokens from a developer identity using the CLI + +If you have selected self-custody for holding your ICP utility tokens, and the tokens are associated with your developer identity instead of your registered Internet Identity, you need to transfer the ICP utility tokens to your NNS account if you want to manage them using the [NNS dapp](https://nns.ic0.app). + +To transfer ICP utility tokens controlled by your developer identity: + +- #### Step 1: Open a terminal shell on your local computer. + +- #### Step 2: Check that you are using an identity with control over the ledger account by running the following command: + +``` bash +dfx identity whoami +``` + +In most cases, you should see that you are currently using your `default` developer identity. For example: + +``` +default +``` + +- #### Step 3: View the textual representation of the principal for your current identity by running the following command: + +``` bash +dfx identity get-principal +``` + +This command displays output similar to the following: + +``` +tsqwz-udeik-5migd-ehrev-pvoqv-szx2g-akh5s-fkyqc-zy6q7-snav6-uqe +``` + +- #### Step 4: Check the current balance in the ledger account associated with your identity by running the following command: + +``` bash +dfx ledger --network ic balance +``` + +- #### Step 5: Transfer ICP utility tokens to your Main account or a linked subaccount you create by running a command similar to the following: + +``` bash +dfx ledger --network ic transfer --icp --memo +``` + +To find your account on the NNS dapp wallet, proceed as explained above. +For example, assume your account is `0dff47055d84fd0d89cc55ff477c24026b5c2c9175f8fd36bcb66bb68cac81be` + +If you want to transfer 1 ICP utility token to this account, you can run the following command: + +``` +dfx ledger --network ic transfer 0dff47055d84fd0d89cc55ff477c24026b5c2c9175f8fd36bcb66bb68cac81be --memo 12345 --icp 1 +``` + +:::info +This example illustrates how to transfer ICP utility tokens using a whole number with the `--icp` command line option. +- You can also specify fractional units of ICP utility tokens—called **e8s**—using the `--e8s` option, either on its own or in conjunction with the `--icp` option. +- Alternatively, you can use the `--amount` to specify the number of ICP utility tokens to transfer with fractional units up to 8 decimal places, for example, as `5.00000025`. +::: + +The destination address can be any address in the ledger canister which might correspond to: + +- A wallet that is owned by a developer principal. +- An account you have added using the NNS dapp. +- An address for a wallet you have on an exchange. + +If you transfer the ICP utility tokens to an account in the [NNS dapp](https://nns.ic0.app), you might need to refresh the browser to see the transaction reflected. + +For more information about using the `dfx ledger` command line options, see [dfx ledger](/docs/current/developer-docs/developer-tools/cli-tools/cli-reference/dfx-ledger). + + +## Send ICP tokens with your NNS dapp account +Once you have ICP tokens in your NNS dapp account, you can send them to other accounts by following these steps. + +- #### Step 1: On the default 'Tokens' tab, assure that the Internet Computer token has been selected, then click **Send** on the bottom of the window. + +![Send](../../_attachments/nns4.png) + +- #### Step 2: In the 'Send' window, select your linked account or wallet for the source, then input the destination address and the amount of ICP to send. + +Transactions are charged a ledger fee, which is independent from the NNS dapp and applies to any transaction. For ICP tokens, this fee is 0.0001 ICP. + +The maximum amount you can send is your token balance minus the ledger fee. The minimum amount you can send is 0.00000001 ICP. + +![Send ICP](../../_attachments/nns7.png) + +- #### Step 3: Then select **Continue** to send the transaction. + +Similarly to the CLI transfer above, the destination address can be any address in the ledger canister. \ No newline at end of file diff --git a/docs/developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-staking-a-neuron.mdx b/docs/developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-staking-a-neuron.mdx new file mode 100644 index 0000000000..f1d43c56ae --- /dev/null +++ b/docs/developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-staking-a-neuron.mdx @@ -0,0 +1,114 @@ +--- +keywords: [beginner, governance, tutorial, nns] +--- + +import { MarkdownChipRow } from "/src/components/Chip/MarkdownChipRow"; +import '/src/components/CenterImages/center.scss'; + +# Staking a neuron + + + +When a person or organization has ICP utility tokens locked up in a neuron, they can propose and vote on governance proposals. +To encourage participation, neuron holders are also rewarded for voting in proportion to the number of ICP utility tokens they have locked up, +the length of the lock-up period, called the *dissolve delay*, and the age of their neuron. + +After network participants create a neuron, the locked balance of ICP utility tokens can only be unlocked by fully **dissolving** the neuron. +It's **dissolve delay** determines the time it takes for a neuron to be unlocked once it is in the dissolving state. +A dissolving neuron can always be put back into the non-dissolving state. +When the dissolve timer reaches zero, the neuron owner can dissolve the neuron and unlock the neuron's balance of ICP. + +## Stake ICP utility tokens in a neuron + +After you transfer ICP utility tokens to the NNS dapp, you can use it to create and manage neurons, +vote on proposals, and create canisters on the Internet Computer. + +Neurons are required to participate in governance to earn rewards. To create a neuron, you must lock up some number of ICP utility tokens for a period of time. +The minimum stake required to create a neuron is 1 ICP utility token. You can configure the period of time the stake is locked from 6 months up to a maximum of 8 years. + + +To stake ICP utility tokens: + +- #### Step 1: In the NNS dapp, select **Neuron Staking** from the left navigation bar, then click **Stake Neurons** in the bottom of the window. + +![Neuron staking](../../_attachments/nns8.png) + +- #### Step 2 : Select which wallet you'd like to use as the source, then type the number of ICP utility tokens to stake, then click **Create**. + +![Neuron staking](../../_attachments/nns9.png) + +- #### Step 3: Set the dissolve delay for the neuron to control the length of time the stake is locked, then click **Update Delay**. + +For example: + +![dissolve delay](../../_attachments/nns-dissolve.png) + +- #### Step 4: Click **Confirm and Set Delay** to confirm the lock up period. + +![neuron properties](../../_attachments/nns-settings.png) + +## What you can do after creating a neuron +After you have locked the stake and created a neuron, you can set it up and modify it. +These are some of the things you can modify: + +- Start the dissolve delay timer by clicking **Start Unlock**. +- Increase the dissolve delay period by clicking **Increase Dissolve Delay**. +- Stop the dissolve delay after starting the unlock countdown by clicking **Lockup**. +- Increase the number of ICP utility tokens you have staked. + +For more tutorials on what you can do with your neuron, we refer to +[Advanced neuron operations](/docs/current/developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-advanced-neuron-operations). + +### Start and stop dissolving the neuron + +Creating a new neuron does not automatically start the dissolve delay timer. You must explicitly start the timer countdown by clicking **Start Unlock**. + +For example, if you set a dissolve delay of 1 year and want to immediately begin the countdown, you should click **Start Unlock** as part of the process of creating the neuron. If you change your mind and want to stop a current countdown in progress, you can click **Lockup**. + +After you click **Lockup** to stop the dissolve delay, you can click **Start Unlock** to resume the countdown without changing the existing dissolve delay period. If you want to continue a countdown already in progress but extend the lock up period, you can click **Increase Dissolve Delay** then select a longer dissolve delay. + +### Top up an existing neuron with additional ICP utility tokens + +After you create a neuron, you can increase the number of ICP utility tokens you have staked in that neuron to increase your voting power and rewards. For example, if you initially stake a small number of ICP utility tokens, then decide to purchase additional tokens, you have the option to create a new neuron or "top-up" your existing neuron. + +To increase the stake in an existing neuron: + +- #### Step 1: Follow the steps in [stake ICP utility tokens in a neuron](#stake-icp) to stake the original neuron using the [Network Nervous System (NNS)](https://nns.ic0.app) dapp. + +- #### Step 2: Look up the transaction in the Internet Computer Association [transaction dashboard](https://dashboard.internetcomputer.org/transactions) to get the neuron address. + +You can use the account identifier for your main ICP ledger account to search for your transactions. + +- #### Step 3: Return to the [Network Nervous System (NNS)](https://nns.ic0.app) dapp, then from the 'My Neuron Staking' window, click **New Transaction**. + +- #### Step 4: Paste the neuron address from the transaction dashboard into the **Destination** address field, then click **Continue**. + +- #### Step 5: Type the amount of ICP utility tokens you want to add to the specified neuron, then click **Continue**. + +![Increase stake](../../_attachments/nns10.png) + +- #### Step 6: Verify the transaction details, then click **Send Now**. + +![Confirm increase stake](../../_attachments/nns11.png) + +- #### Step 7: Once the transaction has completed, you will see the increased stake value. + +![Increased stake](../../_attachments/nns12.png) + +### Disburse a dissolved neuron into an account + +When the dissolve delay timer for a neuron reaches zero, you can disburse the neuron’s stake and transfer its locked ICP utility token balance to the ledger account you specify. + +To disburse a neuron and return its ICP utility tokens: + +- #### Step 1: From the NNS dapp, select 'My Neuron Staking', then click on an unlocked neuron that has reach the ended of its dissolve delay period. + +- #### Step 2: Click **Disburse**: + +- #### Step 3: Type an address or select an account to receive the ICP utility tokens. + +![select account](../../_attachments/select-account.png) + +- #### Step 4: Verify the transaction information, then click **Confirm and Send**. + + diff --git a/docs/developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-voting-on-proposals.mdx b/docs/developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-voting-on-proposals.mdx new file mode 100644 index 0000000000..b342284775 --- /dev/null +++ b/docs/developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-voting-on-proposals.mdx @@ -0,0 +1,51 @@ +--- +keywords: [beginner, governance, tutorial, nns] +--- + +import { MarkdownChipRow } from "/src/components/Chip/MarkdownChipRow"; +import '/src/components/CenterImages/center.scss'; + +# Voting on proposals + + + + + +Active participation in governance is an important factor in the long-term health of the Internet Computer and participants receive voting rewards. + +To maximize your rewards, you should vote on as many proposals as possible. +This can be done by voting manually or by delegating your voting power to other neurons using [following](/docs/current/developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-voting-on-proposals). + +To manually vote on proposals: + +- #### Step 1: From the NNS dapp, select 'Voting' from the left navigation bar. + +![Proposals](../../_attachments/nns19.png) + +- #### Step 2: Then, select which Nervous System you'd like to view proposals for. + +By default, the Internet Computer NNS proposals are shown, but other proposals for SNSs like OpenChat and Kinic are also available. + +- #### Step 3: Click on any proposals to view more information on it, such as the proposals summary, the type of proposals, the topic, and when the proposal's voting ends. + +![Proposal detail](../../_attachments/nns20.png) + +By default, the NNS dapp will show you all **actionable proposals** where you have neurons that are eligible to vote. This includes the proposals of all DAOs, NNS and SNSs, where you have neurons. + +If you would like to look only at proposals of one DAO, for example the NNS, you can select the respective "Nervous System" on the left. +You can also use the selection on top to see all proposals, including the ones where you cannot take any action, for example because you do not have a neuorn that is eligible to vote or because you already voted. +Moreover, you can use the filter on the top right to only see proposals of a specific topic or in a specific status. + +:::info +For more information about voting and voting rewards, see the following articles: + +- [Earn substantial voting rewards by staking in the Network Nervous System](https://medium.com/dfinity/earn-substantial-voting-rewards-by-staking-in-the-network-nervous-system-7eb5cf988182) + +- [Understanding the Internet Computer’s Network Nervous System, neurons, and ICP utility tokens](https://medium.com/dfinity/understanding-the-internet-computers-network-nervous-system-neurons-and-icp-utility-tokens-730dab65cae8) + +- [Getting started on the Internet Computer’s Network Nervous System app and wallet](https://medium.com/dfinity/getting-started-on-the-internet-computers-network-nervous-system-app-wallet-61ecf111ea11) + +For more advanced information about proposals' lifecycle and how to verify proposals in depth when voting, +refer to [Proposals](/docs/current/developer-docs/daos/nns/concepts/proposals/proposal-overview) +and [Verify proposals](/docs/current/developer-docs/daos/nns/concepts/proposals/verify-proposals). +::: diff --git a/docs/developer-docs/daos/overview.mdx b/docs/developer-docs/daos/overview.mdx index 91318e0bb0..b91708de55 100644 --- a/docs/developer-docs/daos/overview.mdx +++ b/docs/developer-docs/daos/overview.mdx @@ -36,11 +36,11 @@ Some examples of proposals for changes that the NNS is responsible for deciding You can learn more about the NNS [here](/docs/current/developer-docs/daos/nns/overview). -Proposals, voting and rewards are [explained here](/docs/current/developer-docs/daos/nns/staking-voting-rewards) can be explored in the [Governance section](https://dashboard.internetcomputer.org/governance) on the dashboard. +Proposals, voting and rewards are [explained here](/docs/current/developer-docs/daos/nns/concepts/neurons/staking-voting-rewards) can be explored in the [Governance section](https://dashboard.internetcomputer.org/governance) on the dashboard. Read about the [neurons' fund(/docs/current/developer-docs/daos/nns/neurons-fund). -Start participating in the NNS app by checking out the [NNS introduction](/docs/current/developer-docs/daos/nns/nns-app-quickstart). +Start participating in the NNS app by checking out the [NNS introduction](/docs/current/developer-docs/daos/nns/using-the-nns-dapp/nns-app-quickstart). ## Service Nervous System (SNS) diff --git a/docs/developer-docs/daos/sns/managing/making-proposals.mdx b/docs/developer-docs/daos/sns/managing/making-proposals.mdx index f914a44740..a150aeb5cb 100644 --- a/docs/developer-docs/daos/sns/managing/making-proposals.mdx +++ b/docs/developer-docs/daos/sns/managing/making-proposals.mdx @@ -550,7 +550,7 @@ quill sns --canister-ids-file ./sns_canister_ids.json --pem-file $PEM_FILE make- name = null; - description = "UPDATED Sample SNS used for educational purposes"; + description = opt "UPDATED Sample SNS used for educational purposes"; }; }; } diff --git a/docs/developer-docs/daos/sns/managing/managing-nervous-system-parameters.mdx b/docs/developer-docs/daos/sns/managing/managing-nervous-system-parameters.mdx index 917036896e..af1a2b9f35 100644 --- a/docs/developer-docs/daos/sns/managing/managing-nervous-system-parameters.mdx +++ b/docs/developer-docs/daos/sns/managing/managing-nervous-system-parameters.mdx @@ -13,11 +13,12 @@ import { MarkdownChipRow } from "/src/components/Chip/MarkdownChipRow"; The nervous system parameters define the settings of a particular SNS. -Since all SNSs are upgraded along the same upgrade path [refer to architecture part], this is what allows SNSs to nevertheless customise the rules of their governance, the tokenomics, etc to meet their needs. +Since all SNSs are upgraded along the same upgrade path, this is what allows SNSs to customize the rules of their governance, the tokenomics, etc to meet their needs. ## The `ManageNervousSystemParameters` proposal The proposal `ManageNervousSystemParameters` allows the SNS community to adjust these parameters at any time. +Any fields that are left empty in the proposal are not changed and will keep their old value. ### Relevant type signatures diff --git a/docs/developer-docs/daos/sns/tokenomics/preparation.mdx b/docs/developer-docs/daos/sns/tokenomics/preparation.mdx index 7a2f64fca6..ba7b1ce15d 100644 --- a/docs/developer-docs/daos/sns/tokenomics/preparation.mdx +++ b/docs/developer-docs/daos/sns/tokenomics/preparation.mdx @@ -68,10 +68,4 @@ This means that rather than one neuron, they can get many neurons with different dissolve delays. The details of these neurons can be set in the initialization. -If only parts of the swap tokens are sold in the initial decentralization swap, -the developer neurons' voting power is restricted by a multiplier. This multiplier -is proportional to the portion of swap tokens that are sold in the initial -decentralization swap. As more of the swap tokens are sold in the future, the -voting power multiplier increases until it is 1 when all swap tokens have been -sold. diff --git a/docs/developer-docs/defi/_attachments/hardware-wallet.png b/docs/developer-docs/defi/_attachments/hardware-wallet.png new file mode 100644 index 0000000000..d012e81d93 Binary files /dev/null and b/docs/developer-docs/defi/_attachments/hardware-wallet.png differ diff --git a/docs/developer-docs/defi/cycles/cycles-wallet.mdx b/docs/developer-docs/defi/cycles/cycles-wallet.mdx index 9d531ab8fd..ab7e2d4f15 100644 --- a/docs/developer-docs/defi/cycles/cycles-wallet.mdx +++ b/docs/developer-docs/defi/cycles/cycles-wallet.mdx @@ -90,7 +90,7 @@ If you are doing local development, your local cycles wallet is created when you If you are deploying on the Internet Computer mainnet, you typically create your cycles wallet by converting ICP tokens to cycles, transferring the cycles to a new canister principal, and updating the canister with the default cycles wallet WebAssembly module (Wasm). -There are dapps that can help you convert ICP to cycles and create a new cycles wallet, e.g., [NNS dapp](/docs/current/developer-docs/daos/nns/nns-app-quickstart#_deploy_a_canister_with_cycles). +There are dapps that can help you convert ICP to cycles and create a new cycles wallet, e.g., [NNS dapp](/docs/current/developer-docs/daos/nns/using-the-nns-dapp/nns-app-quickstart#_deploy_a_canister_with_cycles). - #### Step 1: Create a new canister with cycles by transferring ICP tokens from your ledger account. You can do so by running a command similar to the following: ``` diff --git a/docs/developer-docs/defi/overview.mdx b/docs/developer-docs/defi/overview.mdx index 852680baa9..9e41a95e1f 100644 --- a/docs/developer-docs/defi/overview.mdx +++ b/docs/developer-docs/defi/overview.mdx @@ -133,7 +133,7 @@ Once you have selected a wallet or other custody solution, you can obtain tokens - Receiving airdrops or transfers from others. -- [Receiving ICP tokens as governance rewards](/docs/current/developer-docs/daos/nns/staking-voting-rewards/). +- [Receiving ICP tokens as governance rewards](/docs/current/developer-docs/daos/nns/concepts/neurons/staking-voting-rewards/). The ICP index canister is running on the NNS subnet with the canister ID [qhbym-qaaaa-aaaaa-aaafq-cai](https://dashboard.internetcomputer.org/canister/qhbym-qaaaa-aaaaa-aaafq-cai). As there are multiple ICRC-1 compatible ledgers, there will also be multiple ICRC-1 index canisters. For example, the ICRC-1 index canister recording ckBTC transactions is running under the canister ID [n5wcd-faaaa-aaaar-qaaea-cai](https://dashboard.internetcomputer.org/canister/n5wcd-faaaa-aaaar-qaaea-cai). diff --git a/docs/developer-docs/defi/wallets/self-custody/hardware-wallet-cli.mdx b/docs/developer-docs/defi/wallets/self-custody/hardware-wallet-cli.mdx index 9e8fcbbd83..d33bd74429 100644 --- a/docs/developer-docs/defi/wallets/self-custody/hardware-wallet-cli.mdx +++ b/docs/developer-docs/defi/wallets/self-custody/hardware-wallet-cli.mdx @@ -30,7 +30,7 @@ Choose a PIN. To connect your Ledger device to an Internet Identity, select "Rec - #### Step 3: On your computer, install Ledger Live from ledger.com and start it. -If offered to upgrade to a newer version then do so. +Upgrade to a newer version if prompted. - #### Step 4: Connect the Nano device to USB and, if necessary, unlock it with the PIN. @@ -74,8 +74,60 @@ The hardware wallet CLI tool supports the following commands and options: - `--principal `: Specifies the derivation path to use for the principal. +## Staking ICP with a hardware wallet + + + +- #### Step 1: Connect the Ledger device to your computer and [configure the device using the instructions above](#ledger-nano-device-setup). + +- #### Step 2: Open the [NNS dapp](https://nns.ic0.app/) and login with Internet Identity. + +- #### Step 3: Create a new ICP account in the NNS dapp and select 'New Account (Hardware Wallet)'. + +![NNS Hardware account](../../_attachments/hardware-wallet.png) + +- #### Step 4: Provide a name for your hardware wallet. + +- #### Step 5: A pop-up window will appear asking you to select which hardware wallet connected to the computer you'd like to use. Select the Ledger device. + +- #### Step 6: The principal and account identifier for the device will be shown. Copy the account identifier for the hardware wallet. + +- #### Step 7: Send ICP tokens to the hardware wallet account identifier from a centralized exchange, decentralized exchange, or another wallet. + +- #### Step 8: From the NNS dapp, go to the 'Neuron Staking' tab and select 'Stake ICP'. + +- #### Step 9: When prompted for the 'Source' account to use, select the hardware wallet account. + +- #### Step 10: Confirm the neuron staking transaction on the Ledger device. + +For additional information about using hardware wallets for staking neurons, check out the [NNS explained video](https://www.youtube.com/watch?v=0-nSOBC3bxE). + +## Connecting the NNS to a neuron created with quill + + + +- #### Step 1: Connect the Ledger device to your computer. Recover the identity you used with [quill on the device](/docs/current/developer-docs/developer-tools/cli-tools/quill-cli-reference/quill-generate), or configure quill to use the identity already on the device. + +- #### Step 2: [Create a neuron with quill](/docs/current/developer-docs/developer-tools/cli-tools/quill-cli-reference/quill-neuron-stake) using the identity stored on the Ledger device. + +- #### Step 3: Open the [NNS dapp](https://nns.ic0.app/) and login with Internet Identity. + +- #### Step 4: Create a new ICP account in the NNS dapp and select 'New Account (Hardware Wallet)'. + +![NNS Hardware account](../../_attachments/hardware-wallet.png) + +- #### Step 5: Select 'Show neurons' from the address's details. + +- #### Step 6: Confirm the transaction on the Ledger device. + +- #### Step 7: Select 'Add to NNS dapp'. + +- #### Step 8: Confirm the addition of a hotkey, then confirm the transaction on the Ledger device. + +[Learn more in the NNS explained video](https://www.youtube.com/watch?v=lKbYUmqF7J4). + ## Resources - [Hardware wallet CLI Github](https://github.com/dfinity/hardware-wallet-cli) -- [How to claim neurons for seed participants](https://wiki.internetcomputer.org/wiki/How-To:_Claim_neurons_for_seed_participants) \ No newline at end of file +- [How to claim neurons for seed participants](https://wiki.internetcomputer.org/wiki/How-To:_Claim_neurons_for_seed_participants) diff --git a/docs/developer-docs/developer-tools/cli-tools/advanced-dfx/check-chunk-store.mdx b/docs/developer-docs/developer-tools/cli-tools/advanced-dfx/check-chunk-store.mdx new file mode 100644 index 0000000000..bd468fe91f --- /dev/null +++ b/docs/developer-docs/developer-tools/cli-tools/advanced-dfx/check-chunk-store.mdx @@ -0,0 +1,61 @@ +--- +keywords: [advanced, dfx, migration guide] +--- + +import { MarkdownChipRow } from "/src/components/Chip/MarkdownChipRow"; + +# Checking a canister's chunk store + + + +## Overview + +A canister's chunk store must be empty before a Wasm module can be installed in the canister. + +## Checking chunk store + +You can check if a canister’s chunk store is empty using the following command: + +```bash +dfx canister call --ic aaaaa-aa stored_chunks '(record { canister_id = principal "PRINCIPAL_ID" })' +``` + +Replace `PRINCIPAL_ID` with a canister ID such as `bkyz2-fmaaa-aaaaa-qaaaq-cai`. + +If the result returns a `vec` value, the chunk store is not empty. + +``` +( + vec { + record { + 1_158_164_430 = blob "\96\a2\96\d2\24\f2\85\c6\7b\ee\93\c3\0f\8a\30\91\57\f0\da\a3\5d\c5\b8\7e\41\0b\78\63\0a\09\cf\c7"; + }; + }, +) +``` + +## Resolving installation errors related to chunk store + +If you try to install a Wasm module into a canister that has an existing chunk store, the installation will fail with an error such as: + +``` +Failed during wasm installation call: Candid returned an error: input: 4449444c036d016c01cedfa0a804026d7b010003_204b7cb7e28621a6f1110913a33e11455d407f584d3cfe91edf6c12c75b6bd00a2204f7deaf907cea359eda7caa340b204e1558cf451da3fe7582a4cb010a57290d020f52735197797ef2a9e1d2b5d7ed8c13bcd1f41fc65a4731742c12b87f2346bc3 +table: type table0 = vec table1 +type table1 = record { 1_158_164_430 : table2 } +type table2 = vec nat8 +wire_type: record { 1_158_164_430 : table2 }, expect_type: vec nat8 +``` + +To verify that chunk store is the cause of this error, verify the chunk store has an existing `vec` value by running the [command shown above](#checking-chunk-store). + +Then, clear the chunk store with the command: + +``` +dfx canister call --ic aaaaa-aa clear_chunk_store '(record { canister_id = principal "bkyz2-fmaaa-aaaaa-qaaaq-cai" })' +``` + +Then re-run the canister installation command. + +## Resources + +[Canister chunk store forum discussion](https://forum.dfinity.org/t/embedding-wasm-dfx-0-17-0-crashing-where-previous-version-works/27916/) \ No newline at end of file diff --git a/docs/developer-docs/getting-started/deploy/mainnet.mdx b/docs/developer-docs/getting-started/deploy/mainnet.mdx index d9a7108c1b..6d2987f86a 100644 --- a/docs/developer-docs/getting-started/deploy/mainnet.mdx +++ b/docs/developer-docs/getting-started/deploy/mainnet.mdx @@ -31,7 +31,7 @@ You must have **cycles** available to complete this guide. To get cycles, you mu For information about how to get ICP tokens, see [how you can get ICP tokens](/docs/current/developer-docs/defi/cycles/converting_icp_tokens_into_cycles). -For an introduction to using the Network Nervous System application to manage ICP tokens, see [Network Nervous System dapp quick start](/docs/current/developer-docs/daos/nns/nns-app-quickstart). +For an introduction to using the Network Nervous System application to manage ICP tokens, see [Network Nervous System dapp quickstart](/docs/current/developer-docs/daos/nns/using-the-nns-dapp/nns-app-quickstart). ::: ## Check the connection to the mainnet diff --git a/docs/developer-docs/getting-started/install/index.mdx b/docs/developer-docs/getting-started/install/index.mdx index 334dc0fcf6..a3b7793234 100644 --- a/docs/developer-docs/getting-started/install/index.mdx +++ b/docs/developer-docs/getting-started/install/index.mdx @@ -71,7 +71,13 @@ You can download and install the latest version of [`dfxvm`](https://github.com/ sh -ci "$(curl -fsSL https://internetcomputer.org/install.sh)" ``` -If you are using a machine running Apple silicon, you will need to have [Rosetta](https://support.apple.com/en-us/HT211861) installed. You can install Rosetta by running `softwareupdate --install-rosetta` in your terminal. +If you are using a machine running Apple silicon (M1 or M2 CPU chips), you will need to have [Rosetta](https://support.apple.com/en-us/HT211861) installed, otherwise you will receive the error, `Bad CPU type in executable (os error 86)`. + +You can install Rosetta by running the command: + +``` +softwareupdate --install-rosetta +``` diff --git a/docs/developer-docs/getting-started/quickstart/juno-quickstart.mdx b/docs/developer-docs/getting-started/quickstart/juno-quickstart.mdx index 38b24a85aa..32acb5213b 100644 --- a/docs/developer-docs/getting-started/quickstart/juno-quickstart.mdx +++ b/docs/developer-docs/getting-started/quickstart/juno-quickstart.mdx @@ -19,7 +19,7 @@ This quickstart guide will walkthrough how to deploy a simple Next.js app using ## Prerequisites -- Download and install [Node.js](https://nodejs.org/en/download). +- [x] Download and install [Node.js](https://nodejs.org/en/download). ## Creating a satellite diff --git a/docs/developer-docs/identity/internet-identity/alternative-origins.mdx b/docs/developer-docs/identity/internet-identity/alternative-origins.mdx index 0f5db643f4..b509a15e4e 100644 --- a/docs/developer-docs/identity/internet-identity/alternative-origins.mdx +++ b/docs/developer-docs/identity/internet-identity/alternative-origins.mdx @@ -16,7 +16,7 @@ If your application has reached the stage where you want to change domain names, You may need this guide if you are doing any of the following: -- Moving from `.icp0.io` to a custom domain. +- Moving from `.icp0.io` to a [custom domain](/docs/current/developer-docs/web-apps/custom-domains/using-custom-domains/). - Asking users to login at `/login` instead of `/`. - Supporting users using `raw.icp0.io`. - Configuring multiple apps in your organization to use the same principals. @@ -27,7 +27,7 @@ Currently, a maximum of **10** alternative origins can be listed. II will only follow this specification when the origin configuring these alternatives is hosted on a canister using **certified assets**. -For more information, see the [Internet Identity specification](https://github.com/dfinity/internet-identity/blob/main/docs/ii-spec.md#alternative-frontend-origins). +For more information, see the [Internet Identity specification](/docs/current/references/ii-spec/#alternative-frontend-origins). ## Configuring alternative origins @@ -35,12 +35,12 @@ For this example, you will have two domains, **A** and **B**. **A** will be the In this example, **A** would be `https://yourcustomdomain.com`. -**B** would be the alternative origin, or `https://www.yourdomain.com`. - :::info -Your custom domains must be registered with the boundary nodes. +For production use cases, domain **A** would use a domain on ICP, such as `ic0.app` or `icp0.io`. ::: +**B** would be the alternative origin, or `https://www.yourdomain.com`. + ### Listing origins On origin **A**, you will need to provide a file that tells Internet Identity that **B** is a valid alternative origin. You'll be placing the config files in `src/assets` directory of your frontend canister. If your frontend canister is currently configured to deploy assets from a `dist` folder, make sure to update the `sources` for your canister to include both: diff --git a/docs/developer-docs/multi-chain/ethereum/evm-rpc/evm-rpc-canister.mdx b/docs/developer-docs/multi-chain/ethereum/evm-rpc/evm-rpc-canister.mdx index fdbf6248da..341391721c 100644 --- a/docs/developer-docs/multi-chain/ethereum/evm-rpc/evm-rpc-canister.mdx +++ b/docs/developer-docs/multi-chain/ethereum/evm-rpc/evm-rpc-canister.mdx @@ -120,51 +120,53 @@ import EvmRpc "canister:evm_rpc"; import Cycles "mo:base/ExperimentalCycles"; import Debug "mo:base/Debug"; -// Configure RPC request - -let services = #EthMainnet; -let config = null; - -// Add cycles to next call - -Cycles.add(1000000000); - -// Call an RPC method - -let result = await EvmRpc.eth_getLogs( - services, - config, - { - addresses = ["0xB9B002e70AdF0F544Cd0F6b80BF12d4925B0695F"]; - fromBlock = ?#Number 19520540; - toBlock = ?#Number 19520940; - topics = ?[ - ["0x4d69d0bd4287b7f66c548f90154dc81bc98f65a1b362775df5ae171a2ccd262b"], - [ - "0x000000000000000000000000352413d00d2963dfc58bc2d6c57caca1e714d428", - "0x000000000000000000000000b6bc16189ec3d33041c893b44511c594b1736b8a", - ], - ]; - }, -); - -// Process results - -switch result { - // Consistent, successful results - case (#Consistent(#Ok value)) { - Debug.print("Success: " # debug_show value); - }; - // Consistent error message - case (#Consistent(#Err error)) { - Debug.trap("Error: " # debug_show error); - }; - // Inconsistent results between RPC providers - case (#Inconsistent(results)) { - Debug.trap("Inconsistent results"); - }; +actor { + public func getLogs() : async ?[EvmRpc.LogEntry] { + + // Configure RPC request + let services = #EthMainnet(null); + let config = null; + + // Add cycles to next call + Cycles.add(1000000000); + + // Call an RPC method + let result = await EvmRpc.eth_getLogs( + services, + config, + { + addresses = ["0xB9B002e70AdF0F544Cd0F6b80BF12d4925B0695F"]; + fromBlock = ?#Number 19520540; + toBlock = ?#Number 19520940; + topics = ?[ + ["0x4d69d0bd4287b7f66c548f90154dc81bc98f65a1b362775df5ae171a2ccd262b"], + [ + "0x000000000000000000000000352413d00d2963dfc58bc2d6c57caca1e714d428", + "0x000000000000000000000000b6bc16189ec3d33041c893b44511c594b1736b8a", + ], + ]; + }, + ); + + // Process results + switch result { + // Consistent, successful results + case (#Consistent(#Ok value)) { + ?value + }; + // Consistent error message + case (#Consistent(#Err error)) { + Debug.trap("Error: " # debug_show error); + null + }; + // Inconsistent results between RPC providers + case (#Inconsistent(results)) { + Debug.trap("Inconsistent results: " # debug_show results); + null + }; + }; + }; }; - ``` As described in the official [Ethereum JSON-RPC documentation](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getlogs), the topics field is an order-dependent two-dimensional array which encodes the boolean logic for the relevant topics. @@ -236,33 +238,37 @@ import EvmRpc "canister:evm_rpc"; import Cycles "mo:base/ExperimentalCycles"; import Debug "mo:base/Debug"; -// Configure RPC request - -let services = #EthMainnet; -let config = null; - -// Add cycles to next call - -Cycles.add(1000000000); - -// Call an RPC method - -let result = await EvmRpc.eth_getBlockByNumber(services, config, #Latest); - -// Process results - -switch result { - // Consistent, successful results - case (#Consistent(#Ok value)) { - Debug.print("Success: " # debug_show value); - }; - // Consistent error message - case (#Consistent(#Err error)) { - Debug.trap("Error: " # debug_show error); - }; - // Inconsistent results between RPC providers - case (#Inconsistent(results)) { - Debug.trap("Inconsistent results"); +actor { + public func getLatestBlock() : async ?EvmRpc.Block { + + // Configure RPC request + let services = #EthMainnet(null); + let config = null; + + // Add cycles to next call + Cycles.add(1000000000); + + // Call an RPC method + let result = await EvmRpc.eth_getBlockByNumber(services, config, #Latest); + + // Process results + switch result { + // Consistent, successful results + case (#Consistent(#Ok block)) { + Debug.print("Success: " # debug_show block); + ?block + }; + // Consistent error message + case (#Consistent(#Err error)) { + Debug.trap("Error: " # debug_show error); + null + }; + // Inconsistent results between RPC providers + case (#Inconsistent(_results)) { + Debug.trap("Inconsistent results"); + null + }; + }; }; }; ``` @@ -320,37 +326,39 @@ import EvmRpc "canister:evm_rpc"; import Cycles "mo:base/ExperimentalCycles"; import Debug "mo:base/Debug"; -// Configure RPC request - -let services = #EthMainnet; -let config = null; - -// Add cycles to next call - -Cycles.add(1000000000); - -// Call an RPC method - -let result = await EvmRpc.eth_getTransactionReceipt(services, config, "0xdd5d4b18923d7aae953c7996d791118102e889bea37b48a651157a4890e4746f"); - - -// Process results - -switch result { - // Consistent, successful results - case (#Consistent(#Ok value)) { - Debug.print("Success: " # debug_show value); - }; - // Consistent error message - case (#Consistent(#Err error)) { - Debug.trap("Error: " # debug_show error); - }; - // Inconsistent results between RPC providers - case (#Inconsistent(results)) { - Debug.trap("Inconsistent results"); +actor { + public func getTransactionReceipt() : async ?EvmRpc.TransactionReceipt { + + // Configure RPC request + let services = #EthMainnet(null); + let config = null; + + // Add cycles to next call + Cycles.add(1000000000); + + // Call an RPC method + let result = await EvmRpc.eth_getTransactionReceipt(services, config, "0xdd5d4b18923d7aae953c7996d791118102e889bea37b48a651157a4890e4746f"); + + // Process results + switch result { + // Consistent, successful results + case (#Consistent(#Ok receipt)) { + Debug.print("Success: " # debug_show receipt); + receipt + }; + // Consistent error message + case (#Consistent(#Err error)) { + Debug.trap("Error: " # debug_show error); + null + }; + // Inconsistent results between RPC providers + case (#Inconsistent(_results)) { + Debug.trap("Inconsistent results"); + null + }; + }; }; }; - ``` @@ -485,41 +493,44 @@ import EvmRpc "canister:evm_rpc"; import Cycles "mo:base/ExperimentalCycles"; import Debug "mo:base/Debug"; -// Configure RPC request +actor { + public func getTransactionCount() : async ?Nat { -let services = #EthMainnet; -let config = null; + // Configure RPC request + let services = #EthMainnet(null); + let config = null; -// Add cycles to next call + // Add cycles to next call + Cycles.add(1000000000); -Cycles.add(1000000000); - -// Call an RPC method - -let result = await EvmRpc.eth_getTransactionCount( - services, - config, - { + // Call an RPC method + let result = await EvmRpc.eth_getTransactionCount( + services, + config, + { address = "0x1789F79e95324A47c5Fd6693071188e82E9a3558"; block = #Latest; - }, -); - - -// Process results + }, + ); -switch result { - // Consistent, successful results - case (#Consistent(#Ok value)) { - Debug.print("Success: " # debug_show value); - }; - // Consistent error message - case (#Consistent(#Err error)) { - Debug.trap("Error: " # debug_show error); - }; - // Inconsistent results between RPC providers - case (#Inconsistent(results)) { - Debug.trap("Inconsistent results"); + // Process results + switch result { + // Consistent, successful results + case (#Consistent(#Ok count)) { + Debug.print("Success: " # debug_show count); + ?count + }; + // Consistent error message + case (#Consistent(#Err error)) { + Debug.trap("Error: " # debug_show error); + null + }; + // Inconsistent results between RPC providers + case (#Inconsistent(_results)) { + Debug.trap("Inconsistent results"); + null + }; + }; }; }; ``` @@ -582,41 +593,44 @@ import EvmRpc "canister:evm_rpc"; import Cycles "mo:base/ExperimentalCycles"; import Debug "mo:base/Debug"; -// Configure RPC request - -let services = #EthMainnet; -let config = null; - -// Add cycles to next call +actor { + public func getFeeHistory() : async ?EvmRpc.FeeHistory { -Cycles.add(1000000000); + // Configure RPC request + let services = #EthMainnet(null); + let config = null; -// Call an RPC method + // Add cycles to next call + Cycles.add(1000000000); -let result = await EvmRpc.eth_feeHistory( - services, - config, - { + // Call an RPC method + let result = await EvmRpc.eth_feeHistory( + services, + config, + { blockCount = 3; newestBlock = #Latest; rewardPercentiles = null; - }, -); - -// Process results + }, + ); -switch result { - // Consistent, successful results - case (#Consistent(#Ok value)) { - Debug.print("Success: " # debug_show value); - }; - // Consistent error message - case (#Consistent(#Err error)) { - Debug.trap("Error: " # debug_show error); - }; - // Inconsistent results between RPC providers - case (#Inconsistent(results)) { - Debug.trap("Inconsistent results"); + // Process results + + switch result { + // Consistent, successful results + case (#Consistent(#Ok history)) { + Debug.print("Success: " # debug_show history); + history + }; + // Consistent error message + case (#Consistent(#Err error)) { + Debug.trap("Error: " # debug_show error); + }; + // Inconsistent results between RPC providers + case (#Inconsistent(_results)) { + Debug.trap("Inconsistent results"); + }; + }; }; }; ``` @@ -695,22 +709,42 @@ import EvmRpc "canister:evm_rpc"; import Cycles "mo:base/ExperimentalCycles"; import Debug "mo:base/Debug"; -// Configure RPC request - -let services = #EthMainnet; -let config = null; +actor { + public func sendRawTransaction() : async ?EvmRpc.SendRawTransactionStatus { -// Add cycles to next call + // Configure RPC request + let services = #EthMainnet(null); + let config = null; -Cycles.add(1000000000); + // Add cycles to next call + Cycles.add(1000000000); -// Call an RPC method + // Call an RPC method + let result = await EvmRpc.eth_sendRawTransaction( + services, + config, + "0xf86c098504a817c800825208943535353535353535353535353535353535353535880de0b6b3a76400008025a028ef61340bd939bc2195fe537567866003e1a15d3c71ff63e1590620aa636276a067cbe9d8997f761aecb703304b3800ccf555c9f3dc64214b297fb1966a3b6d83", + ); -let result = await canister.eth_sendRawTransaction( - services, - null, - "0xf86c098504a817c800825208943535353535353535353535353535353535353535880de0b6b3a76400008025a028ef61340bd939bc2195fe537567866003e1a15d3c71ff63e1590620aa636276a067cbe9d8997f761aecb703304b3800ccf555c9f3dc64214b297fb1966a3b6d83", -); + switch result { + // Consistent, successful results + case (#Consistent(#Ok status)) { + Debug.print("Status: " # debug_show status); + ?status + }; + // Consistent error message + case (#Consistent(#Err error)) { + Debug.trap("Error: " # debug_show error); + null + }; + // Inconsistent results between RPC providers + case (#Inconsistent(_results)) { + Debug.trap("Inconsistent results"); + null + }; + }; + }; +}; ``` @@ -790,32 +824,39 @@ import EvmRpc "canister:evm_rpc"; import Cycles "mo:base/ExperimentalCycles"; import Debug "mo:base/Debug"; -// Configure JSON-RPC request -let service = #EthMainnet; -let json = "{\"jsonrpc\":\"2.0\",\"method\":\"eth_gasPrice\",\"params\":[],\"id\":1}"; -let maxResponseBytes = 1000; +actor { + public func rawJsonRpcRequest() : async ?Text { -// Optionally retrieve the exact number of cycles for an RPC request -let cyclesResult = await EvmRpc.requestCost(service, json, maxResponseBytes); -let cycles = switch cyclesResult { - case (#Ok cycles) { cycles }; - case (#Err err) { + // Configure JSON-RPC request + let service = #EthMainnet(#PublicNode); + let json = "{\"jsonrpc\":\"2.0\",\"method\":\"eth_gasPrice\",\"params\":[],\"id\":1}"; + let maxResponseBytes : Nat64 = 1000; + + // Optionally retrieve the exact number of cycles for an RPC request + let cyclesResult = await EvmRpc.requestCost(service, json, maxResponseBytes); + let cycles = switch cyclesResult { + case (#Ok cycles) { cycles }; + case (#Err err) { Debug.trap("Error while calling `requestCost`: " # debug_show err); + }; }; -}; -// Submit the RPC request -Cycles.add(cycles); -let result = await EvmRpc.request(service, json, maxResponseBytes); + // Submit the RPC request + Cycles.add(cycles); + let result = await EvmRpc.request(service, json, maxResponseBytes); -// Process response -let cycles = switch result { - case (#Ok response) { + // Process response + switch result { + case (#Ok response) { Debug.print("Success:" # debug_show response); - }; - case (#Err err) { + ?response + }; + case (#Err err) { Debug.trap("Error while calling `request`: " # debug_show err); + null + }; }; + }; }; ``` diff --git a/docs/developer-docs/multi-chain/overview.mdx b/docs/developer-docs/multi-chain/overview.mdx index 0b2bfba46e..87479afdcf 100644 --- a/docs/developer-docs/multi-chain/overview.mdx +++ b/docs/developer-docs/multi-chain/overview.mdx @@ -4,6 +4,9 @@ keywords: [advanced, Chain Fusion, overview] import useBaseUrl from "@docusaurus/useBaseUrl"; import { MarkdownChipRow } from "/src/components/Chip/MarkdownChipRow"; +import TabItem from "@theme/TabItem"; +import { AdornedTabs } from "/src/components/Tabs/AdornedTabs"; +import { AdornedTab } from "/src/components/Tabs/AdornedTab"; # Chain Fusion overview @@ -118,6 +121,305 @@ In case of direct chain integration, the only trust assumption needed is that a ## How to build applications using Chain Fusion +### Example code + +To showcase how powerful Chain Fusion is, here is a simple example that shows three chains interacting in one smart contract: a single **ICP** smart contract that can have custody of **bitcoin** and programmatically trigger sending it based on events observed on an **Ethereum** DeFi smart contract. + +This code snippet is written in both Rust and Motoko, but a similar example can also be written in TypeScript, Python, and other languages. + + + + +```motoko + +import evm "ic:a6d44-nyaaa-aaaap-abp7q-cai"; +import ic "ic:aaaaa-aa"; +import Cycles "mo:base/ExperimentalCycles"; +import Timer "mo:base/Timer"; + +//Actor is the computational unit of ICP smart contract +actor { + let EVM_FEE = 1000; + let BITCOIN_FEE = 1000; + + //Function checks the logs of an ETH smart contract for an event + //If a particular event is found, it sends bitcoin to an address + func check_evm_log() : async () { + Cycles.add(EVM_FEE); + let log = await evm.eth_getLogs( + #EthMainnet(null), + null, + { + // dummy address. Replace with the right one + addresses = ["address"]; + fromBlock = ? #Finalized; + toBlock = ? #Finalized; + //dummy topics to look at. Replace with topics of interest + topics = ?[["topic1", "topic2"]]; + }, + ); + switch log { + case (#Consistent(#Ok(_))) { + // if we get a consistent log, send bitcoin + await send_bitcoin(); + }; + case _ {}; + }; + }; + + // Function that sends bitcoin. This is used by check_evm_log() + func send_bitcoin() : async () { + Cycles.add(BITCOIN_FEE); + await ic.bitcoin_send_transaction({ + transaction = "\be\ef"; + network = #testnet; + }); + }; + + // Check for evm logs every 2 seconds + let _ = Timer.setTimer(#seconds 2, check_evm_log); + +}; +``` + + + + +```rust +#![allow(non_snake_case, clippy::large_enum_variant, clippy::enum_variant_names)] +use std::time::Duration; + +use candid::{self, CandidType, Deserialize, Principal}; + +pub const SCRAPING_LOGS_INTERVAL: Duration = Duration::from_secs(3 * 60); + +fn setup_timers() { + // // Start scraping logs immediately after the install, then repeat with the interval. + ic_cdk_timers::set_timer(Duration::ZERO, || ic_cdk::spawn(check_evm_log())); + ic_cdk_timers::set_timer_interval(SCRAPING_LOGS_INTERVAL, || ic_cdk::spawn(check_evm_log())); +} + +#[ic_cdk::init] +fn init() { + // start timers upon canister initialization + setup_timers(); +} + +// Function checks the logs of an ETH smart contract for an event +// If a particular event is found, it sends bitcoin to an address +async fn check_evm_log() { + // the cycles we attach to the message to pay for the service provide by + // the EVM RPC canister + let cycles = 10_000_000_000; + // This is a test canister without API keys, for production use 7hfb6-caaaa-aaaar-qadga-cai + let canister_id = + Principal::from_text("a6d44-nyaaa-aaaap-abp7q-cai").expect("principal should be valid"); + // call the eth_getLogs function on the EVM RPC canister + let (result,) = ic_cdk::api::call::call_with_payment128::< + (RpcServices, Option, GetLogsArgs), + (MultiGetLogsResult,), + >( + canister_id, + "eth_getLogs", + ( + RpcServices::EthMainnet(None), + None, + // for more information on eth_getLogs check + // https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getlogs + GetLogsArgs { + fromBlock: Some(BlockTag::Finalized), + toBlock: Some(BlockTag::Finalized), + addresses: vec!["dummy_address".to_string()], + topics: Some(vec![vec!["topic1".to_string()], vec!["topic2".to_string()]]), + }, + ), + cycles, + ) + .await + .expect("Call failed"); + + match result { + MultiGetLogsResult::Consistent(_) => send_bitcoin().await, + MultiGetLogsResult::Inconsistent(_) => { + panic!("RPC providers gave inconsistent results") + } + } +} + +// Function that sends bitcoin. This is used by check_evm_log() +async fn send_bitcoin() { + // for more information on bitcoin_send_transaction check + // https://internetcomputer.org/docs/current/references/ic-interface-spec/#ic-bitcoin_send_transaction + ic_cdk::api::management_canister::bitcoin::bitcoin_send_transaction( + ic_cdk::api::management_canister::bitcoin::SendTransactionRequest { + transaction: b"beef".into(), + network: ic_cdk::api::management_canister::bitcoin::BitcoinNetwork::Testnet, + }, + ) + .await + .expect("Call failed"); +} + +//TYPE DECLARATIONSpush + +#[derive(CandidType, Deserialize, Debug, Clone)] +pub enum EthSepoliaService { + Alchemy, + BlockPi, + PublicNode, + Ankr, +} + +#[derive(CandidType, Deserialize, Debug, Clone)] +pub struct HttpHeader { + pub value: String, + pub name: String, +} + +#[derive(CandidType, Deserialize, Debug, Clone)] +pub struct RpcApi { + pub url: String, + pub headers: Option>, +} + +#[derive(CandidType, Deserialize, Debug, Clone)] +pub enum EthMainnetService { + Alchemy, + BlockPi, + Cloudflare, + PublicNode, + Ankr, +} + +#[derive(CandidType, Deserialize, Debug, Clone)] +pub enum RpcServices { + EthSepolia(Option>), + Custom { chainId: u64, services: Vec }, + EthMainnet(Option>), +} + +#[derive(CandidType, Deserialize)] +pub struct RpcConfig { + pub responseSizeEstimate: Option, +} + +#[derive(CandidType, Deserialize, Debug, Clone)] +pub enum BlockTag { + Earliest, + Safe, + Finalized, + Latest, + Number(candid::Nat), + Pending, +} + +#[derive(CandidType, Deserialize, Debug)] +pub struct JsonRpcError { + pub code: i64, + pub message: String, +} + +#[derive(CandidType, Deserialize, Debug)] +pub enum ProviderError { + TooFewCycles { + expected: candid::Nat, + received: candid::Nat, + }, + MissingRequiredProvider, + ProviderNotFound, + NoPermission, +} + +#[derive(CandidType, Deserialize, Debug)] +pub enum ValidationError { + CredentialPathNotAllowed, + HostNotAllowed(String), + CredentialHeaderNotAllowed, + UrlParseError(String), + Custom(String), + InvalidHex(String), +} + +#[derive(CandidType, Deserialize, Debug, PartialEq)] +pub enum RejectionCode { + NoError, + CanisterError, + SysTransient, + DestinationInvalid, + Unknown, + SysFatal, + CanisterReject, +} + +#[derive(CandidType, Deserialize, Debug)] +pub enum HttpOutcallError { + IcError { + code: RejectionCode, + message: String, + }, + InvalidHttpJsonRpcResponse { + status: u16, + body: String, + parsingError: Option, + }, +} + +#[derive(CandidType, Deserialize, Debug)] +pub enum RpcError { + JsonRpcError(JsonRpcError), + ProviderError(ProviderError), + ValidationError(ValidationError), + HttpOutcallError(HttpOutcallError), +} + +#[derive(CandidType, Deserialize)] +pub enum RpcService { + EthSepolia(EthSepoliaService), + Custom(RpcApi), + EthMainnet(EthMainnetService), + Chain(u64), + Provider(u64), +} + +#[derive(CandidType, Deserialize)] +pub struct GetLogsArgs { + pub fromBlock: Option, + pub toBlock: Option, + pub addresses: Vec, + pub topics: Option>>, +} + +#[derive(CandidType, Deserialize, Debug, Clone, PartialEq)] +pub struct LogEntry { + pub transactionHash: Option, + pub blockNumber: Option, + pub data: String, + pub blockHash: Option, + pub transactionIndex: Option, + pub topics: Vec, + pub address: String, + pub logIndex: Option, + pub removed: bool, +} + +#[derive(CandidType, Deserialize)] +pub enum GetLogsResult { + Ok(Vec), + Err(RpcError), +} + +#[derive(CandidType, Deserialize)] +pub enum MultiGetLogsResult { + Consistent(GetLogsResult), + Inconsistent(Vec<(RpcService, GetLogsResult)>), +} +``` + + + + +### Building blocks + There are several building blocks available to augment non-ICP smart contracts with ICP’s Chain Fusion capabilities or to leverage Chain Fusion in existing ICP dapps: - **Chain-key tokens**: Using the primitives described above, DFINITY has built canisters implementing the [ICRC-2](https://github.com/dfinity/ICRC) token standard to represent native Bitcoin, Ethereum, and ERC-20 tokens on ICP: [ckBTC](/docs/current/developer-docs/multi-chain/chain-key-tokens/ckbtc/overview), [ckETH](/docs/current/developer-docs/multi-chain/chain-key-tokens/cketh/overview), and [ckERC20](/docs/current/developer-docs/multi-chain/chain-key-tokens/ckerc20/overview). These tokens are digital twins of their corresponding native token and are backed 1:1 by the native assets which are managed 100% on-chain through a canister smart contract without any intermediaries. diff --git a/docs/developer-docs/security/security-best-practices/_attachments/II_mobile_naive_integration.png b/docs/developer-docs/security/security-best-practices/_attachments/II_mobile_naive_integration.png new file mode 100644 index 0000000000..a3441ab7ca Binary files /dev/null and b/docs/developer-docs/security/security-best-practices/_attachments/II_mobile_naive_integration.png differ diff --git a/docs/developer-docs/security/security-best-practices/_attachments/ii_mobile_delegation_chain.png b/docs/developer-docs/security/security-best-practices/_attachments/ii_mobile_delegation_chain.png new file mode 100644 index 0000000000..3f12f22e2e Binary files /dev/null and b/docs/developer-docs/security/security-best-practices/_attachments/ii_mobile_delegation_chain.png differ diff --git a/docs/developer-docs/security/security-best-practices/_attachments/ii_mobile_secure_integration.png b/docs/developer-docs/security/security-best-practices/_attachments/ii_mobile_secure_integration.png new file mode 100644 index 0000000000..d9222ea23f Binary files /dev/null and b/docs/developer-docs/security/security-best-practices/_attachments/ii_mobile_secure_integration.png differ diff --git a/docs/developer-docs/security/security-best-practices/iam.mdx b/docs/developer-docs/security/security-best-practices/iam.mdx index 66779b4e86..640047ebe9 100644 --- a/docs/developer-docs/security/security-best-practices/iam.mdx +++ b/docs/developer-docs/security/security-best-practices/iam.mdx @@ -105,3 +105,65 @@ The [auth-client](https://github.com/dfinity/agent-js/tree/main/packages/auth-cl ### Recommendation Never use `agent.fetchRootKey()` in production builds, only in test builds. Not calling this method will result in the hard coded root subnet public key of the mainnet being used for signature verification, which is the desired behavior in production. + +## Integrating Internet Identity on mobile devices + +### Security concern + +Internet Identity has a standardized way for web applications to request authentication of a user. This [client authentication protocol](/docs/current/references/ic-interface-spec#client-authentication-protocol) allows a client dapp frontend to obtain a delegation signed by the Internet Identity for a locally generated session key pair. Using this delegation in combination with the session key allows the dapp frontend to make authenticated calls towards the backend canister. Such calls need to be digitally signed by the session private key. The IC will verify the signature and verify if there is a delegation (or chain of delegations) from II key to the session public key. + +The II client authentication protocol leverages the browser’s `postMessage` API to communicate between the client origin and the II origin. This protocol allows II to authenticate the origin of the authorization request using the hostname. + +:::info +Note that as part of the client authentication protocol, a dapp can specify an alternative origin by following the [alternative frontend origins](/docs/current/references/ii-spec#alternative-frontend-origins) requirements. +::: + +Upon successful authentication, II will return a delegation for the principal derived from the users’ II for the specific frontend origin. This serves two purposes. First, a client dapp can’t use this delegation on other dapps to impersonate the user. Second, multiple client dapps can’t correlate user behavior across dapps, thereby reducing privacy. A dapp with a different frontend origin won’t be able to request authentication for your dapp which provides protection against certain phishing attacks. + +When integrating a mobile application with II, the implementation is not straightforward, since a mobile app can’t call the `postMessage` API. It is tempting to create a simple “proxy” web frontend served by the dapp as shown in the sequence diagram below. The mobile application can load this proxy to complete the normal II authorization flow. Upon completion, this proxy web app provides the delegation back to the mobile app. + +![Naive integration sequence diagram](./_attachments/II_mobile_naive_integration.png) + +However, without any precautions, this proxy would happily accept malicious requests to authenticate the user and might return the delegation back to an attacker. + +Such an attack would start by phishing the user by means of a malicious mobile or web application. The user is asked to authenticate through II. However, instead of using II directly, the attacker abuses the open proxy to authenticate the user for the dapp, under which the vulnerable proxy is running. The attacker would generate a session key and ask the proxy to use the session public key in the II authentication protocol. Through this method, II issues a signed delegation for the user's II derived for the frontend origin of the proxy. This delegation could leak to the attacker who can use it to impersonate the user. For example, if the attacker can trick the proxy to redirect to the malicious application (e.g. by registering Android deep links or iOS custom schemes), it could directly obtain the delegation. Furthermore, the delegation could leak through an insecure communication channel between the proxy and the mobile app or through observation of the IC state. + +The attack requires four conditions: +1. An attacker can provide a session key to be used in the II client authentication protocol. +2. The client authentication protocol is initiated for a target frontend hostname. +3. The user completes the II authentication protocol. +4. The attacker can obtain the delegation which is signed by the II canister. + +Conditions 1, 2 and 3 can be satisfied by convincing the user to initiate an authentication flow with a session public key which is chosen by the attacker by loading the proxy from an attacker controlled mobile or web application. Concretely, an attacker would execute a phishing attack where a victim is directed to the proxy from an unsuspicious application. For example, the victim is convinced that the attacker is issuing an airdrop. The victim has to download a corresponding malicious mobile app that requires II authentication. This malicious mobile app would load the proxy (step 3) similarly to how the legitimate mobile app would. The malicious app would ask the proxy to authenticate the user for an attacker chosen session key. The victim might not realize they are completing an authorization flow for a different dapp origin. Condition 2 is met for any dapp that exposes such an open II authentication proxy on their domain. + +Condition 4 can be satisfied by controlling a replica or boundary node which can observe the delegation in step 7. Alternatively, the delegation could leak in step 9 by using an HTTP GET parameter in an URI pointing to the IC. In such cases, if the mobile app that should receive the URI isn’t installed, the browser loads the web app by making a request to the URI. Boundary and replica nodes would again receive the delegation as part of the URI. Condition 4 can also be met if the mobile app issues a request to the IC in step 11 without verifying the delegation obtained in step 9. + +Finally, condition 4 can also be satisfied if the delegation is returned insecurely from the proxy frontend to the mobile app. For example, by using Android deep links or iOS custom schemes which can be intercepted by a malicious app. + +### Recommendation + +In the standard integration between a client web app and the II web frontend, the origin of the client is verified **before** starting the client authentication protocol. Unfortunately, loading the URI of the proxy app in step 3 does not provide any information about the mobile application. Therefore, the proxy frontend is unable to authenticate the client. This creates an open endpoint for attackers to use, as described in the previous section. + +This risk can be addressed by adopting the following remediations shown in the sequence diagram and explained further below. + +![Secure integration sequence diagram](./_attachments/ii_mobile_secure_integration.png) + +* Introduce an intermediate session key which is generated and stored by the web app proxy frontend. +* Initiate the II client authentication protocol using this intermediate session key. By using a new session key which the attacker can’t control, the delegation issued by II would no longer be usable by the attacker if it were stolen in step 8, as the attacker doesn’t have access to the intermediate session private key. +* [Create a delegation chain](/docs/current/references/ic-interface-spec#authentication) to allow the mobile application to use their session key. The delegation chain consists of two delegations as shown in the figure below. The first one delegates from the II canister key to the intermediate key and is generated by the II canister. The second one delegates from the intermediate key to the mobile app public key and is signed by the proxy frontend’s intermediate session private key. Note, this means the intermediate key can impersonate the user. Since the proxy frontend is served from the IC, it can be trusted to handle this key properly. It is up to the developer to ensure the confidentiality of this key. For example, using the WebCrypto API to create unextractable keys as is used internally by agent-js. Ideally, this intermediate key is short lived to reduce the risk of exposure. + +![Delegation Chain](./_attachments/ii_mobile_delegation_chain.png) +* Return the delegation chain to the mobile app using [app links](https://developer.android.com/training/app-links) on Android and [universal links](https://developer.apple.com/documentation/xcode/allowing-apps-and-websites-to-link-to-your-content) on iOS. These mechanisms bind the domain name/hostname to the mobile app which prevents an attacker from using a malicious mobile app to receive the delegation chain. The domain to mobile app binding occurs through a JSON file that has to be hosted under the `/.well-known` directory of your web application. See [iOS](https://developer.apple.com/documentation/xcode/supporting-associated-domains) +and [Android](https://developer.android.com/training/app-links/verify-android-applinks) documentation for details. +* Return the delegation chain to the mobile app using a [URI fragment](https://www.w3.org/DesignIssues/Fragment.html) (everything following the # in the URI). The browser will load the URI if the mobile app linked to the app/univeral link isn't installed on the mobile device. The benefit of URI fragments is that they are not included in the request to the server if the browser were to resolve the URI. A URL parameter or path would be included in such a request and therefore it would leak the delegation chain to the proxy app backend (most likely the IC boundary and replica nodes). A URI fragment is still available to the mobile app for extraction. +* Verify the delegation chain in the mobile application before using it in an IC message. The mobile application likely uses an agent that does not verify whether the session key generated in step 2 corresponds to the delegation found in the delegation chain returned in step 11. Using such an agent to make a signed update call would simply create a message with the provided delegation chain and sign it with a mismatching key. Obviously, the IC would reject such a message as the signature does not correspond to the delegation chain but the delegation chain would already have leaked to the boundary and potentially replica nodes where an attacker could steal it. +* Optionally, the proxy frontend could explicitly warn the user that it is about to sign in with II for your dapp. It could include the dapp’s name and logo. This might alarm the user who is being phished since the pretense used by the attacker would likely not match with the purpose of your dapp. For example, the attacker claims the authentication is required as part of an airdrop while you are running an unrelated decentralized exchange. When the proxy dapp is opened, the user would see your dapp’s logo and abort the sign in. + +For more information, view an [example implementation in the form of a Unity app](https://github.com/dfinity/examples/tree/main/native-apps/unity_ii_deeplink). The following pieces of that codebase are most important: + +* Generation of the intermediate session key [in index.js](https://github.com/dfinity/examples/blob/main/native-apps/unity_ii_deeplink/ii_integration_dapp/src/greet_frontend/src/index.js#L25). +* [Authentication using the intermediate session key](https://github.com/dfinity/examples/blob/main/native-apps/unity_ii_deeplink/ii_integration_dapp/src/greet_frontend/src/index.js#L26-L36) instead of the mobile app public key. +* [Generating the delegation chain](https://github.com/dfinity/examples/blob/main/native-apps/unity_ii_deeplink/ii_integration_dapp/src/greet_frontend/src/index.js#L48-L57) by combining the delegation obtained from II with a delegation created by the front-end. +* [Returning the delegation chain using an applink/universal link](https://github.com/dfinity/examples/blob/main/native-apps/unity_ii_deeplink/ii_integration_dapp/src/greet_frontend/src/index.js#L71) +* Returning the delegation chain [using a URI fragment](https://github.com/dfinity/examples/blob/main/native-apps/unity_ii_deeplink/ii_integration_dapp/src/greet_frontend/src/index.js#L73). +* The example is currently being improved whereby the delegation chain will also be verified in the mobile app before using it. diff --git a/docs/developer-docs/smart-contracts/advanced-features/serving-http-request.mdx b/docs/developer-docs/smart-contracts/advanced-features/serving-http-request.mdx index 56bdb7fb95..51824af6f9 100644 --- a/docs/developer-docs/smart-contracts/advanced-features/serving-http-request.mdx +++ b/docs/developer-docs/smart-contracts/advanced-features/serving-http-request.mdx @@ -14,56 +14,85 @@ import { MarkdownChipRow } from "/src/components/Chip/MarkdownChipRow"; ## Overview -Canisters can serve or handle an incoming HTTP request using the [HTTP Gateway Protocol](/docs/current/references/http-gateway-protocol-spec). +Canisters can serve or handle an incoming HTTP request using the +[HTTP Gateway Protocol](/docs/current/references/http-gateway-protocol-spec). This allows developers to host web applications and APIs from a canister. ## How it works -An HTTP request from a client gets intercepted by the HTTP Gateway Protocol, which identifies the target canister and encodes the request in Candid. This encoded request is then sent to the canister for processing. Once processed, the canister replies with an HTTP response. Finally, the HTTP Gateway Protocol decodes the response using Candid and sends it back to the client, completing the communication loop. +An HTTP request from a client gets intercepted by the HTTP Gateway Protocol, +which identifies the target canister and encodes the request in Candid. This +encoded request is then sent to the canister for processing. Once processed, the +canister replies with an HTTP response. Finally, the HTTP Gateway Protocol +decodes the response using Candid and sends it back to the client, completing +the communication loop. -For detailed information on how it works, please refer to the [HTTP Gateway Protocol specification](/docs/current/references/http-gateway-protocol-spec). +For detailed information on how it works, please refer to the +[HTTP Gateway Protocol specification](/docs/current/references/http-gateway-protocol-spec). ## How to make a request -The following example returns 'Hello, World!' in the body at the `/hello` endpoint. +The following example returns 'Hello, World!' in the body at the `/hello` +endpoint. ```motoko -import Buffer "mo:base/Buffer"; +import HashMap = "mo:base/HashMap"; +import Blob = "mo:base/Blob"; +import Text "mo:base/Text"; +import Option "mo:base/Option"; + +actor { + + public type HttpRequest = { + body: Blob; + headers: [HeaderField]; + method: Text; + url: Text; + }; -type HeaderField = (Text, Text); + public type ChunkId = Nat; + public type SetAssetContentArguments = { + chunk_ids: [ChunkId]; + content_encoding: Text; + key: Key; + sha256: ?Blob; + }; + public type Path = Text; + public type Key = Text; -type HttpResponse = { - status_code: Nat16; - headers: [HeaderField]; - body: Blob; -}; + public type HttpResponse = { + body: Blob; + headers: [HeaderField]; + status_code: Nat16; + }; -type HttpRequest = { - method: Text; - url: Text; - headers: [HeaderField]; - body: Blob; - }; - -public query func http_request(req: HttpRequest): async (HttpResponse) { - let path = removeQuery(req.url); - if(path == "/hello") { - return { - status_code = 200, - headers = [], - body = Buffer.from('Hello, World!'), - }; + public type HeaderField = (Text, Text); + + private func removeQuery(str: Text): Text { + return Option.unwrap(Text.split(str, #char '?').next()); }; + + public query func http_request(req: HttpRequest): async (HttpResponse) { + let path = removeQuery(req.url); + if(path == "/hello") { + return { + body = Text.encodeUtf8("root page :" # path); + headers = []; + status_code = 200; + }; + }; + return { - body = Text.encodeUtf8("404 Not found :"); + body = Text.encodeUtf8("404 Not found :" # path); headers = []; status_code = 404; + }; }; -}; +} ``` @@ -212,26 +241,32 @@ class Token(Record): @query def http_request(req: HttpRequest) -> HttpResponse: - return { - "status_code": 200, - "headers": [], - "body": bytes(), - "streaming_strategy": None, - "upgrade": False, - } + path = req.url.path + if path == "/hello": + return { + "status_code": 200, + "headers": [], + "body": Buffer.from_text("hello, world!").encode("utf-8"), + } + else: + return { + "status_code": 404, + "headers": [], + "body": b"404 Not found :", +} ``` -:::caution - -Kybra canisters must be deployed from a Python virtual environment. [Learn more in the Kybra docs](/docs/current/developer-docs/backend/python/). - -::: - -To learn more about serving an HTTP request in Python, refer to [the Kybra book reference on incoming HTTP requests](https://demergent-labs.github.io/kybra/http.html). +To learn more about serving an HTTP request in Python, refer to +[the Kybra book reference on incoming HTTP requests](https://demergent-labs.github.io/kybra/http.html). ## Additional examples -The [HTTP counter project](../../../references/samples/motoko/http_counter) is an example in Motoko of a 'counter' application that uses the `http_request` method to read the current counter value or access some pre-stored data and the `http_request_update` method to increment the counter and retrieve the updated value. +The +[HTTP counter project](https://github.com/dfinity/examples/tree/master/motoko/http_counter) +is an example in Motoko of a 'counter' application that uses the `http_request` +method to read the current counter value or access some pre-stored data and the +`http_request_update` method to increment the counter and retrieve the updated +value. diff --git a/docs/developer-docs/smart-contracts/deploy/custom-testnets.mdx b/docs/developer-docs/smart-contracts/deploy/custom-testnets.mdx index a2d8d006ec..7aae737949 100644 --- a/docs/developer-docs/smart-contracts/deploy/custom-testnets.mdx +++ b/docs/developer-docs/smart-contracts/deploy/custom-testnets.mdx @@ -159,7 +159,7 @@ To define a project-specific network, add a "networks" section to your `dfx.json "networks": {     "myNetwork": {       "providers": [ -        "https://ic0.app" +        "https://icp0.io"       ],       "type": "persistent"     } diff --git a/docs/developer-docs/smart-contracts/overview/canister-lifecycle.mdx b/docs/developer-docs/smart-contracts/overview/canister-lifecycle.mdx index f92fd46dee..04c9512ba3 100644 --- a/docs/developer-docs/smart-contracts/overview/canister-lifecycle.mdx +++ b/docs/developer-docs/smart-contracts/overview/canister-lifecycle.mdx @@ -20,7 +20,7 @@ Usually, developers write code in a higher-level language and then compile the c ## Create A developer can create an empty canister on ICP by calling the system canister. -It can be done using the [NNS frontend dapp](/docs/current/developer-docs/daos/nns/nns-app-quickstart#deploying-and-managing-canisters-from-the-nns-dapp) in the browser or [`dfx`](/docs/current/developer-docs/developer-tools/cli-tools/cli-reference/) in the command line. +It can be done using the [NNS frontend dapp](/docs/current/developer-docs/daos/nns/using-the-nns-dapp/nns-app-quickstart#deploying-and-managing-canisters-from-the-nns-dapp) in the browser or [`dfx`](/docs/current/developer-docs/developer-tools/cli-tools/cli-reference/) in the command line. The developer can specify the initial canister settings and choose the target subnet. Once the canister is created, the developer gets its canister ID and becomes the controller of the canister. @@ -32,7 +32,7 @@ Once the canister is created, the developer gets its canister ID and becomes the ## Compile -Once an empty canister has been created, the canister's code must be compiled into a Wasm binary.  +Once an empty canister has been created, the canister's code must be compiled into a Wasm binary. [Learn more about compiling code into Wasm](../compile.mdx). @@ -48,7 +48,7 @@ The `dfx` tool has [a command](/docs/current/developer-docs/developer-tools/cli- ## Deploy -Once a canister has an installed Wasm binary, it can be deployed to the local, testnet, or mainnet environments.  +Once a canister has an installed Wasm binary, it can be deployed to the local, testnet, or mainnet environments. [Learn more about deploying canisters](../deploy/overview.mdx). diff --git a/docs/developer-docs/smart-contracts/test/reproducible-builds.mdx b/docs/developer-docs/smart-contracts/test/reproducible-builds.mdx index 5ce03ab2a3..6d09213129 100644 --- a/docs/developer-docs/smart-contracts/test/reproducible-builds.mdx +++ b/docs/developer-docs/smart-contracts/test/reproducible-builds.mdx @@ -11,79 +11,95 @@ import { GlossaryTooltip } from "/src/components/Tooltip/GlossaryTooltip"; ## Overview -Thanks to its consensus protocol, the Internet Computer always runs canister code correctly. But this doesn’t mean that it’s running the **correct** code for a canister. If you are using a canister somebody else developed, you may want to verify that the canister is indeed running the intended code before giving it control to make important decision for you, e.g., sending your ICP to another canister. Verifying this requires answering two questions: -1. Which WebAssembly (Wasm) code is being executed for a canister? -2. The canisters are normally written in a higher-level language, such as Motoko or Rust, and not directly in Wasm. The second question is then: is the Wasm that’s running really the result of compiling the purported source code? +If you are using a canister that you did not develop yourself, you may want to verify that the canister is running the code that you expect it to be before giving it control to make important decisions for you, such as accepting ICP for a payment. Verifying a canister's code requires confirming that the Wasm module is the correct result of compiling the canister source code and that the canister is in fact running that Wasm module and not another Wasm module. -The rest of the document answers these questions. For the first question, you will see how the Internet Computer provides information about canister code. To be able to answer the second question, canister authors should ensure trusted and [reproducible builds](https://reproducible-builds.org/docs/definition/) of the Wasm code from the source. Such builds allow anyone to follow the same steps as the canister authors and yield the exact same Wasm code, which can then be compared to the Wasm code executing in the canister on the Internet Computer. +It is therefore recommended that canister authors ensure trusted and [reproducible builds](https://reproducible-builds.org/docs/definition/) of the Wasm module are possible from their source code. Such builds allow anyone to follow the same steps as the canister authors and yield the exact same Wasm module, which can then be compared to the Wasm module executing on ICP. -The impatient reader who is familiar with the topic of reproducible builds can skip straight to the [conclusion](#repro-build-summary). +## Considerations for developers -## Finding out which canister code the Internet Computer is executing +When developing code meant to be reproducible, it is recommended to use [Docker or a similar technology](#build-environments-using-docker) to conveniently set up the operating system and the build tools and fix their versions for the user. If the build tools you are using don’t guarantee fully reproducible builds, Docker can also help by minimizing the differences in paths, environment variables, etc. The build tools and the base Docker image should be sourced from somewhere that the user can trust. Ideally, you want to minimize the number of dependencies, as the user may have to rebuild all of your dependencies to properly reproduce your build. -Internet Computer does not allow you to access the Wasm code of an arbitrary canister. This is a design decision, as developers might want to keep some code private. However, the Internet Computer does allow you to access the SHA-256 of the Wasm code of a canister. +However, build tools aren’t perfect, and may fail to ensure reproducible builds. If reproducibility is critical for your canister (e.g., it holds other users' funds), [test it](#testing-reproducibility). -To obtain this hash, you must first note the principal of the Internet Computer canister whose code you want to check. For example, assume we’re interested in the code of the Internet Identity canister, whose principal is `rdmx6-jaaaa-aaaaa-aaadq-cai`. Then, the easiest way to access this data is using the [IC SDK](docs/current/developer-docs/getting-started/install/) from the terminal. Open your terminal, and run: +## Obtaining the Wasm module hash -``` +ICP does not allow you to access the Wasm module of an arbitrary canister. This is a design decision, as developers might want to keep some code private. However, ICP does allow anyone to access the SHA-256 of the Wasm module. + +To obtain this hash, you must first note the principal of the canister whose code you want to check. For example, to check the code of the Internet Identity canister, the principal is `rdmx6-jaaaa-aaaaa-aaadq-cai`. Then, the easiest way to access this data is using [`dfx`](docs/current/developer-docs/getting-started/install/) from a command line using the following command: + +```bash dfx canister --network ic info rdmx6-jaaaa-aaaaa-aaadq-cai +``` + +This will return the controller(s) of the canister and the Wasm module hash: + +``` Controllers: r7inp-6aaaa-aaaaa-aaabq-cai -Module hash: 0xa9a5d0492d1455d6b6b84fdc102fb182f55975145a2f99a403eb10ea7e37aee6 +Module hash: 0x86ab08ea53e4da5bba4f27baa931e2edc5ab2a1f228c204a5340992c16389f66 ``` -If you are running an older version of the IC SDK, you will need to run this command from a directory that contains a valid `dfx.json` file. If you don’t have such a directory, you can create it using `dfx new`. +You will need to run this command from a directory that contains a valid `dfx.json` file. If you don’t have such a directory, you can create one using `dfx new`. -Here, the Internet Computer tells us that the hash of the Wasm module of the `rdmx6-jaaaa-aaaaa-aaadq-cai` canister (which happens to be the Internet Identity canister) is `0xa9a5d0492d1455d6b6b84fdc102fb182f55975145a2f99a403eb10ea7e37aee6`. +Here, ICP tells us that the hash of the Wasm module of the `rdmx6-jaaaa-aaaaa-aaadq-cai` canister is `0x86ab08ea53e4da5bba4f27baa931e2edc5ab2a1f228c204a5340992c16389f66`. -The check above provides you the **current** hash of the canister’s Wasm module, but the **controllers** of an Internet Computer canister may change the code at any time (e.g., to upgrade a canister). However, if the list of controllers is empty or the only controller is a [black-hole](https://github.com/ninegua/ic-blackhole) canister, you know that the canister is immutable since nobody has the power to change the code. +The check above provides you the **current** hash of the canister’s Wasm module, but the **controllers** of a canister may change the code at any time, such as to upgrade the canister. However, if the list of controllers is empty or the only controller is a [blackhole](https://github.com/ninegua/ic-blackhole) canister, you know that the canister is immutable since no one has the power to change the code. -Armed with this hash, you can next check whether it corresponds to some given source code. This only works if the build process for the code is reproducible. +## Verifying the build is reproducible -## Reproducible builds +Next, check whether this hash corresponds to some given source code. This only works if the build process for the code is reproducible. As a canister author, there are a few things you have to provide to your users to allow them to reproduce your build: -- The same source code that you used to create the Wasm module for the canister. - -- Instructions on how to recreate your build environment. +-   The same source code that you used to create the Wasm module for the canister. -- Instructions on how to repeat the process of building the Wasm from the source code. Crucially, the process must be deterministic, to ensure that it results in the exact same Wasm. It also has to be trusted, such that the user can be convinced that the Wasm is a faithful translation of the source code, and not an artifact of a malicious build tool. In particular, look for `.dfx`, `node_modules`, and `target` directories that could contain pre-built files. +-   Instructions on how to recreate your build environment. -Next, you will look at each of these points in more detail. +-   Instructions on how to repeat the process of building the Wasm from the source code. The process must be deterministic to ensure that it results in the exact same Wasm. It also has to be trusted, such that the user can be convinced that the Wasm is a faithful translation of the source code and not an artifact of a malicious build tool. In particular, look for `.dfx`, `node_modules`, and `target` directories that could contain prebuilt files. -### Providing source code +### Providing the source code -Typically, you will version your code in `git` or some other version control system, and your versioned code may be available in a public repository, e.g., GitHub. In this case, you should note the particular commit that you used when producing the code to be deployed to the Internet Computer, and communicate it to the users who are trying to verify your canister. Alternatively, you can also provide a package (e.g., a zip file or a tarball) containing the source code you used to build your canister. +Typically, it is recommended that developers version your code in `git` or some other version control system, and versioned code may be available in a public repository such as GitHub. In this case, as the developer, you should note the particular commit that was used when producing the code that has been deployed to ICP and communicate it to the users who may want to verify your canister. Alternatively, you can also provide a package (i.e., a zip file or a tarball) containing the source code you used to build your canister. ### Reproducing build environments -Before building your code, you should document the build environment you are using in detail. In particular, for the languages supported by the Internet Computer SDK: +Before building your code, you should document the build environment you are using in detail. In particular, for the languages supported by the IC SDK (Motoko, Rust, TypeScript, Python): -- Note down the operating system and its version you are using to build your canister. +-   Note your local machine's operating system and its version. -- If you are using the IC SDK, note the version used, as specified in `dfx.json`. You can install arbitrary versions of the IC SDK using `dfx toolchain install `, or by running the installation script with the `DFX_VERSION` environment variable set to the desired version. +-   If you are using the IC SDK, note the version used. You can install arbitrary versions of the IC SDK using [`dfxvm`](/docs/current/developer-docs/developer-tools/cli-tools/dfxvm/docs/cli-reference/dfxvm/dfxvm-install). -- If you are building Motoko code in a way other than `dfx build`, note the version of `moc` you are using. +-   If you are building Motoko code in a way other than `dfx build`, note the version of `moc` you are using. -- If you are building Rust, note the version of `cargo` you are using. +-   If you are building Rust, note the version of `cargo` you are using. -- If you are using Node.js and/or `webpack` for frontend development, note their versions. +- If you are building TypeScript, note the version of [Azle](https://demergent-labs.github.io/azle/). -- If your build process depends on any environment variables (such as the time zone or locale), note them down. +- If you are building Python, note the version of Python and [Kybra](https://demergent-labs.github.io/kybra/). -You should communicate all of these to your user in the instructions. Ideally, do so by providing an executable recipe to recreate the build environment, using tools such as Docker or Nix. It is recommended to use Docker, as this allows you to also pinpoint the operating system used for building the software. +-   If you are using a framework for frontend development, such as React, Vite, or webpack, note their versions. + +-   If your build process depends on any environment variables (such as the timezone or locale), note them. + +You should communicate all of these to your user in the reproducible build instructions. Ideally, provide an executable recipe or script to recreate the build environment using tools such as Docker or Nix. It is recommended to use Docker, as it allows you to also pinpoint the operating system used for building the software. ### Build environments using Docker -[Docker containers](https://docs.docker.com/) are a popular solution for providing build environments. For developers using OS X, it is recommended to install Docker using [lima](https://github.com/lima-vm/lima), as it proves more stable than Docker Desktop or Docker Machine, in particular, it avoids some QEMU bugs on Apple M1 machines. +[Docker containers](https://docs.docker.com/) are a popular solution for providing reproducible build environments. -After setting Docker up, you can use a `Dockerfile` such as the following to provide the user with a particular version of the operating system, as well as `dfx`, Node.js and the Rust toolchain. Make sure to stick with `x86_64` for running the Docker container, as builds are generally not reproducible across architectures. See [docs](https://github.com/lima-vm/lima/blob/master/docs/multi-arch.md) on setting up cross-platform Docker containers in case your host environment is not `x86_64`. +:::info +For developers using macOS, it is recommended to install Docker using [lima](https://github.com/lima-vm/lima), as it proves more stable than Docker Desktop or Docker Machine. In particular, it avoids some QEMU bugs on Apple M1 machines. +::: -This Dockerfile is an example of how a Rust build environment can be standardized using Docker. +After setting Docker up, you can use a `Dockerfile` to provide the user with a particular version of the operating system, as well as other necessary tooling, such as `dfx`, Node.js, and the Rust toolchain. -#### Example Dockerfile -```dockerfile +:::caution +It is advised to stick with `x86_64` for running the Docker container, as builds are generally not reproducible across architectures. See the [docs](https://github.com/lima-vm/lima/blob/master/docs/multi-arch.md) on setting up cross-platform Docker containers in case your host environment is not `x86_64`. +::: + +Below is an example Dockerfile that creates a standardized Rust build environment. + +```dockerfile title="Dockerfile" FROM ubuntu:22.04 ENV NVM_DIR=/root/.nvm @@ -94,12 +110,12 @@ ENV RUSTUP_HOME=/opt/rustup ENV CARGO_HOME=/opt/cargo ENV RUST_VERSION=1.62.0 -ENV DFX_VERSION=0.14.1 +ENV DFX_VERSION=0.23.0 -# Install a basic environment needed for our build tools +# Install the basic environment needed for our build tools. RUN apt -yq update && \ - apt -yqq install --no-install-recommends curl ca-certificates \ - build-essential pkg-config libssl-dev llvm-dev liblmdb-dev clang cmake rsync +    apt -yqq install --no-install-recommends curl ca-certificates \ +        build-essential pkg-config libssl-dev llvm-dev liblmdb-dev clang cmake rsync # Install Node.js using nvm ENV PATH="/root/.nvm/versions/node/v${NODE_VERSION}/bin:${PATH}" @@ -111,10 +127,10 @@ RUN . "${NVM_DIR}/nvm.sh" && nvm alias default v${NODE_VERSION} # Install Rust and Cargo ENV PATH=/opt/cargo/bin:${PATH} RUN curl --fail https://sh.rustup.rs -sSf \ - | sh -s -- -y --default-toolchain ${RUST_VERSION}-x86_64-unknown-linux-gnu --no-modify-path && \ - rustup default ${RUST_VERSION}-x86_64-unknown-linux-gnu && \ - rustup target add wasm32-unknown-unknown &&\ - cargo install ic-wasm +        | sh -s -- -y --default-toolchain ${RUST_VERSION}-x86_64-unknown-linux-gnu --no-modify-path && \ +    rustup default ${RUST_VERSION}-x86_64-unknown-linux-gnu && \ +    rustup target add wasm32-unknown-unknown &&\ +    cargo install ic-wasm # Install dfx RUN sh -ci "$(curl -fsSL https://internetcomputer.org/install.sh)" @@ -122,29 +138,43 @@ RUN sh -ci "$(curl -fsSL https://internetcomputer.org/install.sh)" COPY . /canister WORKDIR /canister ``` + #### What this does + There are a couple of things worth noting about this `Dockerfile`: -- It starts from an official Docker image. Furthermore, all the installed tools are standard, and come from standard sources. This provides the user with confidence that the build environment hasn’t been tampered with, and thus that the build process using Docker can be trusted. +-   It starts from an official Docker image, such that all the installed tools are standard and come from standard sources. This provides the user with confidence that the build environment hasn’t been tampered with, and thus that the build process using Docker can be trusted. -- To ensure that specific versions of the build tools are installed, it installs them directly, rather than through `apt` (the package manager of Ubuntu, the Linux distribution running inside of the container). Such package managers usually don’t provide a way of pinning the build tools to specific versions. +-   To ensure that specific versions of the build tools are installed, it installs them directly rather than through a package manager. Package managers usually don’t provide a way of pinning the build tools to specific versions. To use this `Dockerfile`, get Docker [up and running](https://docs.docker.com), place the `Dockerfile` in the project directory of your canister, and create the Docker container by running: -``` + +```bash docker build -t mycanister . ``` -This creates a Docker container image called `mycanister`, with Node.js, Rust and `dfx` installed in it, and your canister source code copied to `/canister` (recall that you should invoke `docker build` from the canister project directory). You can then enter an interactive shell inside of your container by running: -``` + +This creates a Docker container image called `mycanister`, with Node.js, Rust, and `dfx` installed in it. Your canister source code will be copied to the directory `/canister` You should invoke `docker build` from the canister project directory. You can then enter an interactive shell inside of your Docker container by running: + +```bash docker run -it --rm mycanister ``` -From here, you can experiment with the steps needed to build your canister. Once you are confident that the steps are deterministic, you can also put them in the `Dockerfile` (e.g., as `RUN ./build_script.sh` for a build script such as the example below, saved as `./build_script.sh`), to allow the user to automatically reproduce the build of your canister. You can see an example in the [Dockerfile of the Internet Identity canister](https://github.com/dfinity/internet-identity/blob/397d0087a29855564c47f0fd3323f60b5b67a8fa/Dockerfile). -#### Example script for building a Rust project -An example script to build a Rust project looks as follows: +From here, you can experiment with the steps needed to build your canister. Once you are confident that the steps are deterministic, you can also put them in the `Dockerfile`. For example, to run a build script, add the line: + +```dockerfile +RUN ./build_script.sh +``` + +You can see an example in the [Dockerfile of the Internet Identity canister](https://github.com/dfinity/internet-identity/blob/397d0087a29855564c47f0fd3323f60b5b67a8fa/Dockerfile). + +### Example build script + +Below is an example script that can be used to programmatically build a Rust project: :::info -This is an example build script for a Rust project, and does not include a fully comprehensive example of what a build script may contain, nor does it include build instructions for other languages such as Motoko. +This is an example build script for a Rust project and does not include a fully comprehensive example of what a build script may contain, nor does it include build instructions for other languages such as Motoko. ::: + ```bash #!/bin/bash # @@ -155,57 +185,74 @@ export RUSTFLAGS="--remap-path-prefix $(readlink -f $(dirname ${0}))=/build --re cargo build --locked --target wasm32-unknown-unknown --release ic-wasm target/wasm32-unknown-unknown/release/example_backend.wasm -o example_backend.wasm shrink ``` -A build script such as the one above can be specified as a custom build script in `dfx.json` as follows: -``` + +A build script such as the one above can be specified as a custom build script in `dfx.json`: + +```json title="dfx.json" "canisters": { - "example_backend": { - "candid": "src/example_backend/example_backend.did", - "package": "example_backend", - "type": "custom", - "wasm": "./example_backend.wasm", - "build": "./build_script.sh" - } +  "example_backend": { +    "candid": "src/example_backend/example_backend.did", +    "package": "example_backend", +    "type": "custom", +    "wasm": "./example_backend.wasm", +    "build": "./build_script.sh" +  } } ``` ### Ensuring the determinism of the build process -Next, investigate what is necessary to make the build deterministic. For the build process to be deterministic: -- #### Step 1: You will need to ensure that any dependencies of your canister are always resolved in the same way. Most build tools now support a way of pinning dependencies to a particular version. +Next, consider if it is necessary to make the build deterministic. For the build process to be deterministic: + +- #### Step 1: You will need to ensure that any dependencies of your canister are always resolved in the same way. Most build tools support a way of pinning dependencies to a particular version. + +    -   For `npm`, running `npm install` will create a `package-lock.json` file with some fixed versions of all (transitive) dependencies of your project that satisfy the requirements specified in your `package.json`. However, `npm install` will overwrite the `package-lock.json` file every time it is invoked. Thus, once you are ready to create the final version of your canister, run `npm install` only once. After that, commit `package-lock.json` to your version control system. Finally, when checking the build for reproducibility, use `npm ci` instead of `npm install`. + +    -   For Rust code, Cargo will automatically generate a `Cargo.lock` file with the fixed versions of your (transitive) dependencies. Like with `package-lock.json`, you should commit this file to your version control system once you are ready to produce the final version of your canister. Furthermore, Cargo by default ignores the locked versions of dependencies. Pass the `--locked` flag to the `cargo` command to ensure that the locked dependencies are used. + +- #### Step 2: Your own build scripts must not introduce non-determinism. + +Sources of non-determinism include randomness, timestamps, concurrency, or code obfuscators. Less obvious sources include locales, absolute file paths, the order of files in a directory, and remote URLs whose content can change. Furthermore, relying on third-party build plug-ins exposes you to any non-determinism introduced by these. + +- #### Step 3. Given the same dependencies and deterministic build scripts, the build tools themselves (`moc` for Motoko, `cargo` for Rust, `npx` for TypeScript, `pip` for Python, or `webpack` for frontend development) must also be deterministic. + +These tools aim to be deterministic. However, they are complicated pieces of software, and ensuring determinism is non-trivial. Thus, non-determinism bugs can and do occur. + +#### Motoko deterministic considerations - - For `npm`, running `npm install` will create a `package-lock.json` file with some fixed versions of all (transitive) dependencies of your project that satisfy the requirements specified in your `package.json`. However, `npm install` will overwrite the `package-lock.json` file every time it is invoked. Thus, once you are ready to create the final version of your canister, run `npm install` only once. After that, commit `package-lock.json` to your version control system. Finally, when checking the build for reproducibility, use `npm ci` instead of `npm install`. +The Motoko compiler aims to be deterministic and reproducible; if you find reproducibility issues, please submit a [new issue](https://github.com/dfinity/motoko/issues/new/choose), and the team will try to address them to the extent possible. - - For Rust code, Cargo will automatically generate a `Cargo.lock` file with the fixed versions of your (transitive) dependencies. Like with `package-lock.json`, you should commit this file to your version control system once you are ready to produce the final version of your canister. Furthermore, Cargo by default ignores the locked versions of dependencies. Pass the `--locked` flag to the `cargo` command to ensure that the locked dependencies are used. +#### Rust deterministic considerations - - You have to allocate canister IDs in advance, as canisters refer to each other by their IDs. +For Rust, see the [list of current potential non-determinism issues in Rust](https://github.com/rust-lang/rust/labels/A-reproducibility). If you have observed differences between Rust code compiled to Wasm under Linux and macOS, it is recommended to pin the build platform and its version. -- #### Step 2: Your own build scripts must not introduce non-determinism. -Obvious sources of non-determinism include randomness, timestamps, concurrency, or code obfuscators. Less obvious sources include locales, absolute file paths, order of files in a directory, and remote URLs whose content can change. Furthermore, relying on third-party build plug-ins exposes you to any non-determinism introduced by these. +#### Webpack deterministic considerations -- #### Step 3. Given the same dependencies and deterministic build scripts, the build tools themselves (`moc` for Motoko, `cargo` for Rust, `webpack` by default for frontend development) must also be deterministic. -The good news is that all of these tools aim to be deterministic. However, they are complicated pieces of software, and ensuring determinism is non-trivial. Thus, non-determinism bugs can and do occur. For Rust, see the [list of current potential non-determinism issues in Rust](https://github.com/rust-lang/rust/labels/A-reproducibility). Furthermore, you have observed differences between Rust code compiled to Wasm under Linux and macOS, and thus it is recommended to pin the build platform and its version. For webpack, [deterministic naming of module and chunk IDs](https://webpack.js.org/configuration/optimization/) that you should use have been introduced since version 5. The Motoko compiler aims to be deterministic and reproducible; if you find reproducibility issues, please submit a [new issue](https://github.com/dfinity/motoko/issues/new/choose), and the team will try to address them to the extent possible. +For webpack, [deterministic naming of module and chunk IDs](https://webpack.js.org/configuration/optimization/) that you should use have been introduced since version 5. ### Testing reproducibility -If reproducibility is vital for your code, you should test your builds to increase your confidence in their reproducibility. Such testing is non-trivial: there have been real-world examples where non-determinism in a canister build took a month to show up! Fortunately, the **Debian Reproducible Builds** project created a tool called [reprotest](https://salsa.debian.org/reproducible-builds/reprotest), which can help you automate reproducibility tests. It tests your build by running it in two different environments that differ in characteristics such as paths, time, file order, and others, and comparing the results. To check your build with `reprotest`, add the following line to your `Dockerfile`: +If reproducibility is vital for your code, you should test the build to increase your confidence in its reproducibility. The tool [reprotest](https://salsa.debian.org/reproducible-builds/reprotest) can help you automate reproducibility tests, as it tests your build by running it in two different environments that differ in characteristics such as paths, time, file order, and others, and comparing the results. To check your build with `reprotest`, add the following line to your `Dockerfile`: + ```dockerfile RUN apt -yqq install --no-install-recommends reprotest disorderfs faketime rsync sudo wabt ``` -When using `dfx build --network ic`, you need to prebuild your frontend dependencies (e.g., by running `npm ci` before `dfx build --network ic` or by setting the custom build type in `dfx.json` and running `npm ci` in your build script) and your project directory should contain a `canister_ids.json` file containing the IDs of your canisters on the Internet Computer. An example `canister_ids.json` file looks as follows: -```json +When using `dfx build --network ic`, you need to prebuild your frontend dependencies by running `npm ci` before `dfx build --network ic` or by setting the custom build type in `dfx.json` and running `npm ci` in your build script. Your project directory should contain a `canister_ids.json` file containing the IDs of your canisters on the mainnet. Below is an example `canister_ids.json` file: + +```json title="canister_ids.json" { - "example_backend": { - "ic": "rrkah-fqaaa-aaaaa-aaaaq-cai" - }, - "example_frontend": { - "ic": "ryjl3-tyaaa-aaaaa-aaaba-cai" - } +  "example_backend": { +    "ic": "rrkah-fqaaa-aaaaa-aaaaq-cai" +  }, +  "example_frontend": { +    "ic": "ryjl3-tyaaa-aaaaa-aaaba-cai" +  } } ``` -Now, from the root directory of your canister project, you can test the reproducibility of your IC SDK builds as follows: +Now, from the root directory of your canister project, you can test the reproducibility of your build using the commands: ``` docker build -t mycanister . @@ -216,9 +263,13 @@ docker run --rm --privileged -it mycanister #### What this does - The first command builds the Docker container using the `Dockerfile` provided earlier. -- The second one opens an interactive shell (hence the `-it` flags) in the container. You can run this in privileged mode (the `--privileged` flag), as `reprotest` uses kernel modules for some build environment variations. You can also run it in non-privileged mode by excluding some of the variations; see the [reprotest manual](https://manpages.debian.org/stretch/reprotest/reprotest.1.en.html). The `--rm` flag will destroy the container after you close its shell. -- Once inside of the container, create a directory for the build artifacts and launch `reprotest` in verbose mode (the `-vv` flags). You need to give it the build command you want to run as the first argument. Here, assume that it’s `dfx build --network ic` - adjust it if you’re using a different build process. It will then run the build in two different environments. -- Finally, you need to tell `reprotest` which paths to compare at the end of the two builds. Here, compare the Wasm code for all canisters, which is found in the `.dfx/ic` directory. This workflow omits the time variation because the Rust compiler uses `jemalloc` for dynamic memory allocation and this library is not [compatible](https://github.com/wolfcw/libfaketime/issues/130) with `faketime` used by `reprotest` to implement the time variation. Nevertheless, it is encouraged that you to compare the artifacts produced by `reprotest` while manually changing your system time. +- The second command opens an interactive shell in the container, indicated by the flag `-it`. You can run this in privileged mode using the `--privileged` flag, as `reprotest` uses kernel modules for some build environment variations. You can also run it in non-privileged mode by excluding some of the variations; see the [reprotest manual](https://manpages.debian.org/stretch/reprotest/reprotest.1.en.html). The `--rm` flag will destroy the container after you close its shell. +- Once inside the container, a directory is created for the build artifacts, and `reprotest` is launched in verbose mode using the `-vv` flags. You need to give it the build command you want to run as the first argument; in this example it is `dfx build --network ic`. It will then run the build in two different environments. +- Finally, you need to tell `reprotest` which paths to compare at the end of the two builds. In this example, it compares the Wasm code for all canisters, which is found in the `.dfx/ic` directory. It is encouraged that you compare the artifacts produced by 'reprotest` while manually changing your system time. + +:::info +This workflow omits the time variation because the Rust compiler uses `jemalloc` for dynamic memory allocation, and this library is not [compatible](https://github.com/wolfcw/libfaketime/issues/130) with `faketime` used by `reprotest` to implement the time variation. +::: If the comparison doesn’t find any differences, you will see an output similar to this one: @@ -227,55 +278,38 @@ If the comparison doesn’t find any differences, you will see an output similar Reproduction successful ======================= No differences in ./.dfx/ic/canisters/*/*.wasm -6b2a15a918219138836e88e9c95f9c5d2d7b6d465df83ae05d6fd2b0f14f8a97 ./.dfx/ic/canisters/example_backend/example_backend.wasm -a047686c1d517e21d447bcd42c9394a12cdb240e06425b830c99d3a689b5ee20 ./.dfx/ic/canisters/example_frontend/assetstorage.wasm -a047686c1d517e21d447bcd42c9394a12cdb240e06425b830c99d3a689b5ee20 ./.dfx/ic/canisters/example_frontend/example_frontend.wasm +6b2a15a918219138836e88e9c95f9c5d2d7b6d465df83ae05d6fd2b0f14f8a97  ./.dfx/ic/canisters/example_backend/example_backend.wasm +a047686c1d517e21d447bcd42c9394a12cdb240e06425b830c99d3a689b5ee20  ./.dfx/ic/canisters/example_frontend/assetstorage.wasm +a047686c1d517e21d447bcd42c9394a12cdb240e06425b830c99d3a689b5ee20  ./.dfx/ic/canisters/example_frontend/example_frontend.wasm ``` -Congratulations - this is a good indicator that your build is not affected by your environment! +This is a good indicator that your build is not affected by your environment. :::info -Note that `reprotest` can’t check that your dependencies are pinned properly; use guidelines from the previous section for that. Moreover, it is recommended that you to run the container `reprotest` builds under several host operating systems and compare the results. If the comparison does find differences between the Wasm code produced in two builds, it will output a diff. You will then likely want to use the `--store-dir` flag of `reprotest` to store the outputs and the diff somewhere where you can analyze them. If you are struggling to achieve reproducibility, consider also using [DetTrace](https://github.com/dettrace/dettrace), which is a container abstraction that tries to make arbitrary builds deterministic. +Note that `reprotest` can’t check that your dependencies are pinned properly. It is recommended that you run the container `reprotest` builds under several host operating systems and compare the results. If the comparison does find differences between the Wasm code produced in two builds, it will output a diff. You will then likely want to use the `--store-dir` flag of `reprotest` to store the outputs and the diff somewhere where you can analyze them. If you are struggling to achieve reproducibility, consider also using [DetTrace](https://github.com/dettrace/dettrace), which is a container abstraction that tries to make arbitrary builds deterministic. ::: -Even after you achieve reproducibility for your builds, there are still other things to consider for the long term. - -### Long-term considerations - -Reproducibility can be more demanding if you expect your canister code to stay around for years, and stay reproducible. The biggest challenges are to ensure that your: - -- Build toolchain is still available in the future. - -- Dependencies are available. - -- Toolchain still runs and still correctly builds your dependencies. - -Distributions and package archives may drop old versions of packages, including both your toolchain and their dependencies. Web sites may go offline and URLs might stop working. Thus, it’s prudent to back up all of your toolchain and dependencies. You should consider getting involved in projects such as [Software Heritage](https://www.softwareheritage.org/), which do this on a large scale. At some later point in time, you might have to adjust your build process (e.g., by changing URLs) to ensure that your canister still builds. Even if the build changes, if it still yields the same result, your users can be confident that your canister is running the correct code. The trust argument is easier if your dependencies come from a trustworthy source, such as the Software Heritage project. - -## Conclusion - -Summarizing our recommendations for canister authors: +Finally, if your build is reproducible, you can compare the hash of the resulting Wasm code to the hash of the code that is running in a canister, which you retrieve as follows: -- Ideally, when producing the final version of your container code, use Docker or a similar technology to conveniently set up the operating system and the build tools, and fix their versions for the user. If the build tools you are using don’t guarantee fully reproducible builds, Docker can also help by minimizing the differences in paths, environment variables etc. +``` +dfx canister --network ic info +``` -- The build tools and the base Docker image should be sourced from somewhere that the user can trust. +Beware that this hash might change if the controllers upgrade the canister code. -- Rust and Motoko compilers aim to be deterministic, and thus to support reproducible builds. If you notice non-determinism, file bug reports. +## Long-term considerations -- When using NPM, ensure that you specify the exact versions of all your dependencies (commit `package_lock.json` to your git repo!). Invoke NPM using the `ci` command rather than `install` to reproduce the build. Similarly, for Rust packages commit `Cargo.lock` to your repository, and then use `cargo build --locked` when building the package. +Even after you achieve reproducibility for your builds, there are still other things to consider for the long term. -- Webpack builds should be deterministic, but obfuscators and similar tools may compromise reproducibility. Make sure you use deterministic chunk and module IDs. +Reproducibility can be more demanding if you expect your canister code to stay around for years and remain reproducible. The biggest challenges are to ensure that your: -- Build tools aren’t perfect, and may fail to ensure reproducible builds. If reproducibility is critical for your canister (e.g., it holds other users' funds), test it. Reprotest is a useful tool for this purpose. +-  Build toolchain is available in the future. -- Ideally, you want to minimize the number of dependencies, as, in order to do a full audit, the user may have to (reproducibly) rebuild all of your dependencies too. +-  Dependencies are available. -- Achieving reproducibility is harder over longer time scales, primarily as you need to ensure that a trustworthy source of your dependencies and build tools stays available. +-  Toolchain still runs and correctly builds your dependencies. -Finally, if your build is reproducible, you can compare the hash of the resulting Wasm code to the hash of the code that is running in a canister, which you retrieve as follows: +Distributions and package archives may drop old versions of packages, including both your toolchain and their dependencies. Web sites may go offline, and URLs might stop working. It’s prudent to back up all of your toolchain and dependencies. You should consider getting involved in projects such as [Software Heritage](https://www.softwareheritage.org/), which do this on a large scale. -``` -dfx canister --network ic info -``` +You might have to adjust your build process to ensure that your canister still builds. Even if the build changes, if it still yields the same result, your users can be confident that your canister is running the correct code. The trust argument is easier if your dependencies come from a trustworthy source, such as the Software Heritage project. -Beware that this hash might change if the controllers upgrade the canister code. diff --git a/docs/developer-docs/smart-contracts/topping-up/cycles_management_services.mdx b/docs/developer-docs/smart-contracts/topping-up/cycles_management_services.mdx index 147380bd50..d8a29b0b30 100644 --- a/docs/developer-docs/smart-contracts/topping-up/cycles_management_services.mdx +++ b/docs/developer-docs/smart-contracts/topping-up/cycles_management_services.mdx @@ -7,30 +7,30 @@ import { GlossaryTooltip } from "/src/components/Tooltip/GlossaryTooltip"; ## Overview -Once a canister is deployed to the Internet Computer, the compute and storage it utilizes must be pre-paid. The process of burning ICP to obtain cycles and transferring them to a canister is referred to as "topping-up" a canister. +Once a canister is deployed to the Internet Computer, the compute and storage it utilizes must be pre-paid. The process of burning ICP to obtain cycles and transferring them to a canister is referred to as "topping up" a canister. -Cycles management services provide canister monitoring and automated cycles top-ups to ensure canister applications remain up and running and do not run out of cycles. +Cycles management services provide canister monitoring and automated cycles top ups to ensure canister applications remain up and running and do not run out of cycles. -Instead of manually topping up a canister via `dfx` or scripting a custom solution, cycles management services provide tested top-up automation and canister metric insights. +Instead of manually topping up a canister via `dfx` or scripting a custom solution, cycles management services provide tested top up automation and canister metric insights. ## Popular cycles management services Popular cycles management services include: -* [CycleOps](https://cycleops.dev) - On-chain, proactive, no-code canister monitoring with historical trend graphs, top-up email notifications & downloadable transaction history. -* [TipJar](https://k25co-pqaaa-aaaab-aaakq-cai.ic0.app/) - Donate cycles to your favorite canisters on the Internet Computer and keep them alive and healthy! -* [Canistergeek](https://cusyh-iyaaa-aaaah-qcpba-cai.raw.icp0.io/) – Top up your canisters, monitor cycles, memory, and logs, and get your monthly reports in one place. +* [CycleOps](https://cycleops.dev): On-chain, proactive, no-code canister monitoring with historical trend graphs, top up email notifications & downloadable transaction history. +* [TipJar](https://k25co-pqaaa-aaaab-aaakq-cai.ic0.app/): Donate cycles to your favorite canisters on the Internet Computer and keep them alive and healthy! +* [Canistergeek](https://cusyh-iyaaa-aaaah-qcpba-cai.raw.icp0.io/): Top up your canisters, monitor cycles, memory, and logs, and get your monthly reports in one place. ## Cycles management libraries ### Motoko -* [cycles-manager](https://github.com/CycleOperators/cycles-manager) - Provides a simplified, permissioned cycles management framework for multi-canister applications (sponsored by CycleOps). -* [canistergeek-ic-motoko](https://github.com/usergeek/canistergeek-ic-motoko) – Canistergeek-IC-Motoko is an open-source tool for Internet Computer to track your project canisters cycles and memory status and collect log messages. -* [canistergeek_ic_rust](https://github.com/usergeek/canistergeek_ic_rust) – canistergeek_ic_rust is an open-source tool for Internet Computer to track your project canisters cycles and memory status and collect log messages. +* [cycles-manager](https://github.com/CycleOperators/cycles-manager): Provides a simplified, permissioned cycles management framework for multi-canister applications (sponsored by CycleOps). +* [canistergeek-ic-motoko](https://github.com/usergeek/canistergeek-ic-motoko): An open source Motoko tool for Internet Computer to track your project canisters cycles and memory status and collect log messages. +* [canistergeek_ic_rust](https://github.com/usergeek/canistergeek_ic_rust): An open source Rust tool for Internet Computer to track your project canisters cycles and memory status and collect log messages. -## Creating custom autonomous top-up solutions +## Creating custom autonomous top up solutions -To create an autonomous canister that doesn't rely on a third-party service, you can create your own autonomous canister top-up solution. One option is to use a similar architecture implemented by [CycleOps](https://github.com/CycleOperators/cycles-manager/tree/main), where one canister acts as the cycles manager for the project and provides the API used to request more cycles when a canister within the project has its cycles balance dip below a preset threshold. Below is sample code for this architecture, where 'CyclesManager' is the management canister and 'Child' is another canister in the project that requests cycles from the 'CyclesManager'. +To create an autonomous canister that doesn't rely on a third-party service, you can create your own autonomous canister top up solution. One option is to use a similar architecture implemented by [CycleOps](https://github.com/CycleOperators/cycles-manager/tree/main), where one canister acts as the cycles manager for the project and provides the API used to request more cycles when a canister within the project has its cycles balance dip below a preset threshold. Below is sample code for this architecture, where 'CyclesManager' is the management canister and 'Child' is another canister in the project that requests cycles from the 'CyclesManager'. :::caution @@ -38,6 +38,8 @@ You will still need to top up the CyclesManager canister manually. ::: +Here is example code for the 'CyclesManager' canister: + ```motoko title="CyclesManager.mo" // Import packages import { logand } "mo:base/Bool"; @@ -118,6 +120,8 @@ actor CyclesManager { } ``` +Here is example code for the 'Child' canister: + ```motoko Child.mo // Import the Mops package CyclesManager diff --git a/docs/developer-docs/web-apps/custom-domains/dns-setup.mdx b/docs/developer-docs/web-apps/custom-domains/dns-setup.mdx index 412aebfb3e..cdc3f73de0 100644 --- a/docs/developer-docs/web-apps/custom-domains/dns-setup.mdx +++ b/docs/developer-docs/web-apps/custom-domains/dns-setup.mdx @@ -48,7 +48,7 @@ The resulting configuration should look similar to the following screenshot: ### Subdomain To configure a subdomain (e.g., `example.ic-domain.live`), add the following records by clicking on **Add new record**: -* Create a `CNAME` record for which you set the host field to `example` and the target field to `example.ic-domain.live.icp1.io`; +* Create a `ALIAS` record for which you set the host field to `example` and the target field to `example.ic-domain.live.icp1.io`; * Create a `CNAME` record for which you set the host field to `_acme-challenge.example` and the target field to `_acme-challenge.example.ic-domain.live.icp2.io`; diff --git a/docs/other/updates/release-notes/release-notes.md b/docs/other/updates/release-notes/release-notes.md index bfaf1e9532..ddef00fbc6 100644 --- a/docs/other/updates/release-notes/release-notes.md +++ b/docs/other/updates/release-notes/release-notes.md @@ -2,6 +2,7 @@ | Version | Release Notes | Migration Guide | |---------|---------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------| +| 0.23.0 | [release notes](https://github.com/dfinity/sdk/releases/tag/0.23.0) | | 0.22.0 | [release notes](https://github.com/dfinity/sdk/releases/tag/0.22.0) | | 0.21.0 | [release notes](https://github.com/dfinity/sdk/releases/tag/0.21.0) | | 0.20.1 | [release notes](https://github.com/dfinity/sdk/releases/tag/0.20.1) | diff --git a/docs/tutorials/developer-journey/_attachments/ic-eth-1.png b/docs/tutorials/developer-journey/_attachments/ic-eth-1.png index fc53b68e4b..1bc41ec948 100644 Binary files a/docs/tutorials/developer-journey/_attachments/ic-eth-1.png and b/docs/tutorials/developer-journey/_attachments/ic-eth-1.png differ diff --git a/docs/tutorials/developer-journey/_attachments/ic-eth-10.png b/docs/tutorials/developer-journey/_attachments/ic-eth-10.png deleted file mode 100644 index 6f05f5c8c7..0000000000 Binary files a/docs/tutorials/developer-journey/_attachments/ic-eth-10.png and /dev/null differ diff --git a/docs/tutorials/developer-journey/_attachments/ic-eth-11.png b/docs/tutorials/developer-journey/_attachments/ic-eth-11.png deleted file mode 100644 index e168e68a20..0000000000 Binary files a/docs/tutorials/developer-journey/_attachments/ic-eth-11.png and /dev/null differ diff --git a/docs/tutorials/developer-journey/_attachments/ic-eth-12.png b/docs/tutorials/developer-journey/_attachments/ic-eth-12.png deleted file mode 100644 index 19924f81ed..0000000000 Binary files a/docs/tutorials/developer-journey/_attachments/ic-eth-12.png and /dev/null differ diff --git a/docs/tutorials/developer-journey/_attachments/ic-eth-13.png b/docs/tutorials/developer-journey/_attachments/ic-eth-13.png deleted file mode 100644 index 6ebc84ea8b..0000000000 Binary files a/docs/tutorials/developer-journey/_attachments/ic-eth-13.png and /dev/null differ diff --git a/docs/tutorials/developer-journey/_attachments/ic-eth-14.png b/docs/tutorials/developer-journey/_attachments/ic-eth-14.png deleted file mode 100644 index d6758a328f..0000000000 Binary files a/docs/tutorials/developer-journey/_attachments/ic-eth-14.png and /dev/null differ diff --git a/docs/tutorials/developer-journey/_attachments/ic-eth-15.png b/docs/tutorials/developer-journey/_attachments/ic-eth-15.png deleted file mode 100644 index 49d8f7a131..0000000000 Binary files a/docs/tutorials/developer-journey/_attachments/ic-eth-15.png and /dev/null differ diff --git a/docs/tutorials/developer-journey/_attachments/ic-eth-16.png b/docs/tutorials/developer-journey/_attachments/ic-eth-16.png deleted file mode 100644 index 046a5dcdb0..0000000000 Binary files a/docs/tutorials/developer-journey/_attachments/ic-eth-16.png and /dev/null differ diff --git a/docs/tutorials/developer-journey/_attachments/ic-eth-17.png b/docs/tutorials/developer-journey/_attachments/ic-eth-17.png deleted file mode 100644 index 8c73438705..0000000000 Binary files a/docs/tutorials/developer-journey/_attachments/ic-eth-17.png and /dev/null differ diff --git a/docs/tutorials/developer-journey/_attachments/ic-eth-18.png b/docs/tutorials/developer-journey/_attachments/ic-eth-18.png deleted file mode 100644 index 4d61a25993..0000000000 Binary files a/docs/tutorials/developer-journey/_attachments/ic-eth-18.png and /dev/null differ diff --git a/docs/tutorials/developer-journey/_attachments/ic-eth-2.png b/docs/tutorials/developer-journey/_attachments/ic-eth-2.png index ea9091f788..7912c0d01a 100644 Binary files a/docs/tutorials/developer-journey/_attachments/ic-eth-2.png and b/docs/tutorials/developer-journey/_attachments/ic-eth-2.png differ diff --git a/docs/tutorials/developer-journey/_attachments/ic-eth-3.png b/docs/tutorials/developer-journey/_attachments/ic-eth-3.png deleted file mode 100644 index a39d10126f..0000000000 Binary files a/docs/tutorials/developer-journey/_attachments/ic-eth-3.png and /dev/null differ diff --git a/docs/tutorials/developer-journey/_attachments/ic-eth-4.png b/docs/tutorials/developer-journey/_attachments/ic-eth-4.png deleted file mode 100644 index 70004a99a9..0000000000 Binary files a/docs/tutorials/developer-journey/_attachments/ic-eth-4.png and /dev/null differ diff --git a/docs/tutorials/developer-journey/_attachments/ic-eth-5.png b/docs/tutorials/developer-journey/_attachments/ic-eth-5.png deleted file mode 100644 index 933bd81c4e..0000000000 Binary files a/docs/tutorials/developer-journey/_attachments/ic-eth-5.png and /dev/null differ diff --git a/docs/tutorials/developer-journey/_attachments/ic-eth-6.png b/docs/tutorials/developer-journey/_attachments/ic-eth-6.png deleted file mode 100644 index 446a1383f1..0000000000 Binary files a/docs/tutorials/developer-journey/_attachments/ic-eth-6.png and /dev/null differ diff --git a/docs/tutorials/developer-journey/_attachments/ic-eth-7.png b/docs/tutorials/developer-journey/_attachments/ic-eth-7.png deleted file mode 100644 index 45707f2258..0000000000 Binary files a/docs/tutorials/developer-journey/_attachments/ic-eth-7.png and /dev/null differ diff --git a/docs/tutorials/developer-journey/_attachments/ic-eth-8.png b/docs/tutorials/developer-journey/_attachments/ic-eth-8.png deleted file mode 100644 index ca9ec49bdf..0000000000 Binary files a/docs/tutorials/developer-journey/_attachments/ic-eth-8.png and /dev/null differ diff --git a/docs/tutorials/developer-journey/_attachments/ic-eth-9.png b/docs/tutorials/developer-journey/_attachments/ic-eth-9.png deleted file mode 100644 index 2b98dd388f..0000000000 Binary files a/docs/tutorials/developer-journey/_attachments/ic-eth-9.png and /dev/null differ diff --git a/docs/tutorials/developer-journey/_attachments/metamask-1.png b/docs/tutorials/developer-journey/_attachments/metamask-1.png deleted file mode 100644 index c611afc32c..0000000000 Binary files a/docs/tutorials/developer-journey/_attachments/metamask-1.png and /dev/null differ diff --git a/docs/tutorials/developer-journey/_attachments/metamask-2.png b/docs/tutorials/developer-journey/_attachments/metamask-2.png deleted file mode 100644 index 6522a81ab5..0000000000 Binary files a/docs/tutorials/developer-journey/_attachments/metamask-2.png and /dev/null differ diff --git a/docs/tutorials/developer-journey/_attachments/metamask-3.png b/docs/tutorials/developer-journey/_attachments/metamask-3.png deleted file mode 100644 index 5e040cfb9c..0000000000 Binary files a/docs/tutorials/developer-journey/_attachments/metamask-3.png and /dev/null differ diff --git a/docs/tutorials/developer-journey/_attachments/metamask-4.png b/docs/tutorials/developer-journey/_attachments/metamask-4.png deleted file mode 100644 index c7990359af..0000000000 Binary files a/docs/tutorials/developer-journey/_attachments/metamask-4.png and /dev/null differ diff --git a/docs/tutorials/developer-journey/_attachments/metamask-5.png b/docs/tutorials/developer-journey/_attachments/metamask-5.png deleted file mode 100644 index 8b5f1a6b9c..0000000000 Binary files a/docs/tutorials/developer-journey/_attachments/metamask-5.png and /dev/null differ diff --git a/docs/tutorials/developer-journey/_attachments/sepolia-1.png b/docs/tutorials/developer-journey/_attachments/sepolia-1.png deleted file mode 100644 index d0f118daeb..0000000000 Binary files a/docs/tutorials/developer-journey/_attachments/sepolia-1.png and /dev/null differ diff --git a/docs/tutorials/developer-journey/_attachments/sepolia-2.png b/docs/tutorials/developer-journey/_attachments/sepolia-2.png deleted file mode 100644 index 4fe3d4c91e..0000000000 Binary files a/docs/tutorials/developer-journey/_attachments/sepolia-2.png and /dev/null differ diff --git a/docs/tutorials/developer-journey/_attachments/sepolia-3.png b/docs/tutorials/developer-journey/_attachments/sepolia-3.png deleted file mode 100644 index 27683702fb..0000000000 Binary files a/docs/tutorials/developer-journey/_attachments/sepolia-3.png and /dev/null differ diff --git a/docs/tutorials/developer-journey/_attachments/sepolia-4.png b/docs/tutorials/developer-journey/_attachments/sepolia-4.png deleted file mode 100644 index 82e97bbd37..0000000000 Binary files a/docs/tutorials/developer-journey/_attachments/sepolia-4.png and /dev/null differ diff --git a/docs/tutorials/developer-journey/_attachments/sepolia-5.png b/docs/tutorials/developer-journey/_attachments/sepolia-5.png deleted file mode 100644 index 41c225215e..0000000000 Binary files a/docs/tutorials/developer-journey/_attachments/sepolia-5.png and /dev/null differ diff --git a/docs/tutorials/developer-journey/_attachments/sepolia-6.png b/docs/tutorials/developer-journey/_attachments/sepolia-6.png deleted file mode 100644 index 6deb6a76bf..0000000000 Binary files a/docs/tutorials/developer-journey/_attachments/sepolia-6.png and /dev/null differ diff --git a/docs/tutorials/developer-journey/_attachments/sepolia-7.png b/docs/tutorials/developer-journey/_attachments/sepolia-7.png deleted file mode 100644 index 64aae318b6..0000000000 Binary files a/docs/tutorials/developer-journey/_attachments/sepolia-7.png and /dev/null differ diff --git a/docs/tutorials/developer-journey/_attachments/sepolia-8.png b/docs/tutorials/developer-journey/_attachments/sepolia-8.png deleted file mode 100644 index 9b8ea8c50c..0000000000 Binary files a/docs/tutorials/developer-journey/_attachments/sepolia-8.png and /dev/null differ diff --git a/docs/tutorials/developer-journey/_attachments/sepolia-9.png b/docs/tutorials/developer-journey/_attachments/sepolia-9.png deleted file mode 100644 index 767a135a8c..0000000000 Binary files a/docs/tutorials/developer-journey/_attachments/sepolia-9.png and /dev/null differ diff --git a/docs/tutorials/developer-journey/level-4/4.4-nns-governance.mdx b/docs/tutorials/developer-journey/level-4/4.4-nns-governance.mdx index 054a39987b..5be7236d9d 100644 --- a/docs/tutorials/developer-journey/level-4/4.4-nns-governance.mdx +++ b/docs/tutorials/developer-journey/level-4/4.4-nns-governance.mdx @@ -8,6 +8,8 @@ import { MarkdownChipRow } from "/src/components/Chip/MarkdownChipRow"; + + ## Overview When blockchain networks need to be upgraded, traditionally they use a method known as a 'hard fork', which involves substantial work and manual coordination. In comparison, the Internet Computer upgrades itself weekly, which can be seen on the [ICP dashboard](https://dashboard.internetcomputer.org/releases). @@ -257,7 +259,7 @@ From the neuron's detailed menu, you can execute actions such as increase the st ![NNS dapp 13](../_attachments/nns13.png) -If you scroll further, you can see advanced details and settings, such as when the neuron was created, its neuron account ID, and options to participate in the neurons' fund or split the neuron. [Learn more about these advanced options](/docs/current/developer-docs/daos/nns/nns-app-quickstart). +If you scroll further, you can see advanced details and settings, such as when the neuron was created, its neuron account ID, and options to participate in the neurons' fund or split the neuron. [Learn more about these advanced options](/docs/current/developer-docs/daos/nns/using-the-nns-dapp/nns-app-quickstart). ![NNS dapp 14](../_attachments/nns14.png) @@ -275,7 +277,7 @@ If you click on one, however, you'll notice that you cannot vote on it. That's b ![NNS dapp 17](../_attachments/nns17.png) -For additional information the NNS dapp, proposals, and neuron staking, check out the [NNS quick start guide](/docs/current/developer-docs/daos/nns/nns-app-quickstart) and the [NNS explained series](https://youtu.be/1uX-fRgvXjU?feature=shared). +For additional information the NNS dapp, proposals, and neuron staking, check out the [NNS quick start guide](/docs/current/developer-docs/daos/nns/using-the-nns-dapp/nns-app-quickstart) and the [NNS explained series](https://youtu.be/1uX-fRgvXjU?feature=shared). ## Need help? diff --git a/docs/tutorials/developer-journey/level-5/5.2-ICP-ETH-tutorial.mdx b/docs/tutorials/developer-journey/level-5/5.2-ICP-ETH-tutorial.mdx index e61fbbcfb9..ff020d6790 100644 --- a/docs/tutorials/developer-journey/level-5/5.2-ICP-ETH-tutorial.mdx +++ b/docs/tutorials/developer-journey/level-5/5.2-ICP-ETH-tutorial.mdx @@ -4,41 +4,44 @@ keywords: [advanced, tutorial, developer journey, icp eth, ethereum] import { MarkdownChipRow } from "/src/components/Chip/MarkdownChipRow"; import '/src/components/CenterImages/center.scss'; +import useBaseUrl from "@docusaurus/useBaseUrl"; -# 5.2 Deploying an ETH starter project on ICP +# 5.2 Using the EVM RPC canister ## Overview -As you explored in a previous tutorial, the Internet Computer is integrated with the Bitcoin network, allowing for smart contracts to seamlessly communicate from ICP to Bitcoin for multi-chain functionality. The ICP ETH native integration is currently in development, and will include extensive capabilities for Ethereum dapps and tokens on ICP. For example, ICP ETH integration will include capabilities such as interacting with Ethereum smart contracts from canisters on ICP, creating ckETH and ckERC-20 tokens, which can be swapped with negligible fees. Furthermore, the Bitfinity EVM allows deploying Ethereum smart contracts on ICP. +As you explored in a previous tutorial, the Internet Computer is integrated with the Bitcoin network, allowing for smart contracts to seamlessly communicate from ICP to Bitcoin for multi-chain functionality. ICP also has an integration with Ethereum and EVM networks, but in a different manner than the Bitcoin integration. -These capabilities will be enabled through a protocol-level ETH integration, which will initially use HTTPS outcalls to interact with Ethereum APIs to securely query and send transactions to the Ethereum network. These HTTPS outcalls will eventually be replaced by an on-chain Ethereum API on ICP, made possible by running full Ethereum nodes on each ICP replica. +The Bitcoin integration is a direct integration, meaning there are nodes running on the ICP mainnet that run the Bitcoin node software. ICP currently does not have any nodes running the Ethereum node software and instead communicates with the Ethereum and EVM-compatible networks through a decentralized RPC integration. To facilitate communication to RPC services, the **EVM RPC** canister is used. -Through ICP's chain-key cryptography feature, the ETH integration will include chain-key tokens, similar to the design of ckBTC. The ETH integration will expand the possibilities of chain-key tokens to include ckETH and ckERC-20 tokens, including ckUSDC and ckUSDT. Lastly, the ETH integration will provide developers the ability to run existing Solidity code and dapps on ICP through an on-chain EVM solution. +
Chain Fusion overview +
-:::caution -As mentioned, the ICP ETH integration is still in development. In the future, a there will be an additional variation of this developer journey series that focuses solely on Ethereum development on ICP. -::: +The EVM RPC canister enables your dapp to sign and submit transactions to Ethereum and other EVM networks using [HTTPS outcalls](/docs/current/developer-docs/smart-contracts/advanced-features/https-outcalls/https-outcalls-overview) and [threshold ECDSA signatures](/docs/current/developer-docs/smart-contracts/signatures/t-ecdsa). The EVM RPC canister will eventually be replaced by an on-chain Ethereum API on ICP, made possible by running full Ethereum nodes on each ICP replica. -For this tutorial, a sample boilerplate project will be explored that showcases the basis of the ICP ETH integration, which uses HTTPS outcalls to query information from the Ethereum network. +Through ICP's chain-key cryptography feature, the ETH integration also includes chain-key tokens, similar to the design of ckBTC. The ETH integration expands the possibilities of chain-key tokens to include ckETH and ckERC-20 tokens, including ckUSDC, ckEURC, and ckUSDT. ## Deploying the ETH starter project -In this tutorial, you'll use the DFINITY ICP ETH starter project to deploy a boilerplate dapp that showcases how ICP can query information from the Ethereum network using HTTPS outcalls. This starter dapp is used to verify the ownership of NFTs minted on the Ethereum network, and supports queries to the Ethereum mainnet and the Sepolia and Goerli test networks. +For this tutorial, a sample boilerplate project will be explored that showcases how to use the EVM RPC canister to query information from the Ethereum network. ### Project technology stack -This starter project is comprised of four canisters: +This starter project is comprised of three canisters: -- The frontend canister, which uses TypeScript, Vite and React as the core components to create the user interface. +- The frontend canister, which uses TypeScript, Vite, and React as the core components to create the user interface. - The backend canister, written in Motoko, that uses the Motoko package manager Mops and mo-dev, a live development server for Motoko. -- The Ethereum integration canister, which is written in Rust to utilize the `ethers-core` library in order to interact with Ethereum data structures. This canister also includes Metamask, which is a wallet and browser extension used for interacting with Ethereum dapps. - -- The Internet Identity canister, which is used to authenticate with the dapp within the user interface. +- The EVM RPC canister, which is pulled into the project using [`dfx deps`](/docs/current/developer-docs/smart-contracts/maintain/import). We'll dive deeper into the project's files in the [exploring the project's files](#exploring-the-projects-files) section below. @@ -46,17 +49,14 @@ We'll dive deeper into the project's files in the [exploring the project's files Before you start, verify that you have set up your developer environment according to the instructions in [0.3 Developer environment setup](/docs/current/tutorials/developer-journey/level-0/dev-env). -Additionally, this project requires the installation of Rust, since the canister responsible for communicating with the Ethereum network is written in Rust. Since this tutorial series is focused on Motoko development, we won't dive very deep into the Rust canister in this project, but you will need Rust downloaded to run the project locally. - -[Download and install Rust](https://www.rust-lang.org/). - ### Downloading the starter project's files To get started, open a new terminal window, navigate into your working directory (`developer_journey`), then use the following commands to clone the DFINITY `ic-eth-starter` repo: ```bash -git clone https://github.com/dfinity/ic-eth-starter.git -cd ic-eth-starter +git clone https://github.com/rvanasa/vite-react-motoko.git +cd vite-react-motoko +git switch evm-rpc // Switch to the EVM RPC branch of the repo. ``` ### Exploring the project's files @@ -65,234 +65,102 @@ First, let's start by looking at the contents of the project's `dfx.json` file. ```json title="dfx.json" { - "canisters": { - "frontend": { - "dependencies": ["backend", "internet_identity"], - "type": "assets", - "frontend": { - "entrypoint": "dist/index.html" - }, - "source": ["dist/"] - }, - "backend": { - "dependencies": ["ic_eth"], - "type": "motoko", - "main": "canisters/backend/Main.mo" - }, - "ic_eth": { - "type": "rust", - "candid": "canisters/ic_eth/ic_eth.did", - "package": "ic_eth" - }, - "internet_identity": { - "type": "custom", - "candid": "https://github.com/dfinity/internet-identity/releases/latest/download/internet_identity.did", - "wasm": "https://github.com/dfinity/internet-identity/releases/latest/download/internet_identity_dev.wasm.gz", - "remote": { - "id": { - "ic": "rdmx6-jaaaa-aaaaa-aaadq-cai" - } - }, - "frontend": {} - } - }, - "defaults": { - "build": { - "packtool": "npm run --silent sources" - } - } +  "canisters": { +    "evm_rpc": { +      "type": "pull", +      "id": "7hfb6-caaaa-aaaar-qadga-cai" +    }, +    "backend": { +      "dependencies": ["evm_rpc"], +      "type": "motoko", +      "main": "backend/Backend.mo", +      "declarations": { +        "node_compatibility": true +      } +    }, +    "frontend": { +      "dependencies": ["backend"], +      "type": "assets", +      "source": ["dist/"] +    } +  }, +  "defaults": { +    "build": { +      "packtool": "npm run --silent sources" +    } +  }, +  "output_env_file": ".env", +  "version": 2 } ``` In this file, you can see the definitions for the project's four canisters: -- `frontend`: The dapp's frontend canister, which has type "assets" to declare it as an asset canister, and uses the files stored in the `dist` directory. This canister has the dependencies of `backend` and `internet_identity`, which are two of the other canisters defined in this project's `dfx.json` file. - -- `backend`: The dapp's backend canister, which has type "motoko" since it uses Motoko source code stored in the file `canisters/backend/Main.mo`. This canister has the dependency of `ic_eth`. - -- `ic_eth`: This canister is responsible for interacting with the Ethereum network, and has type "rust" since this canister uses source code written in Rust that is stored in the `canisters/ic_eth` subdirectory. This file specifies the canister's Candid file at `canisters/ic_eth/ic_eth.did`. - -- `internet_identity`: This canister is a local instance of the Internet Identity canister, and is built from the Candid and Wasm files from the latest DFINITY Internet Identity release. - -Next, let's take a look at the source code for the backend canister. Open the `canisters/backend/Main.mo` file, which will contain the following content. This code has been annotated with notes to explain the code's logic: - -```motoko title="canisters/backend/Main.mo" - -// Import the necessary libraries: - -import System "lib/System"; -import Types "Types"; -import Core "Core"; -import State "State"; -import History "History"; -import Snapshot "Snapshot"; - -// Define a shared actor: -shared ({ caller = installer }) actor class Main() { - -// Declare two stable variables; one for the canister's state and one of the canister's history: - let sys = System.IC(); - stable var _state_v0 : State.Stable.State = State.Stable.initialState(sys); - stable var _history_v0 : History.History = History.init(sys, installer); +- `frontend`: The dapp's frontend canister, which has type "assets" to declare it as an asset canister, and uses the files stored in the `dist` directory. This canister has a dependency on the `backend` canister. - let core = Core.Core(installer, sys, _state_v0, _history_v0); +- `backend`: The dapp's backend canister, which has type "motoko" since it uses Motoko source code stored in the file `backend/Backend.mo`. This canister has the dependency of `evm_rpc`. - /// Define a method to login and fetch user details. This will create an account if one does not exist for the caller principal. - public shared ({ caller }) func login() : async Types.Resp.Login { - core.login(caller); - }; +- `evm_rpc`: This canister is responsible for facilitating communication from the backend canister to RPC services to interact with the Ethereum network. This canister is pulled using `dfx deps` and has canister ID `7hfb6-caaaa-aaaar-qadga-cai`. - /// If you've already created an account, you can use this method to speed up the login process: - public query ({ caller }) func fastLogin() : async ?Types.Resp.Login { - core.fastLogin(caller); - }; +Next, let's take a look at the source code for the backend canister. Open the `backend/Backend.mo` file, which will contain the following content. This code has been annotated with notes to explain the code's logic: - /// Get a list of connected Ethereum wallets: - public query ({ caller }) func getEthWallets() : async Types.Resp.GetEthWallets { - core.getEthWallets(caller); - }; +```motoko title="backend/Backend.mo" - /// Connect a new Ethereum wallet, using the given ECDSA signature for authorization: - public shared ({ caller }) func connectEthWallet(wallet : Types.EthWallet, signedPrincipal : Types.SignedPrincipal) : async Types.Resp.ConnectEthWallet { - await core.connectEthWallet(caller, wallet, signedPrincipal); - }; +import EvmRpc "canister:evm_rpc"; - /// Define a method to check if an NFT is currently owned by the given principal: - public shared ({ caller }) func isNftOwned(principal : Principal, nft : Types.Nft.Nft) : async Bool { - await core.isNftOwned(caller, principal, nft); - }; +import Debug "mo:base/Debug"; +import Cycles "mo:base/ExperimentalCycles"; - /// Define a method to verify that the given NFTs are owned by the caller, and store the results: - public shared ({ caller }) func addNfts(nfts : [Types.Nft.Nft]) : async Bool { - await core.addNfts(caller, nfts); - }; +actor { - /// Define a method to retrieve the NFTs which were previously verified via `addNfts()`: - public query ({ caller }) func getNfts() : async [Types.Nft.Nft] { - core.getNfts(caller); - }; +  /// Retrieve the latest block on the Ethereum blockchain. +  public func getLatestEthereumBlock() : async EvmRpc.Block { - /// Define a method to hide or show all NFTs with the given smart contract or wallet address: - public shared ({ caller }) func setAddressFiltered(address : Types.Address.Address, filtered : Bool) : async Bool { - await core.setAddressFiltered(caller, address, filtered); - }; +    // Select RPC services +    let services : EvmRpc.RpcServices = #EthMainnet(?[#Cloudflare]); - /// Define a method to retrieve the full log for this canister: - public query ({ caller }) func getHistory() : async ?[History.Event] { - core.getHistory(caller); - }; - - /// Define a method to retrieve a public-facing log for this canister: - public query ({ caller }) func getPublicHistory() : async [Types.PublicEvent] { - core.getPublicHistory(caller); - }; - - /// Define a method to retrieve a Candid representation of the canister's internal state: - public query ({ caller }) func getState() : async ?[Snapshot.Entry] { - core.getState(caller); - }; +    // Call `eth_getBlockByNumber` RPC method (unused cycles will be refunded) +    Cycles.add(1000000000); +    let result = await EvmRpc.eth_getBlockByNumber(services, null, #Latest); +    switch result { +      // Consistent, successful results +      case (#Consistent(#Ok block)) { +        block; +      }; +      // Consistent error message +      case (#Consistent(#Err error)) { +        Debug.trap("Error: " # debug_show error); +      }; +      // Inconsistent results between RPC providers +      case (#Inconsistent(results)) { +        Debug.trap("Inconsistent results"); +      }; +    }; +  }; }; ``` -Next, take a look at the Candid file for the `ic_eth` canister. Recall that Candid is used to describe the interfaces of a canister. The Candid file for the project's `ic_eth` canister will provide insight into the functions defined within the canister that are responsible for the dapp's interactions with the Ethereum network: - -```candid -service : { - verify_ecdsa : (eth_address : text, message : text, signature : text) -> (bool) query; - erc721_owner_of : (network : text, contract_address : text, token_id : nat64) -> (text); - erc1155_balance_of : (network : text, contract_address : text, owner_address : text, token_id : nat64) -> (nat); -} -``` - -In this Candid file, you can see that there are three services defined: +#### What this code does -- `verify_ecdsa`: This service takes input of an `eth_address`, `message`, and `signature`, all of type `text` and returns a query call of type `bool`. Type `bool` instances can have the value of either 'True' or 'False'. - -- `erc721_owner_of`: This service takes input of `network` and `contract_address` of type `text`, and `token_id` of type `nat64`, and returns a `text` value. - -- `erc1155_balance_of`: This service takes input of `network`, `contract_address`, and `owner_address` of type `text`, and `token_id` of type `nat64`, and returns a `nat` value. +This backend code has a single function that retrieves the latest block from the Ethereum mainnet. It configures the RPC service to make the call through the Cloudflare RPC provider and attaches cycles to the call. By default, the EVM RPC canister replicates this call across at least three providers to decentralize the RPC call and verify that the results returned from each provider match one another. This backend code checks to make sure the result returned matches the result of the other RPC services. This tutorial will not dive into the frontend's configuration. [Learn more about frontend canisters](/docs/current/developer-docs/web-apps/application-frontends/overview). -### Creating a testnet wallet - -Before you can deploy this starter project and test functionality, you will need an Ethereum testnet wallet. To get one, first install [MetaMask](https://metamask.io/). MetaMask is supported as a browser extension for most web browsers. - -Once installed, a MetaMask window will open prompting you to create a new wallet or import an existing one. Select 'Create a new wallet': - -![Metamask 1](../_attachments/metamask-1.png) - -Create a password for local authentication with your wallet: - -![Metamask 2](../_attachments/metamask-2.png) - -Next, you will be prompted to secure your wallet by downloading your wallet's recovery phrase. This step is recommended. - -![Metamask 3](../_attachments/metamask-3.png) - -After the wallet has been created, you'll see a screen that confirms the creation was successful: - -![Metamask 4](../_attachments/metamask-4.png) - -Then, you can see the account's information, such as the account's balance of tokens or NFTs, and actions such as sending or swapping assets, by clicking on the extension in your web browser: - -![Metamask 5](../_attachments/metamask-5.png) - -### Obtaining Sepolia testnet tokens - -Next, you will need to obtain some tokens to pay for the gas fees on the Ethereum Sepolia testnet network. To do this, start by switching your MetaMask network to Sepolia through the following steps. - -First, click on the extension within your web browser. Select the Ethereum icon drop down menu in the top left corner: - -![Sepolia 1](../_attachments/sepolia-1.png) - -Next, toggle the 'Show test networks' button: - -![Sepolia 2](../_attachments/sepolia-2.png) - -Then, select the Sepolia network: - -![Sepolia 3](../_attachments/sepolia-3.png) - -To confirm that you've switched your wallet to use Sepolia, your wallet's balance should now show SepoliaETH instead of ETH: - -![Sepolia 4](../_attachments/sepolia-4.png) - -Next, navigate to the Sepolia faucet at https://sepoliafaucet.com/. - -![Sepolia 5](../_attachments/sepolia-5.png) - -You will need to create or login to an Alchemy account to use this faucet. You can [create a free Alchemy account](https://auth.alchemy.com/signup). - -Once logged in, the Sepolia faucet will confirm that you can receive 0.5 SepoliaETH. - -![Sepolia 6](../_attachments/sepolia-6.png) - -To receive the 0.5 SepoliaETH, you will need your wallet address from MetaMask. To get this wallet address, select the MetaMask extension and select the wallet address in the top center of the window to copy the address: - -![Sepolia 7](../_attachments/sepolia-7.png) - -Paste this wallet address into the faucet and then select the 'Send Me ETH' button: - -![Sepolia 8](../_attachments/sepolia-8.png) - -Once sent, you will see the transaction hash returned in the faucet window, and the balance of 0.5 SepoliaETH in the MetaMask wallet extension: - -![Sepolia 9](../_attachments/sepolia-9.png) - ### Deploying the project -Now that you have an Ethereum wallet with some SepoliaETH testnet tokens, it's time to deploy your ICP ETH starter project. To do this, first assure that a local replica is running: +It's time to deploy the boilerplate project. To do this, first assure that a local replica is running: ```bash dfx start --clean --background ``` -Then, set up local Rust canister development with the command; remember that this step is necessary since the canister responsible for communicating with the Ethereum network is written in Rust: +Then, pull and deploy the `evm_rpc` canister locally with `dfx deps`: ```bash -rustup target add wasm32-unknown-unknown +dfx deps pull +dfx deps init evm_rpc --argument '(record { nodesInSubnet = 28 })' +dfx deps deploy ``` Install the program's packages, generate Candid type bindings, and deploy the canisters with the command: @@ -313,113 +181,173 @@ This command will return the local URL that the dapp is running at; by default, ### Using the dapp -It's time to use the ICP ETH starter dapp to verify the ownership of an NFT! To get started, open the local URL that was returned by the `npm start` command, such as `http://localhost:3000`. You'll see the frontend of the dapp: +To use the dapp and query information about the latest Ethereum block, open the local URL that was returned by the `npm start` command, such as `http://localhost:3000`. You'll see the frontend of the dapp: ![ICP ETH 1](../_attachments/ic-eth-1.png) -Next, you can log into the dapp with Internet Identity by selecting the II icon next to the 'Sign in' text: +Click on the "Get latest block" to query the latest block from the Ethereum mainnet. ![ICP ETH 2](../_attachments/ic-eth-2.png) -Select your local Internet Identity to authenticate with the dapp. Need a reminder on how to create an Internet Identity? Review the [3.5 Identities and authentication](/docs/current/tutorials/developer-journey/level-3/3.5-identities-and-auth) level of the developer journey. - -![ICP ETH 3](../_attachments/ic-eth-3.png) - -Next, you'll need to use the Ethereum 'E2E Test Dapp' at the URL https://metamask.github.io/test-dapp/. This dapp can be used to simulate different transactions and assets on the Sepolia testnet. We'll use this dapp to simulate an NFT being minted, that way we can verify that our Sepolia testnet wallet owns that test NFT. - -Once you open this dapp in a web browser, select the 'Connect' option under 'Basic actions'. - -![ICP ETH 4](../_attachments/ic-eth-4.png) - -This will open a prompt through the MetaMask extension that will verify you'd like to connect your MetaMask wallet to the E2E test dapp. - -![ICP ETH 5](../_attachments/ic-eth-5.png) - -Once authenticated, scroll down on the E2E test dapp window. On the left, you will see a menu for 'NFTs', with the first option being 'Deploy'. Click 'Deploy'. - -![ICP ETH 6](../_attachments/ic-eth-6.png) - -This 'Deploy' option will deploy a test Ethereum smart contract that will provide the ability for an NFT to be minted from that test smart contract. You will be prompted to authenticate the deployment of this test smart contract via your MetaMask wallet. - -![ICP ETH 7](../_attachments/ic-eth-7.png) - -Once confirmed, you'll notice your SepoliaETH balance has decreased, since some SepoliaETH tokens were used to pay for the smart contract's gas fees. - -![ICP ETH 8](../_attachments/ic-eth-8.png) - -Next, back on the E2E test dapp window, select the 'Mint' option under the 'NFTs' menu. This will mint an NFT using the test smart contract that you just deployed. For this example, leave the amount of NFTs to mint as the default value of `1`. - -![ICP ETH 9](../_attachments/ic-eth-9.png) - -Authenticate the request through your MetaMask wallet when prompted. - -![ICP ETH 10](../_attachments/ic-eth-10.png) - -Now that you have an NFT minted, you will need to select 'Watch all NFTs' to get your test NFT in your Sepolia testnet wallet. This will watch all NFTs that you minted using this sample smart contract. - -![ICP ETH 11](../_attachments/ic-eth-11.png) - -Your MetaMask wallet will prompt you to add the NFT to your wallet. Select 'Add NFT' when prompted. - -![ICP ETH 12](../_attachments/ic-eth-12.png) - -Now, in your MetaMask wallet, under the 'NFTs' tab, you will see the single NFT under a collection called 'TestDappNFTs'. +When this button is clicked, the following is happening in the background: -![ICP ETH 13](../_attachments/ic-eth-13.png) +- The frontend canister triggers the `getLatestEthereumBlock()` method of the backend canister. -Click on the NFT, then select the NFT's menu by selecting the three dots icon next to 'Account / TestDappNFTs' in the top of the window. Select 'View on Opensea' to open the NFT's URL in a new tab. +- The backend canister uses HTTPS outcalls to send an [`eth_getBlockByNumber`](https://docs.alchemy.com/reference/eth-call) RPC request to an Ethereum JSON-RPC API using the Cloudflare provider. By default, the EVM RPC canister replicates this call across at least 2 other RPC providers. -![ICP ETH 14](../_attachments/ic-eth-14.png) - -You will now have a tab open with the NFT's full URL on the Opensea testnet website. Copy the full URL shown in the navigation bar of your web browser. - -![ICP ETH 15](../_attachments/ic-eth-15.png) - -Now, head back to your local dapp at http://localhost:3000. Select the 'Verify' tab, then click the 'Connect to MetaMask' button. - -![ICP ETH 16](../_attachments/ic-eth-16.png) +- This request involves encoding and decoding ABI, which is the Candid equivalent in the Ethereum ecosystem. -Authenticate with your MetaMask wallet. Then in the dapp, select 'Verify wallet' button. Once authenticated, you will see your Ethereum address displayed in the dapp. +- The latest block information is returned to the backend canister. Three responses are returned; one from the specified RPC provider Cloudflare and two from the other RPC providers that the EVM RPC canister queried automatically for decentralization purposes. The backend canister checks to be sure that all three responses contain the same information. -![ICP ETH 17](../_attachments/ic-eth-17.png) +- Then, the frontend displays the block information that was returned. -Now, you can enter the Opensea URL that you previously copied to verify that your Sepolia testnet wallet owns that testnet NFT. If successful, the text box will turn green and have a green checkmark indicating that the test is successful. +:::info +In this tutorial, you deployed this starter dapp locally. To deploy this dapp on the mainnet, run `dfx deploy --network ic`. +::: -![ICP ETH 18](../_attachments/ic-eth-18.png) +## Calling the EVM RPC canister from the CLI -To verify this URL, the following is happening in the background: +You can make calls directly to the EVM RPC canister from the CLI. For example, to get the latest Ethereum gas fee information, use the `dfx` command: -- The canister use HTTPS outcalls to send an [`eth_call`](https://docs.alchemy.com/reference/eth-call) RPC request to an Ethereum JSON-RPC API. +```bash +IDENTITY=default +CYCLES=1500000000 +WALLET=$(dfx identity get-wallet) +RPC_SOURCE=EthMainnet +JSON_RPC_SOURCE=Chain=1 +RPC_CONFIG=null + +dfx canister call evm_rpc eth_feeHistory "(variant {$RPC_SOURCE}, $RPC_CONFIG, record {blockCount = 3; newestBlock = variant {Latest}})" --with-cycles=$CYCLES --wallet=$WALLET +``` -- This request involves encoding and decoding ABI, which is the Candid equivalent in the Ethereum ecosystem. +If the results from each RPC provider match, the result returned will be 'Consistent': -- Then, the canister calls the `ownerOf` smart contract function for standard ERC-721 NFTs, and the `balanceOf` function for ERC-1155 multi-token contracts. This step checks that the user currently owns the given token. +```bash +( +  variant { +    Consistent = variant { +      Ok = opt record { +        reward = vec {}; +        gasUsedRatio = vec { +          0.4901801333333333 : float64; +          0.2692428 : float64; +          0.6662872333333333 : float64; +        }; +        oldestBlock = 20_594_047 : nat; +        baseFeePerGas = vec { +          2_790_453_437 : nat; +          2_783_602_967 : nat; +          2_623_018_861 : nat; +          2_732_062_498 : nat; +        }; +      } +    } +  }, +) +``` -- Then, the frontend reflects the result of whether the user owns the token or not. +If the results returned are 'Inconsistent', each individual response will be returned: -:::info -In this tutorial, you deployed this starter dapp locally. To deploy this dapp on the mainnet, run `dfx deploy --network ic`. -::: +```bash +( +  variant { +    Inconsistent = vec { +      record { +        variant { EthMainnet = variant { Ankr } }; +        variant { +          Ok = opt record { +            reward = vec {}; +            gasUsedRatio = vec { +              0.4223029666666666 : float64; +              0.4901801333333333 : float64; +              0.2692428 : float64; +            }; +            oldestBlock = 20_594_046 : nat; +            baseFeePerGas = vec { +              2_845_729_624 : nat; +              2_790_453_437 : nat; +              2_783_602_967 : nat; +              2_623_018_861 : nat; +            }; +          } +        }; +      }; +      record { +        variant { EthMainnet = variant { PublicNode } }; +        variant { +          Err = variant { +            ProviderError = variant { +              TooFewCycles = record { +                expected = 555_296_000 : nat; +                received = 449_408_000 : nat; +              } +            } +          } +        }; +      }; +      record { +        variant { EthMainnet = variant { Cloudflare } }; +        variant { +          Ok = opt record { +            reward = vec {}; +            gasUsedRatio = vec { +              0.4223029666666666 : float64; +              0.4901801333333333 : float64; +              0.2692428 : float64; +            }; +            oldestBlock = 20_594_046 : nat; +            baseFeePerGas = vec { +              2_845_729_624 : nat; +              2_790_453_437 : nat; +              2_783_602_967 : nat; +              2_623_018_861 : nat; +            }; +          } +        }; +      }; +    } +  }, +) +``` -## Going further +You can also sign and submit transactions directly to Ethereum with a command such as: -Since this dapp is designed as a starter boilerplate, it is highly encouraged to build off of this template to develop your own ICP ETH dapp. Here are some tips and tricks to help you get started: +```bash +NETWORK=local +IDENTITY=default +CYCLES=1500000000 +WALLET=$(dfx identity get-wallet) +RPC_SOURCE=EthMainnet +JSON_RPC_SOURCE=Chain=1 +RPC_CONFIG=null + +dfx canister call evm_rpc eth_sendRawTransaction "(variant {$RPC_SOURCE}, $RPC_CONFIG, \"0xf86c098504a817c800825208943535353535353535353535353535353535353535880de0b6b3a76400008025a028ef61340bd939bc2195fe537567866003e1a15d3c71ff63e1590620aa636276a067cbe9d8997f761aecb703304b3800ccf555c9f3dc64214b297fb1966a3b6d83\")" --with-cycles=$CYCLES --wallet=$WALLET +``` -- Customize your project's code style by editing the `.prettierrc` file and then running `npm run format`. +Your transaction ID will be returned from the RPC provider. For example, here is the transaction ID returned from PublicNode: -- Reduce the latency of update calls by passing the `--emulator` flag to `dfx start`. +```bash +  record { +    variant { EthMainnet = variant { PublicNode } }; +    variant { +      Ok = variant { +        Ok = opt "0x33469b22e9f636356c4160a87eb19df52b7412e8eac32a4a55ffe88ea8350788" +      } +    }; +  }; +``` -- Install a Motoko package by running `npx ic-mops add `. [View the full list of available packages](https://mops.one/). +## Resources -- Split your frontend and backend console output by running `npm run frontend` and `npm run backend` in separate terminals. +- [View the full Github repo for this starter project](https://github.com/rvanasa/vite-react-motoko/tree/evm-rpc). -## Resources +- [How it works: EVM RPC canister](/docs/current/developer-docs/multi-chain/ethereum/evm-rpc/how-it-works). -[View the full Github repo for this starter project](https://github.com/dfinity/ic-eth-starter). +- [Using the EVM RPC canister](/docs/current/developer-docs/multi-chain/ethereum/evm-rpc/evm-rpc-canister). -Here are additional examples that build off of this starter project: +- [Costs of RPC requests](/docs/current/developer-docs/multi-chain/ethereum/evm-rpc/costs). -- [Adding ERC-20 verification](https://github.com/jennifertrin/erc20icp) +- [Samples using the EVM RPC canister](/docs/current/developer-docs/multi-chain/ethereum/evm-rpc/samples). ## Need help? diff --git a/docs/tutorials/hackathon-prep-course/index.mdx b/docs/tutorials/hackathon-prep-course/index.mdx index 3397c382a3..193d1f6197 100644 --- a/docs/tutorials/hackathon-prep-course/index.mdx +++ b/docs/tutorials/hackathon-prep-course/index.mdx @@ -10,7 +10,7 @@ import { MarkdownChipRow } from "/src/components/Chip/MarkdownChipRow"; -- [1: What is the Internet Computer?](/docs/current/tutorials/hackathon-prep-course/what-is-icp). +- [1: What is the Internet Computer?](/docs/current/tutorials/hackathon-prep-course/what-is-icp) - [2: Deploying your first fullstack dapp](/docs/current/tutorials/hackathon-prep-course/deploying-first-fullstack-dapp). diff --git a/docusaurus.config.js b/docusaurus.config.js index 20ff576b9d..bc76fd6e62 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -222,7 +222,7 @@ const marketingNav = { },*/ ], featured: { - title: "Chain Fusion Technology", + title: "Chain Fusion", href: "/chainfusion", image: "/img/nav/featured-chainfusion.webp", }, @@ -582,7 +582,27 @@ const config = { searchCanisterId: "5qden-jqaaa-aaaam-abfpa-cai", marketingNav, }, - scripts: [], + markdown: { + mermaid: true, + }, + scripts: [ + { + src: "https://widget.kapa.ai/kapa-widget.bundle.js", + "data-website-id": "08910249-851f-465b-b60f-238d84e1afc1", + "data-project-name": "Internet Computer", + "data-project-color": "#172234", + "data-project-logo": + "https://s3.coinmarketcap.com/static-gravity/image/2fb1bc84c1494178beef0822179d137d.png", + "data-modal-override-open-class": "ask-ai-widget-trigger", + "data-modal-ask-ai-input-placeholder": + "Ask me a question about the Internet Computer Protocol", + "data-modal-example-questions": + "What is the ICP token?, How is the Internet Computer governed?, How do I start building fully on-chain Web3?", + "data-modal-disclaimer": + " This LLM provides responses are generated automatically and may be inaccurate or outdated. Please take care to verify or validate any responses before making any critical decisions.", + async: true, + }, + ], plugins: [ "docusaurus-plugin-sass", customWebpack, @@ -748,8 +768,7 @@ const config = { }, { label: "Press Kit", - href: "https://internetcomputer.org/press-kit.zip", - isDownload: true, + href: "https://dfinity.frontify.com/d/pD7yZhsmpqos/press-kit", }, ], }, @@ -830,7 +849,7 @@ const config = { playgroundPosition: "bottom", }, }, - themes: ["@docusaurus/theme-live-codeblock"], + themes: ["@docusaurus/theme-live-codeblock", "@docusaurus/theme-mermaid"], clientModules: [require.resolve("./static/load_moc.ts")], }; diff --git a/package-lock.json b/package-lock.json index 7cb2d7bc99..cd8d3143a8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "@dfinity/agent": "^0.15.4", "@dfinity/candid": "^0.15.4", "@dfinity/principal": "^0.15.4", + "@docusaurus/theme-mermaid": "^2.4.3", "@floating-ui/react": "^0.26.9", "chart.js": "^3.8.0", "chartjs-plugin-datalabels": "^2.0.0", @@ -281,7 +282,6 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", - "dev": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -294,7 +294,6 @@ "version": "7.23.5", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", - "dev": true, "dependencies": { "@babel/highlight": "^7.23.4", "chalk": "^2.4.2" @@ -307,7 +306,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "dependencies": { "color-convert": "^1.9.0" }, @@ -319,7 +317,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -333,7 +330,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "dependencies": { "color-name": "1.1.3" } @@ -341,14 +337,12 @@ "node_modules/@babel/code-frame/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, "engines": { "node": ">=0.8.0" } @@ -357,7 +351,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, "engines": { "node": ">=4" } @@ -366,7 +359,6 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "dependencies": { "has-flag": "^3.0.0" }, @@ -378,7 +370,6 @@ "version": "7.23.5", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -387,7 +378,6 @@ "version": "7.23.7", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.7.tgz", "integrity": "sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw==", - "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.23.5", @@ -417,7 +407,6 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, "bin": { "semver": "bin/semver.js" } @@ -426,7 +415,6 @@ "version": "7.23.6", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", - "dev": true, "dependencies": { "@babel/types": "^7.23.6", "@jridgewell/gen-mapping": "^0.3.2", @@ -441,7 +429,6 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", - "dev": true, "dependencies": { "@babel/types": "^7.22.5" }, @@ -453,7 +440,6 @@ "version": "7.22.15", "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz", "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==", - "dev": true, "dependencies": { "@babel/types": "^7.22.15" }, @@ -465,7 +451,6 @@ "version": "7.23.6", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", - "dev": true, "dependencies": { "@babel/compat-data": "^7.23.5", "@babel/helper-validator-option": "^7.23.5", @@ -481,7 +466,6 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, "bin": { "semver": "bin/semver.js" } @@ -490,7 +474,6 @@ "version": "7.23.7", "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.7.tgz", "integrity": "sha512-xCoqR/8+BoNnXOY7RVSgv6X+o7pmT5q1d+gGcRlXYkI+9B31glE4jeejhKVpA04O1AtzOt7OSQ6VYKP5FcRl9g==", - "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-environment-visitor": "^7.22.20", @@ -513,7 +496,6 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, "bin": { "semver": "bin/semver.js" } @@ -522,7 +504,6 @@ "version": "7.22.15", "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz", "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==", - "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "regexpu-core": "^5.3.1", @@ -539,7 +520,6 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, "bin": { "semver": "bin/semver.js" } @@ -548,7 +528,6 @@ "version": "0.5.0", "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.5.0.tgz", "integrity": "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q==", - "dev": true, "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", "@babel/helper-plugin-utils": "^7.22.5", @@ -564,7 +543,6 @@ "version": "7.22.20", "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -573,7 +551,6 @@ "version": "7.23.0", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", - "dev": true, "dependencies": { "@babel/template": "^7.22.15", "@babel/types": "^7.23.0" @@ -586,7 +563,6 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", - "dev": true, "dependencies": { "@babel/types": "^7.22.5" }, @@ -598,7 +574,6 @@ "version": "7.23.0", "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", - "dev": true, "dependencies": { "@babel/types": "^7.23.0" }, @@ -610,7 +585,6 @@ "version": "7.22.15", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", - "dev": true, "dependencies": { "@babel/types": "^7.22.15" }, @@ -622,7 +596,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", - "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-module-imports": "^7.22.15", @@ -641,7 +614,6 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", - "dev": true, "dependencies": { "@babel/types": "^7.22.5" }, @@ -653,7 +625,6 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -662,7 +633,6 @@ "version": "7.22.20", "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", - "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-environment-visitor": "^7.22.20", @@ -679,7 +649,6 @@ "version": "7.22.20", "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz", "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==", - "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-member-expression-to-functions": "^7.22.15", @@ -696,7 +665,6 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", - "dev": true, "dependencies": { "@babel/types": "^7.22.5" }, @@ -708,7 +676,6 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", - "dev": true, "dependencies": { "@babel/types": "^7.22.5" }, @@ -720,7 +687,6 @@ "version": "7.22.6", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", - "dev": true, "dependencies": { "@babel/types": "^7.22.5" }, @@ -732,7 +698,6 @@ "version": "7.23.4", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -741,7 +706,6 @@ "version": "7.22.20", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -750,7 +714,6 @@ "version": "7.23.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -759,7 +722,6 @@ "version": "7.22.20", "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", - "dev": true, "dependencies": { "@babel/helper-function-name": "^7.22.5", "@babel/template": "^7.22.15", @@ -773,7 +735,6 @@ "version": "7.23.8", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.8.tgz", "integrity": "sha512-KDqYz4PiOWvDFrdHLPhKtCThtIcKVy6avWD2oG4GEvyQ+XDZwHD4YQd+H2vNMnq2rkdxsDkU82T+Vk8U/WXHRQ==", - "dev": true, "dependencies": { "@babel/template": "^7.22.15", "@babel/traverse": "^7.23.7", @@ -787,7 +748,6 @@ "version": "7.23.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", - "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.22.20", "chalk": "^2.4.2", @@ -801,7 +761,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "dependencies": { "color-convert": "^1.9.0" }, @@ -813,7 +772,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -827,7 +785,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "dependencies": { "color-name": "1.1.3" } @@ -835,14 +792,12 @@ "node_modules/@babel/highlight/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "node_modules/@babel/highlight/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, "engines": { "node": ">=0.8.0" } @@ -851,7 +806,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, "engines": { "node": ">=4" } @@ -860,7 +814,6 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "dependencies": { "has-flag": "^3.0.0" }, @@ -872,7 +825,6 @@ "version": "7.23.6", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", - "dev": true, "bin": { "parser": "bin/babel-parser.js" }, @@ -884,7 +836,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.23.3.tgz", "integrity": "sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -899,7 +850,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.23.3.tgz", "integrity": "sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", @@ -916,7 +866,6 @@ "version": "7.23.7", "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.7.tgz", "integrity": "sha512-LlRT7HgaifEpQA1ZgLVOIJZZFVPWN5iReq/7/JixwBtwcoeVGDBD53ZV28rrsLYOZs1Y/EHhA8N/Z6aazHR8cw==", - "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-plugin-utils": "^7.22.5" @@ -933,7 +882,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz", "integrity": "sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA==", "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-object-rest-spread instead.", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.10.4", "@babel/plugin-syntax-object-rest-spread": "^7.8.0", @@ -947,7 +895,6 @@ "version": "7.21.0-placeholder-for-preset-env.2", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", - "dev": true, "engines": { "node": ">=6.9.0" }, @@ -959,7 +906,6 @@ "version": "7.8.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -971,7 +917,6 @@ "version": "7.12.13", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" }, @@ -983,7 +928,6 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -998,7 +942,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1010,7 +953,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.3" }, @@ -1022,7 +964,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz", "integrity": "sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1037,7 +978,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.23.3.tgz", "integrity": "sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1052,7 +992,6 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -1064,7 +1003,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1076,7 +1014,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz", "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1091,7 +1028,6 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -1103,7 +1039,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1115,7 +1050,6 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -1127,7 +1061,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1139,7 +1072,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1151,7 +1083,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1163,7 +1094,6 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -1178,7 +1108,6 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -1193,7 +1122,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz", "integrity": "sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1208,7 +1136,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", - "dev": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -1224,7 +1151,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz", "integrity": "sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1239,7 +1165,6 @@ "version": "7.23.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.7.tgz", "integrity": "sha512-PdxEpL71bJp1byMG0va5gwQcXHxuEYC/BgI/e88mGTtohbZN28O5Yit0Plkkm/dBzCF/BxmbNcses1RH1T+urA==", - "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-plugin-utils": "^7.22.5", @@ -1257,7 +1182,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz", "integrity": "sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw==", - "dev": true, "dependencies": { "@babel/helper-module-imports": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5", @@ -1274,7 +1198,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz", "integrity": "sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1289,7 +1212,6 @@ "version": "7.23.4", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz", "integrity": "sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1304,7 +1226,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.23.3.tgz", "integrity": "sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg==", - "dev": true, "dependencies": { "@babel/helper-create-class-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5" @@ -1320,7 +1241,6 @@ "version": "7.23.4", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.4.tgz", "integrity": "sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==", - "dev": true, "dependencies": { "@babel/helper-create-class-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5", @@ -1337,7 +1257,6 @@ "version": "7.23.8", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.8.tgz", "integrity": "sha512-yAYslGsY1bX6Knmg46RjiCiNSwJKv2IUC8qOdYKqMMr0491SXFhcHqOdRDeCRohOOIzwN/90C6mQ9qAKgrP7dg==", - "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-compilation-targets": "^7.23.6", @@ -1359,7 +1278,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz", "integrity": "sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/template": "^7.22.15" @@ -1375,7 +1293,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz", "integrity": "sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1390,7 +1307,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.23.3.tgz", "integrity": "sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==", - "dev": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5" @@ -1406,7 +1322,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.23.3.tgz", "integrity": "sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1421,7 +1336,6 @@ "version": "7.23.4", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.23.4.tgz", "integrity": "sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-dynamic-import": "^7.8.3" @@ -1437,7 +1351,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.23.3.tgz", "integrity": "sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==", - "dev": true, "dependencies": { "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5" @@ -1453,7 +1366,6 @@ "version": "7.23.4", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.23.4.tgz", "integrity": "sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" @@ -1469,7 +1381,6 @@ "version": "7.23.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.6.tgz", "integrity": "sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" @@ -1485,7 +1396,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz", "integrity": "sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==", - "dev": true, "dependencies": { "@babel/helper-compilation-targets": "^7.22.15", "@babel/helper-function-name": "^7.23.0", @@ -1502,7 +1412,6 @@ "version": "7.23.4", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.23.4.tgz", "integrity": "sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-json-strings": "^7.8.3" @@ -1518,7 +1427,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz", "integrity": "sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1533,7 +1441,6 @@ "version": "7.23.4", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.23.4.tgz", "integrity": "sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" @@ -1549,7 +1456,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz", "integrity": "sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1564,7 +1470,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.3.tgz", "integrity": "sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==", - "dev": true, "dependencies": { "@babel/helper-module-transforms": "^7.23.3", "@babel/helper-plugin-utils": "^7.22.5" @@ -1580,7 +1485,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz", "integrity": "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==", - "dev": true, "dependencies": { "@babel/helper-module-transforms": "^7.23.3", "@babel/helper-plugin-utils": "^7.22.5", @@ -1597,7 +1501,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.3.tgz", "integrity": "sha512-ZxyKGTkF9xT9YJuKQRo19ewf3pXpopuYQd8cDXqNzc3mUNbOME0RKMoZxviQk74hwzfQsEe66dE92MaZbdHKNQ==", - "dev": true, "dependencies": { "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-module-transforms": "^7.23.3", @@ -1615,7 +1518,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.23.3.tgz", "integrity": "sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==", - "dev": true, "dependencies": { "@babel/helper-module-transforms": "^7.23.3", "@babel/helper-plugin-utils": "^7.22.5" @@ -1631,7 +1533,6 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", - "dev": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.5", "@babel/helper-plugin-utils": "^7.22.5" @@ -1647,7 +1548,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.23.3.tgz", "integrity": "sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1662,7 +1562,6 @@ "version": "7.23.4", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.23.4.tgz", "integrity": "sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" @@ -1678,7 +1577,6 @@ "version": "7.23.4", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.23.4.tgz", "integrity": "sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-numeric-separator": "^7.10.4" @@ -1694,7 +1592,6 @@ "version": "7.23.4", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.23.4.tgz", "integrity": "sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g==", - "dev": true, "dependencies": { "@babel/compat-data": "^7.23.3", "@babel/helper-compilation-targets": "^7.22.15", @@ -1713,7 +1610,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz", "integrity": "sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-replace-supers": "^7.22.20" @@ -1729,7 +1625,6 @@ "version": "7.23.4", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.23.4.tgz", "integrity": "sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" @@ -1745,7 +1640,6 @@ "version": "7.23.4", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.4.tgz", "integrity": "sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", @@ -1762,7 +1656,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz", "integrity": "sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1777,7 +1670,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.23.3.tgz", "integrity": "sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g==", - "dev": true, "dependencies": { "@babel/helper-create-class-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5" @@ -1793,7 +1685,6 @@ "version": "7.23.4", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.23.4.tgz", "integrity": "sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==", - "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-create-class-features-plugin": "^7.22.15", @@ -1811,7 +1702,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz", "integrity": "sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1826,7 +1716,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.23.3.tgz", "integrity": "sha512-zP0QKq/p6O42OL94udMgSfKXyse4RyJ0JqbQ34zDAONWjyrEsghYEyTSK5FIpmXmCpB55SHokL1cRRKHv8L2Qw==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1841,7 +1730,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.23.3.tgz", "integrity": "sha512-GnvhtVfA2OAtzdX58FJxU19rhoGeQzyVndw3GgtdECQvQFXPEZIOVULHVZGAYmOgmqjXpVpfocAbSjh99V/Fqw==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1856,7 +1744,6 @@ "version": "7.23.4", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.23.4.tgz", "integrity": "sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA==", - "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-module-imports": "^7.22.15", @@ -1875,7 +1762,6 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz", "integrity": "sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==", - "dev": true, "dependencies": { "@babel/plugin-transform-react-jsx": "^7.22.5" }, @@ -1890,7 +1776,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.23.3.tgz", "integrity": "sha512-qMFdSS+TUhB7Q/3HVPnEdYJDQIk57jkntAwSuz9xfSE4n+3I+vHYCli3HoHawN1Z3RfCz/y1zXA/JXjG6cVImQ==", - "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-plugin-utils": "^7.22.5" @@ -1906,7 +1791,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.23.3.tgz", "integrity": "sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "regenerator-transform": "^0.15.2" @@ -1922,7 +1806,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.23.3.tgz", "integrity": "sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1937,7 +1820,6 @@ "version": "7.23.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.23.7.tgz", "integrity": "sha512-fa0hnfmiXc9fq/weK34MUV0drz2pOL/vfKWvN7Qw127hiUPabFCUMgAbYWcchRzMJit4o5ARsK/s+5h0249pLw==", - "dev": true, "dependencies": { "@babel/helper-module-imports": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5", @@ -1957,7 +1839,6 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, "bin": { "semver": "bin/semver.js" } @@ -1966,7 +1847,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz", "integrity": "sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1981,7 +1861,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz", "integrity": "sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" @@ -1997,7 +1876,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.23.3.tgz", "integrity": "sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -2012,7 +1890,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz", "integrity": "sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -2027,7 +1904,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.23.3.tgz", "integrity": "sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -2042,7 +1918,6 @@ "version": "7.23.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.23.6.tgz", "integrity": "sha512-6cBG5mBvUu4VUD04OHKnYzbuHNP8huDsD3EDqqpIpsswTDoqHCjLoHb6+QgsV1WsT2nipRqCPgxD3LXnEO7XfA==", - "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-create-class-features-plugin": "^7.23.6", @@ -2060,7 +1935,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.23.3.tgz", "integrity": "sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -2075,7 +1949,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.23.3.tgz", "integrity": "sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA==", - "dev": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5" @@ -2091,7 +1964,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz", "integrity": "sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==", - "dev": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5" @@ -2107,7 +1979,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.23.3.tgz", "integrity": "sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw==", - "dev": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5" @@ -2123,7 +1994,6 @@ "version": "7.23.8", "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.8.tgz", "integrity": "sha512-lFlpmkApLkEP6woIKprO6DO60RImpatTQKtz4sUcDjVcK8M8mQ4sZsuxaTMNOZf0sqAq/ReYW1ZBHnOQwKpLWA==", - "dev": true, "dependencies": { "@babel/compat-data": "^7.23.5", "@babel/helper-compilation-targets": "^7.23.6", @@ -2217,7 +2087,6 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, "bin": { "semver": "bin/semver.js" } @@ -2226,7 +2095,6 @@ "version": "0.1.6-no-external-plugins", "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/types": "^7.4.4", @@ -2240,7 +2108,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.23.3.tgz", "integrity": "sha512-tbkHOS9axH6Ysf2OUEqoSZ6T3Fa2SrNH6WTWSPBboxKzdxNc9qOICeLXkNG0ZEwbQ1HY8liwOce4aN/Ceyuq6w==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-validator-option": "^7.22.15", @@ -2260,7 +2127,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.23.3.tgz", "integrity": "sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-validator-option": "^7.22.15", @@ -2278,8 +2144,7 @@ "node_modules/@babel/regjsgen": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", - "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", - "dev": true + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" }, "node_modules/@babel/runtime": { "version": "7.23.8", @@ -2296,7 +2161,6 @@ "version": "7.23.8", "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.23.8.tgz", "integrity": "sha512-2ZzmcDugdm0/YQKFVYsXiwUN7USPX8PM7cytpb4PFl87fM+qYPSvTZX//8tyeJB1j0YDmafBJEbl5f8NfLyuKw==", - "dev": true, "dependencies": { "core-js-pure": "^3.30.2", "regenerator-runtime": "^0.14.0" @@ -2309,7 +2173,6 @@ "version": "7.22.15", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", - "dev": true, "dependencies": { "@babel/code-frame": "^7.22.13", "@babel/parser": "^7.22.15", @@ -2323,7 +2186,6 @@ "version": "7.23.7", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz", "integrity": "sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==", - "dev": true, "dependencies": { "@babel/code-frame": "^7.23.5", "@babel/generator": "^7.23.6", @@ -2344,7 +2206,6 @@ "version": "7.23.6", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", - "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.23.4", "@babel/helper-validator-identifier": "^7.22.20", @@ -2354,11 +2215,15 @@ "node": ">=6.9.0" } }, + "node_modules/@braintree/sanitize-url": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-6.0.4.tgz", + "integrity": "sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==" + }, "node_modules/@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "dev": true, "optional": true, "engines": { "node": ">=0.1.90" @@ -2431,7 +2296,6 @@ "version": "0.5.7", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", - "dev": true, "engines": { "node": ">=10.0.0" } @@ -2478,7 +2342,6 @@ "version": "2.4.3", "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-2.4.3.tgz", "integrity": "sha512-dWH5P7cgeNSIg9ufReX6gaCl/TmrGKD38Orbwuz05WPhAQtFXHd5B8Qym1TiXfvUNvwoYKkAJOJuGe8ou0Z7PA==", - "dev": true, "dependencies": { "@babel/core": "^7.18.6", "@babel/generator": "^7.18.7", @@ -2567,7 +2430,6 @@ "version": "2.4.3", "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-2.4.3.tgz", "integrity": "sha512-ZvGSRCi7z9wLnZrXNPG6DmVPHdKGd8dIn9pYbEOFiYihfv4uDR3UtxogmKf+rT8ZlKFf5Lqne8E8nt08zNM8CA==", - "dev": true, "dependencies": { "cssnano-preset-advanced": "^5.3.8", "postcss": "^8.4.14", @@ -2582,7 +2444,6 @@ "version": "2.4.3", "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-2.4.3.tgz", "integrity": "sha512-Zxws7r3yLufk9xM1zq9ged0YHs65mlRmtsobnFkdZTxWXdTYlWWLWdKyNKAsVC+D7zg+pv2fGbyabdOnyZOM3w==", - "dev": true, "dependencies": { "chalk": "^4.1.2", "tslib": "^2.4.0" @@ -2595,7 +2456,6 @@ "version": "2.4.3", "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-2.4.3.tgz", "integrity": "sha512-b1+fDnWtl3GiqkL0BRjYtc94FZrcDDBV1j8446+4tptB9BAOlePwG2p/pK6vGvfL53lkOsszXMghr2g67M0vCw==", - "dev": true, "dependencies": { "@babel/parser": "^7.18.8", "@babel/traverse": "^7.18.8", @@ -2627,7 +2487,6 @@ "version": "2.4.3", "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-2.4.3.tgz", "integrity": "sha512-cwkBkt1UCiduuvEAo7XZY01dJfRn7UR/75mBgOdb1hKknhrabJZ8YH+7savd/y9kLExPyrhe0QwdS9GuzsRRIA==", - "dev": true, "dependencies": { "@docusaurus/react-loadable": "5.5.2", "@docusaurus/types": "2.4.3", @@ -2671,7 +2530,6 @@ "version": "2.4.3", "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-2.4.3.tgz", "integrity": "sha512-PVhypqaA0t98zVDpOeTqWUTvRqCEjJubtfFUQ7zJNYdbYTbS/E/ytq6zbLVsN/dImvemtO/5JQgjLxsh8XLo8Q==", - "dev": true, "dependencies": { "@docusaurus/core": "2.4.3", "@docusaurus/logger": "2.4.3", @@ -2702,7 +2560,6 @@ "version": "2.4.3", "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-2.4.3.tgz", "integrity": "sha512-N7Po2LSH6UejQhzTCsvuX5NOzlC+HiXOVvofnEPj0WhMu1etpLEXE6a4aTxrtg95lQ5kf0xUIdjX9sh3d3G76A==", - "dev": true, "dependencies": { "@docusaurus/core": "2.4.3", "@docusaurus/logger": "2.4.3", @@ -2733,7 +2590,6 @@ "version": "2.4.3", "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-2.4.3.tgz", "integrity": "sha512-txtDVz7y3zGk67q0HjG0gRttVPodkHqE0bpJ+7dOaTH40CQFLSh7+aBeGnPOTl+oCPG+hxkim4SndqPqXjQ8Bg==", - "dev": true, "dependencies": { "@docusaurus/core": "2.4.3", "@docusaurus/mdx-loader": "2.4.3", @@ -2886,7 +2742,6 @@ "version": "5.5.2", "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-5.5.2.tgz", "integrity": "sha512-A3dYjdBGuy0IGT+wyLIGIKLRE+sAk1iNk0f1HjNDysO7u8lhL4N3VEm+FAubmJbAztn94F7MxBTPmnixbiyFdQ==", - "dev": true, "dependencies": { "@types/react": "*", "prop-types": "^15.6.2" @@ -2939,7 +2794,6 @@ "version": "2.4.3", "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-2.4.3.tgz", "integrity": "sha512-7KaDJBXKBVGXw5WOVt84FtN8czGWhM0lbyWEZXGp8AFfL6sZQfRTluFp4QriR97qwzSyOfQb+nzcDZZU4tezUw==", - "dev": true, "dependencies": { "@docusaurus/mdx-loader": "2.4.3", "@docusaurus/module-type-aliases": "2.4.3", @@ -2990,6 +2844,28 @@ "react-dom": "^16.8.4 || ^17.0.0" } }, + "node_modules/@docusaurus/theme-mermaid": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-mermaid/-/theme-mermaid-2.4.3.tgz", + "integrity": "sha512-S1tZ3xpowtFiTrpTKmvVbRHUYGOlEG5CnPzWlO4huJT1sAwLR+pD6f9DYUlPv2+9NezF3EfUrUyW9xLH0UP58w==", + "dependencies": { + "@docusaurus/core": "2.4.3", + "@docusaurus/module-type-aliases": "2.4.3", + "@docusaurus/theme-common": "2.4.3", + "@docusaurus/types": "2.4.3", + "@docusaurus/utils-validation": "2.4.3", + "@mdx-js/react": "^1.6.22", + "mermaid": "^9.2.2", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=16.14" + }, + "peerDependencies": { + "react": "^16.8.4 || ^17.0.0", + "react-dom": "^16.8.4 || ^17.0.0" + } + }, "node_modules/@docusaurus/theme-search-algolia": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-2.4.3.tgz", @@ -3038,7 +2914,6 @@ "version": "2.4.3", "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-2.4.3.tgz", "integrity": "sha512-W6zNLGQqfrp/EoPD0bhb9n7OobP+RHpmvVzpA+Z/IuU3Q63njJM24hmT0GYboovWcDtFmnIJC9wcyx4RVPQscw==", - "dev": true, "dependencies": { "@types/history": "^4.7.11", "@types/react": "*", @@ -3058,7 +2933,6 @@ "version": "2.4.3", "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-2.4.3.tgz", "integrity": "sha512-fKcXsjrD86Smxv8Pt0TBFqYieZZCPh4cbf9oszUq/AMhZn3ujwpKaVYZACPX8mmjtYx0JOgNx52CREBfiGQB4A==", - "dev": true, "dependencies": { "@docusaurus/logger": "2.4.3", "@svgr/webpack": "^6.2.1", @@ -3093,7 +2967,6 @@ "version": "2.4.3", "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-2.4.3.tgz", "integrity": "sha512-/jascp4GbLQCPVmcGkPzEQjNaAk3ADVfMtudk49Ggb+131B1WDD6HqlSmDf8MxGdy7Dja2gc+StHf01kiWoTDQ==", - "dev": true, "dependencies": { "tslib": "^2.4.0" }, @@ -3113,7 +2986,6 @@ "version": "2.4.3", "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-2.4.3.tgz", "integrity": "sha512-G2+Vt3WR5E/9drAobP+hhZQMaswRwDlp6qOMi7o7ZypB+VO7N//DZWhZEwhcRGepMDJGQEwtPv7UxtYwPL9PBw==", - "dev": true, "dependencies": { "@docusaurus/logger": "2.4.3", "@docusaurus/utils": "2.4.3", @@ -3191,14 +3063,12 @@ "node_modules/@hapi/hoek": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", - "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==", - "dev": true + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" }, "node_modules/@hapi/topo": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", - "dev": true, "dependencies": { "@hapi/hoek": "^9.0.0" } @@ -3224,7 +3094,6 @@ "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", - "dev": true, "dependencies": { "@sinclair/typebox": "^0.27.8" }, @@ -3236,7 +3105,6 @@ "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", - "dev": true, "dependencies": { "@jest/schemas": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", @@ -3253,7 +3121,6 @@ "version": "0.3.3", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", - "dev": true, "dependencies": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -3275,7 +3142,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true, "engines": { "node": ">=6.0.0" } @@ -3284,7 +3150,6 @@ "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", - "dev": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -3299,7 +3164,6 @@ "version": "0.3.22", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz", "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==", - "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -3308,14 +3172,12 @@ "node_modules/@leichtgewicht/ip-codec": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", - "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==", - "dev": true + "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" }, "node_modules/@mdx-js/mdx": { "version": "1.6.22", "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-1.6.22.tgz", "integrity": "sha512-AMxuLxPz2j5/6TpF/XSdKpQP1NlG0z11dFOlq+2IP/lSgl11GY8ji6S/rgsViN/L0BDvHvUMruRb7ub+24LUYA==", - "dev": true, "dependencies": { "@babel/core": "7.12.9", "@babel/plugin-syntax-jsx": "7.12.1", @@ -3346,7 +3208,6 @@ "version": "7.12.9", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.9.tgz", "integrity": "sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ==", - "dev": true, "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/generator": "^7.12.5", @@ -3377,7 +3238,6 @@ "version": "7.12.1", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.1.tgz", "integrity": "sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -3388,14 +3248,12 @@ "node_modules/@mdx-js/mdx/node_modules/convert-source-map": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" }, "node_modules/@mdx-js/mdx/node_modules/semver": { "version": "5.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, "bin": { "semver": "bin/semver" } @@ -3404,7 +3262,6 @@ "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -3413,7 +3270,6 @@ "version": "9.2.0", "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.0.tgz", "integrity": "sha512-vx2Z0vY+a3YoTj8+pttM3tiJHCwY5UFbYdiWrwBEbHmK8pvsPj2rtAX2BFfgXen8T39CJWblWRDT4L5WGXtDdg==", - "dev": true, "dependencies": { "bail": "^1.0.0", "extend": "^3.0.0", @@ -3431,7 +3287,6 @@ "version": "1.6.22", "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-1.6.22.tgz", "integrity": "sha512-TDoPum4SHdfPiGSAaRBw7ECyI8VaHpK8GJugbJIJuqyh6kzw9ZLJZW3HGL3NNrJGxcAixUvqROm+YuQOo5eXtg==", - "dev": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" @@ -3444,7 +3299,6 @@ "version": "1.6.22", "resolved": "https://registry.npmjs.org/@mdx-js/util/-/util-1.6.22.tgz", "integrity": "sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA==", - "dev": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" @@ -3512,7 +3366,6 @@ "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -3525,7 +3378,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, "engines": { "node": ">= 8" } @@ -3534,7 +3386,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -3697,8 +3548,7 @@ "node_modules/@polka/url": { "version": "1.0.0-next.24", "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.24.tgz", - "integrity": "sha512-2LuNTFBIO0m7kKIQvvPHN6UE63VjpmL9rnEEaOOaiSPbZK+zUOYIzBAWcED+3XYzhYsd/0mD57VdxAEqqV52CQ==", - "dev": true + "integrity": "sha512-2LuNTFBIO0m7kKIQvvPHN6UE63VjpmL9rnEEaOOaiSPbZK+zUOYIzBAWcED+3XYzhYsd/0mD57VdxAEqqV52CQ==" }, "node_modules/@react-leaflet/core": { "version": "2.1.0", @@ -3714,7 +3564,6 @@ "version": "4.1.4", "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==", - "dev": true, "dependencies": { "@hapi/hoek": "^9.0.0" } @@ -3722,26 +3571,22 @@ "node_modules/@sideway/formula": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", - "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==", - "dev": true + "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==" }, "node_modules/@sideway/pinpoint": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", - "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", - "dev": true + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", - "dev": true + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==" }, "node_modules/@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", - "dev": true, "engines": { "node": ">=6" } @@ -3750,7 +3595,6 @@ "version": "4.0.7", "resolved": "https://registry.npmjs.org/@slorber/static-site-generator-webpack-plugin/-/static-site-generator-webpack-plugin-4.0.7.tgz", "integrity": "sha512-Ug7x6z5lwrz0WqdnNFOMYrDQNTPAprvHLSh6+/fmml3qUiz6l5eq+2MzLKWtn/q5K5NpSiFsZTP/fck/3vjSxA==", - "dev": true, "dependencies": { "eval": "^0.1.8", "p-map": "^4.0.0", @@ -3764,7 +3608,6 @@ "version": "6.5.1", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-6.5.1.tgz", "integrity": "sha512-9PYGcXrAxitycIjRmZB+Q0JaN07GZIWaTBIGQzfaZv+qr1n8X1XUEJ5rZ/vx6OVD9RRYlrNnXWExQXcmZeD/BQ==", - "dev": true, "engines": { "node": ">=10" }, @@ -3780,7 +3623,6 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz", "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==", - "dev": true, "engines": { "node": ">=14" }, @@ -3796,7 +3638,6 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz", "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==", - "dev": true, "engines": { "node": ">=14" }, @@ -3812,7 +3653,6 @@ "version": "6.5.1", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-6.5.1.tgz", "integrity": "sha512-8DPaVVE3fd5JKuIC29dqyMB54sA6mfgki2H2+swh+zNJoynC8pMPzOkidqHOSc6Wj032fhl8Z0TVn1GiPpAiJg==", - "dev": true, "engines": { "node": ">=10" }, @@ -3828,7 +3668,6 @@ "version": "6.5.1", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-6.5.1.tgz", "integrity": "sha512-FwOEi0Il72iAzlkaHrlemVurgSQRDFbk0OC8dSvD5fSBPHltNh7JtLsxmZUhjYBZo2PpcU/RJvvi6Q0l7O7ogw==", - "dev": true, "engines": { "node": ">=10" }, @@ -3844,7 +3683,6 @@ "version": "6.5.1", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-6.5.1.tgz", "integrity": "sha512-gWGsiwjb4tw+ITOJ86ndY/DZZ6cuXMNE/SjcDRg+HLuCmwpcjOktwRF9WgAiycTqJD/QXqL2f8IzE2Rzh7aVXA==", - "dev": true, "engines": { "node": ">=10" }, @@ -3860,7 +3698,6 @@ "version": "6.5.1", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-6.5.1.tgz", "integrity": "sha512-2jT3nTayyYP7kI6aGutkyfJ7UMGtuguD72OjeGLwVNyfPRBD8zQthlvL+fAbAKk5n9ZNcvFkp/b1lZ7VsYqVJg==", - "dev": true, "engines": { "node": ">=10" }, @@ -3876,7 +3713,6 @@ "version": "6.5.1", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-6.5.1.tgz", "integrity": "sha512-a1p6LF5Jt33O3rZoVRBqdxL350oge54iZWHNI6LJB5tQ7EelvD/Mb1mfBiZNAan0dt4i3VArkFRjA4iObuNykQ==", - "dev": true, "engines": { "node": ">=12" }, @@ -3892,7 +3728,6 @@ "version": "6.5.1", "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-6.5.1.tgz", "integrity": "sha512-6127fvO/FF2oi5EzSQOAjo1LE3OtNVh11R+/8FXa+mHx1ptAaS4cknIjnUA7e6j6fwGGJ17NzaTJFUwOV2zwCw==", - "dev": true, "dependencies": { "@svgr/babel-plugin-add-jsx-attribute": "^6.5.1", "@svgr/babel-plugin-remove-jsx-attribute": "*", @@ -3918,7 +3753,6 @@ "version": "6.5.1", "resolved": "https://registry.npmjs.org/@svgr/core/-/core-6.5.1.tgz", "integrity": "sha512-/xdLSWxK5QkqG524ONSjvg3V/FkNyCv538OIBdQqPNaAta3AsXj/Bd2FbvR87yMbXO2hFSWiAe/Q6IkVPDw+mw==", - "dev": true, "dependencies": { "@babel/core": "^7.19.6", "@svgr/babel-preset": "^6.5.1", @@ -3938,7 +3772,6 @@ "version": "6.5.1", "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-6.5.1.tgz", "integrity": "sha512-1hnUxxjd83EAxbL4a0JDJoD3Dao3hmjvyvyEV8PzWmLK3B9m9NPlW7GKjFyoWE8nM7HnXzPcmmSyOW8yOddSXw==", - "dev": true, "dependencies": { "@babel/types": "^7.20.0", "entities": "^4.4.0" @@ -3955,7 +3788,6 @@ "version": "6.5.1", "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-6.5.1.tgz", "integrity": "sha512-+UdQxI3jgtSjCykNSlEMuy1jSRQlGC7pqBCPvkG/2dATdWo082zHTTK3uhnAju2/6XpE6B5mZ3z4Z8Ns01S8Gw==", - "dev": true, "dependencies": { "@babel/core": "^7.19.6", "@svgr/babel-preset": "^6.5.1", @@ -3977,7 +3809,6 @@ "version": "6.5.1", "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-6.5.1.tgz", "integrity": "sha512-omvZKf8ixP9z6GWgwbtmP9qQMPX4ODXi+wzbVZgomNFsUIlHA1sf4fThdwTWSsZGgvGAG6yE+b/F5gWUkcZ/iQ==", - "dev": true, "dependencies": { "cosmiconfig": "^7.0.1", "deepmerge": "^4.2.2", @@ -3998,7 +3829,6 @@ "version": "6.5.1", "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-6.5.1.tgz", "integrity": "sha512-cQ/AsnBkXPkEK8cLbv4Dm7JGXq2XrumKnL1dRpJD9rIO2fTIlJI9a1uCciYG1F2aUsox/hJQyNGbt3soDxSRkA==", - "dev": true, "dependencies": { "@babel/core": "^7.19.6", "@babel/plugin-transform-react-constant-elements": "^7.18.12", @@ -4021,7 +3851,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", - "dev": true, "dependencies": { "defer-to-connect": "^1.0.1" }, @@ -4048,7 +3877,6 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", - "dev": true, "engines": { "node": ">=10.13.0" } @@ -4083,7 +3911,6 @@ "version": "1.19.5", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", - "dev": true, "dependencies": { "@types/connect": "*", "@types/node": "*" @@ -4093,7 +3920,6 @@ "version": "3.5.13", "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", - "dev": true, "dependencies": { "@types/node": "*" } @@ -4102,7 +3928,6 @@ "version": "3.4.38", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "dev": true, "dependencies": { "@types/node": "*" } @@ -4111,7 +3936,6 @@ "version": "1.5.4", "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", - "dev": true, "dependencies": { "@types/express-serve-static-core": "*", "@types/node": "*" @@ -4121,7 +3945,6 @@ "version": "8.56.2", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.2.tgz", "integrity": "sha512-uQDwm1wFHmbBbCZCqAlq6Do9LYwByNZHWzXppSnay9SuwJ+VRbjkbLABer54kcPnMSlG6Fdiy2yaFXm/z9Z5gw==", - "dev": true, "dependencies": { "@types/estree": "*", "@types/json-schema": "*" @@ -4131,7 +3954,6 @@ "version": "3.7.7", "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", - "dev": true, "dependencies": { "@types/eslint": "*", "@types/estree": "*" @@ -4140,14 +3962,12 @@ "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" }, "node_modules/@types/express": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", - "dev": true, "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", @@ -4159,7 +3979,6 @@ "version": "4.17.41", "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz", "integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==", - "dev": true, "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -4177,7 +3996,6 @@ "version": "2.3.9", "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.9.tgz", "integrity": "sha512-pTHyNlaMD/oKJmS+ZZUyFUcsZeBZpC0lmGquw98CqRVNgAdJZJeD7GoeLiT6Xbx5rU9VCjSt0RwEvDgzh4obFw==", - "dev": true, "dependencies": { "@types/unist": "^2" } @@ -4185,26 +4003,22 @@ "node_modules/@types/history": { "version": "4.7.11", "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", - "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==", - "dev": true + "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==" }, "node_modules/@types/html-minifier-terser": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==", - "dev": true + "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==" }, "node_modules/@types/http-errors": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", - "dev": true + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" }, "node_modules/@types/http-proxy": { "version": "1.17.14", "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", - "dev": true, "dependencies": { "@types/node": "*" } @@ -4212,14 +4026,12 @@ "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "dev": true + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==" }, "node_modules/@types/istanbul-lib-report": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", - "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "*" } @@ -4228,7 +4040,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", - "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" } @@ -4257,7 +4068,6 @@ "version": "3.0.15", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", - "dev": true, "dependencies": { "@types/unist": "^2" } @@ -4265,14 +4075,12 @@ "node_modules/@types/mime": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", - "dev": true + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" }, "node_modules/@types/node": { "version": "20.11.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.5.tgz", "integrity": "sha512-g557vgQjUUfN76MZAN/dt1z3dzcUsimuysco0KeluHgrPdJXkP/XdAURgyO2W9fZWHRtRBiVKzKn8vyOAwlG+w==", - "dev": true, "dependencies": { "undici-types": "~5.26.4" } @@ -4281,7 +4089,6 @@ "version": "1.3.11", "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", - "dev": true, "dependencies": { "@types/node": "*" } @@ -4289,38 +4096,32 @@ "node_modules/@types/parse-json": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", - "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", - "dev": true + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" }, "node_modules/@types/parse5": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-5.0.3.tgz", - "integrity": "sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw==", - "dev": true + "integrity": "sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw==" }, "node_modules/@types/prop-types": { "version": "15.7.11", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", - "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==", - "dev": true + "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" }, "node_modules/@types/qs": { "version": "6.9.11", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.11.tgz", - "integrity": "sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ==", - "dev": true + "integrity": "sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ==" }, "node_modules/@types/range-parser": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", - "dev": true + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" }, "node_modules/@types/react": { "version": "18.2.48", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.48.tgz", "integrity": "sha512-qboRCl6Ie70DQQG9hhNREz81jqC1cs9EVNcjQ1AU+jH6NFfSAhVVbrrY/+nSF+Bsk4AOwm9Qa61InvMCyV+H3w==", - "dev": true, "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -4331,7 +4132,6 @@ "version": "5.1.20", "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz", "integrity": "sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==", - "dev": true, "dependencies": { "@types/history": "^4.7.11", "@types/react": "*" @@ -4341,7 +4141,6 @@ "version": "5.0.11", "resolved": "https://registry.npmjs.org/@types/react-router-config/-/react-router-config-5.0.11.tgz", "integrity": "sha512-WmSAg7WgqW7m4x8Mt4N6ZyKz0BubSj/2tVUMsAHp+Yd2AMwcSbeFq9WympT19p5heCFmF97R9eD5uUR/t4HEqw==", - "dev": true, "dependencies": { "@types/history": "^4.7.11", "@types/react": "*", @@ -4352,7 +4151,6 @@ "version": "5.3.3", "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz", "integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==", - "dev": true, "dependencies": { "@types/history": "^4.7.11", "@types/react": "*", @@ -4362,8 +4160,7 @@ "node_modules/@types/retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", - "dev": true + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" }, "node_modules/@types/sax": { "version": "1.2.7", @@ -4377,14 +4174,12 @@ "node_modules/@types/scheduler": { "version": "0.16.8", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", - "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==", - "dev": true + "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==" }, "node_modules/@types/send": { "version": "0.17.4", "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", - "dev": true, "dependencies": { "@types/mime": "^1", "@types/node": "*" @@ -4394,7 +4189,6 @@ "version": "1.9.4", "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", - "dev": true, "dependencies": { "@types/express": "*" } @@ -4403,7 +4197,6 @@ "version": "1.15.5", "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", - "dev": true, "dependencies": { "@types/http-errors": "*", "@types/mime": "*", @@ -4414,7 +4207,6 @@ "version": "0.3.36", "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", - "dev": true, "dependencies": { "@types/node": "*" } @@ -4422,14 +4214,12 @@ "node_modules/@types/unist": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==", - "dev": true + "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" }, "node_modules/@types/ws": { "version": "8.5.10", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", - "dev": true, "dependencies": { "@types/node": "*" } @@ -4438,7 +4228,6 @@ "version": "17.0.32", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", - "dev": true, "dependencies": { "@types/yargs-parser": "*" } @@ -4446,14 +4235,12 @@ "node_modules/@types/yargs-parser": { "version": "21.0.3", "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "dev": true + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==" }, "node_modules/@webassemblyjs/ast": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", - "dev": true, "dependencies": { "@webassemblyjs/helper-numbers": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6" @@ -4462,26 +4249,22 @@ "node_modules/@webassemblyjs/floating-point-hex-parser": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", - "dev": true + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==" }, "node_modules/@webassemblyjs/helper-api-error": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", - "dev": true + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==" }, "node_modules/@webassemblyjs/helper-buffer": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", - "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", - "dev": true + "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==" }, "node_modules/@webassemblyjs/helper-numbers": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", - "dev": true, "dependencies": { "@webassemblyjs/floating-point-hex-parser": "1.11.6", "@webassemblyjs/helper-api-error": "1.11.6", @@ -4491,14 +4274,12 @@ "node_modules/@webassemblyjs/helper-wasm-bytecode": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", - "dev": true + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==" }, "node_modules/@webassemblyjs/helper-wasm-section": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", - "dev": true, "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-buffer": "1.11.6", @@ -4510,7 +4291,6 @@ "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", - "dev": true, "dependencies": { "@xtuc/ieee754": "^1.2.0" } @@ -4519,7 +4299,6 @@ "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", - "dev": true, "dependencies": { "@xtuc/long": "4.2.2" } @@ -4527,14 +4306,12 @@ "node_modules/@webassemblyjs/utf8": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", - "dev": true + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==" }, "node_modules/@webassemblyjs/wasm-edit": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", - "dev": true, "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-buffer": "1.11.6", @@ -4550,7 +4327,6 @@ "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", - "dev": true, "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", @@ -4563,7 +4339,6 @@ "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", - "dev": true, "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-buffer": "1.11.6", @@ -4575,7 +4350,6 @@ "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", - "dev": true, "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-api-error": "1.11.6", @@ -4589,7 +4363,6 @@ "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", - "dev": true, "dependencies": { "@webassemblyjs/ast": "1.11.6", "@xtuc/long": "4.2.2" @@ -4634,20 +4407,17 @@ "node_modules/@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" }, "node_modules/@xtuc/long": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dev": true, "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" @@ -4694,7 +4464,6 @@ "version": "1.9.0", "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", - "dev": true, "peerDependencies": { "acorn": "^8" } @@ -4720,7 +4489,6 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", - "dev": true, "engines": { "node": ">= 10.0.0" } @@ -4729,7 +4497,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" @@ -4757,7 +4524,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dev": true, "dependencies": { "ajv": "^8.0.0" }, @@ -4774,7 +4540,6 @@ "version": "8.12.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -4789,8 +4554,7 @@ "node_modules/ajv-formats/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, "node_modules/ajv-keywords": { "version": "3.5.2", @@ -4838,7 +4602,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", - "dev": true, "dependencies": { "string-width": "^4.1.0" } @@ -4847,7 +4610,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "engines": { "node": ">=8" } @@ -4855,14 +4617,12 @@ "node_modules/ansi-align/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "node_modules/ansi-align/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -4876,7 +4636,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -4897,7 +4656,6 @@ "version": "0.0.8", "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", - "dev": true, "engines": [ "node >= 0.8.0" ], @@ -4909,7 +4667,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, "engines": { "node": ">=12" }, @@ -4921,7 +4678,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -4942,7 +4698,6 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -4960,20 +4715,17 @@ "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "dev": true + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, "node_modules/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==", - "dev": true, "engines": { "node": ">=8" } @@ -4994,7 +4746,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true, "engines": { "node": ">= 4.0.0" } @@ -5003,7 +4754,6 @@ "version": "10.4.17", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.17.tgz", "integrity": "sha512-/cpVNRLSfhOtcGflT13P2794gVSgmPgTR+erw5ifnMLZb0UnSlkK4tquLmkd3BhA+nLo5tX8Cu0upUsGKvKbmg==", - "dev": true, "funding": [ { "type": "opencollective", @@ -5050,7 +4800,6 @@ "version": "8.3.0", "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.3.0.tgz", "integrity": "sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==", - "dev": true, "dependencies": { "find-cache-dir": "^3.3.1", "loader-utils": "^2.0.0", @@ -5069,7 +4818,6 @@ "version": "1.6.22", "resolved": "https://registry.npmjs.org/babel-plugin-apply-mdx-type-prop/-/babel-plugin-apply-mdx-type-prop-1.6.22.tgz", "integrity": "sha512-VefL+8o+F/DfK24lPZMtJctrCVOfgbqLAGZSkxwhazQv4VxPg3Za/i40fu22KR2m8eEda+IfSOlPLUSIiLcnCQ==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "7.10.4", "@mdx-js/util": "1.6.22" @@ -5085,14 +4833,12 @@ "node_modules/babel-plugin-apply-mdx-type-prop/node_modules/@babel/helper-plugin-utils": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", - "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", - "dev": true + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==" }, "node_modules/babel-plugin-dynamic-import-node": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", - "dev": true, "dependencies": { "object.assign": "^4.1.0" } @@ -5101,7 +4847,6 @@ "version": "1.6.22", "resolved": "https://registry.npmjs.org/babel-plugin-extract-import-names/-/babel-plugin-extract-import-names-1.6.22.tgz", "integrity": "sha512-yJ9BsJaISua7d8zNT7oRG1ZLBJCIdZ4PZqmH8qa9N5AK01ifk3fnkc98AXhtzE7UkfCsEumvoQWgoYLhOnJ7jQ==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "7.10.4" }, @@ -5113,14 +4858,12 @@ "node_modules/babel-plugin-extract-import-names/node_modules/@babel/helper-plugin-utils": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", - "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", - "dev": true + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==" }, "node_modules/babel-plugin-polyfill-corejs2": { "version": "0.4.8", "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.8.tgz", "integrity": "sha512-OtIuQfafSzpo/LhnJaykc0R/MMnuLSSVjVYy9mHArIZ9qTCSZ6TpWCuEKZYVoN//t8HqBNScHrOtCrIK5IaGLg==", - "dev": true, "dependencies": { "@babel/compat-data": "^7.22.6", "@babel/helper-define-polyfill-provider": "^0.5.0", @@ -5134,7 +4877,6 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, "bin": { "semver": "bin/semver.js" } @@ -5143,7 +4885,6 @@ "version": "0.8.7", "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.7.tgz", "integrity": "sha512-KyDvZYxAzkC0Aj2dAPyDzi2Ym15e5JKZSK+maI7NAwSqofvuFglbSsxE7wUOvTg9oFVnHMzVzBKcqEb4PJgtOA==", - "dev": true, "dependencies": { "@babel/helper-define-polyfill-provider": "^0.4.4", "core-js-compat": "^3.33.1" @@ -5156,7 +4897,6 @@ "version": "0.4.4", "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.4.tgz", "integrity": "sha512-QcJMILQCu2jm5TFPGA3lCpJJTeEP+mqeXooG/NZbg/h5FTFi6V0+99ahlRsW8/kRLyb24LZVCCiclDedhLKcBA==", - "dev": true, "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", "@babel/helper-plugin-utils": "^7.22.5", @@ -5172,7 +4912,6 @@ "version": "0.5.5", "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.5.tgz", "integrity": "sha512-OJGYZlhLqBh2DDHeqAxWB1XIvr49CxiJ2gIt61/PU55CQK4Z58OzMqjDe1zwQdQk+rBYsRc+1rJmdajM3gimHg==", - "dev": true, "dependencies": { "@babel/helper-define-polyfill-provider": "^0.5.0" }, @@ -5184,7 +4923,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==", - "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -5231,8 +4969,7 @@ "node_modules/batch": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", - "dev": true + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" }, "node_modules/big-integer": { "version": "1.6.52", @@ -5262,7 +4999,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, "engines": { "node": ">=8" } @@ -5271,7 +5007,6 @@ "version": "1.20.1", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "dev": true, "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.4", @@ -5295,7 +5030,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true, "engines": { "node": ">= 0.8" } @@ -5304,7 +5038,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "dependencies": { "ms": "2.0.0" } @@ -5312,14 +5045,12 @@ "node_modules/body-parser/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/body-parser/node_modules/qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dev": true, "dependencies": { "side-channel": "^1.0.4" }, @@ -5334,7 +5065,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", - "dev": true, "dependencies": { "fast-deep-equal": "^3.1.3", "multicast-dns": "^7.2.5" @@ -5343,8 +5073,7 @@ "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "dev": true + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" }, "node_modules/borc": { "version": "2.1.2", @@ -5372,7 +5101,6 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/boxen/-/boxen-6.2.1.tgz", "integrity": "sha512-H4PEsJXfFI/Pt8sjDWbHlQPx4zL/bvSQjcilJmaulGt5mLDorHOHpmdXAJcBcmru7PhYSp/cDMWRko4ZUMFkSw==", - "dev": true, "dependencies": { "ansi-align": "^3.0.1", "camelcase": "^6.2.0", @@ -5403,7 +5131,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, "dependencies": { "fill-range": "^7.0.1" }, @@ -5430,7 +5157,6 @@ "version": "4.22.2", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", - "dev": true, "funding": [ { "type": "opencollective", @@ -5622,14 +5348,12 @@ "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, "node_modules/bytes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", - "dev": true, "engines": { "node": ">= 0.8" } @@ -5638,7 +5362,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", - "dev": true, "dependencies": { "clone-response": "^1.0.2", "get-stream": "^5.1.0", @@ -5656,7 +5379,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, "dependencies": { "pump": "^3.0.0" }, @@ -5671,7 +5393,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true, "engines": { "node": ">=8" } @@ -5680,7 +5401,6 @@ "version": "4.5.1", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", - "dev": true, "engines": { "node": ">=8" } @@ -5702,7 +5422,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, "engines": { "node": ">=6" } @@ -5711,7 +5430,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", - "dev": true, "dependencies": { "pascal-case": "^3.1.2", "tslib": "^2.0.3" @@ -5721,7 +5439,6 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, "engines": { "node": ">=10" }, @@ -5733,7 +5450,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", - "dev": true, "engines": { "node": ">= 6" } @@ -5742,7 +5458,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", - "dev": true, "dependencies": { "browserslist": "^4.0.0", "caniuse-lite": "^1.0.0", @@ -5754,7 +5469,6 @@ "version": "1.0.30001640", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001640.tgz", "integrity": "sha512-lA4VMpW0PSUrFnkmVuEKBUovSWKhj7puyCg8StBChgu298N1AtuF1sKWEvfDuimSEDbhlb/KqPKC3fs1HbuQUA==", - "dev": true, "funding": [ { "type": "opencollective", @@ -5774,7 +5488,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.1.0.tgz", "integrity": "sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==", - "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -5784,7 +5497,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -5800,7 +5512,6 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", - "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -5810,7 +5521,6 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", - "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -5820,7 +5530,6 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", - "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -5843,7 +5552,6 @@ "version": "1.0.0-rc.12", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", - "dev": true, "dependencies": { "cheerio-select": "^2.1.0", "dom-serializer": "^2.0.0", @@ -5864,7 +5572,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", - "dev": true, "dependencies": { "boolbase": "^1.0.0", "css-select": "^5.1.0", @@ -5881,7 +5588,6 @@ "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, "funding": [ { "type": "individual", @@ -5908,7 +5614,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "dev": true, "engines": { "node": ">=6.0" } @@ -5917,7 +5622,6 @@ "version": "3.9.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "dev": true, "funding": [ { "type": "github", @@ -5937,7 +5641,6 @@ "version": "5.3.3", "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", - "dev": true, "dependencies": { "source-map": "~0.6.0" }, @@ -5949,7 +5652,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, "engines": { "node": ">=6" } @@ -5958,7 +5660,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", - "dev": true, "engines": { "node": ">=10" }, @@ -5982,7 +5683,6 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", - "dev": true, "dependencies": { "string-width": "^4.2.0" }, @@ -5997,7 +5697,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "engines": { "node": ">=8" } @@ -6005,14 +5704,12 @@ "node_modules/cli-table3/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "node_modules/cli-table3/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -6026,7 +5723,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -6038,7 +5734,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, "dependencies": { "is-plain-object": "^2.0.4", "kind-of": "^6.0.2", @@ -6052,7 +5747,6 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, "dependencies": { "isobject": "^3.0.1" }, @@ -6064,7 +5758,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", - "dev": true, "dependencies": { "mimic-response": "^1.0.0" }, @@ -6097,7 +5790,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz", "integrity": "sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==", - "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -6107,7 +5799,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -6118,26 +5809,22 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/colord": { "version": "2.9.3", "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", - "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", - "dev": true + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==" }, "node_modules/colorette": { "version": "2.0.20", "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" }, "node_modules/combine-promises": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/combine-promises/-/combine-promises-1.2.0.tgz", "integrity": "sha512-VcQB1ziGD0NXrhKxiwyNbCDmRzs/OShMs2GqW2DlU2A/Sd0nQxE1oWDAE5O0ygSx5mgQOn9eIFh7yKPgFRVkPQ==", - "dev": true, "engines": { "node": ">=10" } @@ -6158,7 +5845,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==", - "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -6168,7 +5854,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", - "dev": true, "engines": { "node": ">= 6" } @@ -6176,8 +5861,7 @@ "node_modules/commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" }, "node_modules/component-props": { "version": "1.1.1", @@ -6195,7 +5879,6 @@ "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "dev": true, "dependencies": { "mime-db": ">= 1.43.0 < 2" }, @@ -6207,7 +5890,6 @@ "version": "1.7.4", "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", - "dev": true, "dependencies": { "accepts": "~1.3.5", "bytes": "3.0.0", @@ -6225,7 +5907,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "dependencies": { "ms": "2.0.0" } @@ -6233,14 +5914,12 @@ "node_modules/compression/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/compression/node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "node_modules/concat-map": { "version": "0.0.1", @@ -6251,7 +5930,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", - "dev": true, "dependencies": { "dot-prop": "^5.2.0", "graceful-fs": "^4.1.2", @@ -6268,7 +5946,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", - "dev": true, "engines": { "node": ">=0.8" } @@ -6276,14 +5953,12 @@ "node_modules/consola": { "version": "2.15.3", "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz", - "integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==", - "dev": true + "integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==" }, "node_modules/content-disposition": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", "integrity": "sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -6292,7 +5967,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -6346,14 +6020,12 @@ "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" }, "node_modules/cookie": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -6361,8 +6033,7 @@ "node_modules/cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "dev": true + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, "node_modules/copy-text-to-clipboard": { "version": "3.2.0", @@ -6380,7 +6051,6 @@ "version": "11.0.0", "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz", "integrity": "sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==", - "dev": true, "dependencies": { "fast-glob": "^3.2.11", "glob-parent": "^6.0.1", @@ -6404,7 +6074,6 @@ "version": "8.12.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -6420,7 +6089,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, "dependencies": { "fast-deep-equal": "^3.1.3" }, @@ -6432,7 +6100,6 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, "dependencies": { "is-glob": "^4.0.3" }, @@ -6444,7 +6111,6 @@ "version": "13.2.2", "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", - "dev": true, "dependencies": { "dir-glob": "^3.0.1", "fast-glob": "^3.3.0", @@ -6462,14 +6128,12 @@ "node_modules/copy-webpack-plugin/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, "node_modules/copy-webpack-plugin/node_modules/schema-utils": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", - "dev": true, "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", @@ -6488,7 +6152,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", - "dev": true, "engines": { "node": ">=12" }, @@ -6500,7 +6163,6 @@ "version": "3.35.1", "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.35.1.tgz", "integrity": "sha512-IgdsbxNyMskrTFxa9lWHyMwAJU5gXOPP+1yO+K59d50VLVAIDAbs7gIv705KzALModfK3ZrSZTPNpC0PQgIZuw==", - "dev": true, "hasInstallScript": true, "funding": { "type": "opencollective", @@ -6511,7 +6173,6 @@ "version": "3.35.1", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.35.1.tgz", "integrity": "sha512-sftHa5qUJY3rs9Zht1WEnmkvXputCyDBczPnr7QDgL8n3qrF3CMXY4VPSYtOLLiOUJcah2WNXREd48iOl6mQIw==", - "dev": true, "dependencies": { "browserslist": "^4.22.2" }, @@ -6524,7 +6185,6 @@ "version": "3.35.1", "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.35.1.tgz", "integrity": "sha512-zcIdi/CL3MWbBJYo5YCeVAAx+Sy9yJE9I3/u9LkFABwbeaPhTMRWraM8mYFp9jW5Z50hOy7FVzCc8dCrpZqtIQ==", - "dev": true, "hasInstallScript": true, "funding": { "type": "opencollective", @@ -6534,14 +6194,20 @@ "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "node_modules/cose-base": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-1.0.3.tgz", + "integrity": "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==", + "dependencies": { + "layout-base": "^1.0.0" + } }, "node_modules/cosmiconfig": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", - "dev": true, "dependencies": { "@types/parse-json": "^4.0.0", "import-fresh": "^3.2.1", @@ -6571,7 +6237,6 @@ "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -6585,7 +6250,6 @@ "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==", - "dev": true, "engines": { "node": ">=8" } @@ -6594,7 +6258,6 @@ "version": "6.4.1", "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz", "integrity": "sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==", - "dev": true, "engines": { "node": "^10 || ^12 || >=14" }, @@ -6606,7 +6269,6 @@ "version": "6.9.1", "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.9.1.tgz", "integrity": "sha512-OzABOh0+26JKFdMzlK6PY1u5Zx8+Ck7CVRlcGNZoY9qwJjdfu2VWFuprTIpPW+Av5TZTVViYWcFQaEEQURLknQ==", - "dev": true, "dependencies": { "icss-utils": "^5.1.0", "postcss": "^8.4.33", @@ -6632,7 +6294,6 @@ "version": "4.2.2", "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-4.2.2.tgz", "integrity": "sha512-s3Of/4jKfw1Hj9CxEO1E5oXhQAxlayuHO2y/ML+C6I9sQ7FdzfEV6QgMLN3vI+qFsjJGIAFLKtQK7t8BOXAIyA==", - "dev": true, "dependencies": { "cssnano": "^5.1.8", "jest-worker": "^29.1.2", @@ -6676,7 +6337,6 @@ "version": "8.12.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -6692,7 +6352,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, "dependencies": { "fast-deep-equal": "^3.1.3" }, @@ -6703,14 +6362,12 @@ "node_modules/css-minimizer-webpack-plugin/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, "node_modules/css-minimizer-webpack-plugin/node_modules/schema-utils": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", - "dev": true, "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", @@ -6729,7 +6386,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", - "dev": true, "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", @@ -6745,7 +6401,6 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "dev": true, "dependencies": { "mdn-data": "2.0.14", "source-map": "^0.6.1" @@ -6758,7 +6413,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", - "dev": true, "engines": { "node": ">= 6" }, @@ -6770,7 +6424,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true, "bin": { "cssesc": "bin/cssesc" }, @@ -6782,7 +6435,6 @@ "version": "5.1.15", "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.15.tgz", "integrity": "sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==", - "dev": true, "dependencies": { "cssnano-preset-default": "^5.2.14", "lilconfig": "^2.0.3", @@ -6803,7 +6455,6 @@ "version": "5.3.10", "resolved": "https://registry.npmjs.org/cssnano-preset-advanced/-/cssnano-preset-advanced-5.3.10.tgz", "integrity": "sha512-fnYJyCS9jgMU+cmHO1rPSPf9axbQyD7iUhLO5Df6O4G+fKIOMps+ZbU0PdGFejFBBZ3Pftf18fn1eG7MAPUSWQ==", - "dev": true, "dependencies": { "autoprefixer": "^10.4.12", "cssnano-preset-default": "^5.2.14", @@ -6823,7 +6474,6 @@ "version": "5.2.14", "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz", "integrity": "sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==", - "dev": true, "dependencies": { "css-declaration-sorter": "^6.3.1", "cssnano-utils": "^3.1.0", @@ -6866,7 +6516,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", - "dev": true, "engines": { "node": "^10 || ^12 || >=14.0" }, @@ -6878,7 +6527,6 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", - "dev": true, "dependencies": { "css-tree": "^1.1.2" }, @@ -6889,115 +6537,554 @@ "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "dev": true + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, - "node_modules/data-uri-to-buffer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", - "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", - "dev": true, + "node_modules/cytoscape": { + "version": "3.30.2", + "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.30.2.tgz", + "integrity": "sha512-oICxQsjW8uSaRmn4UK/jkczKOqTrVqt5/1WL0POiJUT2EKNc9STM4hYFHv917yu55aTBMFNRzymlJhVAiWPCxw==", "engines": { - "node": ">= 12" + "node": ">=0.10" } }, - "node_modules/date-fns": { - "version": "2.30.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", - "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "node_modules/cytoscape-cose-bilkent": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz", + "integrity": "sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==", "dependencies": { - "@babel/runtime": "^7.21.0" - }, - "engines": { - "node": ">=0.11" + "cose-base": "^1.0.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/date-fns" + "peerDependencies": { + "cytoscape": "^3.2.0" } }, - "node_modules/date-fns-tz": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/date-fns-tz/-/date-fns-tz-1.3.8.tgz", - "integrity": "sha512-qwNXUFtMHTTU6CFSFjoJ80W8Fzzp24LntbjFFBgL/faqds4e5mo9mftoRLgr3Vi1trISsg4awSpYVsOQCRnapQ==", + "node_modules/cytoscape-fcose": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz", + "integrity": "sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==", + "dependencies": { + "cose-base": "^2.2.0" + }, "peerDependencies": { - "date-fns": ">=2.0.0" + "cytoscape": "^3.2.0" } }, - "node_modules/debounce": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", - "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", - "dev": true - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "node_modules/cytoscape-fcose/node_modules/cose-base": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-2.2.0.tgz", + "integrity": "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==", "dependencies": { - "ms": "2.1.2" + "layout-base": "^2.0.0" + } + }, + "node_modules/cytoscape-fcose/node_modules/layout-base": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-2.0.1.tgz", + "integrity": "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==" + }, + "node_modules/d3": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz", + "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", + "dependencies": { + "d3-array": "3", + "d3-axis": "3", + "d3-brush": "3", + "d3-chord": "3", + "d3-color": "3", + "d3-contour": "4", + "d3-delaunay": "6", + "d3-dispatch": "3", + "d3-drag": "3", + "d3-dsv": "3", + "d3-ease": "3", + "d3-fetch": "3", + "d3-force": "3", + "d3-format": "3", + "d3-geo": "3", + "d3-hierarchy": "3", + "d3-interpolate": "3", + "d3-path": "3", + "d3-polygon": "3", + "d3-quadtree": "3", + "d3-random": "3", + "d3-scale": "4", + "d3-scale-chromatic": "3", + "d3-selection": "3", + "d3-shape": "3", + "d3-time": "3", + "d3-time-format": "4", + "d3-timer": "3", + "d3-transition": "3", + "d3-zoom": "3" }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">=12" } }, - "node_modules/decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", - "dev": true, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", "dependencies": { - "mimic-response": "^1.0.0" + "internmap": "1 - 2" }, "engines": { - "node": ">=4" + "node": ">=12" } }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, + "node_modules/d3-axis": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", + "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", "engines": { - "node": ">=4.0.0" + "node": ">=12" } }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "dev": true, + "node_modules/d3-brush": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", + "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "3", + "d3-transition": "3" + }, "engines": { - "node": ">=0.10.0" + "node": ">=12" } }, - "node_modules/default-gateway": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", - "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", - "dev": true, + "node_modules/d3-chord": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", + "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", "dependencies": { - "execa": "^5.0.0" + "d3-path": "1 - 3" }, "engines": { - "node": ">= 10" + "node": ">=12" } }, - "node_modules/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==", - "dev": true + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "engines": { + "node": ">=12" + } }, - "node_modules/define-data-property": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", - "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "node_modules/d3-contour": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", + "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", + "dependencies": { + "d3-array": "^3.2.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "dependencies": { + "delaunator": "5" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-drag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", + "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "dependencies": { + "commander": "7", + "iconv-lite": "0.6", + "rw": "1" + }, + "bin": { + "csv2json": "bin/dsv2json.js", + "csv2tsv": "bin/dsv2dsv.js", + "dsv2dsv": "bin/dsv2dsv.js", + "dsv2json": "bin/dsv2json.js", + "json2csv": "bin/json2dsv.js", + "json2dsv": "bin/json2dsv.js", + "json2tsv": "bin/json2dsv.js", + "tsv2csv": "bin/dsv2dsv.js", + "tsv2json": "bin/dsv2json.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/d3-dsv/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-fetch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", + "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", + "dependencies": { + "d3-dsv": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-force": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", + "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-quadtree": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-geo": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz", + "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", + "dependencies": { + "d3-array": "2.5.0 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-hierarchy": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", + "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-polygon": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", + "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-quadtree": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", + "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-random": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", + "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", + "dependencies": { + "d3-color": "1 - 3", + "d3-interpolate": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "dependencies": { + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "d3-selection": "2 - 3" + } + }, + "node_modules/d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/dagre-d3-es": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.9.tgz", + "integrity": "sha512-rYR4QfVmy+sR44IBDvVtcAmOReGBvRCWDpO2QjYwqgh9yijw6eSHBqaPG/LIOEy7aBsniLvtMW6pg19qJhq60w==", + "dependencies": { + "d3": "^7.8.2", + "lodash-es": "^4.17.21" + } + }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/date-fns": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "dependencies": { + "@babel/runtime": "^7.21.0" + }, + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, + "node_modules/date-fns-tz": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/date-fns-tz/-/date-fns-tz-1.3.8.tgz", + "integrity": "sha512-qwNXUFtMHTTU6CFSFjoJ80W8Fzzp24LntbjFFBgL/faqds4e5mo9mftoRLgr3Vi1trISsg4awSpYVsOQCRnapQ==", + "peerDependencies": { + "date-fns": ">=2.0.0" + } + }, + "node_modules/dayjs": { + "version": "1.11.13", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz", + "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==" + }, + "node_modules/debounce": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==" + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", + "dependencies": { + "mimic-response": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-gateway": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "dependencies": { + "execa": "^5.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/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==" + }, + "node_modules/define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", "dependencies": { "get-intrinsic": "^1.2.1", "gopd": "^1.0.1", @@ -7011,7 +7098,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", - "dev": true, "engines": { "node": ">=8" } @@ -7020,7 +7106,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", @@ -7037,7 +7122,6 @@ "version": "6.1.1", "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", - "dev": true, "dependencies": { "globby": "^11.0.1", "graceful-fs": "^4.2.4", @@ -7055,6 +7139,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/delaunator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz", + "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", + "dependencies": { + "robust-predicates": "^3.0.2" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -7073,7 +7165,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true, "engines": { "node": ">= 0.8" } @@ -7082,7 +7173,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "dev": true, "engines": { "node": ">= 0.8", "npm": "1.2.8000 || >= 1.4.16" @@ -7092,7 +7182,6 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/detab/-/detab-2.0.4.tgz", "integrity": "sha512-8zdsQA5bIkoRECvCrNKPla84lyoR7DSAyf7p0YgXzBO9PDJx8KntPUay7NS6yp+KdxdVtiE5SpHKtbp2ZQyA9g==", - "dev": true, "dependencies": { "repeat-string": "^1.5.4" }, @@ -7110,7 +7199,6 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.5.1.tgz", "integrity": "sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==", - "dev": true, "dependencies": { "address": "^1.0.1", "debug": "4" @@ -7124,7 +7212,6 @@ "version": "1.1.6", "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", - "dev": true, "dependencies": { "address": "^1.0.1", "debug": "^2.6.0" @@ -7141,7 +7228,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "dependencies": { "ms": "2.0.0" } @@ -7149,8 +7235,7 @@ "node_modules/detect-port-alt/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/didyoumean": { "version": "1.2.2", @@ -7170,7 +7255,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, "dependencies": { "path-type": "^4.0.0" }, @@ -7188,7 +7272,6 @@ "version": "5.6.1", "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", - "dev": true, "dependencies": { "@leichtgewicht/ip-codec": "^2.0.1" }, @@ -7222,7 +7305,6 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", - "dev": true, "dependencies": { "utila": "~0.4" } @@ -7241,7 +7323,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "dev": true, "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", @@ -7255,7 +7336,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "dev": true, "funding": [ { "type": "github", @@ -7267,7 +7347,6 @@ "version": "5.0.3", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "dev": true, "dependencies": { "domelementtype": "^2.3.0" }, @@ -7278,11 +7357,15 @@ "url": "https://github.com/fb55/domhandler?sponsor=1" } }, + "node_modules/dompurify": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.3.tgz", + "integrity": "sha512-q6QaLcakcRjebxjg8/+NP+h0rPfatOgOzc46Fst9VAA3jF2ApfKBNKMzdP4DYTqtUMXSCd5pRS/8Po/OmoCHZQ==" + }, "node_modules/domutils": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", - "dev": true, "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", @@ -7296,7 +7379,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", - "dev": true, "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3" @@ -7306,7 +7388,6 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "dev": true, "dependencies": { "is-obj": "^2.0.0" }, @@ -7318,7 +7399,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true, "engines": { "node": ">=8" } @@ -7368,38 +7448,37 @@ "node_modules/duplexer": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", - "dev": true + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" }, "node_modules/duplexer3": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz", - "integrity": "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==", - "dev": true + "integrity": "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==" }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "dev": true + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { "version": "1.4.643", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.643.tgz", - "integrity": "sha512-QHscvvS7gt155PtoRC0dR2ilhL8E9LHhfTQEq1uD5AL0524rBLAwpAREFH06f87/e45B9XkR6Ki5dbhbCsVEIg==", - "dev": true + "integrity": "sha512-QHscvvS7gt155PtoRC0dR2ilhL8E9LHhfTQEq1uD5AL0524rBLAwpAREFH06f87/e45B9XkR6Ki5dbhbCsVEIg==" + }, + "node_modules/elkjs": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/elkjs/-/elkjs-0.8.2.tgz", + "integrity": "sha512-L6uRgvZTH+4OF5NE/MBbzQx/WYpru1xCBE9respNj6qznEewGUIfhzmm7horWWxbNO2M0WckQypGctR8lH79xQ==" }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" }, "node_modules/emojis-list": { "version": "3.0.0", @@ -7413,7 +7492,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/emoticon/-/emoticon-3.2.0.tgz", "integrity": "sha512-SNujglcLTTg+lDAcApPNgEdudaqQFiAbJCqzjNxJkvN9vAwCGi0uu8IUVvx+f16h+V44KCY6Y2yboroc9pilHg==", - "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -7423,7 +7501,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "dev": true, "engines": { "node": ">= 0.8" } @@ -7432,7 +7509,6 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, "dependencies": { "once": "^1.4.0" } @@ -7441,7 +7517,6 @@ "version": "5.15.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", - "dev": true, "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -7459,7 +7534,6 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "dev": true, "engines": { "node": ">=0.12" }, @@ -7483,7 +7557,6 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, "dependencies": { "is-arrayish": "^0.2.1" } @@ -7491,14 +7564,12 @@ "node_modules/es-module-lexer": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", - "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==", - "dev": true + "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==" }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, "engines": { "node": ">=6" } @@ -7507,7 +7578,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", - "dev": true, "engines": { "node": ">=8" } @@ -7515,14 +7585,12 @@ "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "dev": true + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, "engines": { "node": ">=10" }, @@ -7534,7 +7602,6 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -7547,7 +7614,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -7560,7 +7626,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, "dependencies": { "estraverse": "^5.2.0" }, @@ -7572,7 +7637,6 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, "engines": { "node": ">=4.0" } @@ -7581,7 +7645,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, "engines": { "node": ">=4.0" } @@ -7590,7 +7653,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -7599,7 +7661,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/eta/-/eta-2.2.0.tgz", "integrity": "sha512-UVQ72Rqjy/ZKQalzV5dCCJP80GrmPrMxh6NlNf+erV6ObL0ZFkhCstWRawS85z3smdr3d2wXPsZEY7rDPfGd2g==", - "dev": true, "engines": { "node": ">=6.0.0" }, @@ -7611,7 +7672,6 @@ "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -7620,7 +7680,6 @@ "version": "0.1.8", "resolved": "https://registry.npmjs.org/eval/-/eval-0.1.8.tgz", "integrity": "sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw==", - "dev": true, "dependencies": { "@types/node": "*", "require-like": ">= 0.1.1" @@ -7632,14 +7691,12 @@ "node_modules/eventemitter3": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" }, "node_modules/events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true, "engines": { "node": ">=0.8.x" } @@ -7648,7 +7705,6 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", @@ -7671,7 +7727,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true, "engines": { "node": ">=10" }, @@ -7683,7 +7738,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, "engines": { "node": ">=6" } @@ -7692,7 +7746,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, "dependencies": { "mimic-fn": "^2.1.0" }, @@ -7706,14 +7759,12 @@ "node_modules/execa/node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, "node_modules/express": { "version": "4.18.2", "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", - "dev": true, "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -7755,7 +7806,6 @@ "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dev": true, "dependencies": { "safe-buffer": "5.2.1" }, @@ -7767,7 +7817,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "dependencies": { "ms": "2.0.0" } @@ -7775,20 +7824,17 @@ "node_modules/express/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/express/node_modules/path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", - "dev": true + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, "node_modules/express/node_modules/qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dev": true, "dependencies": { "side-channel": "^1.0.4" }, @@ -7803,7 +7849,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -7811,14 +7856,12 @@ "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, "node_modules/extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, "dependencies": { "is-extendable": "^0.1.0" }, @@ -7841,7 +7884,6 @@ "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -7862,7 +7904,6 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz", "integrity": "sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==", - "dev": true, "dependencies": { "punycode": "^1.3.2" } @@ -7880,7 +7921,6 @@ "version": "1.16.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz", "integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==", - "dev": true, "dependencies": { "reusify": "^1.0.4" } @@ -7889,7 +7929,6 @@ "version": "0.11.4", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", - "dev": true, "dependencies": { "websocket-driver": ">=0.5.1" }, @@ -7931,7 +7970,6 @@ "version": "4.2.2", "resolved": "https://registry.npmjs.org/feed/-/feed-4.2.2.tgz", "integrity": "sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ==", - "dev": true, "dependencies": { "xml-js": "^1.6.11" }, @@ -7987,7 +8025,6 @@ "version": "6.2.0", "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", - "dev": true, "dependencies": { "loader-utils": "^2.0.0", "schema-utils": "^3.0.0" @@ -8007,7 +8044,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dev": true, "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -8025,7 +8061,6 @@ "version": "8.0.7", "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==", - "dev": true, "engines": { "node": ">= 0.4.0" } @@ -8034,7 +8069,6 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, "dependencies": { "to-regex-range": "^5.0.1" }, @@ -8046,7 +8080,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "dev": true, "dependencies": { "debug": "2.6.9", "encodeurl": "~1.0.2", @@ -8064,7 +8097,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "dependencies": { "ms": "2.0.0" } @@ -8072,14 +8104,12 @@ "node_modules/finalhandler/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/find-cache-dir": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", - "dev": true, "dependencies": { "commondir": "^1.0.1", "make-dir": "^3.0.2", @@ -8096,7 +8126,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -8109,7 +8138,6 @@ "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true, "bin": { "flat": "cli.js" } @@ -8139,7 +8167,6 @@ "version": "1.15.5", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", - "dev": true, "funding": [ { "type": "individual", @@ -8175,7 +8202,6 @@ "version": "6.5.3", "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz", "integrity": "sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==", - "dev": true, "dependencies": { "@babel/code-frame": "^7.8.3", "@types/json-schema": "^7.0.5", @@ -8214,7 +8240,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -8224,7 +8249,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", - "dev": true, "dependencies": { "@types/parse-json": "^4.0.0", "import-fresh": "^3.1.0", @@ -8240,7 +8264,6 @@ "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", @@ -8255,7 +8278,6 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -8275,7 +8297,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -8287,7 +8308,6 @@ "version": "2.7.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", - "dev": true, "dependencies": { "@types/json-schema": "^7.0.4", "ajv": "^6.12.2", @@ -8305,7 +8325,6 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true, "engines": { "node": ">=6" } @@ -8340,7 +8359,6 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -8349,7 +8367,6 @@ "version": "4.3.7", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", - "dev": true, "engines": { "node": "*" }, @@ -8390,7 +8407,6 @@ "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -8399,7 +8415,6 @@ "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -8412,8 +8427,7 @@ "node_modules/fs-monkey": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz", - "integrity": "sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==", - "dev": true + "integrity": "sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==" }, "node_modules/fs.realpath": { "version": "1.0.0", @@ -8424,7 +8438,6 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -8446,7 +8459,6 @@ "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==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -8468,14 +8480,12 @@ "node_modules/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==", - "dev": true + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" }, "node_modules/get-stream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, "dependencies": { "pump": "^3.0.0" }, @@ -8486,8 +8496,7 @@ "node_modules/github-slugger": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.5.0.tgz", - "integrity": "sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==", - "dev": true + "integrity": "sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==" }, "node_modules/glob": { "version": "10.3.10", @@ -8515,7 +8524,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -8526,14 +8534,12 @@ "node_modules/glob-to-regexp": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" }, "node_modules/global-dirs": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", - "dev": true, "dependencies": { "ini": "2.0.0" }, @@ -8548,7 +8554,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", - "dev": true, "engines": { "node": ">=10" } @@ -8557,7 +8562,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", - "dev": true, "dependencies": { "global-prefix": "^3.0.0" }, @@ -8569,7 +8573,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", - "dev": true, "dependencies": { "ini": "^1.3.5", "kind-of": "^6.0.2", @@ -8583,7 +8586,6 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, "dependencies": { "isexe": "^2.0.0" }, @@ -8595,7 +8597,6 @@ "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, "engines": { "node": ">=4" } @@ -8604,7 +8605,6 @@ "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -8635,7 +8635,6 @@ "version": "9.6.0", "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", - "dev": true, "dependencies": { "@sindresorhus/is": "^0.14.0", "@szmarczak/http-timer": "^1.1.2", @@ -8656,14 +8655,12 @@ "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" }, "node_modules/gray-matter": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", - "dev": true, "dependencies": { "js-yaml": "^3.13.1", "kind-of": "^6.0.2", @@ -8678,7 +8675,6 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, "dependencies": { "sprintf-js": "~1.0.2" } @@ -8687,7 +8683,6 @@ "version": "3.14.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -8700,7 +8695,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", - "dev": true, "dependencies": { "duplexer": "^0.1.2" }, @@ -8714,14 +8708,12 @@ "node_modules/handle-thing": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", - "dev": true + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, "engines": { "node": ">=8" } @@ -8763,7 +8755,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", - "dev": true, "engines": { "node": ">=8" } @@ -8783,7 +8774,6 @@ "version": "9.0.1", "resolved": "https://registry.npmjs.org/hast-to-hyperscript/-/hast-to-hyperscript-9.0.1.tgz", "integrity": "sha512-zQgLKqF+O2F72S1aa4y2ivxzSlko3MAvxkwG8ehGmNiqd98BIN3JM1rAJPmplEyLmGLO2QZYJtIneOSZ2YbJuA==", - "dev": true, "dependencies": { "@types/unist": "^2.0.3", "comma-separated-tokens": "^1.0.0", @@ -8802,7 +8792,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-6.0.1.tgz", "integrity": "sha512-jeJUWiN5pSxW12Rh01smtVkZgZr33wBokLzKLwinYOUfSzm1Nl/c3GUGebDyOKjdsRgMvoVbV0VpAcpjF4NrJA==", - "dev": true, "dependencies": { "@types/parse5": "^5.0.0", "hastscript": "^6.0.0", @@ -8829,7 +8818,6 @@ "version": "2.2.5", "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz", "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==", - "dev": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" @@ -8839,7 +8827,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-6.0.1.tgz", "integrity": "sha512-ZMuiYA+UF7BXBtsTBNcLBF5HzXzkyE6MLzJnL605LKE8GJylNjGc4jjxazAHUtcwT5/CEt6afRKViYB4X66dig==", - "dev": true, "dependencies": { "@types/hast": "^2.0.0", "hast-util-from-parse5": "^6.0.0", @@ -8860,14 +8847,12 @@ "node_modules/hast-util-raw/node_modules/parse5": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" }, "node_modules/hast-util-to-parse5": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-6.0.0.tgz", "integrity": "sha512-Lu5m6Lgm/fWuz8eWnrKezHtVY83JeRGaNQ2kn9aJgqaxvVkFCZQBEhgodZUDUvoodgyROHDb3r5IxAEdl6suJQ==", - "dev": true, "dependencies": { "hast-to-hyperscript": "^9.0.0", "property-information": "^5.0.0", @@ -8899,7 +8884,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz", "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==", - "dev": true, "dependencies": { "@types/hast": "^2.0.0", "comma-separated-tokens": "^1.0.0", @@ -8916,7 +8900,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, "bin": { "he": "bin/he" } @@ -8930,7 +8913,6 @@ "version": "4.10.1", "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", - "dev": true, "dependencies": { "@babel/runtime": "^7.1.2", "loose-envify": "^1.2.0", @@ -8944,7 +8926,6 @@ "version": "3.3.2", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "dev": true, "dependencies": { "react-is": "^16.7.0" } @@ -8953,7 +8934,6 @@ "version": "2.1.6", "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", - "dev": true, "dependencies": { "inherits": "^2.0.1", "obuf": "^1.0.0", @@ -8964,14 +8944,12 @@ "node_modules/hpack.js/node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" }, "node_modules/hpack.js/node_modules/readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -8985,14 +8963,12 @@ "node_modules/hpack.js/node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "node_modules/hpack.js/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, "dependencies": { "safe-buffer": "~5.1.0" } @@ -9001,7 +8977,6 @@ "version": "2.4.0", "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.4.0.tgz", "integrity": "sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ==", - "dev": true, "funding": [ { "type": "github", @@ -9016,14 +8991,12 @@ "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" }, "node_modules/html-minifier-terser": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", - "dev": true, "dependencies": { "camel-case": "^4.1.2", "clean-css": "^5.2.2", @@ -9044,7 +9017,6 @@ "version": "8.3.0", "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "dev": true, "engines": { "node": ">= 12" } @@ -9053,7 +9025,6 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", - "dev": true, "engines": { "node": ">=8" }, @@ -9065,7 +9036,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-1.0.5.tgz", "integrity": "sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w==", - "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -9075,7 +9045,6 @@ "version": "5.6.0", "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.0.tgz", "integrity": "sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw==", - "dev": true, "dependencies": { "@types/html-minifier-terser": "^6.0.0", "html-minifier-terser": "^6.0.2", @@ -9107,7 +9076,6 @@ "version": "8.0.2", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", - "dev": true, "funding": [ "https://github.com/fb55/htmlparser2?sponsor=1", { @@ -9125,20 +9093,17 @@ "node_modules/http-cache-semantics": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", - "dev": true + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" }, "node_modules/http-deceiver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", - "dev": true + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==" }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dev": true, "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", @@ -9153,14 +9118,12 @@ "node_modules/http-parser-js": { "version": "0.5.8", "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", - "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", - "dev": true + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" }, "node_modules/http-proxy": { "version": "1.18.1", "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "dev": true, "dependencies": { "eventemitter3": "^4.0.0", "follow-redirects": "^1.0.0", @@ -9174,7 +9137,6 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", - "dev": true, "dependencies": { "@types/http-proxy": "^1.17.8", "http-proxy": "^1.18.1", @@ -9198,7 +9160,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", - "dev": true, "engines": { "node": ">=10" }, @@ -9210,7 +9171,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true, "engines": { "node": ">=10.17.0" } @@ -9219,7 +9179,6 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -9231,7 +9190,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "dev": true, "engines": { "node": "^10 || ^12 || >= 14" }, @@ -9262,7 +9220,6 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", - "dev": true, "engines": { "node": ">= 4" } @@ -9271,7 +9228,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.1.1.tgz", "integrity": "sha512-541xKlUw6jr/6gGuk92F+mYM5zaFAc5ahphvkqvNe2bQ6gVBkd6bfrmVJ2t4KDAfikAYZyIqTnktX3i6/aQDrQ==", - "dev": true, "dependencies": { "queue": "6.0.2" }, @@ -9286,7 +9242,6 @@ "version": "9.0.21", "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", - "dev": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/immer" @@ -9302,7 +9257,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -9318,7 +9272,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", "integrity": "sha512-m7ZEHgtw69qOGw+jwxXkHlrlIPdTGkyh66zXZ1ajZbxkDBNjSY/LGbmjc7h0s2ELsUDTAhFr55TrPSSqJGPG0A==", - "dev": true, "engines": { "node": ">=4" } @@ -9346,7 +9299,6 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, "engines": { "node": ">=0.8.19" } @@ -9355,7 +9307,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, "engines": { "node": ">=8" } @@ -9386,20 +9337,25 @@ "node_modules/ini": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, "node_modules/inline-style-parser": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", - "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==", - "dev": true + "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" + }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "engines": { + "node": ">=12" + } }, "node_modules/interpret": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true, "engines": { "node": ">= 0.10" } @@ -9408,7 +9364,6 @@ "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dev": true, "dependencies": { "loose-envify": "^1.0.0" } @@ -9417,7 +9372,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", "integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==", - "dev": true, "engines": { "node": ">= 10" } @@ -9426,7 +9380,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", - "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -9436,7 +9389,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", - "dev": true, "dependencies": { "is-alphabetical": "^1.0.0", "is-decimal": "^1.0.0" @@ -9449,14 +9401,12 @@ "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, "dependencies": { "binary-extensions": "^2.0.0" }, @@ -9468,7 +9418,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", - "dev": true, "funding": [ { "type": "github", @@ -9491,7 +9440,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "dev": true, "dependencies": { "ci-info": "^2.0.0" }, @@ -9502,14 +9450,12 @@ "node_modules/is-ci/node_modules/ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" }, "node_modules/is-core-module": { "version": "2.13.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "dev": true, "dependencies": { "hasown": "^2.0.0" }, @@ -9521,7 +9467,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", - "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -9531,7 +9476,6 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true, "bin": { "is-docker": "cli.js" }, @@ -9546,7 +9490,6 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -9555,7 +9498,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -9564,7 +9506,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, "engines": { "node": ">=8" } @@ -9573,7 +9514,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -9585,7 +9525,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", - "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -9595,7 +9534,6 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", - "dev": true, "dependencies": { "global-dirs": "^3.0.0", "is-path-inside": "^3.0.2" @@ -9611,7 +9549,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-5.0.0.tgz", "integrity": "sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA==", - "dev": true, "engines": { "node": ">=10" }, @@ -9623,7 +9560,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, "engines": { "node": ">=0.12.0" } @@ -9632,7 +9568,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -9641,7 +9576,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true, "engines": { "node": ">=6" } @@ -9650,7 +9584,6 @@ "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==", - "dev": true, "engines": { "node": ">=8" } @@ -9659,7 +9592,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true, "engines": { "node": ">=8" } @@ -9668,7 +9600,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -9677,7 +9608,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -9686,7 +9616,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==", - "dev": true, "engines": { "node": ">=6" } @@ -9695,7 +9624,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, "engines": { "node": ">=8" }, @@ -9706,14 +9634,12 @@ "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" }, "node_modules/is-whitespace-character": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz", "integrity": "sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==", - "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -9723,7 +9649,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.4.tgz", "integrity": "sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==", - "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -9733,7 +9658,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, "dependencies": { "is-docker": "^2.0.0" }, @@ -9744,20 +9668,17 @@ "node_modules/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==", - "dev": true + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==" }, "node_modules/isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "dev": true + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "node_modules/iso-url": { "version": "0.4.7", @@ -9771,7 +9692,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -9812,7 +9732,6 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", - "dev": true, "dependencies": { "@jest/types": "^29.6.3", "@types/node": "*", @@ -9829,7 +9748,6 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", - "dev": true, "dependencies": { "@types/node": "*", "jest-util": "^29.7.0", @@ -9844,7 +9762,6 @@ "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -9859,7 +9776,6 @@ "version": "1.21.0", "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", - "dev": true, "bin": { "jiti": "bin/jiti.js" } @@ -9868,7 +9784,6 @@ "version": "17.12.0", "resolved": "https://registry.npmjs.org/joi/-/joi-17.12.0.tgz", "integrity": "sha512-HSLsmSmXz+PV9PYoi3p7cgIbj06WnEBNT28n+bbBNcPZXZFqCzzvGqpTBPujx/Z0nh1+KNQPDrNgdmQ8dq0qYw==", - "dev": true, "dependencies": { "@hapi/hoek": "^9.3.0", "@hapi/topo": "^5.1.0", @@ -9896,7 +9811,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, "dependencies": { "argparse": "^2.0.1" }, @@ -9908,7 +9822,6 @@ "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, "bin": { "jsesc": "bin/jsesc" }, @@ -9919,14 +9832,12 @@ "node_modules/json-buffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==", - "dev": true + "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==" }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, "node_modules/json-schema-traverse": { "version": "0.4.1", @@ -9970,7 +9881,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, "dependencies": { "universalify": "^2.0.0" }, @@ -10007,16 +9917,19 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", - "dev": true, "dependencies": { "json-buffer": "3.0.0" } }, + "node_modules/khroma": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/khroma/-/khroma-2.1.0.tgz", + "integrity": "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==" + }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -10025,7 +9938,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true, "engines": { "node": ">=6" } @@ -10043,7 +9955,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", - "dev": true, "dependencies": { "package-json": "^6.3.0" }, @@ -10055,12 +9966,16 @@ "version": "2.6.1", "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.1.tgz", "integrity": "sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw==", - "dev": true, "dependencies": { "picocolors": "^1.0.0", "shell-quote": "^1.8.1" } }, + "node_modules/layout-base": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-1.0.2.tgz", + "integrity": "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==" + }, "node_modules/leaflet": { "version": "1.9.4", "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz", @@ -10075,7 +9990,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true, "engines": { "node": ">=6" } @@ -10084,7 +9998,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", - "dev": true, "engines": { "node": ">=10" } @@ -10092,14 +10005,12 @@ "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, "node_modules/loader-runner": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", - "dev": true, "engines": { "node": ">=6.11.5" } @@ -10121,7 +10032,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, "dependencies": { "p-locate": "^4.1.0" }, @@ -10132,8 +10042,12 @@ "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" }, "node_modules/lodash.castarray": { "version": "4.4.0", @@ -10173,8 +10087,7 @@ "node_modules/lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "dev": true + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" }, "node_modules/lodash.merge": { "version": "4.6.2", @@ -10185,8 +10098,7 @@ "node_modules/lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", - "dev": true + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" }, "node_modules/log-update": { "version": "2.3.0", @@ -10278,7 +10190,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "dev": true, "dependencies": { "tslib": "^2.0.3" } @@ -10287,7 +10198,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -10296,7 +10206,6 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, "dependencies": { "yallist": "^3.0.2" } @@ -10314,7 +10223,6 @@ "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==", - "dev": true, "dependencies": { "semver": "^6.0.0" }, @@ -10329,7 +10237,6 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, "bin": { "semver": "bin/semver.js" } @@ -10343,7 +10250,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.4.tgz", "integrity": "sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==", - "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -10373,7 +10279,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/mdast-squeeze-paragraphs/-/mdast-squeeze-paragraphs-4.0.0.tgz", "integrity": "sha512-zxdPn69hkQ1rm4J+2Cs2j6wDEv7O17TfXTJ33tl/+JPIoEmtV9t2ZzBM5LPHE8QlHsmVD8t3vPKCyY3oH+H8MQ==", - "dev": true, "dependencies": { "unist-util-remove": "^2.0.0" }, @@ -10386,7 +10291,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-4.0.0.tgz", "integrity": "sha512-k8AJ6aNnUkB7IE+5azR9h81O5EQ/cTDXtWdMq9Kk5KcEW/8ritU5CeLg/9HhOC++nALHBlaogJ5jz0Ybk3kPMQ==", - "dev": true, "dependencies": { "unist-util-visit": "^2.0.0" }, @@ -10399,7 +10303,6 @@ "version": "10.0.1", "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-10.0.1.tgz", "integrity": "sha512-BW3LM9SEMnjf4HXXVApZMt8gLQWVNXc3jryK0nJu/rOXPOnlkUjmdkDlmxMirpbU9ILncGFIwLH/ubnWBbcdgA==", - "dev": true, "dependencies": { "@types/mdast": "^3.0.0", "@types/unist": "^2.0.0", @@ -10419,7 +10322,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==", - "dev": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" @@ -10428,20 +10330,17 @@ "node_modules/mdn-data": { "version": "2.0.14", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", - "dev": true + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" }, "node_modules/mdurl": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", - "dev": true + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==" }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -10450,7 +10349,6 @@ "version": "3.5.3", "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", - "dev": true, "dependencies": { "fs-monkey": "^1.0.4" }, @@ -10461,29 +10359,48 @@ "node_modules/merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", - "dev": true + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, "engines": { "node": ">= 8" } }, + "node_modules/mermaid": { + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-9.4.3.tgz", + "integrity": "sha512-TLkQEtqhRSuEHSE34lh5bCa94KATCyluAXmFnNI2PRZwOpXFeqiJWwZl+d2CcemE1RS6QbbueSSq9QIg8Uxcyw==", + "dependencies": { + "@braintree/sanitize-url": "^6.0.0", + "cytoscape": "^3.23.0", + "cytoscape-cose-bilkent": "^4.1.0", + "cytoscape-fcose": "^2.1.0", + "d3": "^7.4.0", + "dagre-d3-es": "7.0.9", + "dayjs": "^1.11.7", + "dompurify": "2.4.3", + "elkjs": "^0.8.2", + "khroma": "^2.0.0", + "lodash-es": "^4.17.21", + "non-layered-tidy-tree-layout": "^2.0.2", + "stylis": "^4.1.2", + "ts-dedent": "^2.2.0", + "uuid": "^9.0.0", + "web-worker": "^1.2.0" + } + }, "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -10492,7 +10409,6 @@ "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, "dependencies": { "braces": "^3.0.2", "picomatch": "^2.3.1" @@ -10510,7 +10426,6 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -10519,7 +10434,6 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, "dependencies": { "mime-db": "1.52.0" }, @@ -10540,7 +10454,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true, "engines": { "node": ">=4" } @@ -10549,7 +10462,6 @@ "version": "2.7.7", "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.7.tgz", "integrity": "sha512-+0n11YGyRavUR3IlaOzJ0/4Il1avMvJ1VJfhWfCn24ITQXhRr1gghbhhrda6tgtNcpZaWKdSuwKq20Jb7fnlyw==", - "dev": true, "dependencies": { "schema-utils": "^4.0.0" }, @@ -10568,7 +10480,6 @@ "version": "8.12.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -10584,7 +10495,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, "dependencies": { "fast-deep-equal": "^3.1.3" }, @@ -10595,14 +10505,12 @@ "node_modules/mini-css-extract-plugin/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, "node_modules/mini-css-extract-plugin/node_modules/schema-utils": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", - "dev": true, "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", @@ -10620,8 +10528,7 @@ "node_modules/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==", - "dev": true + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" }, "node_modules/minimatch": { "version": "9.0.3", @@ -10642,7 +10549,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -10698,7 +10604,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", - "dev": true, "engines": { "node": ">=10" } @@ -10712,7 +10617,6 @@ "version": "7.2.5", "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", - "dev": true, "dependencies": { "dns-packet": "^5.2.2", "thunky": "^1.0.2" @@ -10744,7 +10648,6 @@ "version": "3.3.7", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "dev": true, "funding": [ { "type": "github", @@ -10762,7 +10665,6 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -10770,14 +10672,12 @@ "node_modules/neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" }, "node_modules/no-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "dev": true, "dependencies": { "lower-case": "^2.0.2", "tslib": "^2.0.3" @@ -10806,7 +10706,6 @@ "version": "1.11.0", "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", - "dev": true, "dependencies": { "lodash": "^4.17.21" } @@ -10862,7 +10761,6 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", - "dev": true, "engines": { "node": ">= 6.13.0" } @@ -10870,14 +10768,17 @@ "node_modules/node-releases": { "version": "2.0.14", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" + }, + "node_modules/non-layered-tidy-tree-layout": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/non-layered-tidy-tree-layout/-/non-layered-tidy-tree-layout-2.0.2.tgz", + "integrity": "sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw==" }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -10886,7 +10787,6 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -10895,7 +10795,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "dev": true, "engines": { "node": ">=10" }, @@ -10907,7 +10806,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, "dependencies": { "path-key": "^3.0.0" }, @@ -10925,7 +10823,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "dev": true, "dependencies": { "boolbase": "^1.0.0" }, @@ -10962,7 +10859,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, "engines": { "node": ">= 0.4" } @@ -10971,7 +10867,6 @@ "version": "4.1.5", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", - "dev": true, "dependencies": { "call-bind": "^1.0.5", "define-properties": "^1.2.1", @@ -10993,14 +10888,12 @@ "node_modules/obuf": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", - "dev": true + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" }, "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, "dependencies": { "ee-first": "1.1.1" }, @@ -11012,7 +10905,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "dev": true, "engines": { "node": ">= 0.8" } @@ -11041,7 +10933,6 @@ "version": "8.4.2", "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", - "dev": true, "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", @@ -11058,7 +10949,6 @@ "version": "1.5.2", "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", - "dev": true, "bin": { "opener": "bin/opener-bin.js" } @@ -11076,7 +10966,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", - "dev": true, "engines": { "node": ">=6" } @@ -11085,7 +10974,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, "dependencies": { "p-try": "^2.0.0" }, @@ -11100,7 +10988,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, "dependencies": { "p-limit": "^2.2.0" }, @@ -11112,7 +10999,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, "dependencies": { "aggregate-error": "^3.0.0" }, @@ -11127,7 +11013,6 @@ "version": "4.6.2", "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", - "dev": true, "dependencies": { "@types/retry": "0.12.0", "retry": "^0.13.1" @@ -11152,7 +11037,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, "engines": { "node": ">=6" } @@ -11161,7 +11045,6 @@ "version": "6.5.0", "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", - "dev": true, "dependencies": { "got": "^9.6.0", "registry-auth-token": "^4.0.0", @@ -11176,7 +11059,6 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, "bin": { "semver": "bin/semver.js" } @@ -11185,7 +11067,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", - "dev": true, "dependencies": { "dot-case": "^3.0.4", "tslib": "^2.0.3" @@ -11195,7 +11076,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, "dependencies": { "callsites": "^3.0.0" }, @@ -11207,7 +11087,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", - "dev": true, "dependencies": { "character-entities": "^1.0.0", "character-entities-legacy": "^1.0.0", @@ -11225,7 +11104,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -11242,14 +11120,12 @@ "node_modules/parse-numeric-range": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz", - "integrity": "sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==", - "dev": true + "integrity": "sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==" }, "node_modules/parse5": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", - "dev": true, "dependencies": { "entities": "^4.4.0" }, @@ -11261,7 +11137,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", - "dev": true, "dependencies": { "domhandler": "^5.0.2", "parse5": "^7.0.0" @@ -11274,7 +11149,6 @@ "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true, "engines": { "node": ">= 0.8" } @@ -11283,7 +11157,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", - "dev": true, "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3" @@ -11293,7 +11166,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, "engines": { "node": ">=8" } @@ -11309,14 +11181,12 @@ "node_modules/path-is-inside": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", - "dev": true + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==" }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, "engines": { "node": ">=8" } @@ -11324,8 +11194,7 @@ "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "node_modules/path-scurry": { "version": "1.10.1", @@ -11356,7 +11225,6 @@ "version": "1.8.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", - "dev": true, "dependencies": { "isarray": "0.0.1" } @@ -11365,7 +11233,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, "engines": { "node": ">=8" } @@ -11378,14 +11245,12 @@ "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, "engines": { "node": ">=8.6" }, @@ -11415,7 +11280,6 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, "dependencies": { "find-up": "^4.0.0" }, @@ -11427,7 +11291,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", - "dev": true, "dependencies": { "find-up": "^3.0.0" }, @@ -11439,7 +11302,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, "dependencies": { "locate-path": "^3.0.0" }, @@ -11451,7 +11313,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, "dependencies": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" @@ -11464,7 +11325,6 @@ "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==", - "dev": true, "dependencies": { "p-limit": "^2.0.0" }, @@ -11476,7 +11336,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true, "engines": { "node": ">=4" } @@ -11502,7 +11361,6 @@ "version": "8.4.33", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.33.tgz", "integrity": "sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==", - "dev": true, "funding": [ { "type": "opencollective", @@ -11530,7 +11388,6 @@ "version": "8.2.4", "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", - "dev": true, "dependencies": { "postcss-selector-parser": "^6.0.9", "postcss-value-parser": "^4.2.0" @@ -11543,7 +11400,6 @@ "version": "5.3.1", "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.1.tgz", "integrity": "sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==", - "dev": true, "dependencies": { "browserslist": "^4.21.4", "caniuse-api": "^3.0.0", @@ -11561,7 +11417,6 @@ "version": "5.1.3", "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz", "integrity": "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==", - "dev": true, "dependencies": { "browserslist": "^4.21.4", "postcss-value-parser": "^4.2.0" @@ -11577,7 +11432,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==", - "dev": true, "engines": { "node": "^10 || ^12 || >=14.0" }, @@ -11589,7 +11443,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", - "dev": true, "engines": { "node": "^10 || ^12 || >=14.0" }, @@ -11601,7 +11454,6 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", - "dev": true, "engines": { "node": "^10 || ^12 || >=14.0" }, @@ -11613,7 +11465,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", - "dev": true, "engines": { "node": "^10 || ^12 || >=14.0" }, @@ -11625,7 +11476,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-5.1.0.tgz", "integrity": "sha512-KwLWymI9hbwXmJa0dkrzpRbSJEh0vVUd7r8t0yOGPcfKzyJJxFM8kLyC5Ev9avji6nY95pOp1W6HqIrfT+0VGw==", - "dev": true, "dependencies": { "postcss-selector-parser": "^6.0.5" }, @@ -11729,7 +11579,6 @@ "version": "7.3.4", "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.3.4.tgz", "integrity": "sha512-iW5WTTBSC5BfsBJ9daFMPVrLT36MrNiC6fqOZTTaHjBNX6Pfd5p+hSBqe/fEeNd7pc13QiAyGt7VdGMw4eRC4A==", - "dev": true, "dependencies": { "cosmiconfig": "^8.3.5", "jiti": "^1.20.0", @@ -11751,7 +11600,6 @@ "version": "8.3.6", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", - "dev": true, "dependencies": { "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", @@ -11777,7 +11625,6 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-5.1.1.tgz", "integrity": "sha512-pCijL1TREiCoog5nQp7wUe+TUonA2tC2sQ54UGeMmryK3UFGIYKqDyjnqd6RcuI4znFn9hWSLNN8xKE/vWcUQw==", - "dev": true, "dependencies": { "cssnano-utils": "^3.1.0", "postcss-value-parser": "^4.2.0" @@ -11793,7 +11640,6 @@ "version": "5.1.7", "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz", "integrity": "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==", - "dev": true, "dependencies": { "postcss-value-parser": "^4.2.0", "stylehacks": "^5.1.1" @@ -11809,7 +11655,6 @@ "version": "5.1.4", "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz", "integrity": "sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==", - "dev": true, "dependencies": { "browserslist": "^4.21.4", "caniuse-api": "^3.0.0", @@ -11827,7 +11672,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz", "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==", - "dev": true, "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -11842,7 +11686,6 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz", "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==", - "dev": true, "dependencies": { "colord": "^2.9.1", "cssnano-utils": "^3.1.0", @@ -11859,7 +11702,6 @@ "version": "5.1.4", "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz", "integrity": "sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==", - "dev": true, "dependencies": { "browserslist": "^4.21.4", "cssnano-utils": "^3.1.0", @@ -11876,7 +11718,6 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz", "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==", - "dev": true, "dependencies": { "postcss-selector-parser": "^6.0.5" }, @@ -11891,7 +11732,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", - "dev": true, "engines": { "node": "^10 || ^12 || >= 14" }, @@ -11903,7 +11743,6 @@ "version": "4.0.4", "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.4.tgz", "integrity": "sha512-L4QzMnOdVwRm1Qb8m4x8jsZzKAaPAgrUF1r/hjDR2Xj7R+8Zsf97jAlSQzWtKx5YNiNGN8QxmPFIc/sh+RQl+Q==", - "dev": true, "dependencies": { "icss-utils": "^5.0.0", "postcss-selector-parser": "^6.0.2", @@ -11920,7 +11759,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.1.1.tgz", "integrity": "sha512-uZgqzdTleelWjzJY+Fhti6F3C9iF1JR/dODLs/JDefozYcKTBCdD8BIl6nNPbTbcLnGrk56hzwZC2DaGNvYjzA==", - "dev": true, "dependencies": { "postcss-selector-parser": "^6.0.4" }, @@ -11935,7 +11773,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", - "dev": true, "dependencies": { "icss-utils": "^5.0.0" }, @@ -11982,7 +11819,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", - "dev": true, "engines": { "node": "^10 || ^12 || >=14.0" }, @@ -11994,7 +11830,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz", "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==", - "dev": true, "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -12009,7 +11844,6 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz", "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==", - "dev": true, "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -12024,7 +11858,6 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz", "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==", - "dev": true, "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -12039,7 +11872,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz", "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==", - "dev": true, "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -12054,7 +11886,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz", "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==", - "dev": true, "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -12069,7 +11900,6 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz", "integrity": "sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==", - "dev": true, "dependencies": { "browserslist": "^4.21.4", "postcss-value-parser": "^4.2.0" @@ -12085,7 +11915,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz", "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==", - "dev": true, "dependencies": { "normalize-url": "^6.0.1", "postcss-value-parser": "^4.2.0" @@ -12101,7 +11930,6 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz", "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==", - "dev": true, "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -12116,7 +11944,6 @@ "version": "5.1.3", "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz", "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==", - "dev": true, "dependencies": { "cssnano-utils": "^3.1.0", "postcss-value-parser": "^4.2.0" @@ -12132,7 +11959,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-5.2.0.tgz", "integrity": "sha512-BTrLjICoSB6gxbc58D5mdBK8OhXRDqud/zodYfdSi52qvDHdMwk+9kB9xsM8yJThH/sZU5A6QVSmMmaN001gIg==", - "dev": true, "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -12147,7 +11973,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz", "integrity": "sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==", - "dev": true, "dependencies": { "browserslist": "^4.21.4", "caniuse-api": "^3.0.0" @@ -12163,7 +11988,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz", "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==", - "dev": true, "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -12178,7 +12002,6 @@ "version": "6.0.10", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", - "dev": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -12191,7 +12014,6 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/postcss-sort-media-queries/-/postcss-sort-media-queries-4.4.1.tgz", "integrity": "sha512-QDESFzDDGKgpiIh4GYXsSy6sek2yAwQx1JASl5AxBtU1Lq2JfKBljIPNdil989NcSKRQX1ToiaKphImtBuhXWw==", - "dev": true, "dependencies": { "sort-css-media-queries": "2.1.0" }, @@ -12206,7 +12028,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz", "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==", - "dev": true, "dependencies": { "postcss-value-parser": "^4.2.0", "svgo": "^2.7.0" @@ -12222,7 +12043,6 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz", "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==", - "dev": true, "dependencies": { "postcss-selector-parser": "^6.0.5" }, @@ -12236,14 +12056,12 @@ "node_modules/postcss-value-parser": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" }, "node_modules/postcss-zindex": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-5.1.0.tgz", "integrity": "sha512-fgFMf0OtVSBR1va1JNHYgMxYk73yhn/qb4uQDq1DLGYolz8gHCyr/sesEuGUaYs58E3ZJRcpoGuPVoB7Meiq9A==", - "dev": true, "engines": { "node": "^10 || ^12 || >=14.0" }, @@ -12255,7 +12073,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", "integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==", - "dev": true, "engines": { "node": ">=4" } @@ -12279,7 +12096,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", - "dev": true, "dependencies": { "lodash": "^4.17.20", "renderkid": "^3.0.0" @@ -12289,7 +12105,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/pretty-time/-/pretty-time-1.1.0.tgz", "integrity": "sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==", - "dev": true, "engines": { "node": ">=4" } @@ -12314,8 +12129,7 @@ "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "node_modules/progress-webpack-plugin": { "version": "1.0.16", @@ -12418,7 +12232,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" @@ -12441,7 +12254,6 @@ "version": "5.6.0", "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz", "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==", - "dev": true, "dependencies": { "xtend": "^4.0.0" }, @@ -12454,7 +12266,6 @@ "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dev": true, "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" @@ -12467,7 +12278,6 @@ "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "dev": true, "engines": { "node": ">= 0.10" } @@ -12476,7 +12286,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -12491,7 +12300,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", - "dev": true, "dependencies": { "escape-goat": "^2.0.0" }, @@ -12523,7 +12331,6 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==", - "dev": true, "dependencies": { "inherits": "~2.0.3" } @@ -12532,7 +12339,6 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, "funding": [ { "type": "github", @@ -12552,7 +12358,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, "dependencies": { "safe-buffer": "^5.1.0" } @@ -12561,7 +12366,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", "integrity": "sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -12570,7 +12374,6 @@ "version": "2.5.1", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "dev": true, "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -12585,7 +12388,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true, "engines": { "node": ">= 0.8" } @@ -12630,7 +12432,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", @@ -12645,7 +12446,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -12702,7 +12502,6 @@ "version": "12.0.1", "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", "integrity": "sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==", - "dev": true, "dependencies": { "@babel/code-frame": "^7.16.0", "address": "^1.1.2", @@ -12737,7 +12536,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "engines": { "node": ">=8" } @@ -12746,7 +12544,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -12762,7 +12559,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==", - "dev": true, "engines": { "node": ">= 12.13.0" } @@ -12771,7 +12567,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, "dependencies": { "p-locate": "^5.0.0" }, @@ -12786,7 +12581,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, "dependencies": { "yocto-queue": "^0.1.0" }, @@ -12801,7 +12595,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, "dependencies": { "p-limit": "^3.0.2" }, @@ -12816,7 +12609,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -12841,20 +12633,17 @@ "node_modules/react-error-overlay": { "version": "6.0.11", "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", - "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==", - "dev": true + "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" }, "node_modules/react-fast-compare": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", - "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==", - "dev": true + "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==" }, "node_modules/react-helmet-async": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-1.3.0.tgz", "integrity": "sha512-9jZ57/dAn9t3q6hneQS0wukqC2ENOBgMNVEhb/ZG9ZSxUetzVIw4iAmEU38IaVg3QGYauQPhSeUTuIUtFglWpg==", - "dev": true, "dependencies": { "@babel/runtime": "^7.12.5", "invariant": "^2.2.4", @@ -12947,7 +12736,6 @@ "version": "5.5.2", "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-5.5.2.tgz", "integrity": "sha512-A3dYjdBGuy0IGT+wyLIGIKLRE+sAk1iNk0f1HjNDysO7u8lhL4N3VEm+FAubmJbAztn94F7MxBTPmnixbiyFdQ==", - "dev": true, "dependencies": { "@types/react": "*", "prop-types": "^15.6.2" @@ -12960,7 +12748,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/react-loadable-ssr-addon-v5-slorber/-/react-loadable-ssr-addon-v5-slorber-1.0.1.tgz", "integrity": "sha512-lq3Lyw1lGku8zUEJPDxsNm1AfYHBrO9Y1+olAYwpUJ2IGFBskM0DMKok97A6LWUpHm+o7IvQBOWu9MLenp9Z+A==", - "dev": true, "dependencies": { "@babel/runtime": "^7.10.3" }, @@ -13017,7 +12804,6 @@ "version": "5.3.4", "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", "integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==", - "dev": true, "dependencies": { "@babel/runtime": "^7.12.13", "history": "^4.9.0", @@ -13037,7 +12823,6 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/react-router-config/-/react-router-config-5.1.1.tgz", "integrity": "sha512-DuanZjaD8mQp1ppHjgnnUnyOlqYXZVjnov/JzFhjLEwd3Z4dYjMSnqrEzzGThH47vpCOqPPwJM2FtthLeJ8Pbg==", - "dev": true, "dependencies": { "@babel/runtime": "^7.1.2" }, @@ -13050,7 +12835,6 @@ "version": "5.3.4", "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.4.tgz", "integrity": "sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==", - "dev": true, "dependencies": { "@babel/runtime": "^7.12.13", "history": "^4.9.0", @@ -13133,7 +12917,6 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, "dependencies": { "picomatch": "^2.2.1" }, @@ -13144,14 +12927,12 @@ "node_modules/reading-time": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/reading-time/-/reading-time-1.5.0.tgz", - "integrity": "sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg==", - "dev": true + "integrity": "sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg==" }, "node_modules/rechoir": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", - "dev": true, "dependencies": { "resolve": "^1.1.6" }, @@ -13163,7 +12944,6 @@ "version": "2.2.3", "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", - "dev": true, "dependencies": { "minimatch": "^3.0.5" }, @@ -13175,7 +12955,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -13185,7 +12964,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -13196,14 +12974,12 @@ "node_modules/regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" }, "node_modules/regenerate-unicode-properties": { "version": "10.1.1", "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", - "dev": true, "dependencies": { "regenerate": "^1.4.2" }, @@ -13220,7 +12996,6 @@ "version": "0.15.2", "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", - "dev": true, "dependencies": { "@babel/runtime": "^7.8.4" } @@ -13229,7 +13004,6 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", - "dev": true, "dependencies": { "@babel/regjsgen": "^0.8.0", "regenerate": "^1.4.2", @@ -13246,7 +13020,6 @@ "version": "4.2.2", "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.2.tgz", "integrity": "sha512-PC5ZysNb42zpFME6D/XlIgtNGdTl8bBOCw90xQLVMpzuuubJKYDWFAEuUNc+Cn8Z8724tg2SDhDRrkVEsqfDMg==", - "dev": true, "dependencies": { "rc": "1.2.8" }, @@ -13258,7 +13031,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", - "dev": true, "dependencies": { "rc": "^1.2.8" }, @@ -13276,7 +13048,6 @@ "version": "0.9.1", "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", - "dev": true, "dependencies": { "jsesc": "~0.5.0" }, @@ -13288,7 +13059,6 @@ "version": "0.5.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", - "dev": true, "bin": { "jsesc": "bin/jsesc" } @@ -13335,7 +13105,6 @@ "version": "0.2.7", "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", - "dev": true, "engines": { "node": ">= 0.10" } @@ -13354,7 +13123,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/remark-emoji/-/remark-emoji-2.2.0.tgz", "integrity": "sha512-P3cj9s5ggsUvWw5fS2uzCHJMGuXYRb0NnZqYlNecewXt8QBU9n5vW3DUUKOhepS8F9CwdMx9B8a3i7pqFWAI5w==", - "dev": true, "dependencies": { "emoticon": "^3.2.0", "node-emoji": "^1.10.0", @@ -13365,7 +13133,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/remark-footnotes/-/remark-footnotes-2.0.0.tgz", "integrity": "sha512-3Clt8ZMH75Ayjp9q4CorNeyjwIxHFcTkaektplKGl2A1jNGEUey8cKL0ZC5vJwfcD5GFGsNLImLG/NGzWIzoMQ==", - "dev": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" @@ -13385,7 +13152,6 @@ "version": "1.6.22", "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-1.6.22.tgz", "integrity": "sha512-phMHBJgeV76uyFkH4rvzCftLfKCr2RZuF+/gmVcaKrpsihyzmhXjA0BEMDaPTXG5y8qZOKPVo83NAOX01LPnOQ==", - "dev": true, "dependencies": { "@babel/core": "7.12.9", "@babel/helper-plugin-utils": "7.10.4", @@ -13405,7 +13171,6 @@ "version": "7.12.9", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.9.tgz", "integrity": "sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ==", - "dev": true, "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/generator": "^7.12.5", @@ -13435,14 +13200,12 @@ "node_modules/remark-mdx/node_modules/@babel/helper-plugin-utils": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", - "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", - "dev": true + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==" }, "node_modules/remark-mdx/node_modules/@babel/plugin-syntax-jsx": { "version": "7.12.1", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.1.tgz", "integrity": "sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -13453,14 +13216,12 @@ "node_modules/remark-mdx/node_modules/convert-source-map": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" }, "node_modules/remark-mdx/node_modules/semver": { "version": "5.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, "bin": { "semver": "bin/semver" } @@ -13469,7 +13230,6 @@ "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -13478,7 +13238,6 @@ "version": "9.2.0", "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.0.tgz", "integrity": "sha512-vx2Z0vY+a3YoTj8+pttM3tiJHCwY5UFbYdiWrwBEbHmK8pvsPj2rtAX2BFfgXen8T39CJWblWRDT4L5WGXtDdg==", - "dev": true, "dependencies": { "bail": "^1.0.0", "extend": "^3.0.0", @@ -13496,7 +13255,6 @@ "version": "8.0.3", "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-8.0.3.tgz", "integrity": "sha512-E1K9+QLGgggHxCQtLt++uXltxEprmWzNfg+MxpfHsZlrddKzZ/hZyWHDbK3/Ap8HJQqYJRXP+jHczdL6q6i85Q==", - "dev": true, "dependencies": { "ccount": "^1.0.0", "collapse-white-space": "^1.0.2", @@ -13524,7 +13282,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/remark-squeeze-paragraphs/-/remark-squeeze-paragraphs-4.0.0.tgz", "integrity": "sha512-8qRqmL9F4nuLPIgl92XUuxI3pFxize+F1H0e/W3llTk0UsjJaj01+RrirkMw7P21RKe4X6goQhYRSvNWX+70Rw==", - "dev": true, "dependencies": { "mdast-squeeze-paragraphs": "^4.0.0" }, @@ -13542,7 +13299,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", - "dev": true, "dependencies": { "css-select": "^4.1.3", "dom-converter": "^0.2.0", @@ -13555,7 +13311,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "engines": { "node": ">=8" } @@ -13564,7 +13319,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", - "dev": true, "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.0.1", @@ -13580,7 +13334,6 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", - "dev": true, "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.2.0", @@ -13594,7 +13347,6 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "dev": true, "dependencies": { "domelementtype": "^2.2.0" }, @@ -13609,7 +13361,6 @@ "version": "2.8.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "dev": true, "dependencies": { "dom-serializer": "^1.0.1", "domelementtype": "^2.2.0", @@ -13623,7 +13374,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "dev": true, "funding": { "url": "https://github.com/fb55/entities?sponsor=1" } @@ -13632,7 +13382,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", - "dev": true, "funding": [ "https://github.com/fb55/htmlparser2?sponsor=1", { @@ -13651,7 +13400,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -13663,7 +13411,6 @@ "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", - "dev": true, "engines": { "node": ">=0.10" } @@ -13672,7 +13419,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -13681,7 +13427,6 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", "integrity": "sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==", - "dev": true, "engines": { "node": "*" } @@ -13689,8 +13434,7 @@ "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" }, "node_modules/resize-observer-polyfill": { "version": "1.5.1", @@ -13701,7 +13445,6 @@ "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -13739,7 +13482,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, "engines": { "node": ">=4" } @@ -13747,14 +13489,12 @@ "node_modules/resolve-pathname": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", - "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==", - "dev": true + "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" }, "node_modules/responselike": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==", - "dev": true, "dependencies": { "lowercase-keys": "^1.0.0" } @@ -13782,7 +13522,6 @@ "version": "0.13.1", "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", - "dev": true, "engines": { "node": ">= 4" } @@ -13791,7 +13530,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -13855,11 +13593,15 @@ "node": "*" } }, + "node_modules/robust-predicates": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", + "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==" + }, "node_modules/rtl-detect": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/rtl-detect/-/rtl-detect-1.1.2.tgz", - "integrity": "sha512-PGMBq03+TTG/p/cRB7HCLKJ1MgDIi07+QU1faSjiYRfmY5UsAttV9Hs08jDAHVwcOwmVLcSJkpwyfXszVjWfIQ==", - "dev": true + "integrity": "sha512-PGMBq03+TTG/p/cRB7HCLKJ1MgDIi07+QU1faSjiYRfmY5UsAttV9Hs08jDAHVwcOwmVLcSJkpwyfXszVjWfIQ==" }, "node_modules/rtlcss": { "version": "3.5.0", @@ -13941,7 +13683,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, "funding": [ { "type": "github", @@ -13960,11 +13701,15 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" + }, "node_modules/rxjs": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", - "dev": true, "dependencies": { "tslib": "^2.1.0" } @@ -13991,8 +13736,7 @@ "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/sanitize-filename": { "version": "1.6.3", @@ -14077,8 +13821,7 @@ "node_modules/sax": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", - "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==", - "dev": true + "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==" }, "node_modules/scheduler": { "version": "0.19.1", @@ -14093,7 +13836,6 @@ "version": "2.7.1", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", - "dev": true, "dependencies": { "@types/json-schema": "^7.0.5", "ajv": "^6.12.4", @@ -14111,7 +13853,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", - "dev": true, "dependencies": { "extend-shallow": "^2.0.1", "kind-of": "^6.0.0" @@ -14123,14 +13864,12 @@ "node_modules/select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", - "dev": true + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==" }, "node_modules/selfsigned": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", - "dev": true, "dependencies": { "@types/node-forge": "^1.3.0", "node-forge": "^1" @@ -14143,7 +13882,6 @@ "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -14158,7 +13896,6 @@ "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==", - "dev": true, "dependencies": { "semver": "^6.3.0" }, @@ -14170,7 +13907,6 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, "bin": { "semver": "bin/semver.js" } @@ -14179,7 +13915,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, "dependencies": { "yallist": "^4.0.0" }, @@ -14190,14 +13925,12 @@ "node_modules/semver/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/send": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "dev": true, "dependencies": { "debug": "2.6.9", "depd": "2.0.0", @@ -14221,7 +13954,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "dependencies": { "ms": "2.0.0" } @@ -14229,14 +13961,12 @@ "node_modules/send/node_modules/debug/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/send/node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true, "bin": { "mime": "cli.js" }, @@ -14247,14 +13977,12 @@ "node_modules/send/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/send/node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -14263,7 +13991,6 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "dev": true, "dependencies": { "randombytes": "^2.1.0" } @@ -14272,7 +13999,6 @@ "version": "6.1.5", "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.5.tgz", "integrity": "sha512-ijPFle6Hwe8zfmBxJdE+5fta53fdIY0lHISJvuikXB3VYFafRjMRpOffSPvCYsbKyBA7pvy9oYr/BT1O3EArlg==", - "dev": true, "dependencies": { "bytes": "3.0.0", "content-disposition": "0.5.2", @@ -14288,7 +14014,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -14298,7 +14023,6 @@ "version": "1.33.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -14307,7 +14031,6 @@ "version": "2.1.18", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", - "dev": true, "dependencies": { "mime-db": "~1.33.0" }, @@ -14319,7 +14042,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -14330,14 +14052,12 @@ "node_modules/serve-handler/node_modules/path-to-regexp": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.2.1.tgz", - "integrity": "sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==", - "dev": true + "integrity": "sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==" }, "node_modules/serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", - "dev": true, "dependencies": { "accepts": "~1.3.4", "batch": "0.6.1", @@ -14355,7 +14075,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "dependencies": { "ms": "2.0.0" } @@ -14364,7 +14083,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -14373,7 +14091,6 @@ "version": "1.6.3", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", - "dev": true, "dependencies": { "depd": "~1.1.2", "inherits": "2.0.3", @@ -14387,26 +14104,22 @@ "node_modules/serve-index/node_modules/inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", - "dev": true + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" }, "node_modules/serve-index/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/serve-index/node_modules/setprototypeof": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" }, "node_modules/serve-index/node_modules/statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -14415,7 +14128,6 @@ "version": "1.15.0", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "dev": true, "dependencies": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", @@ -14450,14 +14162,12 @@ "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" }, "node_modules/shallow-clone": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dev": true, "dependencies": { "kind-of": "^6.0.2" }, @@ -14468,14 +14178,12 @@ "node_modules/shallowequal": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", - "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", - "dev": true + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -14487,7 +14195,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, "engines": { "node": ">=8" } @@ -14496,7 +14203,6 @@ "version": "1.8.1", "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -14505,7 +14211,6 @@ "version": "0.8.5", "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", - "dev": true, "dependencies": { "glob": "^7.0.0", "interpret": "^1.0.0", @@ -14522,7 +14227,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -14532,7 +14236,6 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -14552,7 +14255,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -14599,7 +14301,6 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", - "dev": true, "dependencies": { "@polka/url": "^1.0.0-next.24", "mrmime": "^2.0.0", @@ -14612,8 +14313,7 @@ "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" }, "node_modules/sitemap": { "version": "7.1.1", @@ -14644,7 +14344,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, "engines": { "node": ">=8" } @@ -14669,7 +14368,6 @@ "version": "0.3.24", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", - "dev": true, "dependencies": { "faye-websocket": "^0.11.3", "uuid": "^8.3.2", @@ -14680,7 +14378,6 @@ "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, "bin": { "uuid": "dist/bin/uuid" } @@ -14689,7 +14386,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/sort-css-media-queries/-/sort-css-media-queries-2.1.0.tgz", "integrity": "sha512-IeWvo8NkNiY2vVYdPa27MCQiR0MN0M80johAYFVxWWXQ44KU84WNxjslwBHmc/7ZL2ccwkM7/e6S5aiKZXm7jA==", - "dev": true, "engines": { "node": ">= 6.3.0" } @@ -14698,7 +14394,6 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -14707,7 +14402,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -14716,7 +14410,6 @@ "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -14733,7 +14426,6 @@ "version": "1.1.5", "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==", - "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -14743,7 +14435,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", - "dev": true, "dependencies": { "debug": "^4.1.0", "handle-thing": "^2.0.0", @@ -14759,7 +14450,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", - "dev": true, "dependencies": { "debug": "^4.1.0", "detect-node": "^2.0.4", @@ -14772,21 +14462,18 @@ "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, "node_modules/stable": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", - "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility", - "dev": true + "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility" }, "node_modules/state-toggle": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.3.tgz", "integrity": "sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==", - "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -14796,7 +14483,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true, "engines": { "node": ">= 0.8" } @@ -14804,8 +14490,7 @@ "node_modules/std-env": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", - "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", - "dev": true + "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==" }, "node_modules/string_decoder": { "version": "1.3.0", @@ -14824,7 +14509,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -14883,7 +14567,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", - "dev": true, "dependencies": { "get-own-enumerable-property-symbols": "^3.0.0", "is-obj": "^1.0.1", @@ -14897,7 +14580,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, "dependencies": { "ansi-regex": "^6.0.1" }, @@ -14934,7 +14616,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -14943,7 +14624,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, "engines": { "node": ">=6" } @@ -14964,7 +14644,6 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.3.0.tgz", "integrity": "sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA==", - "dev": true, "dependencies": { "inline-style-parser": "0.1.1" } @@ -14982,7 +14661,6 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", "integrity": "sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==", - "dev": true, "dependencies": { "browserslist": "^4.21.4", "postcss-selector-parser": "^6.0.4" @@ -14994,6 +14672,11 @@ "postcss": "^8.2.15" } }, + "node_modules/stylis": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.4.tgz", + "integrity": "sha512-osIBl6BGUmSfDkyH2mB7EFvCJntXDrLhKjHTRj/rK6xLH0yuPrHULDRQzKokSOD4VoorhtKpfcfW1GAntu8now==" + }, "node_modules/sucrase": { "version": "3.35.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", @@ -15029,7 +14712,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -15041,7 +14723,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -15052,14 +14733,12 @@ "node_modules/svg-parser": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", - "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==", - "dev": true + "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==" }, "node_modules/svgo": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", - "dev": true, "dependencies": { "@trysound/sax": "0.2.0", "commander": "^7.2.0", @@ -15080,7 +14759,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true, "engines": { "node": ">= 10" } @@ -15089,7 +14767,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", - "dev": true, "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.0.1", @@ -15105,7 +14782,6 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", - "dev": true, "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.2.0", @@ -15119,7 +14795,6 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "dev": true, "dependencies": { "domelementtype": "^2.2.0" }, @@ -15134,7 +14809,6 @@ "version": "2.8.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "dev": true, "dependencies": { "dom-serializer": "^1.0.1", "domelementtype": "^2.2.0", @@ -15148,7 +14822,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "dev": true, "funding": { "url": "https://github.com/fb55/entities?sponsor=1" } @@ -15242,7 +14915,6 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "dev": true, "engines": { "node": ">=6" } @@ -15251,7 +14923,6 @@ "version": "5.27.0", "resolved": "https://registry.npmjs.org/terser/-/terser-5.27.0.tgz", "integrity": "sha512-bi1HRwVRskAjheeYl291n3JC4GgO/Ty4z1nVs5AAsmonJulGxpSektecnNedrwK9C7vpvVtcX3cw00VSLt7U2A==", - "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -15269,7 +14940,6 @@ "version": "5.3.10", "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", - "dev": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.20", "jest-worker": "^27.4.5", @@ -15303,7 +14973,6 @@ "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "dev": true, "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", @@ -15317,7 +14986,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dev": true, "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -15335,7 +15003,6 @@ "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -15350,7 +15017,6 @@ "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "dev": true, "bin": { "acorn": "bin/acorn" }, @@ -15361,14 +15027,12 @@ "node_modules/terser/node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" }, "node_modules/thenify": { "version": "3.3.1", @@ -15394,26 +15058,22 @@ "node_modules/thunky": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", - "dev": true + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" }, "node_modules/tiny-invariant": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", - "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==", - "dev": true + "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==" }, "node_modules/tiny-warning": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", - "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==", - "dev": true + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, "engines": { "node": ">=4" } @@ -15431,7 +15091,6 @@ "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==", - "dev": true, "engines": { "node": ">=6" } @@ -15440,7 +15099,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "dependencies": { "is-number": "^7.0.0" }, @@ -15466,7 +15124,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "dev": true, "engines": { "node": ">=0.6" } @@ -15475,7 +15132,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", - "dev": true, "engines": { "node": ">=6" } @@ -15489,14 +15145,12 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", "integrity": "sha512-YzQV+TZg4AxpKxaTHK3c3D+kRDCGVEE7LemdlQZoQXn0iennk10RsIoY6ikzAqJTc9Xjl9C1/waHom/J86ziAQ==", - "deprecated": "Use String.prototype.trim() instead", - "dev": true + "deprecated": "Use String.prototype.trim() instead" }, "node_modules/trim-trailing-lines": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz", "integrity": "sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ==", - "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -15506,7 +15160,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", - "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -15520,6 +15173,14 @@ "utf8-byte-length": "^1.0.1" } }, + "node_modules/ts-dedent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", + "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==", + "engines": { + "node": ">=6.10" + } + }, "node_modules/ts-interface-checker": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", @@ -15593,7 +15254,6 @@ "version": "2.19.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", - "dev": true, "engines": { "node": ">=12.20" }, @@ -15605,7 +15265,6 @@ "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" @@ -15618,7 +15277,6 @@ "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==", - "dev": true, "dependencies": { "is-typedarray": "^1.0.0" } @@ -15662,8 +15320,7 @@ "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" }, "node_modules/unescape": { "version": "1.0.1", @@ -15681,7 +15338,6 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz", "integrity": "sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==", - "dev": true, "dependencies": { "inherits": "^2.0.0", "xtend": "^4.0.0" @@ -15695,7 +15351,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", - "dev": true, "engines": { "node": ">=4" } @@ -15704,7 +15359,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "dev": true, "dependencies": { "unicode-canonical-property-names-ecmascript": "^2.0.0", "unicode-property-aliases-ecmascript": "^2.0.0" @@ -15717,7 +15371,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", - "dev": true, "engines": { "node": ">=4" } @@ -15726,7 +15379,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", - "dev": true, "engines": { "node": ">=4" } @@ -15735,7 +15387,6 @@ "version": "9.2.2", "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.2.tgz", "integrity": "sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ==", - "dev": true, "dependencies": { "bail": "^1.0.0", "extend": "^3.0.0", @@ -15753,7 +15404,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "dev": true, "dependencies": { "crypto-random-string": "^2.0.0" }, @@ -15765,7 +15415,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-2.0.3.tgz", "integrity": "sha512-f98yt5pnlMWlzP539tPc4grGMsFaQQlP/vM396b00jngsiINumNmsY8rkXjfoi1c6QaM8nQ3vaGDuoKWbe/1Uw==", - "dev": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" @@ -15788,7 +15437,6 @@ "version": "1.1.6", "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-1.1.6.tgz", "integrity": "sha512-cln2Mm1/CZzN5ttGK7vkoGw+RZ8VcUH6BtGbq98DDtRGquAAOXig1mrBQYelOwMXYS8rK+vZDyyojSjp7JX+Lg==", - "dev": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" @@ -15798,7 +15446,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==", - "dev": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" @@ -15808,7 +15455,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-3.1.0.tgz", "integrity": "sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA==", - "dev": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" @@ -15818,7 +15464,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/unist-util-remove/-/unist-util-remove-2.1.0.tgz", "integrity": "sha512-J8NYPyBm4baYLdCbjmf1bhPu45Cr1MWTm77qd9istEkzWpnN6O9tMsEbB2JhNnBCqGENRqEWomQ+He6au0B27Q==", - "dev": true, "dependencies": { "unist-util-is": "^4.0.0" }, @@ -15831,7 +15476,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-2.0.1.tgz", "integrity": "sha512-fDZsLYIe2uT+oGFnuZmy73K6ZxOPG/Qcm+w7jbEjaFcJgbQ6cqjs/eSPzXhsmGpAsWPkqZM9pYjww5QTn3LHMA==", - "dev": true, "dependencies": { "unist-util-visit": "^2.0.0" }, @@ -15844,7 +15488,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", - "dev": true, "dependencies": { "@types/unist": "^2.0.2" }, @@ -15857,7 +15500,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", - "dev": true, "dependencies": { "@types/unist": "^2.0.0", "unist-util-is": "^4.0.0", @@ -15872,7 +15514,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz", "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", - "dev": true, "dependencies": { "@types/unist": "^2.0.0", "unist-util-is": "^4.0.0" @@ -15886,7 +15527,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, "engines": { "node": ">= 10.0.0" } @@ -15904,7 +15544,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "dev": true, "engines": { "node": ">= 0.8" } @@ -15913,7 +15552,6 @@ "version": "1.0.13", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", - "dev": true, "funding": [ { "type": "opencollective", @@ -15943,7 +15581,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.1.0.tgz", "integrity": "sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw==", - "dev": true, "dependencies": { "boxen": "^5.0.0", "chalk": "^4.1.0", @@ -15971,7 +15608,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "engines": { "node": ">=8" } @@ -15980,7 +15616,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", - "dev": true, "dependencies": { "ansi-align": "^3.0.0", "camelcase": "^6.2.0", @@ -16002,7 +15637,6 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", - "dev": true, "engines": { "node": ">=6" }, @@ -16013,14 +15647,12 @@ "node_modules/update-notifier/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "node_modules/update-notifier/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -16034,7 +15666,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -16046,7 +15677,6 @@ "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==", - "dev": true, "engines": { "node": ">=10" }, @@ -16058,7 +15688,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", - "dev": true, "dependencies": { "string-width": "^4.0.0" }, @@ -16070,7 +15699,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -16112,7 +15740,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==", - "dev": true, "dependencies": { "loader-utils": "^2.0.0", "mime-types": "^2.1.27", @@ -16139,7 +15766,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dev": true, "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -16157,7 +15783,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", "integrity": "sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==", - "dev": true, "dependencies": { "prepend-http": "^2.0.0" }, @@ -16209,7 +15834,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", - "dev": true, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } @@ -16227,14 +15851,12 @@ "node_modules/utila": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==", - "dev": true + "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==" }, "node_modules/utility-types": { "version": "3.11.0", "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz", "integrity": "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==", - "dev": true, "engines": { "node": ">= 4" } @@ -16243,7 +15865,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "dev": true, "engines": { "node": ">= 0.4.0" } @@ -16268,14 +15889,12 @@ "node_modules/value-equal": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", - "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==", - "dev": true + "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==" }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "dev": true, "engines": { "node": ">= 0.8" } @@ -16284,7 +15903,6 @@ "version": "4.2.1", "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", - "dev": true, "dependencies": { "@types/unist": "^2.0.0", "is-buffer": "^2.0.0", @@ -16300,7 +15918,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.2.0.tgz", "integrity": "sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA==", - "dev": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" @@ -16310,7 +15927,6 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", - "dev": true, "dependencies": { "@types/unist": "^2.0.0", "unist-util-stringify-position": "^2.0.0" @@ -16330,7 +15946,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-6.0.1.tgz", "integrity": "sha512-zht+KASY3usTY5u2LgaNqn/Cd8MukxLGjdcZxT2ns5QzDmTFc4XoWBgC+C/na+sMRZTuVygQoMYwdcVjHnYIVw==", - "dev": true, "dependencies": { "axios": "^0.25.0", "joi": "^17.6.0", @@ -16349,7 +15964,6 @@ "version": "0.25.0", "resolved": "https://registry.npmjs.org/axios/-/axios-0.25.0.tgz", "integrity": "sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==", - "dev": true, "dependencies": { "follow-redirects": "^1.14.7" } @@ -16358,7 +15972,6 @@ "version": "2.4.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", - "dev": true, "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -16371,7 +15984,6 @@ "version": "1.7.3", "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", - "dev": true, "dependencies": { "minimalistic-assert": "^1.0.0" } @@ -16380,7 +15992,6 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-1.1.4.tgz", "integrity": "sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw==", - "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -16395,6 +16006,11 @@ "node": ">= 8" } }, + "node_modules/web-worker": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.3.0.tgz", + "integrity": "sha512-BSR9wyRsy/KOValMgd5kMyr3JzpdeoR9KVId8u5GVlTTAtNChlsE4yTxeY7zMdNSyOmoKBv8NH2qeRY9Tg+IaA==" + }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", @@ -16404,7 +16020,6 @@ "version": "5.89.0", "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.89.0.tgz", "integrity": "sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw==", - "dev": true, "dependencies": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.0", @@ -16451,7 +16066,6 @@ "version": "4.10.1", "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.1.tgz", "integrity": "sha512-s3P7pgexgT/HTUSYgxJyn28A+99mmLq4HsJepMPzu0R8ImJc52QNqaFYW1Z2z2uIb1/J3eYgaAWVpaC+v/1aAQ==", - "dev": true, "dependencies": { "@discoveryjs/json-ext": "0.5.7", "acorn": "^8.0.4", @@ -16478,7 +16092,6 @@ "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "dev": true, "bin": { "acorn": "bin/acorn" }, @@ -16490,7 +16103,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true, "engines": { "node": ">= 10" } @@ -16576,7 +16188,6 @@ "version": "5.3.3", "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz", "integrity": "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==", - "dev": true, "dependencies": { "colorette": "^2.0.10", "memfs": "^3.4.3", @@ -16599,7 +16210,6 @@ "version": "8.12.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -16615,7 +16225,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, "dependencies": { "fast-deep-equal": "^3.1.3" }, @@ -16626,14 +16235,12 @@ "node_modules/webpack-dev-middleware/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, "node_modules/webpack-dev-middleware/node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -16642,7 +16249,6 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", - "dev": true, "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", @@ -16661,7 +16267,6 @@ "version": "4.15.1", "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.1.tgz", "integrity": "sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA==", - "dev": true, "dependencies": { "@types/bonjour": "^3.5.9", "@types/connect-history-api-fallback": "^1.3.5", @@ -16720,7 +16325,6 @@ "version": "8.12.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -16736,7 +16340,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, "dependencies": { "fast-deep-equal": "^3.1.3" }, @@ -16747,14 +16350,12 @@ "node_modules/webpack-dev-server/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, "node_modules/webpack-dev-server/node_modules/schema-utils": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", - "dev": true, "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", @@ -16773,7 +16374,6 @@ "version": "8.16.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", - "dev": true, "engines": { "node": ">=10.0.0" }, @@ -16794,7 +16394,6 @@ "version": "5.10.0", "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", - "dev": true, "dependencies": { "clone-deep": "^4.0.1", "flat": "^5.0.2", @@ -16808,7 +16407,6 @@ "version": "3.2.3", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", - "dev": true, "engines": { "node": ">=10.13.0" } @@ -16817,7 +16415,6 @@ "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "dev": true, "bin": { "acorn": "bin/acorn" }, @@ -16829,7 +16426,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dev": true, "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -16847,7 +16443,6 @@ "version": "5.0.2", "resolved": "https://registry.npmjs.org/webpackbar/-/webpackbar-5.0.2.tgz", "integrity": "sha512-BmFJo7veBDgQzfWXl/wwYXr/VFus0614qZ8i9znqcl9fnEdiVkdbi0TedLQ6xAK92HZHDJ0QmyQ0fmuZPAgCYQ==", - "dev": true, "dependencies": { "chalk": "^4.1.0", "consola": "^2.15.3", @@ -16865,7 +16460,6 @@ "version": "0.7.4", "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "dev": true, "dependencies": { "http-parser-js": ">=0.5.1", "safe-buffer": ">=5.1.0", @@ -16879,7 +16473,6 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "dev": true, "engines": { "node": ">=0.8.0" } @@ -16897,7 +16490,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "dependencies": { "isexe": "^2.0.0" }, @@ -16912,7 +16504,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==", - "dev": true, "dependencies": { "string-width": "^5.0.1" }, @@ -16926,14 +16517,12 @@ "node_modules/wildcard": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", - "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", - "dev": true + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==" }, "node_modules/wrap-ansi": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", @@ -17009,7 +16598,6 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, "engines": { "node": ">=12" }, @@ -17026,7 +16614,6 @@ "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==", - "dev": true, "dependencies": { "imurmurhash": "^0.1.4", "is-typedarray": "^1.0.0", @@ -17037,14 +16624,12 @@ "node_modules/write-file-atomic/node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, "node_modules/ws": { "version": "7.5.9", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", - "dev": true, "engines": { "node": ">=8.3.0" }, @@ -17065,7 +16650,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", - "dev": true, "engines": { "node": ">=8" } @@ -17074,7 +16658,6 @@ "version": "1.6.11", "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz", "integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==", - "dev": true, "dependencies": { "sax": "^1.2.4" }, @@ -17086,7 +16669,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, "engines": { "node": ">=0.4" } @@ -17094,14 +16676,12 @@ "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "node_modules/yaml": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true, "engines": { "node": ">= 6" } @@ -17118,7 +16698,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, "engines": { "node": ">=10" }, @@ -17130,11 +16709,10 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==", - "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } } } -} \ No newline at end of file +} diff --git a/package.json b/package.json index 197370793b..8f87010853 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "@dfinity/agent": "^0.15.4", "@dfinity/candid": "^0.15.4", "@dfinity/principal": "^0.15.4", + "@docusaurus/theme-mermaid": "^2.4.3", "@floating-ui/react": "^0.26.9", "chart.js": "^3.8.0", "chartjs-plugin-datalabels": "^2.0.0", @@ -95,4 +96,4 @@ "last 1 safari version" ] } -} \ No newline at end of file +} diff --git a/plugins/utils/redirects.js b/plugins/utils/redirects.js index 3a34a9e9d5..c2b2f32461 100644 --- a/plugins/utils/redirects.js +++ b/plugins/utils/redirects.js @@ -137,7 +137,7 @@ const redirects = ` /docs/current/developer-docs/best-practices/* /docs/current/developer-docs/use-cases/:splat /docs/current/developer-docs/deploy/* /docs/current/developer-docs/production/:splat /docs/current/references/security/* /docs/current/developer-docs/security/security-best-practices/overview - /docs/current/tokenomics/nns/community-fund /docs/current/developer-docs/daos/nns/neurons-fund + /docs/current/tokenomics/nns/community-fund /docs/current/developer-docs/daos/nns/concepts/neurons-fund /docs/current/tokenomics/sns/* /docs/current/developer-docs/daos/sns/tokenomics/:splat /docs/developers-guide/cli-reference/* /docs/current/developer-docs/developer-tools/cli-tools/cli-reference/:splat /docs/developers-guide/concepts/* /docs/current/developer-docs/getting-started/overview-of-icp @@ -165,7 +165,7 @@ const redirects = ` /language-guide/ /docs/current/tutorials/developer-journey/level-0/intro-languages /docs/current/developer-docs/build/cdks/cdk-rs-dfinity/rust-quickstart /docs/current/developer-docs/backend/rust/ /docs/quickstart/network-quickstart.html /docs/current/developer-docs/getting-started/install/ - /docs/token-holders/nns-app-quickstart.html /docs/current/developer-docs/daos/nns/nns-app-quickstart + /docs/token-holders/nns-app-quickstart.html /docs/current/developer-docs/daos/nns/using-the-nns-dapp/nns-app-quickstart /developers-guide/quickstart.html /docs/current/tutorials/developer-journey/ /docs/current/tokenomics/identity-auth/auth-how-to /docs/current/developer-docs/identity/internet-identity/overview /docs/developers-guide/tutorials-intro.html /docs/current/tutorials/developer-journey/ @@ -391,10 +391,10 @@ const redirects = ` /docs/current/developer-docs/integrations/sns/managing/sns-asset-canister /docs/current/developer-docs/daos/sns/managing/sns-asset-canister /docs/current/developer-docs/integrations/sns/managing/managing-nervous-system-parameters /docs/current/developer-docs/daos/sns/managing/managing-nervous-system-parameters /docs/current/tokenomics/nns/nns-intro /docs/current/developer-docs/daos/nns/overview - /docs/current/tokenomics/token-holders/nns-app-quickstart /docs/current/developer-docs/daos/nns/nns-app-quickstart - /docs/current/tokenomics/nns/neurons-fund /docs/current/developer-docs/daos/nns/neurons-fund - /docs/current/tokenomics/nns/nns-staking-voting-rewards /docs/current/developer-docs/daos/nns/staking-voting-rewards - /docs/current/tokenomics/nns/proposal-requirements /docs/current/developer-docs/daos/nns/proposal-requirements + /docs/current/tokenomics/token-holders/nns-app-quickstart /docs/current/developer-docs/daos/nns/using-the-nns-dapp/nns-app-quickstart + /docs/current/tokenomics/nns/neurons-fund /docs/current/developer-docs/daos/nns/concepts/neurons-fund + /docs/current/tokenomics/nns/nns-staking-voting-rewards /docs/current/developer-docs/daos/nns/concepts/neurons/staking-voting-rewards + /docs/current/tokenomics/nns/proposal-requirements /docs/current/developer-docs/daos/nns/concepts/proposal-requirements /docs/current/tokenomics/index /docs/current/developer-docs/daos/overview /docs/current/tokenomics/ /docs/current/developer-docs/daos/overview /docs/current/developer-docs/integrations/multi-chain/user-faq /docs/current/developer-docs/multi-chain/faq/user-faq diff --git a/roadmap/roadmap.json b/roadmap/roadmap.json index 1a2f024495..abbd2b5c6c 100644 --- a/roadmap/roadmap.json +++ b/roadmap/roadmap.json @@ -47,7 +47,7 @@ "wiki": "", "docs": "", "eta": "", - "status": "", + "status": "in_progress", "is_community": false, "in_beta": false, "milestone_id": "Tokamak" @@ -84,7 +84,7 @@ "wiki": "", "docs": "", "eta": "", - "status": "in_progress", + "status": "deployed", "is_community": false, "in_beta": false, "milestone_id": "Stellarator" @@ -1016,31 +1016,18 @@ "description": "Today, users have to blindly trust AI models running on centralized servers with no visibility into how data is used and how AI models produce responses. Decentralized AI solves this problem by bringing the trustworthiness, security, verifiability, and resilience of smart contracts to AI applications.", "milestones": [ { - "name": "Onchain AI Inference and Training of Large Models", - "description": "In order to perform AI inference and training of large models on chain, smart contracts need a way to run compute- and memory-intensive computations on hardware such as GPUs. The main challenge of this milestone is to define a deterministic API for smart contracts to access and call GPUs. Additionally, AI-specialized subnets with GPU-enabled nodes need to be added to ICP.", - "milestone_id": "Gyrotron", + "name": "Onchain AI Inference of Larger Models", + "description": "In order to perform AI inference and training of larger models on chain, canister smart contracts need to run more compute- and memory-intensive workloads. This milestone expands the compute and memory capabilities of canisters and paves the way for future GPU hardware acceleration. A special focus is being placed on the developer experience by building tools to simplify writing AI applications.", + "milestone_id": "Ignition", "eta": null, "status": "future", "elements": [ { - "title": "Deterministic API for AI computations on GPU", - "overview": "API for smart contracts that allows them to run deterministic AI computations on GPUs. Requirement for GPU-based AI on chain.", - "description": "All computations running on chain need to be deterministic because they are replicated on multiple nodes and go through consensus. This requirement also applies to AI computations performed on GPUs. The goal of this feature is to design and implement an API that smart contracts can use to run deterministic AI computations on GPUs.", - "status": "", - "milestone_id": "Gyrotron", - "forum": "", - "proposal": "", - "wiki": "", - "docs": "", - "is_community": false, - "in_beta": false - }, - { - "title": "Tooling and libraries for developing AI smart contracts", - "overview": "Providing developer tooling and libraries for building AI smart contracts on ICP, reusing existing AI ecosystem tools wherever possible.", - "description": "Developers need tooling and libraries to implement AI smart contracts. Ideally, the existing AI ecosystem is reused as much as possible, but specialized tools and libraries might be needed for developing on-chain AI applications.", + "title": "API for AI computations", + "overview": "API for smart contracts that allows them to run hardware-accelerated AI computations. Initially, hardware acceleration will rely on the CPU, paving the way for GPU hardware acceleration in the future.", + "description": "AI computations are typically a graph of a large number of floating-point operations. Abstracting those operations into an API streamlines the development of AI applications, and paves the way to introduce optiizations to these specialized workload.", "status": "", - "milestone_id": "Gyrotron", + "milestone_id": "Ignition", "forum": "", "proposal": "", "wiki": "", @@ -1049,43 +1036,30 @@ "in_beta": false }, { - "title": "Public specification for GPU-enabled nodes", - "overview": "The ICP community needs to agree and adopt the hardware specification for replica nodes with GPUs.", - "description": "The ICP community needs to agree and adopt the hardware specification for replica nodes with GPUs.", + "title": "Wasm64 execution environment", + "overview": "The execution environment is lifted to Wasm64 with the benefit of a 64-bit address space and its much larger addressable memory, allowing developers to load larger models in main memory.", + "description": "The execution environment is lifted to Wasm64 with the benefit of a 64-bit address space and its much larger addressable memory.", "status": "", - "milestone_id": "Gyrotron", "forum": "", "proposal": "", "wiki": "", "docs": "", "is_community": false, - "in_beta": false + "in_beta": false, + "milestone_id": "Ignition" }, { - "title": "AI-specialized subnets with GPU-enabled nodes", - "overview": "AI-specialized subnets are created from nodes with GPUs and host AI smart contracts for training and inference of large models.", - "description": "AI-specialized subnets are created from nodes with GPUs and host AI smart contracts for training and inference of large models.", + "title": "Tooling and libraries for developing AI smart contracts", + "overview": "Providing developer tooling and libraries for building AI smart contracts on ICP, reusing existing AI ecosystem tools wherever possible.", + "description": "Developers need tooling and libraries to implement AI smart contracts. Ideally, the existing AI ecosystem is reused as much as possible, but specialized tools and libraries might be needed for developing on-chain AI applications.", "status": "", - "milestone_id": "Gyrotron", + "milestone_id": "Ignition", "forum": "", "proposal": "", "wiki": "", "docs": "", "is_community": false, "in_beta": false - }, - { - "title": "Wasm64 execution environment", - "overview": "The execution environment is lifted to Wasm64 with the benefit of a 64-bit address space and its much larger addressable memory.", - "description": "The execution environment is lifted to Wasm64 with the benefit of a 64-bit address space and its much larger addressable memory.", - "status": "", - "forum": "", - "proposal": "", - "wiki": "", - "docs": "", - "is_community": false, - "in_beta": false, - "milestone_id": "Gyrotron" } ] }, @@ -1098,7 +1072,7 @@ "elements": [ { "title": "Faster deterministic floating-point operations", - "overview": "Accelerating deterministic floating point computations in the Wasm engine.", + "overview": "Accelerating deterministic floating-point computations in the Wasm engine.", "description": "Floating point operations are crucial for AI inference. In order to run on chain inside a smart contract, these operations need to be deterministic. The goal of this feature is to optimize the part of the Wasm engine that makes these operations deterministic.", "status": "deployed", "forum": "", @@ -1176,6 +1150,32 @@ "docs": "", "is_community": false, "in_beta": false + }, + { + "title": "Public specification for GPU-enabled nodes", + "overview": "The ICP community needs to agree and adopt the hardware specification for replica nodes with GPUs.", + "description": "The ICP community needs to agree and adopt the hardware specification for replica nodes with GPUs.", + "status": "", + "milestone_id": "Ignition", + "forum": "", + "proposal": "", + "wiki": "", + "docs": "", + "is_community": false, + "in_beta": false + }, + { + "title": "AI-specialized subnets with GPU-enabled nodes", + "overview": "AI-specialized subnets are created from nodes with GPUs and host AI smart contracts for training and inference of large models.", + "description": "AI-specialized subnets are created from nodes with GPUs and host AI smart contracts for training and inference of large models.", + "status": "", + "milestone_id": "Ignition", + "forum": "", + "proposal": "", + "wiki": "", + "docs": "", + "is_community": false, + "in_beta": false } ] } @@ -1215,7 +1215,7 @@ "wiki": "", "docs": "", "eta": "", - "status": "", + "status": "upcoming", "is_community": false, "in_beta": false, "milestone_id": "Helium" @@ -3653,8 +3653,8 @@ "proposal": "", "wiki": "", "docs": "", - "eta": "2024-06-12", - "status": "in_progress", + "eta": "2024-08-28", + "status": "deployed", "is_community": true, "in_beta": false, "milestone_id": "Beryllium", @@ -3669,7 +3669,7 @@ "wiki": "", "docs": "", "eta": "", - "status": "upcoming", + "status": "in_progress", "is_community": true, "in_beta": false, "milestone_id": "Beryllium", diff --git a/showcase.json b/showcase.json index 001f5de468..977147e1e1 100644 --- a/showcase.json +++ b/showcase.json @@ -4885,17 +4885,17 @@ }, { "id": "cyclestransferstation", - "name": "Cycles Transfer Station", - "oneLiner": "An on-chain order-book market trade platform for ICRC-1 tokens on the world-computer.", + "name": "CYCLES-TRANSFER-STATION", + "oneLiner": "An on-chain order-book market, where the market tokens trade against the stable CYCLES. Mint, hold, transfer, and trade the CYCLES at the CTS market.", "tags": [ "DeFi", "DAO" ], - "website": "https://cycles-transfer-station.com/", - "description": "An on-chain order-book market trade platform for ICRC-1 tokens on the world-computer.", + "website": "https://cycles-transfer-station.com", + "description": "The CYCLES-TRANSFER-STATION is an on-chain order-book market trade platform for ICRC-1 tokens on the world-computer. The key is that the market tokens trade against the native CYCLES, creating a stable trading scenario, and facilitating the general trade of the CYCLES.", "usesInternetIdentity": true, "display": "Normal", - "logo": "/img/showcase/waterneuron_logo.png" + "logo": "/img/showcase/cyclestransferstation_logo.png" }, { "id": "relation", diff --git a/sidebars.js b/sidebars.js index 7b87a3c2de..9a145a013b 100644 --- a/sidebars.js +++ b/sidebars.js @@ -399,6 +399,7 @@ const sidebars = { type: "category", label: "Advanced dfx workflows", items: [ + "developer-docs/developer-tools/cli-tools/advanced-dfx/check-chunk-store", "developer-docs/developer-tools/cli-tools/advanced-dfx/dfx-migration", "developer-docs/developer-tools/cli-tools/advanced-dfx/init-args", "developer-docs/developer-tools/cli-tools/advanced-dfx/networks-json", @@ -1113,33 +1114,48 @@ const sidebars = { { type: "category", label: "Using the NNS dapp", - items: ["developer-docs/daos/nns/nns-app-quickstart"], - }, - { - type: "category", - label: "Neurons", items: [ - "developer-docs/daos/nns/neuron-management", - "developer-docs/daos/nns/staking-voting-rewards", + "developer-docs/daos/nns/using-the-nns-dapp/nns-app-quickstart", + "developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-send-and-receive-tokens", + "developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-staking-a-neuron", + "developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-voting-on-proposals", + "developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-following-other-neurons", + "developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-advanced-neuron-operations", + "developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-manage-quill-neurons", + "developer-docs/daos/nns/using-the-nns-dapp/nns-dapp-additional-features", ], }, - "developer-docs/daos/nns/neurons-fund", { type: "category", - label: "Proposals", + label: "Concepts", items: [ - "developer-docs/daos/nns/proposal-overview", - "developer-docs/daos/nns/proposal-lifecycle", - "developer-docs/daos/nns/proposal-voting", - { - type: "category", - label: "Advanced", - items: ["developer-docs/daos/nns/proposal-advanced"], - }, - ], - }, + { + type: "category", + label: "Neurons", + items: [ + "developer-docs/daos/nns/concepts/neurons/neuron-overview", + "developer-docs/daos/nns/concepts/neurons/neuron-following", + "developer-docs/daos/nns/concepts/neurons/staking-voting-rewards", + "developer-docs/daos/nns/concepts/neurons/neuron-management", + "developer-docs/daos/nns/concepts/neurons/becoming-a-known-neuron", + ], + }, + { + type: "category", + label: "Proposals", + items: [ + "developer-docs/daos/nns/concepts/proposals/proposal-overview", + "developer-docs/daos/nns/concepts/proposals/direct-voting", + "developer-docs/daos/nns/concepts/proposals/proposal-topics", + "developer-docs/daos/nns/concepts/proposals/verify-proposals", + "developer-docs/daos/nns/concepts/proposals/proposal-submit", + ], + }, + "developer-docs/daos/nns/concepts/neurons-fund", ], }, + ], + }, { type: "category", label: "Service Nervous System (SNS)", @@ -1439,6 +1455,113 @@ const sidebars = { ], }, ], +devjourney: [ + { + type: "category", + label: "Developer Journey", + link: { + type: "doc", + id: "tutorials/developer-journey/index", + }, + items: [ + { + type: "category", + label: "Level 0: Pre-flight operations", + items: [ + "tutorials/developer-journey/level-0/ic-overview", + "tutorials/developer-journey/level-0/ic-terms", + "tutorials/developer-journey/level-0/dev-env", + "tutorials/developer-journey/level-0/intro-canisters", + "tutorials/developer-journey/level-0/intro-languages", + "tutorials/developer-journey/level-0/intro-dfx", + ], + }, + { + type: "category", + label: "Level 1: Space cadet", + items: [ + "tutorials/developer-journey/level-1/1.1-live-demo", + "tutorials/developer-journey/level-1/1.2-motoko-lvl1", + "tutorials/developer-journey/level-1/1.3-first-dapp", + "tutorials/developer-journey/level-1/1.4-using-cycles", + "tutorials/developer-journey/level-1/1.5-deploying-canisters", + "tutorials/developer-journey/level-1/1.6-managing-canisters", + ], + }, + { + type: "category", + label: "Level 2: Space explorer", + items: [ + "tutorials/developer-journey/level-2/2.1-storage-persistence", + "tutorials/developer-journey/level-2/2.2-advanced-canister-calls", + "tutorials/developer-journey/level-2/2.3-third-party-canisters", + "tutorials/developer-journey/level-2/2.4-intro-candid", + "tutorials/developer-journey/level-2/2.5-unit-testing", + "tutorials/developer-journey/level-2/2.6-motoko-lvl2", + ], + }, + { + type: "category", + label: "Level 3: Space engineer", + items: [ + "tutorials/developer-journey/level-3/3.1-package-managers", + "tutorials/developer-journey/level-3/3.2-https-outcalls", + "tutorials/developer-journey/level-3/3.3-certified-data", + "tutorials/developer-journey/level-3/3.4-intro-to-agents", + "tutorials/developer-journey/level-3/3.5-identities-and-auth", + "tutorials/developer-journey/level-3/3.6-motoko-lvl3", + ], + }, + { + type: "category", + label: "Level 4: Space pilot", + items: [ + "tutorials/developer-journey/level-4/4.1-icp-ledger", + "tutorials/developer-journey/level-4/4.2-icrc-tokens", + "tutorials/developer-journey/level-4/4.3-ckbtc-and-bitcoin", + "tutorials/developer-journey/level-4/4.4-nns-governance", + "tutorials/developer-journey/level-4/4.5-using-quill", + "tutorials/developer-journey/level-4/4.6-motoko-lvl4", + ], + }, + { + type: "category", + label: "Level 5: Internet Computer astronaut", + items: [ + "tutorials/developer-journey/level-5/5.1-vetKeys-tutorial", + "tutorials/developer-journey/level-5/5.2-ICP-ETH-tutorial", + "tutorials/developer-journey/level-5/5.3-token-swap-tutorial", + "tutorials/developer-journey/level-5/5.4-NFT-tutorial", + "tutorials/developer-journey/level-5/5.5-auction-tutorial", + "tutorials/developer-journey/level-5/5.6-next-steps", + ], + }, + ], + }, +], + +hackathon: [ + { + type: "category", + label: "Hackathon prep course", + link: { + type: "doc", + id: "tutorials/hackathon-prep-course/index", + }, + items: [ + "tutorials/hackathon-prep-course/what-is-icp", + "tutorials/hackathon-prep-course/deploying-first-fullstack-dapp", + "tutorials/hackathon-prep-course/exploring-the-backend", + "tutorials/hackathon-prep-course/exploring-the-frontend", + "tutorials/hackathon-prep-course/integrating-with-tokens", + "tutorials/hackathon-prep-course/authentication", + "tutorials/hackathon-prep-course/obtaining-cycles", + "tutorials/hackathon-prep-course/managing-canisters", + "tutorials/hackathon-prep-course/sample-starter-projects", + "tutorials/hackathon-prep-course/resources", + ], + }, +], rust: [ { type: "category", @@ -1461,6 +1584,7 @@ const sidebars = { "developer-docs/backend/rust/rust-considerations", "developer-docs/backend/rust/timers", "developer-docs/backend/rust/stable-structures", + "developer-docs/backend/rust/rust-limitations", "developer-docs/backend/rust/samples", ], }, diff --git a/src/components/BitcoinIntegrationPage/News/index.tsx b/src/components/BitcoinIntegrationPage/News/index.tsx index a6b7e74ace..0b1795c42c 100644 --- a/src/components/BitcoinIntegrationPage/News/index.tsx +++ b/src/components/BitcoinIntegrationPage/News/index.tsx @@ -46,51 +46,122 @@ function News({ content = "btc" }) {
-
- + ) : ( +
- Bitcoin 2024 Conference - -
-
-

- Jul 25 - 27 |Nashville, - Tennessee -

+ + Bitcoin 2024 Conference + +
+
+

+ Jul 25 - 27 |Nashville, + Tennessee +

-

- Bitcoin Nashville -

+

+ Bitcoin Nashville +

-

- With the upcoming Halvening, 2024 is shaping up to be the - biggest year for bitcoin yet. We are building out core - neighborhoods & content tracks to accelerate - hyperbitcoinizatioin across multiple vectors. -

- - Register now - +

+ With the upcoming Halvening, 2024 is shaping up to be the + biggest year for bitcoin yet. We are building out core + neighborhoods & content tracks to accelerate + hyperbitcoinizatioin across multiple vectors. +

+ + Register now + +
-
+ )}
+ {content === "chainfusion" && ( + <> + + + + + + + + ICP integration helped activate Bitcoin economy.`, + url: "https://medium.com/dfinity/everything-bitcoin-on-icp-dive-into-projects-building-with-native-btc-integration-f9557476a209", + imageUrl: + "https://miro.medium.com/v2/resize:fit:1400/format:webp/0*tGEIQD9N9vuk4bEW", + }} + linkLabel="Read Now" + clampText + /> + + + )} - - {" "} - - - {" "} - + {content === "chainfusion" ? ( + <> + ) : ( + <> + + {" "} + + + {" "} + + + )}
); diff --git a/src/components/ChainfusionPage/CodeSnippets.tsx b/src/components/ChainfusionPage/CodeSnippets.tsx new file mode 100644 index 0000000000..c6037b042d --- /dev/null +++ b/src/components/ChainfusionPage/CodeSnippets.tsx @@ -0,0 +1,197 @@ +import React from "react"; +import TabItem from "@theme/TabItem"; +import { AdornedTabs } from "../Tabs/AdornedTabs"; +// import { Link } from "@docusaurus/Link"; +// import { Link } from "@tanstack/router"; +import { motion, AnimatePresence } from "framer-motion"; +// import { Link } from "@tanstack/router"; +import Link from "@docusaurus/Link"; + +import LinkArrowRight from "../Common/Icons/LinkArrowRight"; +import LinkArrowDown from "../Common/Icons/LinkArrowDown"; +import LinkArrowUp from "../Common/Icons/LinkArrowUp"; + + +// import LinkArrowRight from "@theme/LinkArrowRight"; +// import LinkArrowDown from "@theme/LinkArrowDown"; +// import LinkArrowUp from "@theme/LinkArrowUp"; +// import CodeBlockString from "@theme/CodeBlockString"; +import CodeBlockString from "@site/src/theme/CodeBlock/Content/String"; + + +export interface CodeSnippetsProps {} + +const sampleCodeSnippets: Record = { + motoko: ` + import evm "ic:a6d44-nyaaa-aaaap-abp7q-cai"; + import ic "ic:aaaaa-aa"; + import Cycles "mo:base/ExperimentalCycles"; + import Timer "mo:base/Timer"; + + actor { + let EVM_FEE = 1000; + let BITCOIN_FEE = 1000; + + func check_evm_log() : async () { + Cycles.add(EVM_FEE); + let log = await evm.eth_getLogs( + #EthMainnet(null), + null, + { + addresses = ["address"]; + fromBlock = ? #Finalized; + toBlock = ? #Finalized; + topics = ?[["topic1", "topic2"]]; + }, + ); + switch log { + case (#Consistent(#Ok(_))) { + await send_bitcoin(); + }; + case _ {}; + }; + }; + + func send_bitcoin() : async () { + Cycles.add(BITCOIN_FEE); + await ic.bitcoin_send_transaction({ + transaction = "\\be\\ef"; + network = #testnet; + }); + }; + + let _ = Timer.setTimer(#seconds 2, check_evm_log); + }; + `, + rust: ` + #![allow(non_snake_case, clippy::large_enum_variant, clippy::enum_variant_names)] + use std::time::Duration; + use candid::{self, CandidType, Deserialize, Principal}; + + pub const SCRAPING_LOGS_INTERVAL: Duration = Duration::from_secs(3 * 60); + + fn setup_timers() { + ic_cdk_timers::set_timer(Duration::ZERO, || ic_cdk::spawn(check_evm_log())); + ic_cdk_timers::set_timer_interval(SCRAPING_LOGS_INTERVAL, || ic_cdk::spawn(check_evm_log())); + } + + #[ic_cdk::init] + fn init() { + setup_timers(); + } + + async fn check_evm_log() { + let cycles = 10_000_000_000; + let canister_id = Principal::from_text("a6d44-nyaaa-aaaap-abp7q-cai").expect("principal should be valid"); + let (result,) = ic_cdk::api::call::call_with_payment128::< + (RpcServices, Option, GetLogsArgs), + (MultiGetLogsResult,), + >( + canister_id, + "eth_getLogs", + ( + RpcServices::EthMainnet(None), + None, + GetLogsArgs { + fromBlock: Some(BlockTag::Finalized), + toBlock: Some(BlockTag::Finalized), + addresses: vec!["dummy_address".to_string()], + topics: Some(vec![vec!["topic1".to_string()], vec!["topic2".to_string()]]), + }, + ), + cycles, + ) + .await + .expect("Call failed"); + + match result { + MultiGetLogsResult::Consistent(_) => send_bitcoin().await, + MultiGetLogsResult::Inconsistent(_) => { + panic!("RPC providers gave inconsistent results") + } + } + } + + async fn send_bitcoin() { + ic_cdk::api::management_canister::bitcoin::bitcoin_send_transaction( + ic_cdk::api::management_canister::bitcoin::SendTransactionRequest { + transaction: b"beef".into(), + network: ic_cdk::api::management_canister::bitcoin::BitcoinNetwork::Testnet, + }, + ) + .await + .expect("Call failed"); + } + `, +}; + +export function CodeSnippets() { + const [isCodeSnippetExpanded, toggleCodeSnippetExpand] = React.useState(false); + + return ( +
+ + + {/* + + Deploy the contract in the online editor + */} + + + + + + + + + {sampleCodeSnippets.motoko} + + + +
+ + {sampleCodeSnippets.rust} + +
+ +
+
+
+ + + toggleCodeSnippetExpand(!isCodeSnippetExpanded)} + > + {isCodeSnippetExpanded ? ( + <> + Hide + + ) : ( + <> + Expand + + )} + + +
+
+
+ ); +} diff --git a/src/components/DocsHome/AskAIWidget.tsx b/src/components/DocsHome/AskAIWidget.tsx index f8cf50655e..b16f48cab1 100644 --- a/src/components/DocsHome/AskAIWidget.tsx +++ b/src/components/DocsHome/AskAIWidget.tsx @@ -49,22 +49,8 @@ export function AskAIWidget() { (isDocsPage || currentPath === "/") && ( // AI chatbot integration via Kapa <> - -