From d2ec6f6e466dbbecc4efd965d601394a88ac060a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 28 Nov 2024 09:25:31 +0000 Subject: [PATCH] deploy: eddcc1d732acaa28d9c31c1365b3e112a151f805 --- 404.html | 8 ++++---- Assignments/assignment1/index.html | 8 ++++---- Assignments/assignment2/index.html | 8 ++++---- Assignments/index.html | 8 ++++---- Assignments/project/index.html | 8 ++++---- Lectures/Introduction/index.html | 8 ++++---- Lectures/index.html | 8 ++++---- .../basic_wallet/index.html | 10 +++++----- .../discovery_node/index.html | 10 +++++----- .../Basic Peer-to-Peer Blockchain/index.html | 10 +++++----- .../mining/index.html | 10 +++++----- .../p2p_network/index.html | 10 +++++----- .../sources/index.html | 10 +++++----- .../terminal/index.html | 10 +++++----- .../transactions/index.html | 10 +++++----- .../what_we_build/index.html | 10 +++++----- .../why_golang/index.html | 10 +++++----- Practical Sessions/Env Setup/index.html | 10 +++++----- Practical Sessions/Env Setup/setup/index.html | 10 +++++----- .../Explorer/Block Leader/leader/index.html | 10 +++++----- .../Blockchain Observers/observers/index.html | 10 +++++----- .../validators/index.html | 10 +++++----- Practical Sessions/Explorer/Blocks/index.html | 10 +++++----- .../Consensus Grup/consensus/index.html | 10 +++++----- .../devnet_testnet/index.html | 10 +++++----- .../Time in Blockchain/time/index.html | 10 +++++----- .../Explorer/Transactions/index.html | 10 +++++----- Practical Sessions/Explorer/index.html | 10 +++++----- .../Learning Rust/cryptozombies/index.html | 18 ++++++++++++++++++ Practical Sessions/Learning Rust/index.html | 16 ++++++++++++++++ .../Learning Rust/rust/index.html | 16 ++++++++++++++++ .../Learning Rust/tour-of-rust/index.html | 18 ++++++++++++++++++ Practical Sessions/Money (DeFi)/index.html | 8 ++++---- .../Money (DeFi)/mint_tokens/index.html | 8 ++++---- .../Money (DeFi)/swap/index.html | 8 ++++---- Practical Sessions/Observer/index.html | 10 +++++----- .../Smart Contract Events/events/index.html | 10 +++++----- .../Smart Contract Events/index.html | 10 +++++----- .../Smart Contracts/adder/index.html | 10 +++++----- .../Smart Contracts/cargo_deploy/index.html | 10 +++++----- .../Smart Contracts/empty/index.html | 10 +++++----- Practical Sessions/Smart Contracts/index.html | 10 +++++----- .../Smart Contracts/mxpy_deploy/index.html | 10 +++++----- .../Smart Contracts/mxpy_sc_call/index.html | 10 +++++----- .../Smart Contracts/neversea/index.html | 12 ++++++------ .../Smart Contracts/prerequisites/index.html | 10 +++++----- .../rust_interactors/index.html | 10 +++++----- .../Tokens/fungible-non-fungible/index.html | 10 +++++----- Practical Sessions/Tokens/fungible/index.html | 10 +++++----- Practical Sessions/Tokens/index.html | 10 +++++----- Practical Sessions/Tokens/nft/index.html | 10 +++++----- Practical Sessions/Tokens/standards/index.html | 10 +++++----- .../Cmd line wallet/cmdline_wallet/index.html | 10 +++++----- Practical Sessions/Wallet/Keystore/index.html | 10 +++++----- Practical Sessions/Wallet/Wallet/index.html | 10 +++++----- .../Wallet/browser_wallet/index.html | 10 +++++----- Practical Sessions/Wallet/faucet/index.html | 10 +++++----- Practical Sessions/Wallet/index.html | 10 +++++----- Practical Sessions/Wallet/send_tx/index.html | 10 +++++----- Practical Sessions/index.html | 10 +++++----- assets/js/24730e6e.9b558ace.js | 1 + assets/js/6cba850a.bd0c1791.js | 1 + assets/js/6d865e2f.5c803d27.js | 1 + assets/js/6d865e2f.828e8735.js | 1 - ...df453d.5b6d4205.js => 85df453d.be6e0c4d.js} | 2 +- assets/js/89c345ad.2b9f518c.js | 1 + assets/js/935f2afb.71502fe1.js | 1 + assets/js/935f2afb.ca51ee0c.js | 1 - assets/js/e9cf5841.b66efdba.js | 1 + assets/js/main.54505205.js | 2 ++ ...ICENSE.txt => main.54505205.js.LICENSE.txt} | 0 assets/js/main.f0dbef01.js | 2 -- assets/js/runtime~main.29610d3d.js | 1 - assets/js/runtime~main.6c740d9c.js | 1 + grading/index.html | 8 ++++---- index.html | 8 ++++---- markdown-page/index.html | 8 ++++---- resources/index.html | 8 ++++---- sitemap.xml | 2 +- 79 files changed, 366 insertions(+), 294 deletions(-) create mode 100644 Practical Sessions/Learning Rust/cryptozombies/index.html create mode 100644 Practical Sessions/Learning Rust/index.html create mode 100644 Practical Sessions/Learning Rust/rust/index.html create mode 100644 Practical Sessions/Learning Rust/tour-of-rust/index.html create mode 100644 assets/js/24730e6e.9b558ace.js create mode 100644 assets/js/6cba850a.bd0c1791.js create mode 100644 assets/js/6d865e2f.5c803d27.js delete mode 100644 assets/js/6d865e2f.828e8735.js rename assets/js/{85df453d.5b6d4205.js => 85df453d.be6e0c4d.js} (56%) create mode 100644 assets/js/89c345ad.2b9f518c.js create mode 100644 assets/js/935f2afb.71502fe1.js delete mode 100644 assets/js/935f2afb.ca51ee0c.js create mode 100644 assets/js/e9cf5841.b66efdba.js create mode 100644 assets/js/main.54505205.js rename assets/js/{main.f0dbef01.js.LICENSE.txt => main.54505205.js.LICENSE.txt} (100%) delete mode 100644 assets/js/main.f0dbef01.js delete mode 100644 assets/js/runtime~main.29610d3d.js create mode 100644 assets/js/runtime~main.6c740d9c.js diff --git a/404.html b/404.html index 51e2d337..4c5fe515 100644 --- a/404.html +++ b/404.html @@ -4,13 +4,13 @@ Page Not Found | Blockchain Protocols and Distributed Applications - - + +
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

- - + + \ No newline at end of file diff --git a/Assignments/assignment1/index.html b/Assignments/assignment1/index.html index 4c26c39b..0ffa4265 100644 --- a/Assignments/assignment1/index.html +++ b/Assignments/assignment1/index.html @@ -4,8 +4,8 @@ Trading Card Games | Blockchain Protocols and Distributed Applications - - + +
@@ -13,7 +13,7 @@ the available NFTs' data stored in the SC. This should allow a user of your API to then trade a NFT they own with one of the NFTs which is stored inside the contract. This NFT must exactly match the class, power and rarity attributes.

A complete flow would look like this.

Assignment Tasks

1. Setup Environment

2. Interacting with the Smart Contract

Core Interactions

Note

You can also deploy the homework's SC for local testing.

How do I know if I have successfully finished the homework?

The homework is done if, at the end of the aforementioned flow, you have a BPDA-TRADING-CARD NFT in your MultiversX wallet. Any further attempts to call the functions getYourNftCardProperties or exchangeNFT will result in a SC error with the following message: Congratulations! You already finished the homework!.

3. Frontend Application (BONUS 1)

Develop a simple front-end (React or other frameworks) that allows users to interact with the smart contract through a web interface.

The front-end should:

4. Bug Hunting (BONUS 2)

Present a reproducible way of exploiting the SC or generating unwanted behavior.

Grading Criteria

Note: The fact that you show the lab assistant the SC NFT inside your wallet is not enough. You will be asked questions based on your code for each task.

Notes

Useful Resources

- - + + \ No newline at end of file diff --git a/Assignments/assignment2/index.html b/Assignments/assignment2/index.html index 64915c81..a0286a03 100644 --- a/Assignments/assignment2/index.html +++ b/Assignments/assignment2/index.html @@ -4,13 +4,13 @@ assignment2 | Blockchain Protocols and Distributed Applications - - + +
Skip to main content
- - + + \ No newline at end of file diff --git a/Assignments/index.html b/Assignments/index.html index 9470ec8f..0aa50f31 100644 --- a/Assignments/index.html +++ b/Assignments/index.html @@ -4,13 +4,13 @@ Assignments | Blockchain Protocols and Distributed Applications - - + +
Skip to main content
- - + + \ No newline at end of file diff --git a/Assignments/project/index.html b/Assignments/project/index.html index f823f399..e455ffac 100644 --- a/Assignments/project/index.html +++ b/Assignments/project/index.html @@ -4,8 +4,8 @@ Semester Project | Blockchain Protocols and Distributed Applications - - + +
@@ -15,7 +15,7 @@ Deadline: Wednesday, 17 January 2024, 11:59 PM

List of ideas

You can choose one of the idea below or you can create one of your own.

Infrastructure & Developers Tooling

Idea nameDescription
Cross chain Bridgebuild a cross-chain bridge that enables the secure and seamless transfer of assets between different blockchain networks, enhancing interoperability and expanding the utility of blockchain ecosystems.
Wallet as a servicecreate a solution so that companies can seamlessly integrate wallet functionalities directly into their applications, simplifying user onboarding to the ease of a username and password. Whether facilitating in-game asset trading for gamers or pioneering innovative token-based loyalty programs, WaaS represents a potent resource for enterprises seeking to unlock the full potential of the web3 ecosystem.
Data analyticscreate data analytics tools and platforms tailored for blockchain and DeFI data, offering insights, visualization, and predictive analytics to empower developers and users.
Decentralized storage solutiondesign a decentralized storage solution that leverages blockchain technology for secure and distributed data storage, catering to the needs of decentralized applications and services.
Gas profiling tooldeveloping a gas profiling tool that helps Multiversx developers optimize gas usage in their smart contracts, reducing transaction costs and enhancing overall efficiency.
Digital identity solutioncreate a decentralized digital identity solution that allows users to manage and control their identities securely, offering privacy and data ownership in the digital realm.
Smart contract simulatorbuild a smart contract simulator that enables developers to test and analyze the behavior of their smart contracts in various scenarios before deploying them on the blockchain, enhancing code reliability.
EVM compatible sharddevelop an Ethereum Virtual Machine (EVM)-compatible shard
Blockchains for everybodyNot everybody owns a smart phone or a laptop. How can they interact with the blockchain?

Mobile Apps

Idea nameDescription
Multi-chain WalletDevelop a cross chain user-friendly mobile wallet app that allows users to store, manage, and transact with cryptocurrencies securely. The app should also support decentralized applications (DApps) and DeFi services.
Tokenized Digital Collectiblescreate a mobile app that specializes in collecting, trading, and showcasing blockchain-based digital collectibles and NFTs. Users would be able to explore, discover, and interact with a wide range of digital art, assets, and unique collectibles, all securely stored on the blockchain. The app would offer features such as buying, selling, and trading NFTs, creating an engaging platform for collectors and enthusiasts to connect and showcase their prized digital possessions.
Fitness companionutilizes blockchain for secure data storage, tokenized rewards, and decentralized fitness challenges, creating a motivating and privacy-focused ecosystem for users to achieve their fitness goals. Users can also make seamless cryptocurrency payments to fitness professionals and collect fitness-related NFTs to celebrate their accomplishments within the community.
NFT Ticket mastermobile app that disrupts traditional ticketing by using blockchain and NFTs. It empowers event organizers to issue verifiable and tradable NFT-based tickets, enhancing security and ownership, while attendees enjoy the convenience of secure mobile ticketing and a resale marketplace for tickets.
Quest Mastermobile app that lets groups of three or more users create and join challenges, with each participant contributing tokens to a prize pool. To claim the prize, all participants must reach a consensus that a task has been successfully completed, creating a fun and interactive way to collaborate and compete while using blockchain for transparency and rewards
Tokenized Real Estate Investment PlatformAn app that democratizes real estate investment by allowing users to invest in fractional ownership of properties using blockchain tokens. Users can buy, sell, and trade real estate tokens, making property investment more accessible.
Crypto Savings and Investment AppA user-friendly mobile app that simplifies cryptocurrency savings and investments. It could offer features like automated recurring investments, yield farming, and tracking portfolios, all while utilizing blockchain for transparency and security.
Blockchain-Backed Supply Chain TrackerAn app that allows consumers to trace the journey of products from the source to their hands. Users can scan QR codes to access information about the product's origin, quality, and authenticity, all recorded on the blockchain.
Blockchain-Powered Voting AppA mobile app for secure and transparent voting in elections, referendums, or decision-making processes. Blockchain technology ensures the integrity of votes and provides accessible and verifiable election results.
Blockchain-Powered Voting AppAn app that connects freelancers and clients on a blockchain platform. Smart contracts ensure secure and automatic payment upon project completion, and reputation systems build trust within the freelance community.

Artificial Intelligence

Idea nameDescription
Smart IDE'sIDE that incorporates advanced AI capabilities to enhance the coding experience. This intelligent IDE provides real-time code assistance, predictive suggestions, bug detection, code optimization, and even supports real-time collaboration, significantly improving developer productivity and code quality. It's a powerful tool that leverages AI to make coding more efficient, intuitive, and collaborative.
AI-Powered documentationThe IDE generates documentation and comments based on code, making it easier to maintain and understand codebases.
Security AnalysisAI algorithms continuously analyze code for potential vulnerabilities and provide security recommendations.
Code GenerationThe IDE can generate boilerplate code, common functions, and even entire code segments based on high-level descriptions or user requirements, speeding up the development process.
Generative AI in gamesintegrate advanced AI algorithms that dynamically generate game content, such as levels, characters, and narratives. This innovation creates ever-changing and immersive gaming experiences, providing players with endless challenges and adventures, all driven by the power of AI.
AI agents interactionsa product where AI-powered agents autonomously handle and optimize various types of blockchain transactions, including transfers of assets, smart contract executions, and consensus participation. These AI agents enhance the efficiency, security, and reliability of blockchain interactions, enabling a new and innovative way to study blockchains interactions and why not testing principles.
Chain behavior predictionsBuild an AI-driven platform that predicts the behavior of various blockchain networks based on historical data and current trends. Users can leverage these predictions to make informed decisions when participating in cross-chain transactions or asset swaps.
3D Generated worldsThe integration of blockchain technology ensures secure ownership of digital assets, including virtual land, creatures, and resources, empowering users to explore, interact, trade, and collaborate within this vibrant and blockchain-enhanced 3D universe.

Payments

Idea nameDescription
MicropaymentsExplore groundbreaking solutions that leverage blockchain technology to enable microtransactions. You will delve into the possibilities of frictionless, low-cost micropayments for various use cases, such as content monetization, pay-as-you-go services, and micro-donations
Scheduled paymentsDevelop blockchain-based solutions that enable automated and scheduled transactions. You will explore innovative ways to leverage blockchain technology for seamless and secure scheduled payments, benefiting a wide range of applications, from recurring bills and salary payments to subscription services.
Fund raising platformsDesign blockchain-powered fundraising platforms that redefine how funds are raised, tracked, and allocated for various causes. By leveraging blockchain's transparency and security, you can create efficient, decentralized solutions that enhance the fundraising process and foster trust among donors and fundraisers, ultimately driving social impact and positive change
Cross-Chain paymentsThis idea aims to bridge the gap between different blockchain networks, allowing users to seamlessly transfer and transact digital assets across multiple blockchains. This idea seeks to simplify the process of conducting cross-chain transactions, enhancing interoperability and accessibility in the blockchain ecosystem. It holds the potential to revolutionize the way we move and use cryptocurrencies and tokens across various blockchain platforms, ultimately making blockchain technology more versatile and user-friendly.
No-Code solution for grandmas and grandpasThis idea challenges you to create a no-code blockchain interaction solution that is so user-friendly it can be effortlessly used by individuals of all ages and backgrounds. The primary focus is to streamline the onboarding process for merchants, enabling them to accept MVX tokens with ease through features like simplified wallet setup, integrated point-of-sale systems, and user-friendly interfaces. By fostering inclusivity and accessibility, you can envision a future where blockchain technology is as accessible as everyday mobile devices, revolutionizing the way we engage with digital assets.
Fast pay solutionsThis idea challenges you to revolutionize digital payments by seamlessly integrating QR code scanning with blockchain technology, offering innovative solutions that prioritize user-friendliness and security. This track empowers you to shape the future of financial transactions, bridging the gap between traditional payment methods and the decentralized world of blockchain, ultimately enhancing accessibility and usability for users worldwide.
Payments for all tokensWhat if you have USDC and the merchants accepts only BUSD? Come up with a solution without the need to go through the additional step of converting their tokens on a swapping platform before finalizing their payment for the intended purchase.
NFT Payments solutionsExplore ways to integrate non-fungible tokens (NFTs) into payment systems. You should devise a payment solution that incorporates NFTs for unique, valuable, or collectible transactions.
Programmable money"Although money itself isn't inherently programmable, its full potential can be unlocked through automation and purpose-built tools. This presents an opportunity to create open-source, fee-free, and publicly accessible programs that can harness the power of money and on-chain tokens more effectively.

For example: Facilitating the seamless processing of invoices within a smart contract filled with funds. Person A submits an invoice, and person B can sign an approval transaction to release the funds to the appropriate recipient." | | Loyalty and Rewards Programs | Create a blockchain-based loyalty and rewards program that allows businesses to issue and manage loyalty points or tokens on a blockchain. You should focus on enhancing customer engagement and retention. |

Gaming and Metaverse

Idea nameDescription
Blockchain Gaming EconomyDescription: Develop a comprehensive blockchain-based gaming economy that integrates cryptocurrencies, non-fungible tokens (NFTs), and decentralized exchanges. This challenge involves designing in-game assets, marketplaces, and economic systems that empower players to buy, sell, and trade virtual items and currency securely on the blockchain.
Decentralized Game DevelopmentDescription: Create a decentralized game development platform that allows game creators to collaborate transparently while utilizing blockchain technology for asset ownership and revenue sharing. This challenge encourages teams to design tools and frameworks that foster a community-driven approach to game creation.
Blockchain-Based Game VerificationDescription: Build a system or tool that verifies the authenticity of in-game assets by utilizing blockchain technology. This verification system should ensure that assets, such as characters, weapons, or collectibles, are legitimate and cannot be tampered with, enhancing player trust and security.
In-game advertising platformDescription: Construct an innovative in-game advertising platform that seamlessly integrates advertisements into gaming experiences. This platform should offer targeted and non-disruptive advertising solutions that benefit both advertisers and players while ensuring transparency and fair compensation for developers.
Generative AI in a gameDescription: Integrate generative artificial intelligence (AI) techniques into a game to dynamically generate content such as levels, quests, or narratives. You should leverage AI algorithms to create engaging and ever-evolving gaming experiences that adapt to player behavior.
Generative AI in trailers/videos/tutorialsDescription: Utilize generative AI to automate the creation of game trailers, promotional videos, or tutorial content. This challenge encourages You to develop AI systems that can efficiently generate high-quality multimedia content for games and user guidance purposes.
Game PluginsDescription: Design and develop a set of plugins or extensions for existing game engines or platforms. These plugins should enhance game development workflows, improve performance, or add new features, making it easier for developers to create games across various genres.
Sample gamesDescription: Create sample games that serve as templates or starting points for aspiring game developers. These games should cover different genres and showcase best practices in game design, coding, and user experience.
Game templatesDescription: Develop a library of game templates that provide pre-designed frameworks for specific game types or mechanics. These templates should include customizable assets, code templates, and documentation, enabling developers to kickstart their game projects more efficiently.
- - + + \ No newline at end of file diff --git a/Lectures/Introduction/index.html b/Lectures/Introduction/index.html index 22c7a7a6..7f9a2e56 100644 --- a/Lectures/Introduction/index.html +++ b/Lectures/Introduction/index.html @@ -4,13 +4,13 @@ Introduction | Blockchain Protocols and Distributed Applications - - + +
Skip to main content
- - + + \ No newline at end of file diff --git a/Lectures/index.html b/Lectures/index.html index f5b0cf51..70772614 100644 --- a/Lectures/index.html +++ b/Lectures/index.html @@ -4,13 +4,13 @@ Lectures | Blockchain Protocols and Distributed Applications - - + +
Skip to main content
- - + + \ No newline at end of file diff --git a/Practical Sessions/Basic Peer-to-Peer Blockchain/basic_wallet/index.html b/Practical Sessions/Basic Peer-to-Peer Blockchain/basic_wallet/index.html index 3b592cc1..30ffe807 100644 --- a/Practical Sessions/Basic Peer-to-Peer Blockchain/basic_wallet/index.html +++ b/Practical Sessions/Basic Peer-to-Peer Blockchain/basic_wallet/index.html @@ -4,14 +4,14 @@ Basic Wallet | Blockchain Protocols and Distributed Applications - - + +
-
Skip to main content

Basic Wallet

To create a public key with which we can display our financial gain in the internet we need first to generate a private key using an algorithm, the private key will generate the public key and…from now on we can apply a hash on it and remove some character from behind and add 0x in front to know that this is a public address.

+

Basic Wallet

To create a public key with which we can display our financial gain in the internet we need first to generate a private key using an algorithm, the private key will generate the public key and…from now on we can apply a hash on it and remove some character from behind and add 0x in front to know that this is a public address.

/function to create a public and private key
func CreateKeyPair() (crypto.PrivKey, crypto.PubKey, error) {
// Create a private and public key pair
priv, pub, err := crypto.GenerateKeyPair(crypto.RSA, 2048)
if err != nil {
return nil, nil, err
}

return priv, pub, nil
}

func CreatePairPublicPrivateKey() ([]byte, []byte) {

//create a private and public key
priv, pub, err := CreateKeyPair()
if err != nil {
panic(err)
}

//convert private key to bytes
privBytes, err := crypto.MarshalPrivateKey(priv)
if err != nil {
panic(err)
}

//convert public key to bytes
pubBytes, err := crypto.MarshalPublicKey(pub)
if err != nil {
panic(err)
}

//list of bytes to string
privString := hex.EncodeToString(privBytes)
pubString := hex.EncodeToString(pubBytes)

//create a wallet variable
wallet := types.Wallet{
PrivateKey: []byte(privString),
PublicKey: []byte(pubString),
}
//convert wallet to bytes marshal
walletBytes, _ := json.Marshal(wallet)

//put wallet in the db
fileop.PutInDB("db/usr", []byte("wallet1"), walletBytes)

return []byte(pubString), []byte(privString)

}

For generating privateKey and publicKey we will use RSA because is very common and is easy to understand then we store the data into a wallet struct and the struct will be stored on our local storage.

So well we will mine a block we will get the first transaction from coinbase

{"BlockNumber":0,
"Time":1668970059,
"Hash":"06c6836e73c1676d58f938fd17a91224b50e5de97623dcc80c4f48d6eb96e052",
"Inputs":[{"Txid":0,"Value":1,"Signature":"","PubKey":"coinbase"}],
"Outputs":[{"Txid":0,"Value":1,"PubKeyHash":"0x2432\n","Signature":""}]
}

Every input and output transactions will be signed, so this will be saw by everyone from the blockchain, we will cache this on our wallet because we will be easy when we want to create a transaction.

In bitcoin there isn’t the idea of a balance like having 200 bitcoin, when you send a transaction you also send how you get that money.(we can see how the money where spent.

Our wallet when is creating transaction 3 will say the input from transaction1 and transaction2 and the the outputs like in the json above.

Here is an example of a real bitcoin transaction. Also you signed with your private key what you send to the other peers.


{
"txid": "1b3cb78e7d6cad2cc2050e6dccc2bd5845e98f598062d19fbda8e0a3b5b4b0e6",
"hash": "9d046215268a1d8031c6b4835a68c9c8c6984b576dc82ec37f859e636ec6e660",
"version": 1,
"size": 368,
"vsize": 341,
"weight": 1364,
"locktime": 1064830807,
"vin": [
{
"coinbase": "039ea80b2cfabe6d6df2adbfb95872a2c4bf41bd0af61255f06bc31f0aa11d1c2b11fe673f0a94af3e10000000f09f909f092f4632506f6f6c2f73000000000000000000000000000000000000000000000000000000000000000000000005001d000000",
"txinwitness": [
"0000000000000000000000000000000000000000000000000000000000000000"
],
"sequence": 0
}
],
"vout": [
{
"value": 6.28864092,
"n": 0,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 c825a1ecf2a6830c4401620c3a16f1995057c2ab OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a914c825a1ecf2a6830c4401620c3a16f1995057c2ab88ac",
"address": "1KFHE7w8BhaENAswwryaoccDb6qcT6DbYY",
"type": "pubkeyhash"
}
},
{
"value": 0,
"n": 1,
"scriptPubKey": {
"asm": "OP_RETURN aa21a9ed7c2862196195aa9d4d8b947653d3548ffe4c111d5669a6ec2c96f12f91672884",
"hex": "6a24aa21a9ed7c2862196195aa9d4d8b947653d3548ffe4c111d5669a6ec2c96f12f91672884",
"type": "nulldata"
}
},
{
"value": 0,
"n": 2,
"scriptPubKey": {
"asm": "OP_RETURN 48617468cd302e8d060f04304c01afa1fd1a73a8538f6eee545aa1c0a97e54fa4db86856",
"hex": "6a2448617468cd302e8d060f04304c01afa1fd1a73a8538f6eee545aa1c0a97e54fa4db86856",
"type": "nulldata"
}
},
{
"value": 0,
"n": 3,
"scriptPubKey": {
"asm": "OP_RETURN 52534b424c4f434b3a8350e01a86adc281c624fc5e9e1ba740ac5c1a38c0413a51b5ab342800498b80",
"hex": "6a4c2952534b424c4f434b3a8350e01a86adc281c624fc5e9e1ba740ac5c1a38c0413a51b5ab342800498b80",
"type": "nulldata"
}
}
]
}

This is our code for the signing of the transactions.

func SingUsingKey(privateKey []byte, publicKey []byte, data []byte) []byte {
if GetPrivateKeyAndValidatePublicKey(publicKey) {
//decode private key
privKeyBytes, _ := hex.DecodeString(string(privateKey))
//unmarshal private key
privKey, err := crypto.UnmarshalPrivateKey(privKeyBytes)
if err != nil {
log.Printf("Error unmarshalling private key: %s", err)
return nil
}

//sign data
signature, err := privKey.Sign(data)
if err != nil {
log.Printf("Error signing data: %s", err)
return nil
}

return signature

} else {
fmt.Println("Public key does not match private key")
return nil
}

}

func VerifySign(signature []byte, publicKey []byte, data []byte) bool {

pubKey, err := crypto.UnmarshalPublicKey(publicKey)
if err != nil {
log.Printf("Error unmarshalling public key: %s", err)
return false
}

//verify signature
verify, err := pubKey.Verify(data, signature)
if err != nil {
return false
}

return verify
}

- - + + \ No newline at end of file diff --git a/Practical Sessions/Basic Peer-to-Peer Blockchain/discovery_node/index.html b/Practical Sessions/Basic Peer-to-Peer Blockchain/discovery_node/index.html index 2148b393..85e4926f 100644 --- a/Practical Sessions/Basic Peer-to-Peer Blockchain/discovery_node/index.html +++ b/Practical Sessions/Basic Peer-to-Peer Blockchain/discovery_node/index.html @@ -4,16 +4,16 @@ What is a discovery node? | Blockchain Protocols and Distributed Applications - - + +
-

What is a discovery node?

In the context of Libp2p in Golang, a "discovery node" typically refers to a node that participates in a discovery process to find and connect to other peers in the network. Discovery is an essential aspect of decentralized systems, as it allows nodes to discover and establish connections with their peers dynamically.

Libp2p provides a set of discovery mechanisms, and a discovery node is a peer that actively participates in these mechanisms. These mechanisms help nodes find each other by disseminating information about the network's topology.

Here are some common discovery mechanisms in Libp2p:

MDNS (Multicast DNS): This is a protocol that allows nodes on a local network to discover each other without relying on a centralized server. Nodes announce their presence on the network, and others can listen for these announcements. +

What is a discovery node?

In the context of Libp2p in Golang, a "discovery node" typically refers to a node that participates in a discovery process to find and connect to other peers in the network. Discovery is an essential aspect of decentralized systems, as it allows nodes to discover and establish connections with their peers dynamically.

Libp2p provides a set of discovery mechanisms, and a discovery node is a peer that actively participates in these mechanisms. These mechanisms help nodes find each other by disseminating information about the network's topology.

Here are some common discovery mechanisms in Libp2p:

MDNS (Multicast DNS): This is a protocol that allows nodes on a local network to discover each other without relying on a centralized server. Nodes announce their presence on the network, and others can listen for these announcements.

Bootstrap Nodes: These are well-known nodes that act as initial points of contact for new nodes entering the network. New nodes can connect to these bootstrap nodes to discover other peers in the network.

DHT (Distributed Hash Table): Libp2p uses a DHT to store and retrieve information about peers in a decentralized manner. Nodes in the network can query the DHT to discover the addresses of other peers.

The role of a discovery node is to participate in one or more of these mechanisms, helping peers find each other and establish connections in a decentralized way. This is crucial for the robustness and scalability of decentralized systems, as it enables nodes to adapt to changes in the network's topology dynamically.

- - + + \ No newline at end of file diff --git a/Practical Sessions/Basic Peer-to-Peer Blockchain/index.html b/Practical Sessions/Basic Peer-to-Peer Blockchain/index.html index 3708808a..1f12c76d 100644 --- a/Practical Sessions/Basic Peer-to-Peer Blockchain/index.html +++ b/Practical Sessions/Basic Peer-to-Peer Blockchain/index.html @@ -4,13 +4,13 @@ Basic Peer-to-Peer Blockchain | Blockchain Protocols and Distributed Applications - - + +
-

Basic Peer-to-Peer Blockchain

- - +

Basic Peer-to-Peer Blockchain

+ + \ No newline at end of file diff --git a/Practical Sessions/Basic Peer-to-Peer Blockchain/mining/index.html b/Practical Sessions/Basic Peer-to-Peer Blockchain/mining/index.html index 77017f97..17a61c49 100644 --- a/Practical Sessions/Basic Peer-to-Peer Blockchain/mining/index.html +++ b/Practical Sessions/Basic Peer-to-Peer Blockchain/mining/index.html @@ -4,13 +4,13 @@ Mining a block | Blockchain Protocols and Distributed Applications - - + +
-

Mining a block

In this tutorial we will use the most simple and basic way to mine a block.We will use proof of work.

sha256("0xs2rgi3p4jfbt43hrjweafwefwff"+0)="t09q3pfoewjaiougt80u9ropijdd"
sha256("0dnoirihp32u823u42o324rwfadsq"+1)="981r03q2ipfout8403qrp2ojiht"
sha256("8q349pjrofioh83409prjfdsfaeoi"+2)="802394qrpjiu58u93q4ropjohir"
sha256("9q0fwei0923rupi0u439rp034u9rr"+3)="fo9432ropeif43092oekr3op32r"
sha256("9r01fhewogr9u3jfeopijot0q49ru"+4)="f43epkfoij5t43pwelmfijwerk3"
sha256("t4280fhpibtqgh0w9pitq4ghgpit4"+5)="p9340ropjiot80932orit43jt09"
----------------------------------------------------------------------
//after a lot of iteration we will get to a hash that looks like this
----------------------------------------------------------------------
sha256("t4280fhpibtqgh0w9pitq4ghgpit4"+123)="000p9340ropjiot80932orit43jt09"
//we have some zeros in the front(we chose the number of zeros
//so this hash is valid

 Nonce is the solution to our problem

Proof of work is a computational method employed to arrive at a valid solution by repeatedly hashing data until a hash with a specific number of leading zeros is obtained. Achieving multiple leading zeros in a hash is a challenging and low-probability task.

Alt text

The idea that is present in the code above can expand more, what if we link the transactions with the block? — we concatenate all the content together and apply a hash function on all of them so we will get to a specific number of zeros and that block becomes valid.

In the bottom image we see what is our end goal…so the blocks need to be linked together ( to create a blockchain ). From the bottom image we see that the blocks are linked by the prev hash. And all the transaction are put in a Merkle tree then the root node is added to blockchain.

Alt text

This is the structure of a block.

//block struct
type Block struct {
//is the index of the block ex:0 ,1,2,3
Index int `json:"index"`
//time of the block when is mined
Timestamp int64 `json:"timestamp"`
//list of transaction, we will get here later
Tx [][]byte `json:"tx"`
//merkle root a byte of the merkle transaction tree
MerkleRoot []byte `json:merkle`
//hash of the prevblock
PrevHash string `json:"prevHash"`
//current hash of this block
Hash string `json:"hash"`
//nonce the number that we try to guess when we mine a block
Nonce int `json:"nonce"`
//this is the reward per block
Reward int `json:"reward"`
//this is the current coinbase of the network we grow as the network grows
Coinbase int `json:"coinbase"`
//the miner how mined the block
Miner string `json:"miner"`
}

func ProofOfWork(address string) types.Block {
getLastBlockKey := fileop.GetLastKey("db/blocks/blockchain")
if len(getLastBlockKey) == 0 {
if getLastBlockKey == nil {
//fmt.Println("Genesis:", string(getLastBlockKey))
//create genesis block
return CreateGenesisBlock(address)
}
}
newBlock := CreateBlock()
//get private and public key
_, privateKey := cryptogeneration.GetPublicPrivateKeys()
//create list of transaction
var tx []merkletree.Content
//get all transaction in levelDB
transaction := fileop.GetAllKeys("db/mempool/valide")
if len(transaction) != 0 {
//unmarshall transaction
for _, v := range transaction {
data := fileop.GetFromDB("db/mempool/valide", v)
transactionDB := types.Transaction{}
json.Unmarshal(data, &transactionDB)
transactionDB.BlockNumber = newBlock.Index
//add to list of transaction
tx = append(tx, transactionDB)
}
}

tx = append(tx, CreateTransaction(privateKey, address, nil, 100, 0, 0))

//create merkle tree
merkleTree, _ := merkle.BuildTree(tx)
listOfTransaction, RootNode := merkle.ExportLeafs(merkleTree)

newBlock.Tx = listOfTransaction
newBlock.MerkleRoot = RootNode
//reconstruct merkle tree from string
//merkleTree, _ := merkle.ReconstructTree(newBlock.Tx)
//get merkle tree from string

iterator := 0
for {
newBlock.Nonce = iterator
storeHash := CalculateHash(newBlock)
if storeHash[:2] == "00" {
//fmt.Println("Hash:", storeHash)
newBlock.Hash = storeHash
//clear db//mempool/valide
fileop.EraseAllKeys("db/mempool/valide")
//fmt.Println("proof_of_work_func:", newBlock)
return newBlock
break
}
iterator += 1
}

return types.Block{}
}

Well now we have this block mined so how we will send to other peers(because a blockchain is decentralized( not always)) ?

Up we speak about the channel that we will open to listen to data transfered in the network so… we will have a function that will send that to all the peers that we have stored in our local database.

func SendToAllPeers(node host.Host, data []byte, type_to_send int) {
//read from db all keys
number := fileop.GetNumberOfKeys("db/peers")
if number == 0 {
fmt.Println()
} else {

//get all keys from db/peers
//here we read all the data from the peers table and
//we send the block to every one of this peer
keys := fileop.GetAllKeys("db/peers")
fmt.Println("=================")
//for each key send message
for i := 0; i < len(keys); i++ {
fmt.Println(string(keys[i]))
}
fmt.Println("================")
//for each key convert to string
for i := 0; i < number; i++ {
peer_addres := string(keys[i])
//remove \n from string
//we need \n to read the characters to know where the row of data will end
peer_addres = peer_addres[:len(peer_addres)-1]
fmt.Println("Sending to peer: ", peer_addres)
if type_to_send == 0 {
//send to blocks channel
OpenConnectionMine(peer_addres, node, data)
} else if type_to_send == 1 {
//send to transaction channel
OpenConnectionTransaction(peer_addres, node, data)
}
}
}
}

Here is the the openConnectionMine function:


func OpenConnectionMine(peer_addres string, node host.Host, data []byte) {
//here we will get the address
addr, err := multiaddr.NewMultiaddr(peer_addres)
if err != nil {
println("Error: address format wrong1")
return
}
peer, err := peerstore.AddrInfoFromP2pAddr(addr)
if err != nil {
println("Error: address format wrong2")
return
}

if err := node.Connect(context.Background(), *peer); err != nil {
println("Error: connection failed")
return
}
//we send a block in this section that was mined
//we open a stream to that peer
stream, err := node.NewStream(context.Background(), peer.ID, "/mine/1.0.0")
if err != nil {
//print err
log.Fatal(err)
println("Error: stream creation failed")
return
}
fmt.Print("Sending message...")

//send string to stream
_, err = stream.Write(data)

if err != nil {
println("Error: message sending failed")
return
}
}
- - +

Mining a block

In this tutorial we will use the most simple and basic way to mine a block.We will use proof of work.

sha256("0xs2rgi3p4jfbt43hrjweafwefwff"+0)="t09q3pfoewjaiougt80u9ropijdd"
sha256("0dnoirihp32u823u42o324rwfadsq"+1)="981r03q2ipfout8403qrp2ojiht"
sha256("8q349pjrofioh83409prjfdsfaeoi"+2)="802394qrpjiu58u93q4ropjohir"
sha256("9q0fwei0923rupi0u439rp034u9rr"+3)="fo9432ropeif43092oekr3op32r"
sha256("9r01fhewogr9u3jfeopijot0q49ru"+4)="f43epkfoij5t43pwelmfijwerk3"
sha256("t4280fhpibtqgh0w9pitq4ghgpit4"+5)="p9340ropjiot80932orit43jt09"
----------------------------------------------------------------------
//after a lot of iteration we will get to a hash that looks like this
----------------------------------------------------------------------
sha256("t4280fhpibtqgh0w9pitq4ghgpit4"+123)="000p9340ropjiot80932orit43jt09"
//we have some zeros in the front(we chose the number of zeros
//so this hash is valid

 Nonce is the solution to our problem

Proof of work is a computational method employed to arrive at a valid solution by repeatedly hashing data until a hash with a specific number of leading zeros is obtained. Achieving multiple leading zeros in a hash is a challenging and low-probability task.

Alt text

The idea that is present in the code above can expand more, what if we link the transactions with the block? — we concatenate all the content together and apply a hash function on all of them so we will get to a specific number of zeros and that block becomes valid.

In the bottom image we see what is our end goal…so the blocks need to be linked together ( to create a blockchain ). From the bottom image we see that the blocks are linked by the prev hash. And all the transaction are put in a Merkle tree then the root node is added to blockchain.

Alt text

This is the structure of a block.

//block struct
type Block struct {
//is the index of the block ex:0 ,1,2,3
Index int `json:"index"`
//time of the block when is mined
Timestamp int64 `json:"timestamp"`
//list of transaction, we will get here later
Tx [][]byte `json:"tx"`
//merkle root a byte of the merkle transaction tree
MerkleRoot []byte `json:merkle`
//hash of the prevblock
PrevHash string `json:"prevHash"`
//current hash of this block
Hash string `json:"hash"`
//nonce the number that we try to guess when we mine a block
Nonce int `json:"nonce"`
//this is the reward per block
Reward int `json:"reward"`
//this is the current coinbase of the network we grow as the network grows
Coinbase int `json:"coinbase"`
//the miner how mined the block
Miner string `json:"miner"`
}

func ProofOfWork(address string) types.Block {
getLastBlockKey := fileop.GetLastKey("db/blocks/blockchain")
if len(getLastBlockKey) == 0 {
if getLastBlockKey == nil {
//fmt.Println("Genesis:", string(getLastBlockKey))
//create genesis block
return CreateGenesisBlock(address)
}
}
newBlock := CreateBlock()
//get private and public key
_, privateKey := cryptogeneration.GetPublicPrivateKeys()
//create list of transaction
var tx []merkletree.Content
//get all transaction in levelDB
transaction := fileop.GetAllKeys("db/mempool/valide")
if len(transaction) != 0 {
//unmarshall transaction
for _, v := range transaction {
data := fileop.GetFromDB("db/mempool/valide", v)
transactionDB := types.Transaction{}
json.Unmarshal(data, &transactionDB)
transactionDB.BlockNumber = newBlock.Index
//add to list of transaction
tx = append(tx, transactionDB)
}
}

tx = append(tx, CreateTransaction(privateKey, address, nil, 100, 0, 0))

//create merkle tree
merkleTree, _ := merkle.BuildTree(tx)
listOfTransaction, RootNode := merkle.ExportLeafs(merkleTree)

newBlock.Tx = listOfTransaction
newBlock.MerkleRoot = RootNode
//reconstruct merkle tree from string
//merkleTree, _ := merkle.ReconstructTree(newBlock.Tx)
//get merkle tree from string

iterator := 0
for {
newBlock.Nonce = iterator
storeHash := CalculateHash(newBlock)
if storeHash[:2] == "00" {
//fmt.Println("Hash:", storeHash)
newBlock.Hash = storeHash
//clear db//mempool/valide
fileop.EraseAllKeys("db/mempool/valide")
//fmt.Println("proof_of_work_func:", newBlock)
return newBlock
break
}
iterator += 1
}

return types.Block{}
}

Well now we have this block mined so how we will send to other peers(because a blockchain is decentralized( not always)) ?

Up we speak about the channel that we will open to listen to data transfered in the network so… we will have a function that will send that to all the peers that we have stored in our local database.

func SendToAllPeers(node host.Host, data []byte, type_to_send int) {
//read from db all keys
number := fileop.GetNumberOfKeys("db/peers")
if number == 0 {
fmt.Println()
} else {

//get all keys from db/peers
//here we read all the data from the peers table and
//we send the block to every one of this peer
keys := fileop.GetAllKeys("db/peers")
fmt.Println("=================")
//for each key send message
for i := 0; i < len(keys); i++ {
fmt.Println(string(keys[i]))
}
fmt.Println("================")
//for each key convert to string
for i := 0; i < number; i++ {
peer_addres := string(keys[i])
//remove \n from string
//we need \n to read the characters to know where the row of data will end
peer_addres = peer_addres[:len(peer_addres)-1]
fmt.Println("Sending to peer: ", peer_addres)
if type_to_send == 0 {
//send to blocks channel
OpenConnectionMine(peer_addres, node, data)
} else if type_to_send == 1 {
//send to transaction channel
OpenConnectionTransaction(peer_addres, node, data)
}
}
}
}

Here is the the openConnectionMine function:


func OpenConnectionMine(peer_addres string, node host.Host, data []byte) {
//here we will get the address
addr, err := multiaddr.NewMultiaddr(peer_addres)
if err != nil {
println("Error: address format wrong1")
return
}
peer, err := peerstore.AddrInfoFromP2pAddr(addr)
if err != nil {
println("Error: address format wrong2")
return
}

if err := node.Connect(context.Background(), *peer); err != nil {
println("Error: connection failed")
return
}
//we send a block in this section that was mined
//we open a stream to that peer
stream, err := node.NewStream(context.Background(), peer.ID, "/mine/1.0.0")
if err != nil {
//print err
log.Fatal(err)
println("Error: stream creation failed")
return
}
fmt.Print("Sending message...")

//send string to stream
_, err = stream.Write(data)

if err != nil {
println("Error: message sending failed")
return
}
}
+ + \ No newline at end of file diff --git a/Practical Sessions/Basic Peer-to-Peer Blockchain/p2p_network/index.html b/Practical Sessions/Basic Peer-to-Peer Blockchain/p2p_network/index.html index 5822dd9e..d69c8382 100644 --- a/Practical Sessions/Basic Peer-to-Peer Blockchain/p2p_network/index.html +++ b/Practical Sessions/Basic Peer-to-Peer Blockchain/p2p_network/index.html @@ -4,13 +4,13 @@ Peer to peer network | Blockchain Protocols and Distributed Applications - - + +
-

Peer to peer network

For this part we will use libp2p was used by the guys that build IPFS and Filecoin.

First we need to spawn a p2p node

func RunSourceNode() {
// start a libp2p node that listens on a random local TCP port,
// but without running the built-in ping protocol
node := CreateNode("/ip4/127.0.0.1/tcp/0")

// configure our own ping protocol
pingService := &ping.PingService{Host: node}
node.SetStreamHandler(ping.ID, pingService.PingHandler)

// print the node's PeerInfo in multiaddr format
peerInfo := peerstore.AddrInfo{
ID: node.ID(),
Addrs: node.Addrs(),
}
addrs, err := peerstore.AddrInfoToP2pAddrs(&peerInfo)
if err != nil {
panic(err)
}
fmt.Println("libp2p node address:", addrs[0])
//we need paralel interaction for this
go LogicNodeInteraction(node)

for {
//here will be our local terminal to interact with the blockchain
terminalview.TerminalView(node)
}

}

Here we spawn a basic peer to peer Node now we need a way to interact with the node and some logic to be able to communicate with the other blockchains.

Syncronise peers inside the network

So we have LogicNodeInteraction which will run in parallel with the terminal.

func LogicNodeInteraction(node host.Host) {
//Set stream handler for the "/hello/1.0.0" protocol
go node.SetStreamHandler("/transaction/1.0.0", func(s network.Stream) {
log.Printf("/transaction/1.0.0 stream created")
err := ReadTransactionProtocol(s)
if err != nil {
s.Reset()
} else {
s.Close()
}
})

go node.SetStreamHandler("/mine/1.0.0", func(s network.Stream) {
log.Printf("/mine/1.0.0 stream created")
err := ReadMineProtocol(s)
if err != nil {
log.Printf("Error: %s", err)
s.Reset()
} else {
log.Printf("Closing stream")
s.Close()
}
})

go node.SetStreamHandler("/messages/1.0.0", func(s network.Stream) {
log.Printf("/messages/1.0.0 stream created")
err := ReadMessagesProtocol(s)
if err != nil {
log.Printf("Error: %s", err)
s.Reset()
} else {
log.Printf("Closing stream")
s.Close()
}
})

}

Here we spawn 3 channels to listen for other peers(they need to send messages on one of this channels)

So what are they doing?

This will be out channel of communication between our nodes.

"/transaction/1.0.0" - is responsible for transaction, here is the way our transaction will be send

”/mine/1.0.0" — is responsible for the blocks that are mined, they will come from other nodes to this one ( here will come blocks that are valid and invalid form the other peers)

”/messages/1.0.0" — here will come diffrent messages about the network(transaction that are not valid…etc) (we will not enter into this)```
- - +

Peer to peer network

For this part we will use libp2p was used by the guys that build IPFS and Filecoin.

First we need to spawn a p2p node

func RunSourceNode() {
// start a libp2p node that listens on a random local TCP port,
// but without running the built-in ping protocol
node := CreateNode("/ip4/127.0.0.1/tcp/0")

// configure our own ping protocol
pingService := &ping.PingService{Host: node}
node.SetStreamHandler(ping.ID, pingService.PingHandler)

// print the node's PeerInfo in multiaddr format
peerInfo := peerstore.AddrInfo{
ID: node.ID(),
Addrs: node.Addrs(),
}
addrs, err := peerstore.AddrInfoToP2pAddrs(&peerInfo)
if err != nil {
panic(err)
}
fmt.Println("libp2p node address:", addrs[0])
//we need paralel interaction for this
go LogicNodeInteraction(node)

for {
//here will be our local terminal to interact with the blockchain
terminalview.TerminalView(node)
}

}

Here we spawn a basic peer to peer Node now we need a way to interact with the node and some logic to be able to communicate with the other blockchains.

Syncronise peers inside the network

So we have LogicNodeInteraction which will run in parallel with the terminal.

func LogicNodeInteraction(node host.Host) {
//Set stream handler for the "/hello/1.0.0" protocol
go node.SetStreamHandler("/transaction/1.0.0", func(s network.Stream) {
log.Printf("/transaction/1.0.0 stream created")
err := ReadTransactionProtocol(s)
if err != nil {
s.Reset()
} else {
s.Close()
}
})

go node.SetStreamHandler("/mine/1.0.0", func(s network.Stream) {
log.Printf("/mine/1.0.0 stream created")
err := ReadMineProtocol(s)
if err != nil {
log.Printf("Error: %s", err)
s.Reset()
} else {
log.Printf("Closing stream")
s.Close()
}
})

go node.SetStreamHandler("/messages/1.0.0", func(s network.Stream) {
log.Printf("/messages/1.0.0 stream created")
err := ReadMessagesProtocol(s)
if err != nil {
log.Printf("Error: %s", err)
s.Reset()
} else {
log.Printf("Closing stream")
s.Close()
}
})

}

Here we spawn 3 channels to listen for other peers(they need to send messages on one of this channels)

So what are they doing?

This will be out channel of communication between our nodes.

"/transaction/1.0.0" - is responsible for transaction, here is the way our transaction will be send

”/mine/1.0.0" — is responsible for the blocks that are mined, they will come from other nodes to this one ( here will come blocks that are valid and invalid form the other peers)

”/messages/1.0.0" — here will come diffrent messages about the network(transaction that are not valid…etc) (we will not enter into this)```
+ + \ No newline at end of file diff --git a/Practical Sessions/Basic Peer-to-Peer Blockchain/sources/index.html b/Practical Sessions/Basic Peer-to-Peer Blockchain/sources/index.html index a7ccf4fa..ae18fcba 100644 --- a/Practical Sessions/Basic Peer-to-Peer Blockchain/sources/index.html +++ b/Practical Sessions/Basic Peer-to-Peer Blockchain/sources/index.html @@ -4,16 +4,16 @@ Sources | Blockchain Protocols and Distributed Applications - - + +
-
- - + + \ No newline at end of file diff --git a/Practical Sessions/Basic Peer-to-Peer Blockchain/terminal/index.html b/Practical Sessions/Basic Peer-to-Peer Blockchain/terminal/index.html index c0ebbfc4..f71309ed 100644 --- a/Practical Sessions/Basic Peer-to-Peer Blockchain/terminal/index.html +++ b/Practical Sessions/Basic Peer-to-Peer Blockchain/terminal/index.html @@ -4,13 +4,13 @@ The terminal | Blockchain Protocols and Distributed Applications - - + +
-

The terminal

This terminal will be a way to interact with other nodes.l(“complete code will be available on github”)

func TerminalView(node host.Host) {
//print a menu with 8 options
//1. Create a new wallet
//2. View your wallet
//3. Send coins
//4. View your transactions
//5. Mine
//6. Options
//7. Exit

theEntireMenu()

//read data from keyboard
reader := bufio.NewReader(os.Stdin)
fmt.Print(">")
text, _ := reader.ReadString('\n')
fmt.Println(text)
//remove \n from text
text = text[:len(text)-1]
//verify the input
switch text {
case "1":
createWallet()
case "2":
viewWallet()
case "3":
sendCoins(node)
case "4":
viewTransactions()
case "5":
mine(node)
case "6":
options()
case "7":
exit()
case "8":
addPeers(node)
}

}

func theEntireMenu() {
fmt.Println("+--------------------+")
fmt.Println("|1.)Create new wallet|")
fmt.Println("+--------------------+")
fmt.Println("|2.)View your wallet |")
fmt.Println("+--------------------+")
fmt.Println("|3).Send coins |")
fmt.Println("+--------------------+")
fmt.Println("|4.)View transactions|")
fmt.Println("+--------------------+")
fmt.Println("|5.)Mine |")
fmt.Println("+--------------------+")
fmt.Println("|6.)Options |")
fmt.Println("+--------------------+")
fmt.Println("|7.)Exit |")
fmt.Println("+--------------------+")
fmt.Println("|8.)Add peers |")
fmt.Println("+--------------------+")
}

How will look:

Alt text

At the top of the terminal, you'll find our P2P address. This address makes it easy to share with other nodes for sending requests.

- - +

The terminal

This terminal will be a way to interact with other nodes.l(“complete code will be available on github”)

func TerminalView(node host.Host) {
//print a menu with 8 options
//1. Create a new wallet
//2. View your wallet
//3. Send coins
//4. View your transactions
//5. Mine
//6. Options
//7. Exit

theEntireMenu()

//read data from keyboard
reader := bufio.NewReader(os.Stdin)
fmt.Print(">")
text, _ := reader.ReadString('\n')
fmt.Println(text)
//remove \n from text
text = text[:len(text)-1]
//verify the input
switch text {
case "1":
createWallet()
case "2":
viewWallet()
case "3":
sendCoins(node)
case "4":
viewTransactions()
case "5":
mine(node)
case "6":
options()
case "7":
exit()
case "8":
addPeers(node)
}

}

func theEntireMenu() {
fmt.Println("+--------------------+")
fmt.Println("|1.)Create new wallet|")
fmt.Println("+--------------------+")
fmt.Println("|2.)View your wallet |")
fmt.Println("+--------------------+")
fmt.Println("|3).Send coins |")
fmt.Println("+--------------------+")
fmt.Println("|4.)View transactions|")
fmt.Println("+--------------------+")
fmt.Println("|5.)Mine |")
fmt.Println("+--------------------+")
fmt.Println("|6.)Options |")
fmt.Println("+--------------------+")
fmt.Println("|7.)Exit |")
fmt.Println("+--------------------+")
fmt.Println("|8.)Add peers |")
fmt.Println("+--------------------+")
}

How will look:

Alt text

At the top of the terminal, you'll find our P2P address. This address makes it easy to share with other nodes for sending requests.

+ + \ No newline at end of file diff --git a/Practical Sessions/Basic Peer-to-Peer Blockchain/transactions/index.html b/Practical Sessions/Basic Peer-to-Peer Blockchain/transactions/index.html index 1f785b57..f66bc4b6 100644 --- a/Practical Sessions/Basic Peer-to-Peer Blockchain/transactions/index.html +++ b/Practical Sessions/Basic Peer-to-Peer Blockchain/transactions/index.html @@ -4,13 +4,13 @@ Transactions | Blockchain Protocols and Distributed Applications - - + +
-

Transactions

So we have a wallet we know how a transaction looks lets send a transaction to another address in the blockchain.

First we need to know the address where we want to send the coins.

This is the format of a transaction.


//transaction struct
type Transaction struct {
BlockNumber int
Time int64
Hash string
Inputs []TxInput
Outputs []TxOutput
}

type TxInput struct {
Txid int64
Value int64
Signature string
PubKey string
}

type TxOutput struct {
Txid int64
Value int64
PubKeyHash string
Signature string
}

After we send the transaction from our node, the data will be sent across the network to all the nodes, now the nodes will start to validate the transaction(what means to validate the transaction? — first to check that input money are valid by verify the signature of the one that send money to the person that is sending towards you.

If a transaction is invalid the node will not send the transaction further in the network and will send a message to the node that send the invalid transaction that the transaction is invalid.

But if the transaction is valid will be send further to the other nodes and stored in a mempool until…a node will chose to mine a block and to add the transaction into the blockchain.

- - +

Transactions

So we have a wallet we know how a transaction looks lets send a transaction to another address in the blockchain.

First we need to know the address where we want to send the coins.

This is the format of a transaction.


//transaction struct
type Transaction struct {
BlockNumber int
Time int64
Hash string
Inputs []TxInput
Outputs []TxOutput
}

type TxInput struct {
Txid int64
Value int64
Signature string
PubKey string
}

type TxOutput struct {
Txid int64
Value int64
PubKeyHash string
Signature string
}

After we send the transaction from our node, the data will be sent across the network to all the nodes, now the nodes will start to validate the transaction(what means to validate the transaction? — first to check that input money are valid by verify the signature of the one that send money to the person that is sending towards you.

If a transaction is invalid the node will not send the transaction further in the network and will send a message to the node that send the invalid transaction that the transaction is invalid.

But if the transaction is valid will be send further to the other nodes and stored in a mempool until…a node will chose to mine a block and to add the transaction into the blockchain.

+ + \ No newline at end of file diff --git a/Practical Sessions/Basic Peer-to-Peer Blockchain/what_we_build/index.html b/Practical Sessions/Basic Peer-to-Peer Blockchain/what_we_build/index.html index 63f3b5f9..f5beb57c 100644 --- a/Practical Sessions/Basic Peer-to-Peer Blockchain/what_we_build/index.html +++ b/Practical Sessions/Basic Peer-to-Peer Blockchain/what_we_build/index.html @@ -4,13 +4,13 @@ What we will build? | Blockchain Protocols and Distributed Applications - - + + - - +
+ + \ No newline at end of file diff --git a/Practical Sessions/Basic Peer-to-Peer Blockchain/why_golang/index.html b/Practical Sessions/Basic Peer-to-Peer Blockchain/why_golang/index.html index 2ece832a..7c894ff3 100644 --- a/Practical Sessions/Basic Peer-to-Peer Blockchain/why_golang/index.html +++ b/Practical Sessions/Basic Peer-to-Peer Blockchain/why_golang/index.html @@ -4,13 +4,13 @@ Why golang? | Blockchain Protocols and Distributed Applications - - + +
-

Why golang?

Golang is an excellent choice for building a blockchain due to its readability and widespread use in the field. Its popularity stems from the simplicity of its syntax and the prevalence of libraries commonly employed in blockchain development.

One of Golang's standout features is its speed, a crucial factor when dealing with the intricate operations of a blockchain. This language's efficiency ensures that the blockchain can handle tasks swiftly and responsively.

Moreover, Golang provides the libp2p library, a valuable tool for simplifying the creation of a peer-to-peer network. This library streamlines the process of connecting nodes in a decentralized system, making it easier for developers to establish and maintain a robust network.

Golang's support for parallelism is another asset. Using the 'go' keyword before a function enables easy implementation of parallel and asynchronous operations. This feature enhances the performance of the blockchain by allowing it to execute multiple tasks simultaneously, contributing to a more efficient and responsive system.

  • You can go and install golang from here
  • You can install libp2p from here
- - +

Why golang?

Golang is an excellent choice for building a blockchain due to its readability and widespread use in the field. Its popularity stems from the simplicity of its syntax and the prevalence of libraries commonly employed in blockchain development.

One of Golang's standout features is its speed, a crucial factor when dealing with the intricate operations of a blockchain. This language's efficiency ensures that the blockchain can handle tasks swiftly and responsively.

Moreover, Golang provides the libp2p library, a valuable tool for simplifying the creation of a peer-to-peer network. This library streamlines the process of connecting nodes in a decentralized system, making it easier for developers to establish and maintain a robust network.

Golang's support for parallelism is another asset. Using the 'go' keyword before a function enables easy implementation of parallel and asynchronous operations. This feature enhances the performance of the blockchain by allowing it to execute multiple tasks simultaneously, contributing to a more efficient and responsive system.

  • You can go and install golang from here
  • You can install libp2p from here
+ + \ No newline at end of file diff --git a/Practical Sessions/Env Setup/index.html b/Practical Sessions/Env Setup/index.html index 9b3bcb60..a7c700ba 100644 --- a/Practical Sessions/Env Setup/index.html +++ b/Practical Sessions/Env Setup/index.html @@ -4,13 +4,13 @@ Env Setup | Blockchain Protocols and Distributed Applications - - + + - - +
+ + \ No newline at end of file diff --git a/Practical Sessions/Env Setup/setup/index.html b/Practical Sessions/Env Setup/setup/index.html index e572e0d1..54c98b8c 100644 --- a/Practical Sessions/Env Setup/setup/index.html +++ b/Practical Sessions/Env Setup/setup/index.html @@ -4,17 +4,17 @@ Setting up your environment | Blockchain Protocols and Distributed Applications - - + +
-

Setting up your environment

In this section we will install all the requirements needed for the practical sessions. +

Setting up your environment

In this section we will install all the requirements needed for the practical sessions. This includes the following:

  • rustup - The Rust toolchain installer
  • MetaMask - Ethereum wallet
  • mxpy - tool for interacting with the blockchain
  • sc-meta - universal smart contract management tool

Rustup - The Rust toolchain installer

Rust is installed and managed by the rustup tool. If you've installed rustup in the past, you can update your installation by running rustup update.

For more informantion, please check rustup documentation.

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Configuring the PATH environment variable

In the Rust development environment, all tools are installed to the ~/.cargo/bin directory, and this is where you will find the Rust toolchain, including rustc, cargo, and rustup.

During installation rustup will attempt to configure the PATH. Because of differences between platforms, command shells, and bugs in rustup, the modifications to PATH may not take effect until the console is restarted, or the user is logged out, or it may not succeed at all.

Please make sure you have included ~/.cargo/bin directory in your PATH environment variable.

Please verify that rustup was succesffully install with rustup --version.

Uninstall Rust

If at any point you would like to uninstall Rust, you can run rustup self uninstall.

MultiversX prerequisites

mxpy

Mxpy is a tool for interaction with the blockchain:

----------------------
COMMAND GROUPS summary
----------------------
contract Build, deploy, upgrade and interact with Smart Contracts
tx Create and broadcast Transactions
validator Stake, UnStake, UnBond, Unjail and other actions useful for Validators
account Get Account data (nonce, balance) from the Network
ledger Get Ledger App addresses and version
wallet Create wallet, derive secret key from mnemonic, bech32 address helpers etc.
deps Manage dependencies or multiversx-sdk modules
config Configure multiversx-sdk (default values etc.)
localnet Set up, start and control localnets
data Data manipulation omnitool
staking-provider Staking provider omnitool
dns Operations related to the Domain Name Service

Before installing mxpy, please make sure you have a working Python 3 environment. You'll need Python 3.8 or later on Linux or MacOS.

The recommended way to install mxpy is by using pipx. If you'd like to use mxpy on Windows, we recommend installing it within the Windows Subsystem for Linux (WSL).

In order to install mxpy using pipx, run the following command:

pipx install multiversx-sdk-cli --force

To check that mxpy installed successfully you can run the following command:

mxpy --version

wasm32-unknown-unknown

This is WebAssembly target which uses 32-bit memories. It is used to compile MultiversX smart contracts to WebAssembly.

To add it, please use:

rustup target add wasm32-unknown-unknown

sc-meta

This tool is used to compile smart contracts.

To install it, run:

cargo install multiversx-sc-meta --locked

To verify that it's correctly installed, run:

sc-meta --version

Ethereum prerequisites

MetaMask

MetaMask is a web browser extension and mobile app that allows you to manage your Ethereum private keys. By doing so, it serves as a wallet for Ether and other tokens, and allows you to interact with decentralized applications, or dapps.

Please visit this to install MetaMask as a browser extension (Safari is not supported) or as a mobile app.

Hardhat

Hardhat is a development environment for Ethereum software. It consists of different components for editing, compiling, debugging and deploying your smart contracts and dApps, all of which work together to create a complete development environment.

To install Hardhat, use:

npm install --save-dev hardhat

To verify that hardhat is install, run:

$ npx hardhat
888 888 888 888 888
888 888 888 888 888
888 888 888 888 888
8888888888 8888b. 888d888 .d88888 88888b. 8888b. 888888
888 888 "88b 888P" d88" 888 888 "88b "88b 888
888 888 .d888888 888 888 888 888 888 .d888888 888
888 888 888 888 888 Y88b 888 888 888 888 888 Y88b.
888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888

👷 Welcome to Hardhat v2.22.12 👷‍

? What do you want to do? …
Create a JavaScript project
Create a TypeScript project
Create a TypeScript project (with Viem)
Create an empty hardhat.config.js
❯ Quit

For the ones that prefer, there is a Hardhat for Visual Studio Code.

- - + + \ No newline at end of file diff --git a/Practical Sessions/Explorer/Block Leader/leader/index.html b/Practical Sessions/Explorer/Block Leader/leader/index.html index c3c87a4f..16dff7d4 100644 --- a/Practical Sessions/Explorer/Block Leader/leader/index.html +++ b/Practical Sessions/Explorer/Block Leader/leader/index.html @@ -4,15 +4,15 @@ Blockchain Leader | Blockchain Protocols and Distributed Applications - - + +
-

Blockchain Leader

We will continue with the same block from the previous section (Block Height: 16826695).

Leader

We can observe that the Leader (also called the proposer) is Istari Vision. +

Blockchain Leader

We will continue with the same block from the previous section (Block Height: 16826695).

Leader

We can observe that the Leader (also called the proposer) is Istari Vision. The leader, also known as the block producer or validator, is responsible for performing several critical tasks within a consensus round:

  1. Block Proposal: The leader is tasked with proposing a new block containing a set of transactions. This block proposal is the first step in the process of reaching consensus. The leader selects transactions to include in the proposed block and creates a cryptographic hash of the block's contents.

  2. Signature and Verification: After proposing a block, the leader signs it with their private key to prove its authenticity. Other network participants can verify the leader's signature using their public key. This verification ensures that the proposed block is indeed from the authorized leader.

  3. Broadcasting the Proposal: Once the block is signed, the leader broadcasts it to the network. Other nodes in the network receive and validate the proposed block to ensure its compliance with the consensus rules.

  4. Agreement and Confirmation: If the proposed block meets the consensus criteria, it is accepted by the network. The leader's proposed block becomes part of the blockchain, and consensus is achieved for that round.

Let's see some details about this proposer:

Istari Vision

We can see his public key, version of the software for the blockchain node and other information we will further discuss.

Practice

  • Open 3 different blocks in 3 different tabs. Observe that every time there is another leader. Why do you think the system is designed this way?
  • Open 3 different blocks in 3 different tabs on Ethereum Explorer. Observe that every time there is another leader.
- - + + \ No newline at end of file diff --git a/Practical Sessions/Explorer/Blockchain Observers/observers/index.html b/Practical Sessions/Explorer/Blockchain Observers/observers/index.html index e3fdaf63..f634b88b 100644 --- a/Practical Sessions/Explorer/Blockchain Observers/observers/index.html +++ b/Practical Sessions/Explorer/Blockchain Observers/observers/index.html @@ -4,14 +4,14 @@ Blockchain Observers | Blockchain Protocols and Distributed Applications - - + +
-

Blockchain Observers

Observers are a type of nodes that don't participate in the consensus but keep a peer-to-peer communication with the rest of the blockchain. +

Blockchain Observers

Observers are a type of nodes that don't participate in the consensus but keep a peer-to-peer communication with the rest of the blockchain. They are usually used to see the communication between nodes (ex: debugging).

Let's filter the nodes to see only the observers. There is an Observers tab below the Nodes section.

Observers

We can observer the same fields as the nodes, but there is no Rating. Why is that?

Note that each Observer is only on a Shard.

What should we do if we want to listen to the communication on every shard?

Observer that there are other types of nodes

- - + + \ No newline at end of file diff --git a/Practical Sessions/Explorer/Blockchain Validators/validators/index.html b/Practical Sessions/Explorer/Blockchain Validators/validators/index.html index 2498fc32..a4bf2be7 100644 --- a/Practical Sessions/Explorer/Blockchain Validators/validators/index.html +++ b/Practical Sessions/Explorer/Blockchain Validators/validators/index.html @@ -4,15 +4,15 @@ Blockchain Validators | Blockchain Protocols and Distributed Applications - - + +
-

Blockchain Validators

Every validators/node is publicly displayed on the explorer:

You can check on the explorer the nodes of every blockchain.


NOTE

We call nodes or validators the computers who participate in the blockchain to execute transactions. +

Blockchain Validators

Every validators/node is publicly displayed on the explorer:

You can check on the explorer the nodes of every blockchain.


NOTE

We call nodes or validators the computers who participate in the blockchain to execute transactions. The more available nodes, the more decentralized the blockchain is.


Let's stick to the MultiversX. Go to the Nodes Section.

Nodes

Observe the nodes public information:

  • Public Key
  • Name
  • Shard
  • Node Software Version
  • Status
  • Rating
  • Nonce

We recall that the Nonce is the number of transaction that user transmited on the blockchain.

Rating

Each individual validator has a Rating score, which expresses its overall reliability, performance and responsiveness. When validators join the network immediately after staking, they start with an initial score of 50 points.

Validators gain or lose rating points in a round depending on their role in that round (consensus proposer vs. consensus validator) and on their behavior within that role.

For the overall health of the network, if the rating of a validator drops below 10 points, it will be jailed. Being jailed means that the validator will be taken out of the shards, it will not participate in consensus, and thus it will not earn any rewards.

Rating affects the probability of a validator to be selected in the consensus group of a round. This is done by applying rating modifiers on the probability of selection for each validator.

You can read more on rating shard validators here.

Node details

The explorer offers details on each node participant to the blockchain.

Node Details

Practice

- - + + \ No newline at end of file diff --git a/Practical Sessions/Explorer/Blocks/index.html b/Practical Sessions/Explorer/Blocks/index.html index bc569464..15aa273a 100644 --- a/Practical Sessions/Explorer/Blocks/index.html +++ b/Practical Sessions/Explorer/Blocks/index.html @@ -4,16 +4,16 @@ Blocks in Blockchain | Blockchain Protocols and Distributed Applications - - + +
-

Blocks in Blockchain

For simplicity, we will use MultiversX blockchain and MultiversX Explorer.

Notarization of blocks

Inspect the image below: +

Blocks in Blockchain

For simplicity, we will use MultiversX blockchain and MultiversX Explorer.

Notarization of blocks

Inspect the image below: Blocks on MultiversX

We can observe 4 blocks from 1 second ago for 4 different shards: Shard0, Shard1, Shard2, Metachain. These shard a sub-blockchains and enables MultiversX to scale. You can read more about shard here.

We can observe 4 more blocks from 7 seconds ago. That's because each shard outputs a block every 6 seconds.


NOTE

We previously saw that every 6 seconds starts new round, but not necessarly a new block gets notarized. In this case all the blocks successfully passed the consensus round and got notarized.


Block details

Here is the link for one of the blocks in the previous image (Block Height: 16826695).

Block 16826695

Observe the block details:

  • Round
  • Epoch
  • Age (timestamp)
  • Shard

Based on a simple calculus, the epoch is 1168 which means this blockchain started 3 years and 73 days ago.

We will talk about the other fields in the next section.

Practice

  1. Go to the MultiversX Explorer and check more blocks from different shard;
  2. Go to the Ethereum Explorer and check some blocks details.
- - + + \ No newline at end of file diff --git a/Practical Sessions/Explorer/Consensus Grup/consensus/index.html b/Practical Sessions/Explorer/Consensus Grup/consensus/index.html index ddaa8bfd..555cdf86 100644 --- a/Practical Sessions/Explorer/Consensus Grup/consensus/index.html +++ b/Practical Sessions/Explorer/Consensus Grup/consensus/index.html @@ -4,16 +4,16 @@ Consensus Group | Blockchain Protocols and Distributed Applications - - + +
-

Consensus Group

We will continue with the same block from the previous section (Block Height: 16826695).

Observe the field Consensus Group: +

Consensus Group

We will continue with the same block from the previous section (Block Height: 16826695).

Observe the field Consensus Group: Leader

There are 63 validators which execute every transaction in this block. If you click on the 63 validators (See all) button you will see 63 public keys, which are links to all the 63 nodes that participated in consensus.

Practice

  • Open 3 different blocks in 3 different tabs. Observe that every time there is another consensus group. Why do you think the system is designed this way?
  • Open 3 different blocks in 3 different tabs on Ethereum Explorer. Observe that every time there is another leader.
- - + + \ No newline at end of file diff --git a/Practical Sessions/Explorer/Devnet Blockchains/devnet_testnet/index.html b/Practical Sessions/Explorer/Devnet Blockchains/devnet_testnet/index.html index 16c2ee24..75d2e0b5 100644 --- a/Practical Sessions/Explorer/Devnet Blockchains/devnet_testnet/index.html +++ b/Practical Sessions/Explorer/Devnet Blockchains/devnet_testnet/index.html @@ -4,14 +4,14 @@ Devnet & Testnet Blockchain | Blockchain Protocols and Distributed Applications - - + +
-

Devnet & Testnet Blockchain

While developing applications, there is a need for a development/testing blockchain.

Inspect:

What differences can you observe?

These blockchains offer the Faucet option where you can mint blockchain tokens (eGLD, ETH, etc.). +

Devnet & Testnet Blockchain

While developing applications, there is a need for a development/testing blockchain.

Inspect:

What differences can you observe?

These blockchains offer the Faucet option where you can mint blockchain tokens (eGLD, ETH, etc.). This way the development is easier for the community.


NOTE

All the tokens are "fake" tokens. They are only used to mock the real tokens on the Mainnet.


- - + + \ No newline at end of file diff --git a/Practical Sessions/Explorer/Time in Blockchain/time/index.html b/Practical Sessions/Explorer/Time in Blockchain/time/index.html index 03f11bfd..465cf647 100644 --- a/Practical Sessions/Explorer/Time in Blockchain/time/index.html +++ b/Practical Sessions/Explorer/Time in Blockchain/time/index.html @@ -4,19 +4,19 @@ Understanding Time in Blockchains | Blockchain Protocols and Distributed Applications - - + +
-

Understanding Time in Blockchains

In traditional computer systems, time is relatively straightforward, with a reliance on the system clock. +

Understanding Time in Blockchains

In traditional computer systems, time is relatively straightforward, with a reliance on the system clock. However, in the world of blockchains, time is a unique and critical concept. Blockchains need to maintain a shared understanding of time across all participants, and this introduces some complexities. Here's how time is managed in blockchains:

Rounds

Rounds refer to the cyclic or sequential stages of consensus protocols, particularly in proof-of-stake (PoS) and delegated proof-of-stake (DPoS) blockchains. Each blockchain has it's own length of rounds:

  • MultiversX - 6 seconds;
  • Ethereum - 12 seconds;
  • Solana - 0.4 seconds;
  • Cardano - 5 seconds;
  • NEAR - 1 second;

A round is a time limit to execute a batch of transactions.

Blocks

Every round a new block is being proposed. That proposal can succeed or not. In case of success, a block is added to the blockchain history. The missed blocks are due to not reaching consensus and are usually under 5%.


NOTE

For MultiversX case, every 6 seconds starts new round, but not necessarly a new block gets notarized.


Epochs

This is another time measurement and it's used for larger periods of time (just like minutes, hours, years, decades, etc.).

Each blockchain has it's own length of epochs:

  • MultiversX - 14.400 rounds (24 hours);
  • Ethereum - 30.000 rounds (100 hours);
  • Solana - 432.000 rounds (48 hours);
  • Cardano - 432.000 rounds (5 days);
  • NEAR - 43.200 rounds (12 hours).

Block Timestamps

Blockchains organize transactions into blocks, and each block has a timestamp. This timestamp is crucial for several reasons:

  1. Order of Transactions: The timestamp helps order transactions within a block. Transactions are grouped together and processed in the order in which they are added to a block. This ensures that everyone has a consistent view of the transaction history.

  2. Difficulty Adjustment: Some blockchains, like Bitcoin, use the block timestamp to adjust the difficulty of the proof-of-work (PoW) algorithm. This keeps the block generation rate relatively constant, regardless of the total network hash rate.

  3. Block Validity: Block timestamps are used to determine whether a block is valid. If the timestamp of a new block is too far in the future or past, it can be considered invalid.

Practice

Check MultiversX Explorer and Ethereum Explorer and see how (almost) at every 6, respectively 12 seconds a new block appears.

- - + + \ No newline at end of file diff --git a/Practical Sessions/Explorer/Transactions/index.html b/Practical Sessions/Explorer/Transactions/index.html index 649a20c4..30ddc118 100644 --- a/Practical Sessions/Explorer/Transactions/index.html +++ b/Practical Sessions/Explorer/Transactions/index.html @@ -4,17 +4,17 @@ Transactions | Blockchain Protocols and Distributed Applications - - + +
-

Transactions

We will continue with the same block from the previous section (Block Height: 16826695).

Observe the field Transactions: +

Transactions

We will continue with the same block from the previous section (Block Height: 16826695).

Observe the field Transactions: Block 16826695 We can see that there are 6 transactions in this group.

Miniblocks

Transactions are grouped in miniblocks. Each miniblock is a category with Shard_source - Shard_destionation.

So, for the first miniblock we have 3 transactions from Shard1 to Shard2: Block 16826695

Transaction details

We will use the first transaction from the first miniblock as an example:

Transaction

Observe the fields:

  • Status: Success;
  • Age: timestamp;
  • Miniblock: the one we previously disscussed about;
  • From: The user who created the transaction
  • To: The destination of the transaction. This is a smart contract. We will discuss about it in a further section;
  • Value: The number of EGLD (MultiversX native token) sent in this transaction

There are more fields in this transaction, but we will discuss about it in a further section.

Practice

  • Open 3 different transactions in 3 different tabs. Inspect the fields.
  • Open 3 different transactions in 3 different tabs on Ethereum Explorer. Inspect the fields.
- - + + \ No newline at end of file diff --git a/Practical Sessions/Explorer/index.html b/Practical Sessions/Explorer/index.html index 9d3b2ad4..62f274ca 100644 --- a/Practical Sessions/Explorer/index.html +++ b/Practical Sessions/Explorer/index.html @@ -4,13 +4,13 @@ Explorer | Blockchain Protocols and Distributed Applications - - + + - - +
+ + \ No newline at end of file diff --git a/Practical Sessions/Learning Rust/cryptozombies/index.html b/Practical Sessions/Learning Rust/cryptozombies/index.html new file mode 100644 index 00000000..df4987ab --- /dev/null +++ b/Practical Sessions/Learning Rust/cryptozombies/index.html @@ -0,0 +1,18 @@ + + + + + +CryptoZombies | Blockchain Protocols and Distributed Applications + + + + +
+

CryptoZombies

CryptoZombies is an interactive and gamified platform designed to teach blockchain and Smart Contract development using the Rust or Solidity programming language. +It uses a series of coding lessons where you will build your own blockchain-based zombie-themed game step by step. +Each lesson adds elements to a zombie game, making the learning process engaging and fun.

Please follow the MultiversX CryptoZombie tutorial.

Bonus

If you wish to learn other blockchains, please follow courses for Solidity, Optimism, zkSync, Tron, Chainlink, etc.

+ + + + \ No newline at end of file diff --git a/Practical Sessions/Learning Rust/index.html b/Practical Sessions/Learning Rust/index.html new file mode 100644 index 00000000..16798aaf --- /dev/null +++ b/Practical Sessions/Learning Rust/index.html @@ -0,0 +1,16 @@ + + + + + +Learning Rust | Blockchain Protocols and Distributed Applications + + + + + + + + + \ No newline at end of file diff --git a/Practical Sessions/Learning Rust/rust/index.html b/Practical Sessions/Learning Rust/rust/index.html new file mode 100644 index 00000000..b1211901 --- /dev/null +++ b/Practical Sessions/Learning Rust/rust/index.html @@ -0,0 +1,16 @@ + + + + + +Learning Rust and Rust in Smart Contracts | Blockchain Protocols and Distributed Applications + + + + +
+

Learning Rust and Rust in Smart Contracts

Objectives

In this section you will learn about Rust:

  • The Basics;
  • Basic Control Flow;
  • Basic Data Structure Types;
  • Generic Types;
  • Ownership & Borrowing Data;
  • Object Oriented Programming - Traits;
  • Cryptozombies - learn SC development via an interactive and gamified platform.

There will be 2 approaches:

  1. Tour of Rust - a step by step guide through the features of the Rust programming language;
  2. Cryptozombies - learn Rust and Smart Contract programming in a fun and easy way;
+ + + + \ No newline at end of file diff --git a/Practical Sessions/Learning Rust/tour-of-rust/index.html b/Practical Sessions/Learning Rust/tour-of-rust/index.html new file mode 100644 index 00000000..6fb70a27 --- /dev/null +++ b/Practical Sessions/Learning Rust/tour-of-rust/index.html @@ -0,0 +1,18 @@ + + + + + +Tour of Rust | Blockchain Protocols and Distributed Applications + + + + +
+

Tour of Rust

In this section you will learn Rust via Tour of Rust tutorial. +You can find this guide in multiple languages including English and Romanian.

The following sections are useful for Smart Contract programming:

We recommend going through the whole Tour of Rust tutorial. +Moreover, to fully understand the Rust Progamming Language, please go through the Rust Programming Language book.

+ + + + \ No newline at end of file diff --git a/Practical Sessions/Money (DeFi)/index.html b/Practical Sessions/Money (DeFi)/index.html index aac74acd..5e264dac 100644 --- a/Practical Sessions/Money (DeFi)/index.html +++ b/Practical Sessions/Money (DeFi)/index.html @@ -4,13 +4,13 @@ Page Not Found | Blockchain Protocols and Distributed Applications - - + +

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

- - + + \ No newline at end of file diff --git a/Practical Sessions/Money (DeFi)/mint_tokens/index.html b/Practical Sessions/Money (DeFi)/mint_tokens/index.html index 2b3f2a6c..f89943b6 100644 --- a/Practical Sessions/Money (DeFi)/mint_tokens/index.html +++ b/Practical Sessions/Money (DeFi)/mint_tokens/index.html @@ -4,13 +4,13 @@ Page Not Found | Blockchain Protocols and Distributed Applications - - + +

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

- - + + \ No newline at end of file diff --git a/Practical Sessions/Money (DeFi)/swap/index.html b/Practical Sessions/Money (DeFi)/swap/index.html index 06e60b87..3423eb75 100644 --- a/Practical Sessions/Money (DeFi)/swap/index.html +++ b/Practical Sessions/Money (DeFi)/swap/index.html @@ -4,13 +4,13 @@ Page Not Found | Blockchain Protocols and Distributed Applications - - + +

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

- - + + \ No newline at end of file diff --git a/Practical Sessions/Observer/index.html b/Practical Sessions/Observer/index.html index bc8241d9..934eec19 100644 --- a/Practical Sessions/Observer/index.html +++ b/Practical Sessions/Observer/index.html @@ -4,14 +4,14 @@ Setting up an Observer | Blockchain Protocols and Distributed Applications - - + +
-

Setting up an Observer

In this section we will be setting up an Observer on the MultiversX Testnet.

Clone the installer repository:

git clone https://github.com/multiversx/mx-chain-scripts

Edit ENVIRONMENT and CUSTOM_HOME in config/variables.cfg config file:

ENVIRONMENT="testnet"

CUSTOM_HOME="/home/costin"
CUSTOM_USER="costin

Don't forget to put your Github Token in the GITHUBTOKEN field. +

Setting up an Observer

In this section we will be setting up an Observer on the MultiversX Testnet.

Clone the installer repository:

git clone https://github.com/multiversx/mx-chain-scripts

Edit ENVIRONMENT and CUSTOM_HOME in config/variables.cfg config file:

ENVIRONMENT="testnet"

CUSTOM_HOME="/home/costin"
CUSTOM_USER="costin

Don't forget to put your Github Token in the GITHUBTOKEN field. Please check that the `CUSTOM_HOME`` directory exists.

Run the installation script as follows:

./script.sh observing_squad

Start the nodes and the Proxy using the command:

./script.sh start

If you encounter any issue please check the MultiversX Observing Squad Documentation.

Monitoring and trivial checks

One can monitor the running Observers using the termui utility (installed during the setup process itself in the CUSTOM_HOME="/home/ubuntu" folder), as follows:

~/elrond-utils/termui --address localhost:8080    # Shard 0
~/elrond-utils/termui --address localhost:8081 # Shard 1
~/elrond-utils/termui --address localhost:8082 # Shard 2
~/elrond-utils/termui --address localhost:8083 # Metachain

Observer Output

- - + + \ No newline at end of file diff --git a/Practical Sessions/Smart Contract Events/events/index.html b/Practical Sessions/Smart Contract Events/events/index.html index 9e748268..6d0d6e4e 100644 --- a/Practical Sessions/Smart Contract Events/events/index.html +++ b/Practical Sessions/Smart Contract Events/events/index.html @@ -4,19 +4,19 @@ Events | Blockchain Protocols and Distributed Applications - - + +
-

Events

Key Takeaways:

  • Events in smart contracts serve as a communication mechanism between the contract and user interfaces;
  • By emitting events, smart contracts can notify external applications or listeners about specific actions or changes;
  • Events play a key role in facilitating effective interaction with user interfaces while ensuring secure automated execution of code-based agreements.

Example of events

Notice the Logs section near the Transaction Details. +

Events

Key Takeaways:

  • Events in smart contracts serve as a communication mechanism between the contract and user interfaces;
  • By emitting events, smart contracts can notify external applications or listeners about specific actions or changes;
  • Events play a key role in facilitating effective interaction with user interfaces while ensuring secure automated execution of code-based agreements.

Example of events

Notice the Logs section near the Transaction Details. ESDTNFTCreate

This section shows all the events this transaction emitted. Notice that most transactions have this Logs section.

ESDTNFTTransfer

Let's open this tab and inspect the Events

ESDTNFTTransfer Event

Notice there are 4 data fields:

  • SBPT-774fbd - the token ID;
  • 1 - the nonce;
  • 1 - the value (the Smart display feature doesn't know how to interpret that but the Decimal option does);
  • erd1mqa9wttlzwwdvwgk9dzsfdn79lv5raw0tfe9ynvn0dg92hpruvaqhhd2gx - the destination address.

Let's inspect a more complex operation and check all the log events. Here is the link to the transaction.

Swap Transaction

Notice that the transaction has 4 transfers and 1 burn operations. Let's inspect the logs:

Swap Event1

The first transaction is an ESDTTransfer for the token USDC-c76f1f which has 6 decimals; therefore 580345261 is equal to 580,345261$. You can match the events to the Token Operations from the Transacton Details.

You can check the deposit_swap_fees_event code here.

Notice the burn event below. Keep in mind that MEX-455c57 has 18 decimals. Swap Event2

Here is the code for the swap_no_fee_and_forward event.

Writing your own event in the Smart Contract

The structure of an event is:

    #[event("your_event_name")]
fn the_function_you_call_when_you_want_to_emit_en_event(
&self,
#[indexed] field1: &TokenIdentifier,
#[indexed] field2: &ManagedAddress,
#[indexed] field3: u64,
#[indexed] field4: BigUint,
);

And when you want to emit an event, just call the function:

    self.the_function_you_call_when_you_want_to_emit_en_event(field1, field2, field3, field4);
- - + + \ No newline at end of file diff --git a/Practical Sessions/Smart Contract Events/index.html b/Practical Sessions/Smart Contract Events/index.html index 9873e4bb..5285f713 100644 --- a/Practical Sessions/Smart Contract Events/index.html +++ b/Practical Sessions/Smart Contract Events/index.html @@ -4,13 +4,13 @@ Smart Contract Events | Blockchain Protocols and Distributed Applications - - + + - - +
+ + \ No newline at end of file diff --git a/Practical Sessions/Smart Contracts/adder/index.html b/Practical Sessions/Smart Contracts/adder/index.html index 411c88a2..fde6b1ad 100644 --- a/Practical Sessions/Smart Contracts/adder/index.html +++ b/Practical Sessions/Smart Contracts/adder/index.html @@ -4,13 +4,13 @@ The Adder SC | Blockchain Protocols and Distributed Applications - - + +
-

The Adder SC

The Adder smart contract is a simple smart contract with an add functionality and a global variable that can be incremented.

/// One of the simplest smart contracts possible,
/// it holds a single variable in storage, which anyone can increment.
#[multiversx_sc::contract]
pub trait Adder {
#[view(getSum)]
#[storage_mapper("sum")]
fn sum(&self) -> SingleValueMapper<BigUint>;

#[init]
fn init(&self, initial_value: BigUint) {
self.sum().set(initial_value);
}

#[upgrade]
fn upgrade(&self, initial_value: BigUint) {
self.init(initial_value);
}

/// Add desired amount to the storage variable.
#[endpoint]
fn add(&self, value: BigUint) {
self.sum().update(|sum| *sum += value);
}
}

We notice 4 functions:

  • sum - this is a global variable, a SingleValueMapper (a single value) of type BigUint (unsigned integer);
  • init - the constructor;
  • add - function that increments the global variable (sum) with the value parameter;
  • upgrade - function executed when upgrading the contract.

We notice 5 types of annotations:

  • #[view(getSum)] - this is a function that allows you to read the storage variable by calling the function getSum;
  • #[storage_mapper("sum")] - this is a global variable (also called a storage) stored at the contract address;
  • #[init] - the constructor function; this is called when deploying the contract;
  • #[upgrade] - this function is called when upgrading the contract;
  • #[endpoint] - an endpoint is a function callable directly by the user; A function not having this annotation will not be exposed publicly.

Here is the smart contract code listed above and here are all the files needed for compilation.

Let's compile the contract:

costin@Byblos:~/mvx/mx-contracts-rs/contracts/adder$ sc-meta all build
/home/costin/mvx/mx-contracts-rs/contracts/adder

Found 1 contract crates.

(1/1)
In /home/costin/mvx/mx-contracts-rs/contracts/adder/meta
Calling `cargo run build`
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.05s
Running `/home/costin/mvx/mx-contracts-rs/target/debug/adder-meta build`
Using workspace target directory: /home/costin/mvx/mx-contracts-rs/target ...
Building adder.wasm in /home/costin/mvx/mx-contracts-rs/contracts/adder/wasm ...
RUSTFLAGS="-C link-arg=-s -C link-arg=-zstack-size=131072" cargo build --target=wasm32-unknown-unknown --release --target-dir /home/costin/mvx/mx-contracts-rs/target
Compiling proc-macro2 v1.0.86
Compiling unicode-ident v1.0.13
Compiling smallvec v1.13.2
Compiling autocfg v1.4.0
Compiling hex v0.4.3
Compiling endian-type v0.1.2
Compiling arrayvec v0.7.6
Compiling unwrap-infallible v0.1.5
Compiling bitflags v2.6.0
Compiling hex-literal v0.4.1
Compiling nibble_vec v0.1.0
Compiling radix_trie v0.2.1
Compiling num-traits v0.2.19
Compiling quote v1.0.37
Compiling syn v2.0.77
Compiling multiversx-sc-codec-derive v0.21.0
Compiling multiversx-sc-derive v0.53.2
Compiling multiversx-sc-codec v0.21.0
Compiling multiversx-sc v0.53.2
Compiling adder v0.0.0 (/home/costin/mvx/mx-contracts-rs/contracts/adder)
Compiling multiversx-sc-wasm-adapter v0.53.2
Compiling adder-wasm v0.0.0 (/home/costin/mvx/mx-contracts-rs/contracts/adder/wasm)
Finished `release` profile [optimized] target(s) in 8.69s
Copying /home/costin/mvx/mx-contracts-rs/target/wasm32-unknown-unknown/release/adder_wasm.wasm to ../output/adder.wasm ...
Calling wasm-opt on ../output/adder.wasm ...
Extracting imports to ../output/adder.imports.json ...
Checking EI version: 1.3 ... OK
Packing ../output/adder.mxsc.json ...
Contract size: 696 bytes.

Let's check the contract:

costin@Byblos:~/mvx/mx-contracts-rs/contracts/adder$ ls -l output/
total 16
-rw-rw-r-- 1 costin costin 1792 nov 7 13:28 adder.abi.json
-rw-rw-r-- 1 costin costin 262 nov 7 13:28 adder.imports.json
-rw-rw-r-- 1 costin costin 4070 nov 7 13:28 adder.mxsc.json
-rwxrwxr-x 1 costin costin 696 nov 7 13:28 adder.wasm

We notice that the resulted contract (adder.wasm) has 696 bytes.

Practice

  • Compile the Adder contract.
- - +

The Adder SC

The Adder smart contract is a simple smart contract with an add functionality and a global variable that can be incremented.

/// One of the simplest smart contracts possible,
/// it holds a single variable in storage, which anyone can increment.
#[multiversx_sc::contract]
pub trait Adder {
#[view(getSum)]
#[storage_mapper("sum")]
fn sum(&self) -> SingleValueMapper<BigUint>;

#[init]
fn init(&self, initial_value: BigUint) {
self.sum().set(initial_value);
}

#[upgrade]
fn upgrade(&self, initial_value: BigUint) {
self.init(initial_value);
}

/// Add desired amount to the storage variable.
#[endpoint]
fn add(&self, value: BigUint) {
self.sum().update(|sum| *sum += value);
}
}

We notice 4 functions:

  • sum - this is a global variable, a SingleValueMapper (a single value) of type BigUint (unsigned integer);
  • init - the constructor;
  • add - function that increments the global variable (sum) with the value parameter;
  • upgrade - function executed when upgrading the contract.

We notice 5 types of annotations:

  • #[view(getSum)] - this is a function that allows you to read the storage variable by calling the function getSum;
  • #[storage_mapper("sum")] - this is a global variable (also called a storage) stored at the contract address;
  • #[init] - the constructor function; this is called when deploying the contract;
  • #[upgrade] - this function is called when upgrading the contract;
  • #[endpoint] - an endpoint is a function callable directly by the user; A function not having this annotation will not be exposed publicly.

Here is the smart contract code listed above and here are all the files needed for compilation.

Let's compile the contract:

costin@Byblos:~/mvx/mx-contracts-rs/contracts/adder$ sc-meta all build
/home/costin/mvx/mx-contracts-rs/contracts/adder

Found 1 contract crates.

(1/1)
In /home/costin/mvx/mx-contracts-rs/contracts/adder/meta
Calling `cargo run build`
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.05s
Running `/home/costin/mvx/mx-contracts-rs/target/debug/adder-meta build`
Using workspace target directory: /home/costin/mvx/mx-contracts-rs/target ...
Building adder.wasm in /home/costin/mvx/mx-contracts-rs/contracts/adder/wasm ...
RUSTFLAGS="-C link-arg=-s -C link-arg=-zstack-size=131072" cargo build --target=wasm32-unknown-unknown --release --target-dir /home/costin/mvx/mx-contracts-rs/target
Compiling proc-macro2 v1.0.86
Compiling unicode-ident v1.0.13
Compiling smallvec v1.13.2
Compiling autocfg v1.4.0
Compiling hex v0.4.3
Compiling endian-type v0.1.2
Compiling arrayvec v0.7.6
Compiling unwrap-infallible v0.1.5
Compiling bitflags v2.6.0
Compiling hex-literal v0.4.1
Compiling nibble_vec v0.1.0
Compiling radix_trie v0.2.1
Compiling num-traits v0.2.19
Compiling quote v1.0.37
Compiling syn v2.0.77
Compiling multiversx-sc-codec-derive v0.21.0
Compiling multiversx-sc-derive v0.53.2
Compiling multiversx-sc-codec v0.21.0
Compiling multiversx-sc v0.53.2
Compiling adder v0.0.0 (/home/costin/mvx/mx-contracts-rs/contracts/adder)
Compiling multiversx-sc-wasm-adapter v0.53.2
Compiling adder-wasm v0.0.0 (/home/costin/mvx/mx-contracts-rs/contracts/adder/wasm)
Finished `release` profile [optimized] target(s) in 8.69s
Copying /home/costin/mvx/mx-contracts-rs/target/wasm32-unknown-unknown/release/adder_wasm.wasm to ../output/adder.wasm ...
Calling wasm-opt on ../output/adder.wasm ...
Extracting imports to ../output/adder.imports.json ...
Checking EI version: 1.3 ... OK
Packing ../output/adder.mxsc.json ...
Contract size: 696 bytes.

Let's check the contract:

costin@Byblos:~/mvx/mx-contracts-rs/contracts/adder$ ls -l output/
total 16
-rw-rw-r-- 1 costin costin 1792 nov 7 13:28 adder.abi.json
-rw-rw-r-- 1 costin costin 262 nov 7 13:28 adder.imports.json
-rw-rw-r-- 1 costin costin 4070 nov 7 13:28 adder.mxsc.json
-rwxrwxr-x 1 costin costin 696 nov 7 13:28 adder.wasm

We notice that the resulted contract (adder.wasm) has 696 bytes.

Practice

  • Compile the Adder contract.
+ + \ No newline at end of file diff --git a/Practical Sessions/Smart Contracts/cargo_deploy/index.html b/Practical Sessions/Smart Contracts/cargo_deploy/index.html index 061ab045..03abe859 100644 --- a/Practical Sessions/Smart Contracts/cargo_deploy/index.html +++ b/Practical Sessions/Smart Contracts/cargo_deploy/index.html @@ -4,14 +4,14 @@ Smart Contract deployment via Rust | Blockchain Protocols and Distributed Applications - - + +
-

Smart Contract deployment via Rust

Let's deploy our smart contract(SC) on the blockchain. We will deploy the adder contract from the previous section.

In the repo there is a folder named interact.

Let's take a look into the basic_interact_cli.rs file:

#[derive(Clone, PartialEq, Eq, Debug, Subcommand)]
pub enum InteractCliCommand {
#[command(name = "add", about = "Add value")]
Add(AddArgs),
#[command(name = "deploy", about = "Deploy contract")]
Deploy,
#[command(name = "feed", about = "Feed contract EGLD")]
Feed,
#[command(name = "multi-deploy", about = "Multiple deploy contracts")]
MultiDeploy(MultiDeployArgs),
#[command(name = "sum", about = "Print sum")]
Sum,
}

We have 5 arguments we can use to interact with this contract. We will deploy for now.

Let's take a look into the basic_interact.rs file:

async fn main() {
env_logger::init();

let mut basic_interact = AdderInteract::init().await;

let cli = basic_interact_cli::InteractCli::parse();
match &cli.command {
Some(basic_interact_cli::InteractCliCommand::Add(args)) => {
basic_interact.add(args.value).await;
}
Some(basic_interact_cli::InteractCliCommand::Deploy) => {
basic_interact.deploy().await;
}
Some(basic_interact_cli::InteractCliCommand::Feed) => {
basic_interact.feed_contract_egld().await;
}
Some(basic_interact_cli::InteractCliCommand::MultiDeploy(args)) => {
basic_interact.multi_deploy(&args.count).await;
}
Some(basic_interact_cli::InteractCliCommand::Sum) => {
basic_interact.print_sum().await;
}
None => {}
}
}

SC Deploy

The main function checks the arguments and calls the designated function. +

Smart Contract deployment via Rust

Let's deploy our smart contract(SC) on the blockchain. We will deploy the adder contract from the previous section.

In the repo there is a folder named interact.

Let's take a look into the basic_interact_cli.rs file:

#[derive(Clone, PartialEq, Eq, Debug, Subcommand)]
pub enum InteractCliCommand {
#[command(name = "add", about = "Add value")]
Add(AddArgs),
#[command(name = "deploy", about = "Deploy contract")]
Deploy,
#[command(name = "feed", about = "Feed contract EGLD")]
Feed,
#[command(name = "multi-deploy", about = "Multiple deploy contracts")]
MultiDeploy(MultiDeployArgs),
#[command(name = "sum", about = "Print sum")]
Sum,
}

We have 5 arguments we can use to interact with this contract. We will deploy for now.

Let's take a look into the basic_interact.rs file:

async fn main() {
env_logger::init();

let mut basic_interact = AdderInteract::init().await;

let cli = basic_interact_cli::InteractCli::parse();
match &cli.command {
Some(basic_interact_cli::InteractCliCommand::Add(args)) => {
basic_interact.add(args.value).await;
}
Some(basic_interact_cli::InteractCliCommand::Deploy) => {
basic_interact.deploy().await;
}
Some(basic_interact_cli::InteractCliCommand::Feed) => {
basic_interact.feed_contract_egld().await;
}
Some(basic_interact_cli::InteractCliCommand::MultiDeploy(args)) => {
basic_interact.multi_deploy(&args.count).await;
}
Some(basic_interact_cli::InteractCliCommand::Sum) => {
basic_interact.print_sum().await;
}
None => {}
}
}

SC Deploy

The main function checks the arguments and calls the designated function. We will be using deploy async function to deploy our adder smart contract:

    async fn deploy(&mut self) {
// warning: multi deploy not yet fully supported
// only works with last deployed address

self.set_state().await;

let new_address = self
.interactor
.tx()
.from(&self.wallet_address)
.typed(adder_proxy::AdderProxy)
.init(0u32)
.code(&self.adder_code)
.returns(ReturnsNewBech32Address)
.prepare_async()
.run()
.await;

println!("new address: {new_address}");
self.state.set_adder_address(new_address);
}

The interactor will make a call to the blockchain from a wallet address. This is a test address and it's referenced from the MultiversX Framework SDK.

Let's deploy a contract:

$ cargo run deploy
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.38s
Running `/Users/costincarabas/mvx/mx-contracts-rs/target/debug/basic-interact deploy`
wallet address: erd1uv40ahysflse896x4ktnh6ecx43u7cmy9wnxnvcyp7deg299a4sq6vaywa
sender's recalled nonce: 5498
-- tx nonce: 5498
sc deploy tx hash: 4133385c40fee378f5fc1b6318f53302750c2403a9d02e00ed727c35ba9b41ba
deploy address: erd1qqqqqqqqqqqqqpgqef8xmsatt4tkf5ycv538a2kme3h7dy37a4sqygv9p5

Notice the:

  • sender's nonce - how many transactions he initiated;
  • sc deploy tx hash - the hash of the transaction where we deployed the code on a new SC;
  • deploy address - the address where the new SC is located.

Question 1: Will this transaction show on the Explorer?

Question 2: Will all the validators execute this transaction?

SC Query

Let's read the storage from the SC:

    async fn print_sum(&mut self) {
let sum = self
.interactor
.query()
.to(self.state.current_adder_address())
.typed(adder_proxy::AdderProxy)
.sum()
.returns(ReturnsResultUnmanaged)
.prepare_async()
.run()
.await;

println!("sum: {sum}");
}

Notice that we will make a query on the blockchain to retrieve information.

Question 1: Will this transaction show on the Explorer?

Question 2: Will all the validators execut this transaction?

Remember from the main function and the basic_interact_cli.rs file that we need to call the sum parameter:

$ cargo run sum
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.36s
Running `/Users/costincarabas/mvx/mx-contracts-rs/target/debug/basic-interact sum`
sum: 0

The sum storage is 0, because this was the value used by the interactor.

SC execute endpoint

Let's execute our first endpoint, the add function:

    async fn add(&mut self, value: u64) {
self.interactor
.tx()
.from(&self.wallet_address)
.to(self.state.current_adder_address())
.typed(adder_proxy::AdderProxy)
.add(value)
.prepare_async()
.run()
.await;

println!("successfully performed add");
}

Notice that we use the tx functionality of the interactor. We call the add endpoint of the smart contract.

Please inspect basic_interact.rs file one more time:

pub struct AddArgs {
/// The value to add
#[arg(short = 'v', long = "value", verbatim_doc_comment)]
pub value: u64,
}

We must provide a parameter -v $value or --value $value. Let's try it both ways:

$ cargo run add --value 2
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.23s
Running `/Users/costincarabas/mvx/mx-contracts-rs/target/debug/basic-interact add --value 2`
sender's recalled nonce: 5499
-- tx nonce: 5499
sc call tx hash: 2b85ad0af8bed72f415abcf03ed1615ab2e72c33354400f66aafd22346d1871c
successfully performed add

Notice:

  • tx nonce - this is the sender's nonce;
  • sc call tx hash - this is the hash of the transaction we generated;

We recommend checking every action you perform:

 $ cargo run sum
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.27s
Running `/Users/costincarabas/mvx/mx-contracts-rs/target/debug/basic-interact sum`
sum: 2

Let's try the other way (-v $value):

 $ cargo run add -v 4
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.10s
Running `/Users/costincarabas/mvx/mx-contracts-rs/target/debug/basic-interact add -v 4`
sender's recalled nonce: 5500
-- tx nonce: 5500
sc call tx hash: a7f07975deb4ea01b19572146adb68b1b83abd1e7ed0396475cf389641ab03b5
successfully performed add

Let's check that the storage was incremented:

 $ cargo run sum
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.27s
Running `/Users/costincarabas/mvx/mx-contracts-rs/target/debug/basic-interact sum`
sum: 6

Question 1: Will these transactions (endpoint calling) show on the Explorer?

Question 2: Will all the validators execute these transactions (endpoint calling)?

- - + + \ No newline at end of file diff --git a/Practical Sessions/Smart Contracts/empty/index.html b/Practical Sessions/Smart Contracts/empty/index.html index eeacc1b2..091c5715 100644 --- a/Practical Sessions/Smart Contracts/empty/index.html +++ b/Practical Sessions/Smart Contracts/empty/index.html @@ -4,13 +4,13 @@ The Empty SC | Blockchain Protocols and Distributed Applications - - + +
-

The Empty SC

The smallest smart contract is an empty smart contract with no functionalities. Compiled, it is a binary that is accepted by the blockchain.

/// An empty contract. To be used as a template when starting a new contract from scratch.
#[multiversx_sc::contract]
pub trait EmptyContract {
#[init]
fn init(&self) {}
}

Here is the smart contract code listed above and here are all the files needed for compilation.

We have the annotation #[init] where we specify the constructor function. Only one constructor is allowed per smart contract.

Let's build the smart contract:

costin@Byblos:~/mvx/mx-contracts-rs/contracts/empty$ sc-meta all build
/home/costin/mvx/mx-contracts-rs/contracts/empty

Found 1 contract crates.

(1/1)
In /home/costin/mvx/mx-contracts-rs/contracts/empty/meta
Calling `cargo run build`
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.05s
Running `/home/costin/mvx/mx-contracts-rs/target/debug/empty-meta build`
Using workspace target directory: /home/costin/mvx/mx-contracts-rs/target ...
Building empty.wasm in /home/costin/mvx/mx-contracts-rs/contracts/empty/wasm ...
RUSTFLAGS="-C link-arg=-s -C link-arg=-zstack-size=131072" cargo build --target=wasm32-unknown-unknown --release --target-dir /home/costin/mvx/mx-contracts-rs/target
Compiling proc-macro2 v1.0.86
Compiling unicode-ident v1.0.13
Compiling hex v0.4.3
Compiling smallvec v1.13.2
Compiling autocfg v1.4.0
Compiling endian-type v0.1.2
Compiling arrayvec v0.7.6
Compiling unwrap-infallible v0.1.5
Compiling bitflags v2.6.0
Compiling hex-literal v0.4.1
Compiling nibble_vec v0.1.0
Compiling radix_trie v0.2.1
Compiling num-traits v0.2.19
Compiling quote v1.0.37
Compiling syn v2.0.77
Compiling multiversx-sc-codec-derive v0.21.0
Compiling multiversx-sc-derive v0.53.2
Compiling multiversx-sc-codec v0.21.0
Compiling multiversx-sc v0.53.2
Compiling empty v0.0.0 (/home/costin/mvx/mx-contracts-rs/contracts/empty)
Compiling multiversx-sc-wasm-adapter v0.53.2
Compiling empty-wasm v0.0.0 (/home/costin/mvx/mx-contracts-rs/contracts/empty/wasm)
Finished `release` profile [optimized] target(s) in 8.17s
Copying /home/costin/mvx/mx-contracts-rs/target/wasm32-unknown-unknown/release/empty_wasm.wasm to ../output/empty.wasm ...
Calling wasm-opt on ../output/empty.wasm ...
Extracting imports to ../output/empty.imports.json ...
Checking EI version: 1.3 ... OK
Packing ../output/empty.mxsc.json ...
Contract size: 231 bytes.

The resulted contract is output/empty.wasm, a WebAseembly binary module that is only 232 bytes:

costin@Byblos:~/mvx/mx-contracts-rs/contracts/empty$ ls -l output/
total 16
-rw-rw-r-- 1 costin costin 868 nov 7 12:17 empty.abi.json
-rw-rw-r-- 1 costin costin 60 nov 7 12:17 empty.imports.json
-rw-rw-r-- 1 costin costin 1774 nov 7 12:17 empty.mxsc.json
-rwxrwxr-x 1 costin costin 231 nov 7 12:17 empty.wasm

Practice

  • Clone the Empty SC repo;
  • Compile the contract.
- - +

The Empty SC

The smallest smart contract is an empty smart contract with no functionalities. Compiled, it is a binary that is accepted by the blockchain.

/// An empty contract. To be used as a template when starting a new contract from scratch.
#[multiversx_sc::contract]
pub trait EmptyContract {
#[init]
fn init(&self) {}
}

Here is the smart contract code listed above and here are all the files needed for compilation.

We have the annotation #[init] where we specify the constructor function. Only one constructor is allowed per smart contract.

Let's build the smart contract:

costin@Byblos:~/mvx/mx-contracts-rs/contracts/empty$ sc-meta all build
/home/costin/mvx/mx-contracts-rs/contracts/empty

Found 1 contract crates.

(1/1)
In /home/costin/mvx/mx-contracts-rs/contracts/empty/meta
Calling `cargo run build`
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.05s
Running `/home/costin/mvx/mx-contracts-rs/target/debug/empty-meta build`
Using workspace target directory: /home/costin/mvx/mx-contracts-rs/target ...
Building empty.wasm in /home/costin/mvx/mx-contracts-rs/contracts/empty/wasm ...
RUSTFLAGS="-C link-arg=-s -C link-arg=-zstack-size=131072" cargo build --target=wasm32-unknown-unknown --release --target-dir /home/costin/mvx/mx-contracts-rs/target
Compiling proc-macro2 v1.0.86
Compiling unicode-ident v1.0.13
Compiling hex v0.4.3
Compiling smallvec v1.13.2
Compiling autocfg v1.4.0
Compiling endian-type v0.1.2
Compiling arrayvec v0.7.6
Compiling unwrap-infallible v0.1.5
Compiling bitflags v2.6.0
Compiling hex-literal v0.4.1
Compiling nibble_vec v0.1.0
Compiling radix_trie v0.2.1
Compiling num-traits v0.2.19
Compiling quote v1.0.37
Compiling syn v2.0.77
Compiling multiversx-sc-codec-derive v0.21.0
Compiling multiversx-sc-derive v0.53.2
Compiling multiversx-sc-codec v0.21.0
Compiling multiversx-sc v0.53.2
Compiling empty v0.0.0 (/home/costin/mvx/mx-contracts-rs/contracts/empty)
Compiling multiversx-sc-wasm-adapter v0.53.2
Compiling empty-wasm v0.0.0 (/home/costin/mvx/mx-contracts-rs/contracts/empty/wasm)
Finished `release` profile [optimized] target(s) in 8.17s
Copying /home/costin/mvx/mx-contracts-rs/target/wasm32-unknown-unknown/release/empty_wasm.wasm to ../output/empty.wasm ...
Calling wasm-opt on ../output/empty.wasm ...
Extracting imports to ../output/empty.imports.json ...
Checking EI version: 1.3 ... OK
Packing ../output/empty.mxsc.json ...
Contract size: 231 bytes.

The resulted contract is output/empty.wasm, a WebAseembly binary module that is only 232 bytes:

costin@Byblos:~/mvx/mx-contracts-rs/contracts/empty$ ls -l output/
total 16
-rw-rw-r-- 1 costin costin 868 nov 7 12:17 empty.abi.json
-rw-rw-r-- 1 costin costin 60 nov 7 12:17 empty.imports.json
-rw-rw-r-- 1 costin costin 1774 nov 7 12:17 empty.mxsc.json
-rwxrwxr-x 1 costin costin 231 nov 7 12:17 empty.wasm

Practice

  • Clone the Empty SC repo;
  • Compile the contract.
+ + \ No newline at end of file diff --git a/Practical Sessions/Smart Contracts/index.html b/Practical Sessions/Smart Contracts/index.html index 41058770..f05d311a 100644 --- a/Practical Sessions/Smart Contracts/index.html +++ b/Practical Sessions/Smart Contracts/index.html @@ -4,13 +4,13 @@ Smart Contracts | Blockchain Protocols and Distributed Applications - - + +
-
- - +
+ + \ No newline at end of file diff --git a/Practical Sessions/Smart Contracts/mxpy_deploy/index.html b/Practical Sessions/Smart Contracts/mxpy_deploy/index.html index cba07ec9..b9540e5f 100644 --- a/Practical Sessions/Smart Contracts/mxpy_deploy/index.html +++ b/Practical Sessions/Smart Contracts/mxpy_deploy/index.html @@ -4,17 +4,17 @@ Smart Contract deployment via Python (mxpy) | Blockchain Protocols and Distributed Applications - - + +
-

Smart Contract deployment via Python (mxpy)

Let's deploy our smart contract on the blockchain. For this, we will use mxpy tools previously installed. +

Smart Contract deployment via Python (mxpy)

Let's deploy our smart contract on the blockchain. For this, we will use mxpy tools previously installed. We will deploy the adder contract from the previous section.

In the repo there is a folder named interaction.

Let's inspect the testnet.snippets.sh file:

ALICE="${USERS}/alice.pem"
ADDRESS=$(mxpy data load --key=address-testnet)
PROJECT="../output/adder.wasm"
DEPLOY_TRANSACTION=$(mxpy data load --key=deployTransaction-testnet)
PROXY=https://testnet-api.multiversx.com

deploy() {
mxpy --verbose contract deploy --project=${PROJECT} --recall-nonce --pem=${ALICE} --gas-limit=50000000 --arguments 0 --send --outfile="deploy-testnet.interaction.json" --proxy=${PROXY} --chain=T || return

TRANSACTION=$(mxpy data parse --file="deploy-testnet.interaction.json" --expression="data['emittedTransactionHash']")
ADDRESS=$(mxpy data parse --file="deploy-testnet.interaction.json" --expression="data['contractAddress']")

mxpy data store --key=address-testnet --value=${ADDRESS}
mxpy data store --key=deployTransaction-testnet --value=${TRANSACTION}

echo ""
echo "Smart contract address: ${ADDRESS}"
}

add() {
read -p "Enter number: " NUMBER
mxpy --verbose contract call ${ADDRESS} --recall-nonce --pem=${ALICE} --gas-limit=5000000 --function="add" --arguments ${NUMBER} --send --proxy=${PROXY} --chain=T
}

getSum() {
mxpy --verbose contract query ${ADDRESS} --function="getSum" --proxy=${PROXY}
}

This file helps us to easily make deployment and transactions on the blockchain.

First, let's modify the ALICE variable and put our own pem file.

After that use source command or . in bash to interpret the file:

costin@Byblos:~/mvx/mx-contracts-rs/contracts/adder/interaction$ . testnet.snippets.sh 

This will load all the variables and functions in the environment. Now we can call the deploy function:

costin@Byblos:~/mvx/mx-contracts-rs/contracts/adder/interaction$ deploy 
INFO cli.contracts: Contract address: erd1qqqqqqqqqqqqqpgq9ss82g55h3k96898kmdtp8am3a4qaefcuvaqutqjjd
INFO utils: View this contract address in the MultiversX Testnet Explorer: https://testnet-explorer.multiversx.com/accounts/erd1qqqqqqqqqqqqqpgq9ss82g55h3k96898kmdtp8am3a4qaefcuvaqutqjjd
INFO utils: View this transaction in the MultiversX Testnet Explorer: https://testnet-explorer.multiversx.com/transactions/761d6fb8b42cb0eed546f9c9f55ffbf2457f3fc35854e6030162fb65b6b840df
WARNING cli.data: Never use this command to store sensitive information! Data is unencrypted.
INFO cli.data: Data has been stored at key = 'address-testnet', in partition = '*'.
WARNING cli.data: Never use this command to store sensitive information! Data is unencrypted.
INFO cli.data: Data has been stored at key = 'deployTransaction-testnet', in partition = '*'.

Smart contract address: erd1qqqqqqqqqqqqqpgq9ss82g55h3k96898kmdtp8am3a4qaefcuvaqutqjjd

Now we have performed a deployment of the wasm binary (our adder contract) in the blockchain.

Notice the MultiversX Testnet Explorer: https://testnet-explorer.multiversx.com/transactions/761d6fb8b42cb0eed546f9c9f55ffbf2457f3fc35854e6030162fb65b6b840df. Click on the link to see your transaction.

Notice the Smart contract address: erd1qqqqqqqqqqqqqpgq9ss82g55h3k96898kmdtp8am3a4qaefcuvaqutqjjd. Go to the Testnet Explorer and search for your SC address.

Notice the contract deployed on testnet:

Contract deployed on Testnet

Observe the fields Owner, Deployed (timestamp).

- - + + \ No newline at end of file diff --git a/Practical Sessions/Smart Contracts/mxpy_sc_call/index.html b/Practical Sessions/Smart Contracts/mxpy_sc_call/index.html index 04813159..a7e40678 100644 --- a/Practical Sessions/Smart Contracts/mxpy_sc_call/index.html +++ b/Practical Sessions/Smart Contracts/mxpy_sc_call/index.html @@ -4,14 +4,14 @@ Smart Contract call | Blockchain Protocols and Distributed Applications - - + +
-

Smart Contract call

Now let's call our previous adder smart contract.

Inspect the deploy function in our testnet.snippets.sh. Observer that we provided the arguments: --arguments 0. +

Smart Contract call

Now let's call our previous adder smart contract.

Inspect the deploy function in our testnet.snippets.sh. Observer that we provided the arguments: --arguments 0. In our init function, we provided the argument and saved it in our sum global variable (storage):

#[init]
fn init(&self, initial_value: BigUint) {
self.sum().set(initial_value);
}

Therefore in the SC there is a sum storage initialized with 0.

Let's call the add endpoint to add a value to our storage:

/mvx/mx-contracts-rs/contracts/adder/interaction$ add 
Enter number: 2
INFO utils: View this transaction in the MultiversX Testnet Explorer: https://testnet-explorer.multiversx.com/transactions/2a906bc468008706f928cc5b7a669570c71556c604ae8d1ef2dfdfb100636f74
{
"emittedTransaction": {
"nonce": 313,
"value": "0",
"receiver": "erd1qqqqqqqqqqqqqpgq9ss82g55h3k96898kmdtp8am3a4qaefcuvaqutqjjd",
"sender": "erd1mqa9wttlzwwdvwgk9dzsfdn79lv5raw0tfe9ynvn0dg92hpruvaqhhd2gx",
"senderUsername": "",
"receiverUsername": "",
"gasPrice": 1000000000,
"gasLimit": 5000000,
"data": "YWRkQDAy",
"chainID": "T",
"version": 2,
"options": 0,
"guardian": "",
"signature": "187f19d7daad9b75f3f6469b56698ab84442786f4a592f4cb86efb858d40d63e75307964a4dd838bf114303427e3e4d2c9322936de3ee520c0ee9878bd2a8c0b",
"guardianSignature": ""
},
"emittedTransactionData": "add@02",
"emittedTransactionHash": "2a906bc468008706f928cc5b7a669570c71556c604ae8d1ef2dfdfb100636f74",
"contractAddress": "erd1qqqqqqqqqqqqqpgq9ss82g55h3k96898kmdtp8am3a4qaefcuvaqutqjjd"
}

Inspect the MultiversX Testnet Explorer to see the transaction.

Let's call the getSum view function to read from the storage:

costin@Byblos:~/mvx/mx-contracts-rs/contracts/adder/interaction$ getSum 
[
"02"
]

Notice that the view functions (the queries) are not transactions on blockchain. We didn't pay any gas for this. We didn't create any transaction.

- - + + \ No newline at end of file diff --git a/Practical Sessions/Smart Contracts/neversea/index.html b/Practical Sessions/Smart Contracts/neversea/index.html index 6746edcb..70fe70eb 100644 --- a/Practical Sessions/Smart Contracts/neversea/index.html +++ b/Practical Sessions/Smart Contracts/neversea/index.html @@ -4,17 +4,17 @@ Never Sea Festival Smart Contract | Blockchain Protocols and Distributed Applications - - + +
-

Never Sea Festival Smart Contract

You are the NeverSea Festival 2025 organizers and you decide to create the registration via blockchain. +

Never Sea Festival Smart Contract

You are the NeverSea Festival 2025 organizers and you decide to create the registration via blockchain. Starting from Smart Contract template you have to add more features to coordinate the event.

You can use the empty SC template:

$ sc-meta new --name my_neversea_2025 --template empty
[...]

$ ll my-neversea-2025/
total 16
drwxr-xr-x@ 8 costincarabas staff 256B Nov 6 04:21 .
drwxr-x---+ 54 costincarabas staff 1.7K Nov 6 04:21 ..
-rw-r--r--@ 1 costincarabas staff 343B Nov 6 04:21 Cargo.toml
drwxr-xr-x@ 4 costincarabas staff 128B Nov 6 04:21 meta
-rw-r--r--@ 1 costincarabas staff 26B Nov 6 04:21 multiversx.json
drwxr-xr-x@ 3 costincarabas staff 96B Nov 6 04:21 scenarios
drwxr-xr-x@ 3 costincarabas staff 96B Nov 6 04:21 src
drwxr-xr-x@ 4 costincarabas staff 128B Nov 6 04:21 tests

There are several other templates:

$ sc-meta templates
empty
ping-pong-egld
crypto-zombies
adder

Compile the Smart Contract template

To check that the contract was successfully built, verify that there was a wasm (WebAssembly) file generate: output/your-contract-name.wasm. This is the compiled code of your contract.


NOTE

For any further actions, please check the compilation on your local machine (and the deployment on the explorer, if it's the case). Do not assume that the contract was successfully compiled and deployed.

Any modification of the contract must be succeeded by a compilation and deployment!

Constructor

Implement the init function so that it will take an argument that it's the registration fee and set a registration_fee storage. Implement the upgrade function so that it won't take any argument.

Storages

Add 2 storages:

  • participants - a set of addresses (you can use ManagedAddress) that stores the participants list;
  • registration_fee - you can use BigUint to store the fee.

Add endpoints

Add a register endpoint where clients will pay the fee via EGLD to register to the festival. Add a update_registration_fees endpoint where the owner can update the fee. Use #[only_owner] annotation so that the endpoint can be called only by the owner.

Practice

  • Make a contract call to register a user;
  • Make a contract call to view the registered users;
  • Modify the registration endpoint to enable VIP access;
  • Create a new storage mapper registration_fee_vip;
  • Create a new storage mapper vip_participants to save the VIP participants;
  • In the registration endpoint, make a verification of the tokens received. If the tokens received is registration_fee_vip, add the user to vip_participants, if the amount is registration_fee, add them to participants, else, deny registration;
  • Modify the registration fee to enable Early Bird and Full price access;
  • Create a new endpoint that modifies the registration_fee and registration_fee_vip storage mapper. This endpoint should be call only by the owner.
  • BONUS: Create a feature to enable 50% discount vouchers for friends and partners. Create a list of hardcoded discount codes. Create a new endpoint that receives a discount code as a parameter and registers a user with 50% discount.

Hint -Use #[only_owner] endpoint annotation.


- - +Use #[only_owner] endpoint annotation.


+ + \ No newline at end of file diff --git a/Practical Sessions/Smart Contracts/prerequisites/index.html b/Practical Sessions/Smart Contracts/prerequisites/index.html index 17c38663..fc7ff3d1 100644 --- a/Practical Sessions/Smart Contracts/prerequisites/index.html +++ b/Practical Sessions/Smart Contracts/prerequisites/index.html @@ -4,13 +4,13 @@ Prerequisites | Blockchain Protocols and Distributed Applications - - + +
-

Prerequisites

All of these prerequisites were done at the first lab. You can skip this section if you have already done this.

Install mxpy - blockchain interaction

We use mxpy to interact with the blockchain.

To install mxpy run:

pipx install multiversx-sdk-cli --force

To check the successful installation:

$ mxpy --version
MultiversX Python CLI (mxpy) 9.8.1

If you encounter any errors, follow the guide here.

Install sc-meta - contract interaction

We use sc-meta to compile the contracts and to upgrade the dependencies.

To install sc-meta, simply call:

$ cargo install multiversx-sc-meta

To check for successful installation:

$ sc-meta --version
multiversx-sc-meta 0.54.0

If you encounter any errors, follow the guide here.

Contracts examples

Here is a list of Smart Contract examples. We will use part of them to understand smart contracts on MultiversX.

- - +

Prerequisites

All of these prerequisites were done at the first lab. You can skip this section if you have already done this.

Install mxpy - blockchain interaction

We use mxpy to interact with the blockchain.

To install mxpy run:

pipx install multiversx-sdk-cli --force

To check the successful installation:

$ mxpy --version
MultiversX Python CLI (mxpy) 9.8.1

If you encounter any errors, follow the guide here.

Install sc-meta - contract interaction

We use sc-meta to compile the contracts and to upgrade the dependencies.

To install sc-meta, simply call:

$ cargo install multiversx-sc-meta

To check for successful installation:

$ sc-meta --version
multiversx-sc-meta 0.54.0

If you encounter any errors, follow the guide here.

Contracts examples

Here is a list of Smart Contract examples. We will use part of them to understand smart contracts on MultiversX.

+ + \ No newline at end of file diff --git a/Practical Sessions/Smart Contracts/rust_interactors/index.html b/Practical Sessions/Smart Contracts/rust_interactors/index.html index feef58c6..aa892db9 100644 --- a/Practical Sessions/Smart Contracts/rust_interactors/index.html +++ b/Practical Sessions/Smart Contracts/rust_interactors/index.html @@ -4,14 +4,14 @@ Creating a Rust interactor | Blockchain Protocols and Distributed Applications - - + +
-

Creating a Rust interactor

Rust interactors are used to interact with the blockchain via Rust.

Let's do this for the empty SC:

sc-meta all snippets
/Users/costincarabas/mvx/mx-contracts-rs/contracts/empty

Found 1 contract crates.

(1/1)
In /Users/costincarabas/mvx/mx-contracts-rs/contracts/empty/meta
Calling `cargo run snippets`
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.16s
Running `/Users/costincarabas/mvx/mx-contracts-rs/target/debug/empty-meta snippets`

A new folder interactor was created. +

Creating a Rust interactor

Rust interactors are used to interact with the blockchain via Rust.

Let's do this for the empty SC:

sc-meta all snippets
/Users/costincarabas/mvx/mx-contracts-rs/contracts/empty

Found 1 contract crates.

(1/1)
In /Users/costincarabas/mvx/mx-contracts-rs/contracts/empty/meta
Calling `cargo run snippets`
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.16s
Running `/Users/costincarabas/mvx/mx-contracts-rs/target/debug/empty-meta snippets`

A new folder interactor was created. This will generate code for all the endpoints and view functions you created.

As this is a new and separate Rust binary, you must add it to the main Cargo.toml's members:

members = [
[...]
"contracts/empty/interactor",
[...]
]

Now you can use it:

$ cargo run deploy
[...]
sender's recalled nonce: 10595
-- tx nonce: 10595
sc deploy tx hash: a17a4f51305b6f6dd9c01ec4986d0f90266ef560599b15af613e9aadd816e705
deploy address: erd1qqqqqqqqqqqqqpgqchszakc8fm44c2rndjh09xeuh829g4tgd8sskk0m5e

Practice

  • Create an interactor for you Empty contract.
- - + + \ No newline at end of file diff --git a/Practical Sessions/Tokens/fungible-non-fungible/index.html b/Practical Sessions/Tokens/fungible-non-fungible/index.html index 06c55873..fd7e5b1b 100644 --- a/Practical Sessions/Tokens/fungible-non-fungible/index.html +++ b/Practical Sessions/Tokens/fungible-non-fungible/index.html @@ -4,13 +4,13 @@ Fungible vs Non-Fungible Tokens | Blockchain Protocols and Distributed Applications - - + +
-

Fungible vs Non-Fungible Tokens

  • Fungibility refers to an asset's ability to be exchanged for something else of equal value;
  • Some examples of fungible assets include currencies, commodities, and precious stones;
  • Non-fungible assets are unique, requiring much more complex valuation before a sale and include things like real estate, art, and sports cards.

Throughout the lab, you will need to convert values from decimals to hex to ascii, etc. Use this tool to make your job easier.

Practice

Think about the following example if fungible or non-fungible:

  • Diamond rock;
  • Penthouse apartment in Manhattan;
  • Mona Lisa painting;
  • LeBron James sport card;
  • LeBron James shirt he played in the 2020 NBA Finals;
  • A character in World of Warcraft.
- - +

Fungible vs Non-Fungible Tokens

  • Fungibility refers to an asset's ability to be exchanged for something else of equal value;
  • Some examples of fungible assets include currencies, commodities, and precious stones;
  • Non-fungible assets are unique, requiring much more complex valuation before a sale and include things like real estate, art, and sports cards.

Throughout the lab, you will need to convert values from decimals to hex to ascii, etc. Use this tool to make your job easier.

Practice

Think about the following example if fungible or non-fungible:

  • Diamond rock;
  • Penthouse apartment in Manhattan;
  • Mona Lisa painting;
  • LeBron James sport card;
  • LeBron James shirt he played in the 2020 NBA Finals;
  • A character in World of Warcraft.
+ + \ No newline at end of file diff --git a/Practical Sessions/Tokens/fungible/index.html b/Practical Sessions/Tokens/fungible/index.html index 9b77442f..700099f0 100644 --- a/Practical Sessions/Tokens/fungible/index.html +++ b/Practical Sessions/Tokens/fungible/index.html @@ -4,16 +4,16 @@ Fungible Tokens | Blockchain Protocols and Distributed Applications - - + +
-

Fungible Tokens

Issuance of fungible ESDT tokens via Web Wallet on MultiversX

In this section you will learn how to mint tokens on MultiversX.

There are 2 types of tokens on MultiversX:

  • Native tokens - EGLD;
  • ESDT - eStandard Digital Token.

In the previous section you learnt how to mint xEGLD on MultiversX Testnet using Faucet option.

Testnet Wallet

Mint ESDT via Web Wallet

This time we use the Create Token option.

Token Name:

  • length between 3 and 20 characters
  • alphanumeric characters only

Token Ticker:

  • length between 3 and 10 characters
  • alphanumeric UPPERCASE only

Number of decimals:

  • should be a numerical value between 0 and 18;
  • there are no floats on the blockchain;
  • a token with 3 decimals and value 1000 would be equal with value 1;
  • EGLD has 18 decimals and the value of 1000000000000000000 is 1 EGLD.

Let's create a token new token:

Issue Token

and inspect the transaction

Explorer Token Created

Observe Token Operations field. We received 321.00 BPDA-208994 tokens. BPDA-208994 is the token ID. The token ID is formed by appending to the token ticker the character - and 6 random hexadecimals characters. This is done because there might be mutiple tokens with the same ticker; the token ID is always unique.

We can click on the token ID and see the details of the token:

Token Details

Observe the fields TOKEN, Supply, Holders, Transactions, Owner, Decimals.

Let create another token with the same input:

Issue Token2

Observe that the token ID is different.

Practice

  • Create your own ESDT token;
  • Inspect the transaction;
  • Send some of your tokens to erd1mqa9wttlzwwdvwgk9dzsfdn79lv5raw0tfe9ynvn0dg92hpruvaqhhd2gx;
  • Create another token with the same ticker. Observer that the token ID is different and unique.

Issuance of fungible ESDT tokens via cmdline on MultiversX

Throughout the lab, you will need to convert values from decimals to hex to ascii, etc. Use this tool to make your job easier.

ESDT tokens are issued via a request to the Metachain, which is a transaction submitted by the Account which will manage the tokens. When issuing a token, one must provide a token name, a ticker, the initial supply, the number of decimals for display purpose and optionally additional properties. The issuance cost is set to 0.05 EGLD.

The receiver address erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u is a built-in system smart contract (not a VM-executable contract), which only handles token issuance and other token management operations, and does not handle any transfers. The contract will add a random string to the ticker thus creating the token identifier. The random string starts with “-” and has 6 more random characters (3 bytes - 6 characters hex encoded). For example, a token identifier could look like ALC-6258d2.

Read more about issuance of fungible ESDT tokens here.

Issuance example:

IssuanceTransaction {
Sender: <account address of the token manager>
Receiver: erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u
Value: 50000000000000000 # (0.05 EGLD)
GasLimit: 60000000
Data: "issue" +
"@" + <token name in hexadecimal encoding> +
"@" + <token ticker in hexadecimal encoding> +
"@" + <initial supply in hexadecimal encoding> +
"@" + <number of decimals in hexadecimal encoding>
}

Practice

  • Issue a token of your own using mxpy. Choose whatever name and ticker you want. Check the existance of your token via Testnet Explorer.

Hint: Use mxpy --help

Mint fungible ESDT tokens via cmdline


NOTE

Actions issue and mint are distinct! First, one must issue the token to exist on the blockchain. Second, the owner/issuer of the token must mint tokens.


The transaction to mint tokens is:

LocalMintTransaction {
Sender: <address with ESDTRoleLocalMint role>
Receiver: <same as sender>
Value: 0
GasLimit: 300000
Data: "ESDTLocalMint" +
"@" + <token identifier in hexadecimal encoding> +
"@" + <supply to mint in hexadecimal encoding>
}

Note that the sender and the receiver are the same address, which is the creator of the token. +

Fungible Tokens

Issuance of fungible ESDT tokens via Web Wallet on MultiversX

In this section you will learn how to mint tokens on MultiversX.

There are 2 types of tokens on MultiversX:

  • Native tokens - EGLD;
  • ESDT - eStandard Digital Token.

In the previous section you learnt how to mint xEGLD on MultiversX Testnet using Faucet option.

Testnet Wallet

Mint ESDT via Web Wallet

This time we use the Create Token option.

Token Name:

  • length between 3 and 20 characters
  • alphanumeric characters only

Token Ticker:

  • length between 3 and 10 characters
  • alphanumeric UPPERCASE only

Number of decimals:

  • should be a numerical value between 0 and 18;
  • there are no floats on the blockchain;
  • a token with 3 decimals and value 1000 would be equal with value 1;
  • EGLD has 18 decimals and the value of 1000000000000000000 is 1 EGLD.

Let's create a token new token:

Issue Token

and inspect the transaction

Explorer Token Created

Observe Token Operations field. We received 321.00 BPDA-208994 tokens. BPDA-208994 is the token ID. The token ID is formed by appending to the token ticker the character - and 6 random hexadecimals characters. This is done because there might be mutiple tokens with the same ticker; the token ID is always unique.

We can click on the token ID and see the details of the token:

Token Details

Observe the fields TOKEN, Supply, Holders, Transactions, Owner, Decimals.

Let create another token with the same input:

Issue Token2

Observe that the token ID is different.

Practice

  • Create your own ESDT token;
  • Inspect the transaction;
  • Send some of your tokens to erd1mqa9wttlzwwdvwgk9dzsfdn79lv5raw0tfe9ynvn0dg92hpruvaqhhd2gx;
  • Create another token with the same ticker. Observer that the token ID is different and unique.

Issuance of fungible ESDT tokens via cmdline on MultiversX

Throughout the lab, you will need to convert values from decimals to hex to ascii, etc. Use this tool to make your job easier.

ESDT tokens are issued via a request to the Metachain, which is a transaction submitted by the Account which will manage the tokens. When issuing a token, one must provide a token name, a ticker, the initial supply, the number of decimals for display purpose and optionally additional properties. The issuance cost is set to 0.05 EGLD.

The receiver address erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u is a built-in system smart contract (not a VM-executable contract), which only handles token issuance and other token management operations, and does not handle any transfers. The contract will add a random string to the ticker thus creating the token identifier. The random string starts with “-” and has 6 more random characters (3 bytes - 6 characters hex encoded). For example, a token identifier could look like ALC-6258d2.

Read more about issuance of fungible ESDT tokens here.

Issuance example:

IssuanceTransaction {
Sender: <account address of the token manager>
Receiver: erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u
Value: 50000000000000000 # (0.05 EGLD)
GasLimit: 60000000
Data: "issue" +
"@" + <token name in hexadecimal encoding> +
"@" + <token ticker in hexadecimal encoding> +
"@" + <initial supply in hexadecimal encoding> +
"@" + <number of decimals in hexadecimal encoding>
}

Practice

  • Issue a token of your own using mxpy. Choose whatever name and ticker you want. Check the existance of your token via Testnet Explorer.

Hint: Use mxpy --help

Mint fungible ESDT tokens via cmdline


NOTE

Actions issue and mint are distinct! First, one must issue the token to exist on the blockchain. Second, the owner/issuer of the token must mint tokens.


The transaction to mint tokens is:

LocalMintTransaction {
Sender: <address with ESDTRoleLocalMint role>
Receiver: <same as sender>
Value: 0
GasLimit: 300000
Data: "ESDTLocalMint" +
"@" + <token identifier in hexadecimal encoding> +
"@" + <supply to mint in hexadecimal encoding>
}

Note that the sender and the receiver are the same address, which is the creator of the token. After this transaction, he will receive in his wallet the minted tokens.

Practice

  • Use the token created at the previous section to mint some tokens. Verifiy on the Testnet Explorer and in your wallet.

Setting ESDT Roles

Notice the Properties section in a Token page. UTK tokens

There are several roles assigned to a token. To change those roles we need to make a blockchain transaction:

RolesAssigningTransaction {
Sender: <address of the ESDT manager>
Receiver: erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u
Value: 0
GasLimit: 60000000
Data: "setSpecialRole" +
"@" + <token identifier in hexadecimal encoding> +
"@" + <address to assign the role(s) in a hexadecimal encoding> +
"@" + <role in hexadecimal encoding> +
"@" + <role in hexadecimal encoding> +
...
}

Practice

  • Observe the roles of your newly created token.
  • Add ESDTRoleLocalMint and ESDTRoleLocalBurn for your address.
  • Mint 1000 tokens.

You can read more about roles in the documentation.

Burning ESDT Tokens

Anyone that holds an amount of ESDT tokens may burn it at their discretion, effectively losing them permanently. This operation reduces the total supply of tokens, and cannot be undone, unless the token manager mints more tokens.

Do you have roles for burning?

LocalBurnTransaction {
Sender: <address with ESDTRoleLocalBurn role>
Receiver: <same as sender>
Value: 0
GasLimit: 300000
Data: "ESDTLocalBurn" +
"@" + <token identifier in hexadecimal encoding> +
"@" + <supply to burn in hexadecimal encoding>
}

Practice

  • Burn 500 tokens

Other actions for ESDTTokens

Pausing and Unpausing

The manager of an ESDT token may choose to suspend all transactions of the token, except minting, freezing/unfreezing and wiping. Check more details here.

Freezing and Unfreezing

The manager of an ESDT token may freeze the tokens held by a specific Account. As a consequence, no tokens may be transferred to or from the frozen Account. Freezing and unfreezing the tokens of an Account are operations designed to help token managers to comply with regulations. The manager of an ESDT token may choose to suspend all transactions of the token, except minting, freezing/unfreezing and wiping. Check more details here.

Wiping

The manager of an ESDT token may wipe out all the tokens held by a frozen Account. This operation is similar to burning the tokens, but the Account must have been frozen beforehand, and it must be done by the token manager. Wiping the tokens of an Account is an operation designed to help token managers to comply with regulations. The manager of an ESDT token may choose to suspend all transactions of the token, except minting, freezing/unfreezing and wiping. Check more details here.

- - + + \ No newline at end of file diff --git a/Practical Sessions/Tokens/index.html b/Practical Sessions/Tokens/index.html index bba5de06..db10f72a 100644 --- a/Practical Sessions/Tokens/index.html +++ b/Practical Sessions/Tokens/index.html @@ -4,13 +4,13 @@ Tokens | Blockchain Protocols and Distributed Applications - - + + - - +
+ + \ No newline at end of file diff --git a/Practical Sessions/Tokens/nft/index.html b/Practical Sessions/Tokens/nft/index.html index dc274d4d..9f8fe7ac 100644 --- a/Practical Sessions/Tokens/nft/index.html +++ b/Practical Sessions/Tokens/nft/index.html @@ -4,12 +4,12 @@ Non-Fungible Tokens (NFTs) | Blockchain Protocols and Distributed Applications - - + +
-

Non-Fungible Tokens (NFTs)

These NFTs are unique, one-of-a-kind tokens that are built on blockchain technology, allowing for secure ownership and transfer of these assets. +

Non-Fungible Tokens (NFTs)

These NFTs are unique, one-of-a-kind tokens that are built on blockchain technology, allowing for secure ownership and transfer of these assets. Every token is assigned a unique identification code(ticker) and metadata that distinguishes it from every other token.

The flow of issuing and transferring non-fungible tokens is:

  • register/issue the token (this step creates an empty collection);
  • set roles to the address that will create the NFT/SFTs;
  • create the NFT/SFT;
  • transfer quantity(es).

Issuance of NFT tokens

One has to perform an issuance transaction in order to register a non-fungible token. Non-Fungible Tokens are issued via a request to the Metachain, which is a transaction submitted by the Account which will manage the tokens. When issuing a token, one must provide a token name, a ticker and optionally additional properties. This transaction has the form:

IssuanceTransaction {
Sender: <account address of the token manager>
Receiver: erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u
Value: 50000000000000000 # (0.05 EGLD)
GasLimit: 60000000
Data: "issueNonFungible" +
"@" + <token name in hexadecimal encoding> +
"@" + <token ticker in hexadecimal encoding>
}

Optionally, the properties can be set when issuing a token. Example:

IssuanceTransaction {
Sender: <account address of the token manager>
Receiver: erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u
Value: 50000000000000000 # (0.05 EGLD)
GasLimit: 60000000
Data: "issueNonFungible" +
"@" + <token name in hexadecimal encoding> +
"@" + <token ticker in hexadecimal encoding> +
"@" + <"canFreeze" hexadecimal encoded> + "@" + <"true" or "false" hexadecimal encoded> +
"@" + <"canWipe" hexadecimal encoded> + "@" + <"true" or "false" hexadecimal encoded> +
"@" + <"canPause" hexadecimal encoded> + "@" + <"true" or "false" hexadecimal encoded> +
"@" + <"canTransferNFTCreateRole" hexadecimal encoded> + "@" + <"true" or "false" hexadecimal encoded> +
"@" + <"canChangeOwner" hexadecimal encoded> + "@" + <"true" or "false" hexadecimal encoded> +
"@" + <"canUpgrade" hexadecimal encoded> + "@" + <"true" or "false" hexadecimal encoded> +
"@" + <"canAddSpecialRoles" hexadecimal encoded> + "@" + <"true" or "false" hexadecimal encoded> +
...
}

Practice

Let's create our first NFT collection. We will make a transaction to the testnet blockchain via mxpy tool. @@ -21,7 +21,7 @@ For example, ESDTRoleNFTCreate = 0x45534454526f6c654e4654437265617465.

NFT fields

Below you can find the fields involved when creating an NFT:

  • NFT Name
    • The name of the NFT or SFT;
  • Quantity
    • The quantity of the token. If NFT, it must be 1;
    • There are Semi-Fungible Tokens (SFT). You can read more here;
  • Royalties - Allows the creator to receive royalties for any transaction involving their NFT
    • Allows the creator to receive royalties for any transaction involving their NFT;
    • Base format is a numeric value between 0 an 10000 (0 meaning 0% and 10000 meaning 100%)
  • Hash
    • Arbitrary field that should contain the hash of the NFT metadata;
    • Optional filed, should be left null when building the transaction to create the NFT;
  • Attributes
    • Represents additional information about the NFT or SFT, like picture traits or tags for your NFT/collection;
    • The field should follow a metadata:ipfsCID/fileName.json;tags:tag1,tag2,tag3 format;
    • Below you can find a sample for the extra metadata format that should be stored on IPFS:
{
"description": "This is a sample description",
"attributes": [
{
"trait_type": "Background",
"value": "Yellow",
"{key}": "{value}",
"{...}": "{...}",
"{key}": "{value}"
},
{
"trait_type": "Headwear",
"value": "BlackBeanie"
},
{
"trait_type": "SampleTrait3",
"value": "SampleValue3"
}
],
"collection": "ipfsCID/fileName.json"
}

  • URI(s)
    • Mandatory field that represents the URL to a supported media file ending with the file extension as described in the example below;
    • Field should contain the Uniform Resource Identifier;

NOTE

Please note that each argument must be encoded in hexadecimal format with an even number of characters.


Creation of an NFT

A single address can own the role of creating an NFT for an ESDT token. This role can be transferred by using the ESDTNFTCreateRoleTransfer function.

An NFT can be created on top of an existing ESDT by sending a transaction to self that contains the function call that triggers the creation. Any number of URIs can be assigned (minimum 1).

NFTCreationTransaction {
Sender: <address with ESDTRoleNFTCreate role>
Receiver: <same as sender>
Value: 0
GasLimit: 3000000 + Additional gas (see below)
Data: "ESDTNFTCreate" +
"@" + <token identifier in hexadecimal encoding> +
"@" + <initial quantity in hexadecimal encoding> +
"@" + <NFT name in hexadecimal encoding> +
"@" + <Royalties in hexadecimal encoding> +
"@" + <Hash in hexadecimal encoding> +
"@" + <Attributes in hexadecimal encoding> +
"@" + <URI in hexadecimal encoding> +
"@" + <URI in hexadecimal encoding> +
...
}

Additional gas refers to:

  • Transaction payload cost: Data field length * 1500 (GasPerDataByte = 1500);
  • Storage cost: Size of NFT data * 50000 (StorePerByte = 50000).

Transfer NFT Creation Role

The role of creating an NFT can be transferred by a Transaction like this:

TransferCreationRoleTransaction {
Sender: <address of the current creation role owner>
Receiver: erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u
Value: 0
GasLimit: 60000000 + length of Data field in bytes * 1500
Data: "transferNFTCreateRole" +
"@" + <token identifier in hexadecimal encoding> +
"@" + <the address to transfer the role from in hexadecimal encoding> +
"@" + <the address to transfer the role to in hexadecimal encoding>
}

Change NFT Attributes

An user that has the `ESDTRoleNFTUpdateAttributes`` role set for a given ESDT, can change the attributes of a given NFT/SFT.


NOTE

ESDTNFTUpdateAttributes will remove the old attributes and add the new ones. Therefore, if you want to keep the old attributes you will have to pass them along with the new ones.


This is done by performing a transaction like this:

ESDTNFTUpdateAttributesTransaction {
Sender: <address of an address that has ESDTRoleNFTUpdateAttributes role>
Receiver: <same as sender>
Value: 0
GasLimit: 10000000
Data: "ESDTNFTUpdateAttributes" +
"@" + <token identifier in hexadecimal encoding> +
"@" + <NFT or SFT nonce in hexadecimal encoding> +
"@" + <Attributes in hexadecimal encoding>
}

Transfers

Performing an ESDT NFT transfer is done by specifying the receiver's address inside the Data field, alongside other details. An ESDT NFT transfer transaction has the following form:

TransferTransaction {
Sender: <account address of the sender>
Receiver: <same as sender>
Value: 0
GasLimit: 1000000 + length of Data field in bytes * 1500
Data: "ESDTNFTTransfer" +
"@" + <collection identifier in hexadecimal encoding> +
"@" + <the NFT nonce in hexadecimal encoding> +
"@" + <quantity to transfer in hexadecimal encoding> +
"@" + <destination address in hexadecimal encoding>
}

Branding

Here is SubcarpatiOGs NFT Collection. Stramosi NFT

Observe that there are Social links, a Description and you can even see a Logo.

For branding you NFT collection please read the instructions.

- - + + \ No newline at end of file diff --git a/Practical Sessions/Tokens/standards/index.html b/Practical Sessions/Tokens/standards/index.html index 546b5236..87d77fa8 100644 --- a/Practical Sessions/Tokens/standards/index.html +++ b/Practical Sessions/Tokens/standards/index.html @@ -4,16 +4,16 @@ Token Standards | Blockchain Protocols and Distributed Applications - - + +
-

Token Standards

A crypto token is a representation of an asset or interest that has been tokenized on an existing cryptocurrency's blockchain. Crypto tokens and cryptocurrencies share many similarities, but cryptocurrencies are intended to be used as a medium of exchange, a means of payment, and a measure and store of value.

Crypto tokens are often used to raise funds for projects and are usually created, distributed, sold, and circulated through an initial coin offering (ICO) process, which involves a crowdfunding round.

In this section we will discuss 2 different approaches of token implementation:

  • Ethereum Standard: ERC - Ethereum Request for Comments
  • MultiversX: ESDT - eStandard Digital Token

ERC - Ethereum Request for Comments

ERC (Ethereum Request for Comments) standards provide a set of guidelines and specifications for creating and implementing smart contracts, tokens, and other blockchain-based applications on the Ethereum network. +

Token Standards

A crypto token is a representation of an asset or interest that has been tokenized on an existing cryptocurrency's blockchain. Crypto tokens and cryptocurrencies share many similarities, but cryptocurrencies are intended to be used as a medium of exchange, a means of payment, and a measure and store of value.

Crypto tokens are often used to raise funds for projects and are usually created, distributed, sold, and circulated through an initial coin offering (ICO) process, which involves a crowdfunding round.

In this section we will discuss 2 different approaches of token implementation:

  • Ethereum Standard: ERC - Ethereum Request for Comments
  • MultiversX: ESDT - eStandard Digital Token

ERC - Ethereum Request for Comments

ERC (Ethereum Request for Comments) standards provide a set of guidelines and specifications for creating and implementing smart contracts, tokens, and other blockchain-based applications on the Ethereum network. ERCs are a set of technical standards that are used to create and manage tokens on the Ethereum blockchain. ERC standards define a set of rules and protocols that tokens must follow in order to be compatible with the Ethereum network. These rules cover a variety of aspects, such as token transfer functions, token ownership, and smart contract security. By following these standards, developers can ensure that their tokens are interoperable with other tokens and can be easily exchanged on the Ethereum network.

There are currently several ERC standards, including ERC-20, ERC-721, ERC-777, and ERC-1155, each of which has a specific set of features and functions. ERC-20 is the most widely used token standard and is used to create fungible tokens, while ERC-721 is used to create non-fungible tokens (NFTs). Other ERC standards, such as ERC-777 and ERC-1155, provide additional features and functions for creating more complex tokens.

You can read more about ERC-20 and ERC-721.

Here are the top Ethereum tokens.

ESDT - eStandard Digital Token

The MultiversX network natively supports the issuance of custom tokens, without the need for contracts such as ERC20, but addressing the same use-cases. And due to the native in-protocol support, transactions with custom tokens do not require the VM at all.

Technically, the balances of ESDT tokens held by an Account are stored directly under the data trie of that Account. It also implies that an Account can hold balances of any number of custom tokens, in addition to the native EGLD balance. The protocol guarantees that no Account can modify the storage of ESDT tokens, neither its own nor of other Accounts.

ESDT tokens can be issued, owned and held by any Account on the MultiversX network, which means that both users and smart contracts have the same functionality available to them.

Diferences between ERC and ESDT

The first difference we observe is that ERC standards are smart contracts deployed on blockchain while ESDTs are tokens assigned to users. In ERC user balances are stored in the Smart Contract while in ESDT balances are stored in users' wallets.

Here are the top MultiversX tokens.

- - + + \ No newline at end of file diff --git a/Practical Sessions/Wallet/Cmd line wallet/cmdline_wallet/index.html b/Practical Sessions/Wallet/Cmd line wallet/cmdline_wallet/index.html index f4fd4335..4fe515f2 100644 --- a/Practical Sessions/Wallet/Cmd line wallet/cmdline_wallet/index.html +++ b/Practical Sessions/Wallet/Cmd line wallet/cmdline_wallet/index.html @@ -4,16 +4,16 @@ First Blockchain transaction | Blockchain Protocols and Distributed Applications - - + +
-

First Blockchain transaction

Let's perform our first ever blockchain transaction. +

First Blockchain transaction

Let's perform our first ever blockchain transaction. We will do this on MultiversX blockchain.

First, we need a wallet. Every access, read, write, execute, etc to the blockchain needs to be sign by you with a private key (a wallet).

To create a wallet simply run:

$ mxpy wallet new --format pem --outfile new_wallet.pem

Let's interpret the output:

$ mxpy wallet new --format pem --outfile new_wallet.pem
Mnemonic: bid blind field captain bar produce brush salute luggage double hole wonder meadow glass destroy giraffe auction square crush catalog knee lizard century nasty
Wallet address: erd1pfhel08mq6ucua005qgyvwq0el78ap3ytpcugy35yvqfdeq7afqsydkj3d

First, there is a mnemonic: 24 random words. These words are used to create your private key (wallet) at any time, so you must store them carefully. For now, this is only a test wallet, so just store them in a text file on your computer.

Second, we have a wallet address. This is our blockchain address.

Third, we have a new file new_wallet.pem that contains our private key (wallet):

$ cat new_wallet.pem 
-----BEGIN PRIVATE KEY for erd1pfhel08mq6ucua005qgyvwq0el78ap3ytpcugy35yvqfdeq7afqsydkj3d-----
NjM1N2UxOGQxYjBjMDk5ZjY1MzM2OWUxZGFiZGM3Mzg1Yjc5ZmY0ZWNlZTBiNWY5
NWFmNjE1MzZjZDMwODNhOTBhNmY5ZmJjZmIwNmI5OGU3NWVmYTAxMDQ2MzgwZmNm
ZmM3ZTg2MjQ1ODcxYzQxMjM0MjMwMDk2ZTQxZWVhNDE=
-----END PRIVATE KEY for erd1pfhel08mq6ucua005qgyvwq0el78ap3ytpcugy35yvqfdeq7afqsydkj3d-----
- - + + \ No newline at end of file diff --git a/Practical Sessions/Wallet/Keystore/index.html b/Practical Sessions/Wallet/Keystore/index.html index 929b7f8c..e4d71d2f 100644 --- a/Practical Sessions/Wallet/Keystore/index.html +++ b/Practical Sessions/Wallet/Keystore/index.html @@ -4,13 +4,13 @@ Keystore files | Blockchain Protocols and Distributed Applications - - + +
-

Keystore files

The MultiversX keystore is a JSON file that holds a mnemonic (seed phrase), encrypted with a password (as chosen by the user). Thus, the keystore provides users with a reliable and convenient method for managing their hot wallets and protecting their assets.

Here is an example of a MultiversX Keystore:

{
"version": 4,
"id": "5b448dbc-5c72-4d83-8038-938b1f8dff19",
"kind": "mnemonic",
"crypto": {
"ciphertext": "6d70fbdceba874f56f15af4b1d060223799288cfc5d276d9ebb91732f5a38c3c59f83896fa7e7eb6a04c05475a6fe4d154de9b9441864c507abd0eb6987dac521b64c0c82783a3cd1e09270cd6cb5ae493f9af694b891253ac1f1ffded68b5ef39c972307e3c33a8354337540908acc795d4df72298dda1ca28ac920983e6a39a01e2bc988bd0b21f864c6de8b5356d11e4b77bc6f75ef",
"cipherparams": {
"iv": "2da5620906634972d9a623bc249d63d4"
},
"cipher": "aes-128-ctr",
"kdf": "scrypt",
"kdfparams": {
"dklen": 32,
"salt": "aa9e0ba6b188703071a582c10e5331f2756279feb0e2768f1ba0fd38ec77f035",
"n": 4096,
"r": 8,
"p": 1
},
"mac": "5bc1b20b6d903b8ef3273eedf028112d65eaf85a5ef4215917c1209ec2df715a"
}
}

At first, you will see an unappealing JSON file, which appears to contain magic parameters used for numerous complex cryptographic operations with unclear and vague purpose. But if you dig a little deeper you will see that it contains:

  • kind - Can be secretKey or mnemonic and represents the input to be encrypted using the cipher;
  • ciphertext - Your MultiversX mnemonic or secret key encrypted using the cipher algorithm below;
  • cipher - The name of a symmetric AES algorithm;
  • cipherparams - The parameters required for the cipher algorithm above;
  • kdf - A key derivation function used to let you encrypt your keystore file with a password;
  • kdfparams - The parameters required for the kdf algorithm above;
  • mac - A code used to verify your password.

Keystore files created with the first major version of the web wallet (available prior February 14th, 2023) hold the encrypted secret key, instead of the encrypted mnemonic (as the new keystore files do). Though the older files are still compatible with the new web wallet - compatibility is achieved through the aforementioned "kind" field.

When kind is set (or not set at all) to secretKey, the ciphertext field will contain the encrypted secret key, as it did before. However, when kind is set to mnemonic, the ciphertext field will contain the encrypted mnemonic instead.

Auxiliary reference: ERC-2335: BLS12-381 Keystore.

- - +

Keystore files

The MultiversX keystore is a JSON file that holds a mnemonic (seed phrase), encrypted with a password (as chosen by the user). Thus, the keystore provides users with a reliable and convenient method for managing their hot wallets and protecting their assets.

Here is an example of a MultiversX Keystore:

{
"version": 4,
"id": "5b448dbc-5c72-4d83-8038-938b1f8dff19",
"kind": "mnemonic",
"crypto": {
"ciphertext": "6d70fbdceba874f56f15af4b1d060223799288cfc5d276d9ebb91732f5a38c3c59f83896fa7e7eb6a04c05475a6fe4d154de9b9441864c507abd0eb6987dac521b64c0c82783a3cd1e09270cd6cb5ae493f9af694b891253ac1f1ffded68b5ef39c972307e3c33a8354337540908acc795d4df72298dda1ca28ac920983e6a39a01e2bc988bd0b21f864c6de8b5356d11e4b77bc6f75ef",
"cipherparams": {
"iv": "2da5620906634972d9a623bc249d63d4"
},
"cipher": "aes-128-ctr",
"kdf": "scrypt",
"kdfparams": {
"dklen": 32,
"salt": "aa9e0ba6b188703071a582c10e5331f2756279feb0e2768f1ba0fd38ec77f035",
"n": 4096,
"r": 8,
"p": 1
},
"mac": "5bc1b20b6d903b8ef3273eedf028112d65eaf85a5ef4215917c1209ec2df715a"
}
}

At first, you will see an unappealing JSON file, which appears to contain magic parameters used for numerous complex cryptographic operations with unclear and vague purpose. But if you dig a little deeper you will see that it contains:

  • kind - Can be secretKey or mnemonic and represents the input to be encrypted using the cipher;
  • ciphertext - Your MultiversX mnemonic or secret key encrypted using the cipher algorithm below;
  • cipher - The name of a symmetric AES algorithm;
  • cipherparams - The parameters required for the cipher algorithm above;
  • kdf - A key derivation function used to let you encrypt your keystore file with a password;
  • kdfparams - The parameters required for the kdf algorithm above;
  • mac - A code used to verify your password.

Keystore files created with the first major version of the web wallet (available prior February 14th, 2023) hold the encrypted secret key, instead of the encrypted mnemonic (as the new keystore files do). Though the older files are still compatible with the new web wallet - compatibility is achieved through the aforementioned "kind" field.

When kind is set (or not set at all) to secretKey, the ciphertext field will contain the encrypted secret key, as it did before. However, when kind is set to mnemonic, the ciphertext field will contain the encrypted mnemonic instead.

Auxiliary reference: ERC-2335: BLS12-381 Keystore.

+ + \ No newline at end of file diff --git a/Practical Sessions/Wallet/Wallet/index.html b/Practical Sessions/Wallet/Wallet/index.html index b21be06a..b69541a0 100644 --- a/Practical Sessions/Wallet/Wallet/index.html +++ b/Practical Sessions/Wallet/Wallet/index.html @@ -4,13 +4,13 @@ Setting up a Wallet via Browser | Blockchain Protocols and Distributed Applications - - + +
-

Setting up a Wallet via Browser

We will use MultiversX Testnet Wallet to participate in the blockchain as a user.

If you already have a wallet, there is no need to create another one.

Go to MultiversX Testnet Wallet and create a new wallet by clicking Create new one.

Testnet Wallet

Carefully read and acknowledge the information, then click "Continue".

Create Wallet

Save your secret phrase! This is very important

Each wallet will have 24 secret words that can be used for recovery.

The words, numbered in order, are your Secret Phrase. They are just displayed on your screen once and not saved on a server or anywhere in the world. You only get one chance to save them - please do so now.

Click the “copy” (two rectangles) button and then paste them into a text file. If your pets don’t usually find important pieces of paper to be delicious, you could even write the words down.

Create Wallet

The next page is a test to see if you actually have saved the Secret Phrase. Enter the random words as indicated there and press "Continue".

You are one step away from getting your Keystore File. First, encrypt it with a password.

Wallet Password

In case you forget this password, you can get a new Keystore File with your secret phrase. Remembering it is always better.

Congratulations, you have a new wallet! The associated Keystore File was downloaded to wherever your browser saves files by default. The file has the actual address of the wallet as default name, something like “erd….json”. You can rename it to “something.json” so it’s easier to manage, if you want.)

- - +

Setting up a Wallet via Browser

We will use MultiversX Testnet Wallet to participate in the blockchain as a user.

If you already have a wallet, there is no need to create another one.

Go to MultiversX Testnet Wallet and create a new wallet by clicking Create new one.

Testnet Wallet

Carefully read and acknowledge the information, then click "Continue".

Create Wallet

Save your secret phrase! This is very important

Each wallet will have 24 secret words that can be used for recovery.

The words, numbered in order, are your Secret Phrase. They are just displayed on your screen once and not saved on a server or anywhere in the world. You only get one chance to save them - please do so now.

Click the “copy” (two rectangles) button and then paste them into a text file. If your pets don’t usually find important pieces of paper to be delicious, you could even write the words down.

Create Wallet

The next page is a test to see if you actually have saved the Secret Phrase. Enter the random words as indicated there and press "Continue".

You are one step away from getting your Keystore File. First, encrypt it with a password.

Wallet Password

In case you forget this password, you can get a new Keystore File with your secret phrase. Remembering it is always better.

Congratulations, you have a new wallet! The associated Keystore File was downloaded to wherever your browser saves files by default. The file has the actual address of the wallet as default name, something like “erd….json”. You can rename it to “something.json” so it’s easier to manage, if you want.)

+ + \ No newline at end of file diff --git a/Practical Sessions/Wallet/browser_wallet/index.html b/Practical Sessions/Wallet/browser_wallet/index.html index 6e83f453..5e84e180 100644 --- a/Practical Sessions/Wallet/browser_wallet/index.html +++ b/Practical Sessions/Wallet/browser_wallet/index.html @@ -4,13 +4,13 @@ Browser Wallet Extension | Blockchain Protocols and Distributed Applications - - + +
-

Browser Wallet Extension

The MultiversX DeFi Wallet can be installed on Firefox, Chrome, Brave, and other chromium-based browsers. This extension is free and secure, with compelling features that allow you to create a new wallet or import existing wallets, manage multiple wallets on the MultiversX mainnet, and store MultiversX tokens such as EGLD, ESDT, or NFTs on the MultiversX Network with easy accessibility.

Follow the tutorial here to install a Browser extension.

- - +

Browser Wallet Extension

The MultiversX DeFi Wallet can be installed on Firefox, Chrome, Brave, and other chromium-based browsers. This extension is free and secure, with compelling features that allow you to create a new wallet or import existing wallets, manage multiple wallets on the MultiversX mainnet, and store MultiversX tokens such as EGLD, ESDT, or NFTs on the MultiversX Network with easy accessibility.

Follow the tutorial here to install a Browser extension.

+ + \ No newline at end of file diff --git a/Practical Sessions/Wallet/faucet/index.html b/Practical Sessions/Wallet/faucet/index.html index 50aaae81..9ee0a76a 100644 --- a/Practical Sessions/Wallet/faucet/index.html +++ b/Practical Sessions/Wallet/faucet/index.html @@ -4,13 +4,13 @@ Access a wallet | Blockchain Protocols and Distributed Applications - - + +
-

Access a wallet

Go to Testnet Wallet and click on "PEM" (bottom of the screen); click "Select a file" and locate your wallet new_wallet.pem.

Testnet Wallet

And you’re in! Your EGLD address is on top, you can use the “copy” button (the two rectangles) to copy it to the clipboard.

Faucet

You can request test tokens from the Faucet tab.

Faucet

Practice

Request tokens via Faucet functionality.

- - +

Access a wallet

Go to Testnet Wallet and click on "PEM" (bottom of the screen); click "Select a file" and locate your wallet new_wallet.pem.

Testnet Wallet

And you’re in! Your EGLD address is on top, you can use the “copy” button (the two rectangles) to copy it to the clipboard.

Faucet

You can request test tokens from the Faucet tab.

Faucet

Practice

Request tokens via Faucet functionality.

+ + \ No newline at end of file diff --git a/Practical Sessions/Wallet/index.html b/Practical Sessions/Wallet/index.html index 2bcd6d9a..c3b63f94 100644 --- a/Practical Sessions/Wallet/index.html +++ b/Practical Sessions/Wallet/index.html @@ -4,13 +4,13 @@ Wallet | Blockchain Protocols and Distributed Applications - - + +
-
- - +
+ + \ No newline at end of file diff --git a/Practical Sessions/Wallet/send_tx/index.html b/Practical Sessions/Wallet/send_tx/index.html index 40b6d63a..59ddf318 100644 --- a/Practical Sessions/Wallet/send_tx/index.html +++ b/Practical Sessions/Wallet/send_tx/index.html @@ -4,13 +4,13 @@ Send a transaction | Blockchain Protocols and Distributed Applications - - + +
-

Send a transaction

Click "Send" on the right-hand section of the wallet:

Transaction

Input the destination address & amount, and then click "Send".

Send tokens

After confirming the transaction you can see the progress and completion of the transaction.

Practice

Check transaction history in the "Transactions" menu on the left-hand side of the wallet.

Transaction History

Click on the last transaction (Send Transaction) and check the details.

Open that transaction in the Explorer. At the right hand side of the Hash field, click on the magnifier.

Go to Explorer

- - +

Send a transaction

Click "Send" on the right-hand section of the wallet:

Transaction

Input the destination address & amount, and then click "Send".

Send tokens

After confirming the transaction you can see the progress and completion of the transaction.

Practice

Check transaction history in the "Transactions" menu on the left-hand side of the wallet.

Transaction History

Click on the last transaction (Send Transaction) and check the details.

Open that transaction in the Explorer. At the right hand side of the Hash field, click on the magnifier.

Go to Explorer

+ + \ No newline at end of file diff --git a/Practical Sessions/index.html b/Practical Sessions/index.html index 7e53d41a..f6547c52 100644 --- a/Practical Sessions/index.html +++ b/Practical Sessions/index.html @@ -4,13 +4,13 @@ Practical Sessions | Blockchain Protocols and Distributed Applications - - + + - - +
+ + \ No newline at end of file diff --git a/assets/js/24730e6e.9b558ace.js b/assets/js/24730e6e.9b558ace.js new file mode 100644 index 00000000..3e2f094b --- /dev/null +++ b/assets/js/24730e6e.9b558ace.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkblockchain_protocols_and_distributed_applications=self.webpackChunkblockchain_protocols_and_distributed_applications||[]).push([[3965],{181:t=>{t.exports=JSON.parse('{"title":"Learning Rust","slug":"/Practical Sessions/Learning Rust/","permalink":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Learning Rust/","navigation":{"previous":{"title":"Never Sea Festival Smart Contract","permalink":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/neversea"},"next":{"title":"Learning Rust and Rust in Smart Contracts","permalink":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Learning Rust/rust"}}}')}}]); \ No newline at end of file diff --git a/assets/js/6cba850a.bd0c1791.js b/assets/js/6cba850a.bd0c1791.js new file mode 100644 index 00000000..b148621e --- /dev/null +++ b/assets/js/6cba850a.bd0c1791.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkblockchain_protocols_and_distributed_applications=self.webpackChunkblockchain_protocols_and_distributed_applications||[]).push([[1881],{5680:(e,t,r)=>{r.d(t,{xA:()=>u,yg:()=>y});var n=r(6540);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var c=n.createContext({}),l=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},u=function(e){var t=l(e.components);return n.createElement(c.Provider,{value:t},e.children)},p="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,i=e.originalType,c=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=l(r),m=a,y=p["".concat(c,".").concat(m)]||p[m]||g[m]||i;return r?n.createElement(y,o(o({ref:t},u),{},{components:r})):n.createElement(y,o({ref:t},u))}));function y(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=r.length,o=new Array(i);o[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[p]="string"==typeof e?e:a,o[1]=s;for(var l=2;l{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>g,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var n=r(8168),a=(r(6540),r(5680));const i={},o="Learning Rust and Rust in Smart Contracts",s={unversionedId:"Practical Sessions/Learning Rust/rust",id:"Practical Sessions/Learning Rust/rust",title:"Learning Rust and Rust in Smart Contracts",description:"Objectives",source:"@site/docs/Practical Sessions/Learning Rust/rust.md",sourceDirName:"Practical Sessions/Learning Rust",slug:"/Practical Sessions/Learning Rust/rust",permalink:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Learning Rust/rust",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"sidebar",previous:{title:"Learning Rust",permalink:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Learning Rust/"},next:{title:"Tour of Rust",permalink:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Learning Rust/tour-of-rust"}},c={},l=[{value:"Objectives",id:"objectives",level:2}],u={toc:l},p="wrapper";function g(e){let{components:t,...r}=e;return(0,a.yg)(p,(0,n.A)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,a.yg)("h1",{id:"learning-rust-and-rust-in-smart-contracts"},"Learning Rust and Rust in Smart Contracts"),(0,a.yg)("h2",{id:"objectives"},"Objectives"),(0,a.yg)("p",null,"In this section you will learn about Rust:"),(0,a.yg)("ul",null,(0,a.yg)("li",{parentName:"ul"},"The Basics;"),(0,a.yg)("li",{parentName:"ul"},"Basic Control Flow;"),(0,a.yg)("li",{parentName:"ul"},"Basic Data Structure Types;"),(0,a.yg)("li",{parentName:"ul"},"Generic Types;"),(0,a.yg)("li",{parentName:"ul"},"Ownership & Borrowing Data;"),(0,a.yg)("li",{parentName:"ul"},"Object Oriented Programming - Traits;"),(0,a.yg)("li",{parentName:"ul"},"Cryptozombies - learn SC development via an interactive and gamified platform.")),(0,a.yg)("p",null,"There will be 2 approaches:"),(0,a.yg)("ol",null,(0,a.yg)("li",{parentName:"ol"},"Tour of Rust - a step by step guide through the features of the Rust programming language;"),(0,a.yg)("li",{parentName:"ol"},"Cryptozombies - learn Rust and Smart Contract programming in a fun and easy way;")))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/6d865e2f.5c803d27.js b/assets/js/6d865e2f.5c803d27.js new file mode 100644 index 00000000..7fe6cedc --- /dev/null +++ b/assets/js/6d865e2f.5c803d27.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkblockchain_protocols_and_distributed_applications=self.webpackChunkblockchain_protocols_and_distributed_applications||[]).push([[5205],{5680:(e,t,a)=>{a.d(t,{xA:()=>p,yg:()=>g});var n=a(6540);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function i(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var l=n.createContext({}),c=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},p=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},d="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=c(a),u=r,g=d["".concat(l,".").concat(u)]||d[u]||m[u]||o;return a?n.createElement(g,i(i({ref:t},p),{},{components:a})):n.createElement(g,i({ref:t},p))}));function g(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,i=new Array(o);i[0]=u;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[d]="string"==typeof e?e:r,i[1]=s;for(var c=2;c{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>m,frontMatter:()=>o,metadata:()=>s,toc:()=>c});var n=a(8168),r=(a(6540),a(5680));const o={},i="Never Sea Festival Smart Contract",s={unversionedId:"Practical Sessions/Smart Contracts/neversea",id:"Practical Sessions/Smart Contracts/neversea",title:"Never Sea Festival Smart Contract",description:"You are the NeverSea Festival 2025 organizers and you decide to create the registration via blockchain.",source:"@site/docs/Practical Sessions/Smart Contracts/neversea.md",sourceDirName:"Practical Sessions/Smart Contracts",slug:"/Practical Sessions/Smart Contracts/neversea",permalink:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/neversea",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"sidebar",previous:{title:"Smart Contract call",permalink:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/mxpy_sc_call"},next:{title:"Learning Rust",permalink:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Learning Rust/"}},l={},c=[{value:"Compile the Smart Contract template",id:"compile-the-smart-contract-template",level:2},{value:"Any modification of the contract must be succeeded by a compilation and deployment!",id:"any-modification-of-the-contract-must-be-succeeded-by-a-compilation-and-deployment",level:2},{value:"Constructor",id:"constructor",level:2},{value:"Storages",id:"storages",level:2},{value:"Add endpoints",id:"add-endpoints",level:2},{value:"Practice",id:"practice",level:2}],p={toc:c},d="wrapper";function m(e){let{components:t,...a}=e;return(0,r.yg)(d,(0,n.A)({},p,a,{components:t,mdxType:"MDXLayout"}),(0,r.yg)("h1",{id:"never-sea-festival-smart-contract"},"Never Sea Festival Smart Contract"),(0,r.yg)("p",null,"You are the NeverSea Festival 2025 organizers and you decide to create the registration via blockchain.\nStarting from Smart Contract template you have to add more features to coordinate the event."),(0,r.yg)("p",null,"You can use the empty SC template:"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre",className:"language-bash"},"$ sc-meta new --name my_neversea_2025 --template empty\n[...]\n\n$ ll my-neversea-2025/\ntotal 16\ndrwxr-xr-x@ 8 costincarabas staff 256B Nov 6 04:21 .\ndrwxr-x---+ 54 costincarabas staff 1.7K Nov 6 04:21 ..\n-rw-r--r--@ 1 costincarabas staff 343B Nov 6 04:21 Cargo.toml\ndrwxr-xr-x@ 4 costincarabas staff 128B Nov 6 04:21 meta\n-rw-r--r--@ 1 costincarabas staff 26B Nov 6 04:21 multiversx.json\ndrwxr-xr-x@ 3 costincarabas staff 96B Nov 6 04:21 scenarios\ndrwxr-xr-x@ 3 costincarabas staff 96B Nov 6 04:21 src\ndrwxr-xr-x@ 4 costincarabas staff 128B Nov 6 04:21 tests\n")),(0,r.yg)("p",null,"There are several other templates:"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre",className:"language-bash"},"$ sc-meta templates\nempty\nping-pong-egld\ncrypto-zombies\nadder\n")),(0,r.yg)("h2",{id:"compile-the-smart-contract-template"},"Compile the Smart Contract template"),(0,r.yg)("p",null,"To check that the contract was ",(0,r.yg)("strong",{parentName:"p"},"successfully built"),", verify that there was a ",(0,r.yg)("strong",{parentName:"p"},"wasm")," (WebAssembly) file generate: ",(0,r.yg)("strong",{parentName:"p"},"output/your-contract-name.wasm"),". This is the compiled code of your contract."),(0,r.yg)("hr",null),(0,r.yg)("p",null,(0,r.yg)("strong",{parentName:"p"},"NOTE")),(0,r.yg)("p",null,"For any further actions, please check the compilation on your local machine (and the deployment on the explorer, if it's the case). Do not assume that the contract was successfully compiled and deployed."),(0,r.yg)("h2",{id:"any-modification-of-the-contract-must-be-succeeded-by-a-compilation-and-deployment"},"Any modification of the contract must be succeeded by a compilation and deployment!"),(0,r.yg)("h2",{id:"constructor"},"Constructor"),(0,r.yg)("p",null,"Implement the ",(0,r.yg)("inlineCode",{parentName:"p"},"init")," function so that it will take an argument that it's the registration fee and set a ",(0,r.yg)("inlineCode",{parentName:"p"},"registration_fee")," storage.\nImplement the ",(0,r.yg)("inlineCode",{parentName:"p"},"upgrade")," function so that it won't take any argument."),(0,r.yg)("h2",{id:"storages"},"Storages"),(0,r.yg)("p",null,"Add 2 storages:"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("inlineCode",{parentName:"li"},"participants")," - a set of addresses (you can use ",(0,r.yg)("inlineCode",{parentName:"li"},"ManagedAddress"),") that stores the participants list;"),(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("inlineCode",{parentName:"li"},"registration_fee")," - you can use ",(0,r.yg)("inlineCode",{parentName:"li"},"BigUint")," to store the fee.")),(0,r.yg)("h2",{id:"add-endpoints"},"Add endpoints"),(0,r.yg)("p",null,"Add a ",(0,r.yg)("inlineCode",{parentName:"p"},"register")," endpoint where clients will pay the fee via EGLD to register to the festival.\nAdd a ",(0,r.yg)("inlineCode",{parentName:"p"},"update_registration_fees")," endpoint where the owner can update the fee. Use ",(0,r.yg)("inlineCode",{parentName:"p"},"#[only_owner]")," annotation so that the endpoint can be called only by the owner."),(0,r.yg)("h2",{id:"practice"},"Practice"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},"Make a contract call to register a user;"),(0,r.yg)("li",{parentName:"ul"},"Make a contract call to view the registered users;"),(0,r.yg)("li",{parentName:"ul"},"Modify the registration endpoint to enable VIP access;"),(0,r.yg)("li",{parentName:"ul"},"Create a new storage mapper ",(0,r.yg)("strong",{parentName:"li"},"registration_fee_vip"),";"),(0,r.yg)("li",{parentName:"ul"},"Create a new storage mapper ",(0,r.yg)("strong",{parentName:"li"},"vip_participants")," to save the VIP participants;"),(0,r.yg)("li",{parentName:"ul"},"In the registration endpoint, make a verification of the tokens received. If the tokens received is ",(0,r.yg)("strong",{parentName:"li"},"registration_fee_vip"),", add the user to ",(0,r.yg)("strong",{parentName:"li"},"vip_participants"),", if the amount is ",(0,r.yg)("strong",{parentName:"li"},"registration_fee"),", add them to participants, else, deny registration;"),(0,r.yg)("li",{parentName:"ul"},"Modify the registration fee to enable Early Bird and Full price access;"),(0,r.yg)("li",{parentName:"ul"},"Create a new endpoint that modifies the ",(0,r.yg)("strong",{parentName:"li"},"registration_fee")," and ",(0,r.yg)("strong",{parentName:"li"},"registration_fee_vip")," storage mapper. This endpoint should be call ",(0,r.yg)("strong",{parentName:"li"},"only by the owner"),"."),(0,r.yg)("li",{parentName:"ul"},"BONUS: Create a feature to enable 50% discount vouchers for friends and partners. Create a list of hardcoded discount codes. Create a new endpoint that receives a discount code as a parameter and registers a user with 50% discount.")),(0,r.yg)("hr",null),(0,r.yg)("p",null,(0,r.yg)("strong",{parentName:"p"},"Hint"),"\nUse ",(0,r.yg)("inlineCode",{parentName:"p"},"#[only_owner]")," endpoint annotation."),(0,r.yg)("hr",null))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/6d865e2f.828e8735.js b/assets/js/6d865e2f.828e8735.js deleted file mode 100644 index b550672a..00000000 --- a/assets/js/6d865e2f.828e8735.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkblockchain_protocols_and_distributed_applications=self.webpackChunkblockchain_protocols_and_distributed_applications||[]).push([[5205],{5680:(e,t,a)=>{a.d(t,{xA:()=>p,yg:()=>y});var n=a(6540);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function i(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var l=n.createContext({}),c=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},p=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},d="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=c(a),u=r,y=d["".concat(l,".").concat(u)]||d[u]||m[u]||o;return a?n.createElement(y,i(i({ref:t},p),{},{components:a})):n.createElement(y,i({ref:t},p))}));function y(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,i=new Array(o);i[0]=u;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[d]="string"==typeof e?e:r,i[1]=s;for(var c=2;c{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>m,frontMatter:()=>o,metadata:()=>s,toc:()=>c});var n=a(8168),r=(a(6540),a(5680));const o={},i="Never Sea Festival Smart Contract",s={unversionedId:"Practical Sessions/Smart Contracts/neversea",id:"Practical Sessions/Smart Contracts/neversea",title:"Never Sea Festival Smart Contract",description:"You are the NeverSea Festival 2025 organizers and you decide to create the registration via blockchain.",source:"@site/docs/Practical Sessions/Smart Contracts/neversea.md",sourceDirName:"Practical Sessions/Smart Contracts",slug:"/Practical Sessions/Smart Contracts/neversea",permalink:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/neversea",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"sidebar",previous:{title:"Smart Contract call",permalink:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/mxpy_sc_call"},next:{title:"Observer",permalink:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Observer/"}},l={},c=[{value:"Compile the Smart Contract template",id:"compile-the-smart-contract-template",level:2},{value:"Any modification of the contract must be succeeded by a compilation and deployment!",id:"any-modification-of-the-contract-must-be-succeeded-by-a-compilation-and-deployment",level:2},{value:"Constructor",id:"constructor",level:2},{value:"Storages",id:"storages",level:2},{value:"Add endpoints",id:"add-endpoints",level:2},{value:"Practice",id:"practice",level:2}],p={toc:c},d="wrapper";function m(e){let{components:t,...a}=e;return(0,r.yg)(d,(0,n.A)({},p,a,{components:t,mdxType:"MDXLayout"}),(0,r.yg)("h1",{id:"never-sea-festival-smart-contract"},"Never Sea Festival Smart Contract"),(0,r.yg)("p",null,"You are the NeverSea Festival 2025 organizers and you decide to create the registration via blockchain.\nStarting from Smart Contract template you have to add more features to coordinate the event."),(0,r.yg)("p",null,"You can use the empty SC template:"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre",className:"language-bash"},"$ sc-meta new --name my_neversea_2025 --template empty\n[...]\n\n$ ll my-neversea-2025/\ntotal 16\ndrwxr-xr-x@ 8 costincarabas staff 256B Nov 6 04:21 .\ndrwxr-x---+ 54 costincarabas staff 1.7K Nov 6 04:21 ..\n-rw-r--r--@ 1 costincarabas staff 343B Nov 6 04:21 Cargo.toml\ndrwxr-xr-x@ 4 costincarabas staff 128B Nov 6 04:21 meta\n-rw-r--r--@ 1 costincarabas staff 26B Nov 6 04:21 multiversx.json\ndrwxr-xr-x@ 3 costincarabas staff 96B Nov 6 04:21 scenarios\ndrwxr-xr-x@ 3 costincarabas staff 96B Nov 6 04:21 src\ndrwxr-xr-x@ 4 costincarabas staff 128B Nov 6 04:21 tests\n")),(0,r.yg)("p",null,"There are several other templates:"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre",className:"language-bash"},"$ sc-meta templates\nempty\nping-pong-egld\ncrypto-zombies\nadder\n")),(0,r.yg)("h2",{id:"compile-the-smart-contract-template"},"Compile the Smart Contract template"),(0,r.yg)("p",null,"To check that the contract was ",(0,r.yg)("strong",{parentName:"p"},"successfully built"),", verify that there was a ",(0,r.yg)("strong",{parentName:"p"},"wasm")," (WebAssembly) file generate: ",(0,r.yg)("strong",{parentName:"p"},"output/your-contract-name.wasm"),". This is the compiled code of your contract."),(0,r.yg)("hr",null),(0,r.yg)("p",null,(0,r.yg)("strong",{parentName:"p"},"NOTE")),(0,r.yg)("p",null,"For any further actions, please check the compilation on your local machine (and the deployment on the explorer, if it's the case). Do not assume that the contract was successfully compiled and deployed."),(0,r.yg)("h2",{id:"any-modification-of-the-contract-must-be-succeeded-by-a-compilation-and-deployment"},"Any modification of the contract must be succeeded by a compilation and deployment!"),(0,r.yg)("h2",{id:"constructor"},"Constructor"),(0,r.yg)("p",null,"Implement the ",(0,r.yg)("inlineCode",{parentName:"p"},"init")," function so that it will take an argument that it's the registration fee and set a ",(0,r.yg)("inlineCode",{parentName:"p"},"registration_fee")," storage.\nImplement the ",(0,r.yg)("inlineCode",{parentName:"p"},"upgrade")," function so that it won't take any argument."),(0,r.yg)("h2",{id:"storages"},"Storages"),(0,r.yg)("p",null,"Add 2 storages:"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("inlineCode",{parentName:"li"},"participants")," - a set of addresses (you can use ",(0,r.yg)("inlineCode",{parentName:"li"},"ManagedAddress"),") that stores the participants list;"),(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("inlineCode",{parentName:"li"},"registration_fee")," - you can use ",(0,r.yg)("inlineCode",{parentName:"li"},"BigUint")," to store the fee.")),(0,r.yg)("h2",{id:"add-endpoints"},"Add endpoints"),(0,r.yg)("p",null,"Add a ",(0,r.yg)("inlineCode",{parentName:"p"},"register")," endpoint where clients will pay the fee via EGLD to register to the festival.\nAdd a ",(0,r.yg)("inlineCode",{parentName:"p"},"update_registration_fees")," endpoint where the owner can update the fee. Use ",(0,r.yg)("inlineCode",{parentName:"p"},"#[only_owner]")," annotation so that the endpoint can be called only by the owner."),(0,r.yg)("h2",{id:"practice"},"Practice"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},"Make a contract call to register a user;"),(0,r.yg)("li",{parentName:"ul"},"Make a contract call to view the registered users;"),(0,r.yg)("li",{parentName:"ul"},"Modify the registration endpoint to enable VIP access;"),(0,r.yg)("li",{parentName:"ul"},"Create a new storage mapper ",(0,r.yg)("strong",{parentName:"li"},"registration_fee_vip"),";"),(0,r.yg)("li",{parentName:"ul"},"Create a new storage mapper ",(0,r.yg)("strong",{parentName:"li"},"vip_participants")," to save the VIP participants;"),(0,r.yg)("li",{parentName:"ul"},"In the registration endpoint, make a verification of the tokens received. If the tokens received is ",(0,r.yg)("strong",{parentName:"li"},"registration_fee_vip"),", add the user to ",(0,r.yg)("strong",{parentName:"li"},"vip_participants"),", if the amount is ",(0,r.yg)("strong",{parentName:"li"},"registration_fee"),", add them to participants, else, deny registration;"),(0,r.yg)("li",{parentName:"ul"},"Modify the registration fee to enable Early Bird and Full price access;"),(0,r.yg)("li",{parentName:"ul"},"Create a new endpoint that modifies the ",(0,r.yg)("strong",{parentName:"li"},"registration_fee")," and ",(0,r.yg)("strong",{parentName:"li"},"registration_fee_vip")," storage mapper. This endpoint should be call ",(0,r.yg)("strong",{parentName:"li"},"only by the owner"),"."),(0,r.yg)("li",{parentName:"ul"},"BONUS: Create a feature to enable 50% discount vouchers for friends and partners. Create a list of hardcoded discount codes. Create a new endpoint that receives a discount code as a parameter and registers a user with 50% discount.")),(0,r.yg)("hr",null),(0,r.yg)("p",null,(0,r.yg)("strong",{parentName:"p"},"Hint"),"\nUse ",(0,r.yg)("inlineCode",{parentName:"p"},"#[only_owner]")," endpoint annotation."),(0,r.yg)("hr",null))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/85df453d.5b6d4205.js b/assets/js/85df453d.be6e0c4d.js similarity index 56% rename from assets/js/85df453d.5b6d4205.js rename to assets/js/85df453d.be6e0c4d.js index 72f67e5b..10a91ea1 100644 --- a/assets/js/85df453d.5b6d4205.js +++ b/assets/js/85df453d.be6e0c4d.js @@ -1 +1 @@ -"use strict";(self.webpackChunkblockchain_protocols_and_distributed_applications=self.webpackChunkblockchain_protocols_and_distributed_applications||[]).push([[9932],{1517:i=>{i.exports=JSON.parse('{"title":"Observer","slug":"/Practical Sessions/Observer/","permalink":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Observer/","navigation":{"previous":{"title":"Never Sea Festival Smart Contract","permalink":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/neversea"},"next":{"title":"Setting up an Observer","permalink":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Observer/"}}}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkblockchain_protocols_and_distributed_applications=self.webpackChunkblockchain_protocols_and_distributed_applications||[]).push([[9932],{1517:i=>{i.exports=JSON.parse('{"title":"Observer","slug":"/Practical Sessions/Observer/","permalink":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Observer/","navigation":{"previous":{"title":"CryptoZombies","permalink":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Learning Rust/cryptozombies"},"next":{"title":"Setting up an Observer","permalink":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Observer/"}}}')}}]); \ No newline at end of file diff --git a/assets/js/89c345ad.2b9f518c.js b/assets/js/89c345ad.2b9f518c.js new file mode 100644 index 00000000..344fda25 --- /dev/null +++ b/assets/js/89c345ad.2b9f518c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkblockchain_protocols_and_distributed_applications=self.webpackChunkblockchain_protocols_and_distributed_applications||[]).push([[4402],{5680:(e,t,r)=>{r.d(t,{xA:()=>p,yg:()=>y});var n=r(6540);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),l=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(c.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(r),d=o,y=u["".concat(c,".").concat(d)]||u[d]||m[d]||i;return r?n.createElement(y,a(a({ref:t},p),{},{components:r})):n.createElement(y,a({ref:t},p))}));function y(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:o,a[1]=s;for(var l=2;l{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>m,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var n=r(8168),o=(r(6540),r(5680));const i={},a="CryptoZombies",s={unversionedId:"Practical Sessions/Learning Rust/cryptozombies",id:"Practical Sessions/Learning Rust/cryptozombies",title:"CryptoZombies",description:"CryptoZombies is an interactive and gamified platform designed to teach blockchain and Smart Contract development using the Rust or Solidity programming language.",source:"@site/docs/Practical Sessions/Learning Rust/cryptozombies.md",sourceDirName:"Practical Sessions/Learning Rust",slug:"/Practical Sessions/Learning Rust/cryptozombies",permalink:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Learning Rust/cryptozombies",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"sidebar",previous:{title:"Tour of Rust",permalink:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Learning Rust/tour-of-rust"},next:{title:"Observer",permalink:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Observer/"}},c={},l=[{value:"Bonus",id:"bonus",level:2}],p={toc:l},u="wrapper";function m(e){let{components:t,...r}=e;return(0,o.yg)(u,(0,n.A)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,o.yg)("h1",{id:"cryptozombies"},"CryptoZombies"),(0,o.yg)("p",null,"CryptoZombies is an interactive and gamified platform designed to teach blockchain and Smart Contract development using the Rust or Solidity programming language.\nIt uses a series of coding lessons where you will build your own blockchain-based zombie-themed game step by step.\nEach lesson adds elements to a zombie game, making the learning process engaging and fun."),(0,o.yg)("p",null,"Please follow the ",(0,o.yg)("a",{parentName:"p",href:"https://cryptozombies.io/en/multiversx"},"MultiversX CryptoZombie")," tutorial."),(0,o.yg)("h2",{id:"bonus"},"Bonus"),(0,o.yg)("p",null,"If you wish to learn ",(0,o.yg)("a",{parentName:"p",href:"https://cryptozombies.io/en/course"},"other blockchains"),", please follow courses for Solidity, Optimism, zkSync, Tron, Chainlink, etc."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/935f2afb.71502fe1.js b/assets/js/935f2afb.71502fe1.js new file mode 100644 index 00000000..f692f992 --- /dev/null +++ b/assets/js/935f2afb.71502fe1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkblockchain_protocols_and_distributed_applications=self.webpackChunkblockchain_protocols_and_distributed_applications||[]).push([[8581],{5610:e=>{e.exports=JSON.parse('{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"sidebar":[{"type":"link","label":"Introduction","href":"/blockchain-protocols-and-distributed-applications/","docId":"README"},{"type":"category","label":"Lectures","items":[{"type":"link","label":"Introduction","href":"/blockchain-protocols-and-distributed-applications/Lectures/Introduction","docId":"Lectures/Introduction"}],"collapsed":true,"collapsible":true,"href":"/blockchain-protocols-and-distributed-applications/Lectures/"},{"type":"category","label":"Practical Sessions","items":[{"type":"category","label":"Env Setup","items":[{"type":"link","label":"Setting up the Lab Environment","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Env Setup/setup","docId":"Practical Sessions/Env Setup/setup"}],"collapsed":true,"collapsible":true,"href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Env Setup/"},{"type":"category","label":"Wallet","items":[{"type":"link","label":"Cmd line wallet","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Wallet/Cmd line wallet/cmdline_wallet","docId":"Practical Sessions/Wallet/Cmd line wallet/cmdline_wallet"},{"type":"link","label":"Wallet","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Wallet/Wallet/","docId":"Practical Sessions/Wallet/Wallet/wallet"},{"type":"link","label":"Keystore","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Wallet/Keystore/","docId":"Practical Sessions/Wallet/Keystore/keystore"},{"type":"link","label":"Access & Faucet","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Wallet/faucet","docId":"Practical Sessions/Wallet/faucet"},{"type":"link","label":"Send Transaction","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Wallet/send_tx","docId":"Practical Sessions/Wallet/send_tx"},{"type":"link","label":"Browser Web Wallet","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Wallet/browser_wallet","docId":"Practical Sessions/Wallet/browser_wallet"}],"collapsed":true,"collapsible":true,"href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Wallet/"},{"type":"category","label":"Explorer","items":[{"type":"link","label":"Time in Blockchain","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Time in Blockchain/time","docId":"Practical Sessions/Explorer/Time in Blockchain/time"},{"type":"link","label":"Blocks","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Blocks/","docId":"Practical Sessions/Explorer/Blocks/blocks"},{"type":"link","label":"Block Leader","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Block Leader/leader","docId":"Practical Sessions/Explorer/Block Leader/leader"},{"type":"link","label":"Consensus Grup","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Consensus Grup/consensus","docId":"Practical Sessions/Explorer/Consensus Grup/consensus"},{"type":"link","label":"Transactions","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Transactions/","docId":"Practical Sessions/Explorer/Transactions/transactions"},{"type":"link","label":"Blockchain Validators","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Blockchain Validators/validators","docId":"Practical Sessions/Explorer/Blockchain Validators/validators"},{"type":"link","label":"Blockchain Observers","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Blockchain Observers/observers","docId":"Practical Sessions/Explorer/Blockchain Observers/observers"},{"type":"link","label":"Devnet Blockchains","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Devnet Blockchains/devnet_testnet","docId":"Practical Sessions/Explorer/Devnet Blockchains/devnet_testnet"}],"collapsed":true,"collapsible":true,"href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/"},{"type":"category","label":"Tokens","items":[{"type":"link","label":"Standards","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Tokens/standards","docId":"Practical Sessions/Tokens/standards"},{"type":"link","label":"Fungible & NonFugible Tokens","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Tokens/fungible-non-fungible","docId":"Practical Sessions/Tokens/fungible-non-fungible"},{"type":"link","label":"Fungible","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Tokens/fungible","docId":"Practical Sessions/Tokens/fungible"},{"type":"link","label":"NFT","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Tokens/nft","docId":"Practical Sessions/Tokens/nft"}],"collapsed":true,"collapsible":true,"href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Tokens/"},{"type":"category","label":"Smart Contracts","items":[{"type":"link","label":"Prerequisites","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/prerequisites","docId":"Practical Sessions/Smart Contracts/prerequisites"},{"type":"link","label":"Empty SC","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/empty","docId":"Practical Sessions/Smart Contracts/empty"},{"type":"link","label":"Empty Interactor","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/rust_interactors","docId":"Practical Sessions/Smart Contracts/rust_interactors"},{"type":"link","label":"Adder SC","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/adder","docId":"Practical Sessions/Smart Contracts/adder"},{"type":"link","label":"Rust Deploy SC","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/cargo_deploy","docId":"Practical Sessions/Smart Contracts/cargo_deploy"},{"type":"link","label":"Mxpy Deploy SC","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/mxpy_deploy","docId":"Practical Sessions/Smart Contracts/mxpy_deploy"},{"type":"link","label":"Mxpy Call SC","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/mxpy_sc_call","docId":"Practical Sessions/Smart Contracts/mxpy_sc_call"},{"type":"link","label":"Neversea SC","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/neversea","docId":"Practical Sessions/Smart Contracts/neversea"}],"collapsed":true,"collapsible":true,"href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/"},{"type":"category","label":"Learning Rust","items":[{"type":"link","label":"Objectives","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Learning Rust/rust","docId":"Practical Sessions/Learning Rust/rust"},{"type":"link","label":"Tour of Rust","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Learning Rust/tour-of-rust","docId":"Practical Sessions/Learning Rust/tour-of-rust"},{"type":"link","label":"CryptoZombies","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Learning Rust/cryptozombies","docId":"Practical Sessions/Learning Rust/cryptozombies"}],"collapsed":true,"collapsible":true,"href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Learning Rust/"},{"type":"category","label":"Observer","items":[{"type":"link","label":"Observers","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Observer/","docId":"Practical Sessions/Observer/observer"}],"collapsed":true,"collapsible":true,"href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Observer/"},{"type":"category","label":"Money (DeFi)","items":[{"type":"link","label":"ESDT Tokens","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Money (DeFi)/mint_tokens","docId":"Practical Sessions/Money (DeFi)/mint_tokens"},{"type":"link","label":"Swap Tokens","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Money (DeFi)/swap","docId":"Practical Sessions/Money (DeFi)/swap"}],"collapsed":true,"collapsible":true,"href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Money (DeFi)/"},{"type":"category","label":"Basic Peer-to-Peer Blockchain","items":[{"type":"link","label":"What we will build?","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/what_we_build","docId":"Practical Sessions/Basic Peer-to-Peer Blockchain/what_we_build"},{"type":"link","label":"Why golang?","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/why_golang","docId":"Practical Sessions/Basic Peer-to-Peer Blockchain/why_golang"},{"type":"link","label":"What is a discovery node ?","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/discovery_node","docId":"Practical Sessions/Basic Peer-to-Peer Blockchain/discovery_node"},{"type":"link","label":"Peer to Peer Network","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/p2p_network","docId":"Practical Sessions/Basic Peer-to-Peer Blockchain/p2p_network"},{"type":"link","label":"The terminal","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/terminal","docId":"Practical Sessions/Basic Peer-to-Peer Blockchain/terminal"},{"type":"link","label":"Mine a block","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/mining","docId":"Practical Sessions/Basic Peer-to-Peer Blockchain/mining"},{"type":"link","label":"Basic Wallet","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/basic_wallet","docId":"Practical Sessions/Basic Peer-to-Peer Blockchain/basic_wallet"},{"type":"link","label":"Transactions","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/transactions","docId":"Practical Sessions/Basic Peer-to-Peer Blockchain/transactions"},{"type":"link","label":"Sources","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/sources","docId":"Practical Sessions/Basic Peer-to-Peer Blockchain/sources"}],"collapsed":true,"collapsible":true,"href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/"},{"type":"category","label":"Smart Contract Events","items":[{"type":"link","label":"SC Events","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contract Events/events","docId":"Practical Sessions/Smart Contract Events/events"}],"collapsed":true,"collapsible":true,"href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contract Events/"}],"collapsed":true,"collapsible":true,"href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/"},{"type":"category","label":"Assignments","items":[{"type":"link","label":"Assignment 1","href":"/blockchain-protocols-and-distributed-applications/Assignments/assignment1","docId":"Assignments/assignment1"},{"type":"link","label":"Assignment 2","href":"/blockchain-protocols-and-distributed-applications/Assignments/assignment2","docId":"Assignments/assignment2"},{"type":"link","label":"Project","href":"/blockchain-protocols-and-distributed-applications/Assignments/project","docId":"Assignments/project"}],"collapsed":true,"collapsible":true,"href":"/blockchain-protocols-and-distributed-applications/Assignments/"},{"type":"link","label":"Grading","href":"/blockchain-protocols-and-distributed-applications/grading","docId":"grading"},{"type":"link","label":"Resources","href":"/blockchain-protocols-and-distributed-applications/resources","docId":"resources"}]},"docs":{"Assignments/assignment1":{"id":"Assignments/assignment1","title":"Trading Card Games","description":"Deadline","sidebar":"sidebar"},"Assignments/assignment2":{"id":"Assignments/assignment2","title":"assignment2","description":"TODO","sidebar":"sidebar"},"Assignments/project":{"id":"Assignments/project","title":"Semester Project","description":"The main assignment for this semester is a project on a blockchain. There are no restrictions regarding the blockchain.","sidebar":"sidebar"},"grading":{"id":"grading","title":"Grading","description":"| Section | Percent of total grade |","sidebar":"sidebar"},"Lectures/Introduction":{"id":"Lectures/Introduction","title":"Introduction","description":"Focus the slides and press F for fullscreen viewing.","sidebar":"sidebar"},"Practical Sessions/Basic Peer-to-Peer Blockchain/basic_wallet":{"id":"Practical Sessions/Basic Peer-to-Peer Blockchain/basic_wallet","title":"Basic Wallet","description":"To create a public key with which we can display our financial gain in the internet we need first to generate a private key using an algorithm, the private key will generate the public key and\u2026from now on we can apply a hash on it and remove some character from behind and add 0x in front to know that this is a public address.","sidebar":"sidebar"},"Practical Sessions/Basic Peer-to-Peer Blockchain/discovery_node":{"id":"Practical Sessions/Basic Peer-to-Peer Blockchain/discovery_node","title":"What is a discovery node?","description":"In the context of Libp2p in Golang, a \\"discovery node\\" typically refers to a node that participates in a discovery process to find and connect to other peers in the network. Discovery is an essential aspect of decentralized systems, as it allows nodes to discover and establish connections with their peers dynamically.","sidebar":"sidebar"},"Practical Sessions/Basic Peer-to-Peer Blockchain/mining":{"id":"Practical Sessions/Basic Peer-to-Peer Blockchain/mining","title":"Mining a block","description":"In this tutorial we will use the most simple and basic way to mine a block.We will use proof of work.","sidebar":"sidebar"},"Practical Sessions/Basic Peer-to-Peer Blockchain/p2p_network":{"id":"Practical Sessions/Basic Peer-to-Peer Blockchain/p2p_network","title":"Peer to peer network","description":"For this part we will use libp2p was used by the guys that build IPFS and Filecoin.","sidebar":"sidebar"},"Practical Sessions/Basic Peer-to-Peer Blockchain/sources":{"id":"Practical Sessions/Basic Peer-to-Peer Blockchain/sources","title":"Sources","description":"Github//github.com/bogdan124/master-blockchain-v.0.0.1-","sidebar":"sidebar"},"Practical Sessions/Basic Peer-to-Peer Blockchain/terminal":{"id":"Practical Sessions/Basic Peer-to-Peer Blockchain/terminal","title":"The terminal","description":"This terminal will be a way to interact with other nodes.l(\u201ccomplete code will be available on github\u201d)","sidebar":"sidebar"},"Practical Sessions/Basic Peer-to-Peer Blockchain/transactions":{"id":"Practical Sessions/Basic Peer-to-Peer Blockchain/transactions","title":"Transactions","description":"So we have a wallet we know how a transaction looks lets send a transaction to another address in the blockchain.","sidebar":"sidebar"},"Practical Sessions/Basic Peer-to-Peer Blockchain/what_we_build":{"id":"Practical Sessions/Basic Peer-to-Peer Blockchain/what_we_build","title":"What we will build?","description":"- Peer to peer network","sidebar":"sidebar"},"Practical Sessions/Basic Peer-to-Peer Blockchain/why_golang":{"id":"Practical Sessions/Basic Peer-to-Peer Blockchain/why_golang","title":"Why golang?","description":"Golang is an excellent choice for building a blockchain due to its readability and widespread use in the field. Its popularity stems from the simplicity of its syntax and the prevalence of libraries commonly employed in blockchain development.","sidebar":"sidebar"},"Practical Sessions/Env Setup/setup":{"id":"Practical Sessions/Env Setup/setup","title":"Setting up your environment","description":"In this section we will install all the requirements needed for the practical sessions.","sidebar":"sidebar"},"Practical Sessions/Explorer/Block Leader/leader":{"id":"Practical Sessions/Explorer/Block Leader/leader","title":"Blockchain Leader","description":"We will continue with the same block from the previous section (Block Height: 16826695).","sidebar":"sidebar"},"Practical Sessions/Explorer/Blockchain Observers/observers":{"id":"Practical Sessions/Explorer/Blockchain Observers/observers","title":"Blockchain Observers","description":"Observers are a type of nodes that don\'t participate in the consensus but keep a peer-to-peer communication with the rest of the blockchain.","sidebar":"sidebar"},"Practical Sessions/Explorer/Blockchain Validators/validators":{"id":"Practical Sessions/Explorer/Blockchain Validators/validators","title":"Blockchain Validators","description":"Every validators/node is publicly displayed on the explorer:","sidebar":"sidebar"},"Practical Sessions/Explorer/Blocks/blocks":{"id":"Practical Sessions/Explorer/Blocks/blocks","title":"Blocks in Blockchain","description":"For simplicity, we will use MultiversX blockchain and MultiversX Explorer.","sidebar":"sidebar"},"Practical Sessions/Explorer/Consensus Grup/consensus":{"id":"Practical Sessions/Explorer/Consensus Grup/consensus","title":"Consensus Group","description":"We will continue with the same block from the previous section (Block Height: 16826695).","sidebar":"sidebar"},"Practical Sessions/Explorer/Devnet Blockchains/devnet_testnet":{"id":"Practical Sessions/Explorer/Devnet Blockchains/devnet_testnet","title":"Devnet & Testnet Blockchain","description":"While developing applications, there is a need for a development/testing blockchain.","sidebar":"sidebar"},"Practical Sessions/Explorer/Time in Blockchain/time":{"id":"Practical Sessions/Explorer/Time in Blockchain/time","title":"Understanding Time in Blockchains","description":"In traditional computer systems, time is relatively straightforward, with a reliance on the system clock.","sidebar":"sidebar"},"Practical Sessions/Explorer/Transactions/transactions":{"id":"Practical Sessions/Explorer/Transactions/transactions","title":"Transactions","description":"We will continue with the same block from the previous section (Block Height: 16826695).","sidebar":"sidebar"},"Practical Sessions/Learning Rust/cryptozombies":{"id":"Practical Sessions/Learning Rust/cryptozombies","title":"CryptoZombies","description":"CryptoZombies is an interactive and gamified platform designed to teach blockchain and Smart Contract development using the Rust or Solidity programming language.","sidebar":"sidebar"},"Practical Sessions/Learning Rust/rust":{"id":"Practical Sessions/Learning Rust/rust","title":"Learning Rust and Rust in Smart Contracts","description":"Objectives","sidebar":"sidebar"},"Practical Sessions/Learning Rust/tour-of-rust":{"id":"Practical Sessions/Learning Rust/tour-of-rust","title":"Tour of Rust","description":"In this section you will learn Rust via Tour of Rust tutorial.","sidebar":"sidebar"},"Practical Sessions/Money (DeFi)/mint_tokens":{"id":"Practical Sessions/Money (DeFi)/mint_tokens","title":"Mint tokens","description":"In this section you will learn how to mint tokens on MultiversX.","sidebar":"sidebar"},"Practical Sessions/Money (DeFi)/swap":{"id":"Practical Sessions/Money (DeFi)/swap","title":"Swap tokens on xExchange","description":"In this section, you will learn how to swap a token with another on MultiversX. For this, we will use the Devnet xExchange, a MultiversX Decentralized Exchange.","sidebar":"sidebar"},"Practical Sessions/Observer/observer":{"id":"Practical Sessions/Observer/observer","title":"Setting up an Observer","description":"In this section we will be setting up an Observer on the MultiversX Testnet.","sidebar":"sidebar"},"Practical Sessions/Smart Contract Events/events":{"id":"Practical Sessions/Smart Contract Events/events","title":"Events","description":"Key Takeaways:","sidebar":"sidebar"},"Practical Sessions/Smart Contracts/adder":{"id":"Practical Sessions/Smart Contracts/adder","title":"The Adder SC","description":"The Adder smart contract is a simple smart contract with an add functionality and a global variable that can be incremented.","sidebar":"sidebar"},"Practical Sessions/Smart Contracts/cargo_deploy":{"id":"Practical Sessions/Smart Contracts/cargo_deploy","title":"Smart Contract deployment via Rust","description":"Let\'s deploy our smart contract(SC) on the blockchain. We will deploy the adder contract from the previous section.","sidebar":"sidebar"},"Practical Sessions/Smart Contracts/empty":{"id":"Practical Sessions/Smart Contracts/empty","title":"The Empty SC","description":"The smallest smart contract is an empty smart contract with no functionalities. Compiled, it is a binary that is accepted by the blockchain.","sidebar":"sidebar"},"Practical Sessions/Smart Contracts/mxpy_deploy":{"id":"Practical Sessions/Smart Contracts/mxpy_deploy","title":"Smart Contract deployment via Python (mxpy)","description":"Let\'s deploy our smart contract on the blockchain. For this, we will use mxpy tools previously installed.","sidebar":"sidebar"},"Practical Sessions/Smart Contracts/mxpy_sc_call":{"id":"Practical Sessions/Smart Contracts/mxpy_sc_call","title":"Smart Contract call","description":"Now let\'s call our previous adder smart contract.","sidebar":"sidebar"},"Practical Sessions/Smart Contracts/neversea":{"id":"Practical Sessions/Smart Contracts/neversea","title":"Never Sea Festival Smart Contract","description":"You are the NeverSea Festival 2025 organizers and you decide to create the registration via blockchain.","sidebar":"sidebar"},"Practical Sessions/Smart Contracts/prerequisites":{"id":"Practical Sessions/Smart Contracts/prerequisites","title":"Prerequisites","description":"All of these prerequisites were done at the first lab. You can skip this section if you have already done this.","sidebar":"sidebar"},"Practical Sessions/Smart Contracts/rust_interactors":{"id":"Practical Sessions/Smart Contracts/rust_interactors","title":"Creating a Rust interactor","description":"Rust interactors are used to interact with the blockchain via Rust.","sidebar":"sidebar"},"Practical Sessions/Tokens/fungible":{"id":"Practical Sessions/Tokens/fungible","title":"Fungible Tokens","description":"Issuance of fungible ESDT tokens via Web Wallet on MultiversX","sidebar":"sidebar"},"Practical Sessions/Tokens/fungible-non-fungible":{"id":"Practical Sessions/Tokens/fungible-non-fungible","title":"Fungible vs Non-Fungible Tokens","description":"* Fungibility refers to an asset\'s ability to be exchanged for something else of equal value;","sidebar":"sidebar"},"Practical Sessions/Tokens/nft":{"id":"Practical Sessions/Tokens/nft","title":"Non-Fungible Tokens (NFTs)","description":"These NFTs are unique, one-of-a-kind tokens that are built on blockchain technology, allowing for secure ownership and transfer of these assets.","sidebar":"sidebar"},"Practical Sessions/Tokens/standards":{"id":"Practical Sessions/Tokens/standards","title":"Token Standards","description":"A crypto token is a representation of an asset or interest that has been tokenized on an existing cryptocurrency\'s blockchain. Crypto tokens and cryptocurrencies share many similarities, but cryptocurrencies are intended to be used as a medium of exchange, a means of payment, and a measure and store of value.","sidebar":"sidebar"},"Practical Sessions/Wallet/browser_wallet":{"id":"Practical Sessions/Wallet/browser_wallet","title":"Browser Wallet Extension","description":"The MultiversX DeFi Wallet can be installed on Firefox, Chrome, Brave, and other chromium-based browsers. This extension is free and secure, with compelling features that allow you to create a new wallet or import existing wallets, manage multiple wallets on the MultiversX mainnet, and store MultiversX tokens such as EGLD, ESDT, or NFTs on the MultiversX Network with easy accessibility.","sidebar":"sidebar"},"Practical Sessions/Wallet/Cmd line wallet/cmdline_wallet":{"id":"Practical Sessions/Wallet/Cmd line wallet/cmdline_wallet","title":"First Blockchain transaction","description":"Let\'s perform our first ever blockchain transaction.","sidebar":"sidebar"},"Practical Sessions/Wallet/faucet":{"id":"Practical Sessions/Wallet/faucet","title":"Access a wallet","description":"Go to Testnet Wallet and click on \\"PEM\\" (bottom of the screen); click \\"Select a file\\" and locate your wallet new_wallet.pem.","sidebar":"sidebar"},"Practical Sessions/Wallet/Keystore/keystore":{"id":"Practical Sessions/Wallet/Keystore/keystore","title":"Keystore files","description":"The MultiversX keystore is a JSON file that holds a mnemonic (seed phrase), encrypted with a password (as chosen by the user). Thus, the keystore provides users with a reliable and convenient method for managing their hot wallets and protecting their assets.","sidebar":"sidebar"},"Practical Sessions/Wallet/send_tx":{"id":"Practical Sessions/Wallet/send_tx","title":"Send a transaction","description":"Click \\"Send\\" on the right-hand section of the wallet:","sidebar":"sidebar"},"Practical Sessions/Wallet/Wallet/wallet":{"id":"Practical Sessions/Wallet/Wallet/wallet","title":"Setting up a Wallet via Browser","description":"We will use MultiversX Testnet Wallet to participate in the blockchain as a user.","sidebar":"sidebar"},"README":{"id":"README","title":"Blockchain Protocols and Distributed Applications","description":"Welcome to the course on Blockchain Protocols and Distributed Applications.","sidebar":"sidebar"},"resources":{"id":"resources","title":"Resources and Useful Links","description":"List of Resources:","sidebar":"sidebar"}}}')}}]); \ No newline at end of file diff --git a/assets/js/935f2afb.ca51ee0c.js b/assets/js/935f2afb.ca51ee0c.js deleted file mode 100644 index 4c6913a1..00000000 --- a/assets/js/935f2afb.ca51ee0c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkblockchain_protocols_and_distributed_applications=self.webpackChunkblockchain_protocols_and_distributed_applications||[]).push([[8581],{5610:e=>{e.exports=JSON.parse('{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"sidebar":[{"type":"link","label":"Introduction","href":"/blockchain-protocols-and-distributed-applications/","docId":"README"},{"type":"category","label":"Lectures","items":[{"type":"link","label":"Introduction","href":"/blockchain-protocols-and-distributed-applications/Lectures/Introduction","docId":"Lectures/Introduction"}],"collapsed":true,"collapsible":true,"href":"/blockchain-protocols-and-distributed-applications/Lectures/"},{"type":"category","label":"Practical Sessions","items":[{"type":"category","label":"Env Setup","items":[{"type":"link","label":"Setting up the Lab Environment","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Env Setup/setup","docId":"Practical Sessions/Env Setup/setup"}],"collapsed":true,"collapsible":true,"href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Env Setup/"},{"type":"category","label":"Wallet","items":[{"type":"link","label":"Cmd line wallet","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Wallet/Cmd line wallet/cmdline_wallet","docId":"Practical Sessions/Wallet/Cmd line wallet/cmdline_wallet"},{"type":"link","label":"Wallet","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Wallet/Wallet/","docId":"Practical Sessions/Wallet/Wallet/wallet"},{"type":"link","label":"Keystore","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Wallet/Keystore/","docId":"Practical Sessions/Wallet/Keystore/keystore"},{"type":"link","label":"Access & Faucet","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Wallet/faucet","docId":"Practical Sessions/Wallet/faucet"},{"type":"link","label":"Send Transaction","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Wallet/send_tx","docId":"Practical Sessions/Wallet/send_tx"},{"type":"link","label":"Browser Web Wallet","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Wallet/browser_wallet","docId":"Practical Sessions/Wallet/browser_wallet"}],"collapsed":true,"collapsible":true,"href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Wallet/"},{"type":"category","label":"Explorer","items":[{"type":"link","label":"Time in Blockchain","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Time in Blockchain/time","docId":"Practical Sessions/Explorer/Time in Blockchain/time"},{"type":"link","label":"Blocks","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Blocks/","docId":"Practical Sessions/Explorer/Blocks/blocks"},{"type":"link","label":"Block Leader","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Block Leader/leader","docId":"Practical Sessions/Explorer/Block Leader/leader"},{"type":"link","label":"Consensus Grup","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Consensus Grup/consensus","docId":"Practical Sessions/Explorer/Consensus Grup/consensus"},{"type":"link","label":"Transactions","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Transactions/","docId":"Practical Sessions/Explorer/Transactions/transactions"},{"type":"link","label":"Blockchain Validators","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Blockchain Validators/validators","docId":"Practical Sessions/Explorer/Blockchain Validators/validators"},{"type":"link","label":"Blockchain Observers","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Blockchain Observers/observers","docId":"Practical Sessions/Explorer/Blockchain Observers/observers"},{"type":"link","label":"Devnet Blockchains","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Devnet Blockchains/devnet_testnet","docId":"Practical Sessions/Explorer/Devnet Blockchains/devnet_testnet"}],"collapsed":true,"collapsible":true,"href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/"},{"type":"category","label":"Tokens","items":[{"type":"link","label":"Standards","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Tokens/standards","docId":"Practical Sessions/Tokens/standards"},{"type":"link","label":"Fungible & NonFugible Tokens","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Tokens/fungible-non-fungible","docId":"Practical Sessions/Tokens/fungible-non-fungible"},{"type":"link","label":"Fungible","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Tokens/fungible","docId":"Practical Sessions/Tokens/fungible"},{"type":"link","label":"NFT","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Tokens/nft","docId":"Practical Sessions/Tokens/nft"}],"collapsed":true,"collapsible":true,"href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Tokens/"},{"type":"category","label":"Smart Contracts","items":[{"type":"link","label":"Prerequisites","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/prerequisites","docId":"Practical Sessions/Smart Contracts/prerequisites"},{"type":"link","label":"Empty SC","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/empty","docId":"Practical Sessions/Smart Contracts/empty"},{"type":"link","label":"Empty Interactor","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/rust_interactors","docId":"Practical Sessions/Smart Contracts/rust_interactors"},{"type":"link","label":"Adder SC","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/adder","docId":"Practical Sessions/Smart Contracts/adder"},{"type":"link","label":"Rust Deploy SC","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/cargo_deploy","docId":"Practical Sessions/Smart Contracts/cargo_deploy"},{"type":"link","label":"Mxpy Deploy SC","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/mxpy_deploy","docId":"Practical Sessions/Smart Contracts/mxpy_deploy"},{"type":"link","label":"Mxpy Call SC","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/mxpy_sc_call","docId":"Practical Sessions/Smart Contracts/mxpy_sc_call"},{"type":"link","label":"Neversea SC","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/neversea","docId":"Practical Sessions/Smart Contracts/neversea"}],"collapsed":true,"collapsible":true,"href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/"},{"type":"category","label":"Observer","items":[{"type":"link","label":"Observers","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Observer/","docId":"Practical Sessions/Observer/observer"}],"collapsed":true,"collapsible":true,"href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Observer/"},{"type":"category","label":"Money (DeFi)","items":[{"type":"link","label":"ESDT Tokens","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Money (DeFi)/mint_tokens","docId":"Practical Sessions/Money (DeFi)/mint_tokens"},{"type":"link","label":"Swap Tokens","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Money (DeFi)/swap","docId":"Practical Sessions/Money (DeFi)/swap"}],"collapsed":true,"collapsible":true,"href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Money (DeFi)/"},{"type":"category","label":"Basic Peer-to-Peer Blockchain","items":[{"type":"link","label":"What we will build?","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/what_we_build","docId":"Practical Sessions/Basic Peer-to-Peer Blockchain/what_we_build"},{"type":"link","label":"Why golang?","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/why_golang","docId":"Practical Sessions/Basic Peer-to-Peer Blockchain/why_golang"},{"type":"link","label":"What is a discovery node ?","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/discovery_node","docId":"Practical Sessions/Basic Peer-to-Peer Blockchain/discovery_node"},{"type":"link","label":"Peer to Peer Network","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/p2p_network","docId":"Practical Sessions/Basic Peer-to-Peer Blockchain/p2p_network"},{"type":"link","label":"The terminal","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/terminal","docId":"Practical Sessions/Basic Peer-to-Peer Blockchain/terminal"},{"type":"link","label":"Mine a block","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/mining","docId":"Practical Sessions/Basic Peer-to-Peer Blockchain/mining"},{"type":"link","label":"Basic Wallet","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/basic_wallet","docId":"Practical Sessions/Basic Peer-to-Peer Blockchain/basic_wallet"},{"type":"link","label":"Transactions","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/transactions","docId":"Practical Sessions/Basic Peer-to-Peer Blockchain/transactions"},{"type":"link","label":"Sources","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/sources","docId":"Practical Sessions/Basic Peer-to-Peer Blockchain/sources"}],"collapsed":true,"collapsible":true,"href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/"},{"type":"category","label":"Smart Contract Events","items":[{"type":"link","label":"SC Events","href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contract Events/events","docId":"Practical Sessions/Smart Contract Events/events"}],"collapsed":true,"collapsible":true,"href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contract Events/"}],"collapsed":true,"collapsible":true,"href":"/blockchain-protocols-and-distributed-applications/Practical Sessions/"},{"type":"category","label":"Assignments","items":[{"type":"link","label":"Assignment 1","href":"/blockchain-protocols-and-distributed-applications/Assignments/assignment1","docId":"Assignments/assignment1"},{"type":"link","label":"Assignment 2","href":"/blockchain-protocols-and-distributed-applications/Assignments/assignment2","docId":"Assignments/assignment2"},{"type":"link","label":"Project","href":"/blockchain-protocols-and-distributed-applications/Assignments/project","docId":"Assignments/project"}],"collapsed":true,"collapsible":true,"href":"/blockchain-protocols-and-distributed-applications/Assignments/"},{"type":"link","label":"Grading","href":"/blockchain-protocols-and-distributed-applications/grading","docId":"grading"},{"type":"link","label":"Resources","href":"/blockchain-protocols-and-distributed-applications/resources","docId":"resources"}]},"docs":{"Assignments/assignment1":{"id":"Assignments/assignment1","title":"Trading Card Games","description":"Deadline","sidebar":"sidebar"},"Assignments/assignment2":{"id":"Assignments/assignment2","title":"assignment2","description":"TODO","sidebar":"sidebar"},"Assignments/project":{"id":"Assignments/project","title":"Semester Project","description":"The main assignment for this semester is a project on a blockchain. There are no restrictions regarding the blockchain.","sidebar":"sidebar"},"grading":{"id":"grading","title":"Grading","description":"| Section | Percent of total grade |","sidebar":"sidebar"},"Lectures/Introduction":{"id":"Lectures/Introduction","title":"Introduction","description":"Focus the slides and press F for fullscreen viewing.","sidebar":"sidebar"},"Practical Sessions/Basic Peer-to-Peer Blockchain/basic_wallet":{"id":"Practical Sessions/Basic Peer-to-Peer Blockchain/basic_wallet","title":"Basic Wallet","description":"To create a public key with which we can display our financial gain in the internet we need first to generate a private key using an algorithm, the private key will generate the public key and\u2026from now on we can apply a hash on it and remove some character from behind and add 0x in front to know that this is a public address.","sidebar":"sidebar"},"Practical Sessions/Basic Peer-to-Peer Blockchain/discovery_node":{"id":"Practical Sessions/Basic Peer-to-Peer Blockchain/discovery_node","title":"What is a discovery node?","description":"In the context of Libp2p in Golang, a \\"discovery node\\" typically refers to a node that participates in a discovery process to find and connect to other peers in the network. Discovery is an essential aspect of decentralized systems, as it allows nodes to discover and establish connections with their peers dynamically.","sidebar":"sidebar"},"Practical Sessions/Basic Peer-to-Peer Blockchain/mining":{"id":"Practical Sessions/Basic Peer-to-Peer Blockchain/mining","title":"Mining a block","description":"In this tutorial we will use the most simple and basic way to mine a block.We will use proof of work.","sidebar":"sidebar"},"Practical Sessions/Basic Peer-to-Peer Blockchain/p2p_network":{"id":"Practical Sessions/Basic Peer-to-Peer Blockchain/p2p_network","title":"Peer to peer network","description":"For this part we will use libp2p was used by the guys that build IPFS and Filecoin.","sidebar":"sidebar"},"Practical Sessions/Basic Peer-to-Peer Blockchain/sources":{"id":"Practical Sessions/Basic Peer-to-Peer Blockchain/sources","title":"Sources","description":"Github//github.com/bogdan124/master-blockchain-v.0.0.1-","sidebar":"sidebar"},"Practical Sessions/Basic Peer-to-Peer Blockchain/terminal":{"id":"Practical Sessions/Basic Peer-to-Peer Blockchain/terminal","title":"The terminal","description":"This terminal will be a way to interact with other nodes.l(\u201ccomplete code will be available on github\u201d)","sidebar":"sidebar"},"Practical Sessions/Basic Peer-to-Peer Blockchain/transactions":{"id":"Practical Sessions/Basic Peer-to-Peer Blockchain/transactions","title":"Transactions","description":"So we have a wallet we know how a transaction looks lets send a transaction to another address in the blockchain.","sidebar":"sidebar"},"Practical Sessions/Basic Peer-to-Peer Blockchain/what_we_build":{"id":"Practical Sessions/Basic Peer-to-Peer Blockchain/what_we_build","title":"What we will build?","description":"- Peer to peer network","sidebar":"sidebar"},"Practical Sessions/Basic Peer-to-Peer Blockchain/why_golang":{"id":"Practical Sessions/Basic Peer-to-Peer Blockchain/why_golang","title":"Why golang?","description":"Golang is an excellent choice for building a blockchain due to its readability and widespread use in the field. Its popularity stems from the simplicity of its syntax and the prevalence of libraries commonly employed in blockchain development.","sidebar":"sidebar"},"Practical Sessions/Env Setup/setup":{"id":"Practical Sessions/Env Setup/setup","title":"Setting up your environment","description":"In this section we will install all the requirements needed for the practical sessions.","sidebar":"sidebar"},"Practical Sessions/Explorer/Block Leader/leader":{"id":"Practical Sessions/Explorer/Block Leader/leader","title":"Blockchain Leader","description":"We will continue with the same block from the previous section (Block Height: 16826695).","sidebar":"sidebar"},"Practical Sessions/Explorer/Blockchain Observers/observers":{"id":"Practical Sessions/Explorer/Blockchain Observers/observers","title":"Blockchain Observers","description":"Observers are a type of nodes that don\'t participate in the consensus but keep a peer-to-peer communication with the rest of the blockchain.","sidebar":"sidebar"},"Practical Sessions/Explorer/Blockchain Validators/validators":{"id":"Practical Sessions/Explorer/Blockchain Validators/validators","title":"Blockchain Validators","description":"Every validators/node is publicly displayed on the explorer:","sidebar":"sidebar"},"Practical Sessions/Explorer/Blocks/blocks":{"id":"Practical Sessions/Explorer/Blocks/blocks","title":"Blocks in Blockchain","description":"For simplicity, we will use MultiversX blockchain and MultiversX Explorer.","sidebar":"sidebar"},"Practical Sessions/Explorer/Consensus Grup/consensus":{"id":"Practical Sessions/Explorer/Consensus Grup/consensus","title":"Consensus Group","description":"We will continue with the same block from the previous section (Block Height: 16826695).","sidebar":"sidebar"},"Practical Sessions/Explorer/Devnet Blockchains/devnet_testnet":{"id":"Practical Sessions/Explorer/Devnet Blockchains/devnet_testnet","title":"Devnet & Testnet Blockchain","description":"While developing applications, there is a need for a development/testing blockchain.","sidebar":"sidebar"},"Practical Sessions/Explorer/Time in Blockchain/time":{"id":"Practical Sessions/Explorer/Time in Blockchain/time","title":"Understanding Time in Blockchains","description":"In traditional computer systems, time is relatively straightforward, with a reliance on the system clock.","sidebar":"sidebar"},"Practical Sessions/Explorer/Transactions/transactions":{"id":"Practical Sessions/Explorer/Transactions/transactions","title":"Transactions","description":"We will continue with the same block from the previous section (Block Height: 16826695).","sidebar":"sidebar"},"Practical Sessions/Money (DeFi)/mint_tokens":{"id":"Practical Sessions/Money (DeFi)/mint_tokens","title":"Mint tokens","description":"In this section you will learn how to mint tokens on MultiversX.","sidebar":"sidebar"},"Practical Sessions/Money (DeFi)/swap":{"id":"Practical Sessions/Money (DeFi)/swap","title":"Swap tokens on xExchange","description":"In this section, you will learn how to swap a token with another on MultiversX. For this, we will use the Devnet xExchange, a MultiversX Decentralized Exchange.","sidebar":"sidebar"},"Practical Sessions/Observer/observer":{"id":"Practical Sessions/Observer/observer","title":"Setting up an Observer","description":"In this section we will be setting up an Observer on the MultiversX Testnet.","sidebar":"sidebar"},"Practical Sessions/Smart Contract Events/events":{"id":"Practical Sessions/Smart Contract Events/events","title":"Events","description":"Key Takeaways:","sidebar":"sidebar"},"Practical Sessions/Smart Contracts/adder":{"id":"Practical Sessions/Smart Contracts/adder","title":"The Adder SC","description":"The Adder smart contract is a simple smart contract with an add functionality and a global variable that can be incremented.","sidebar":"sidebar"},"Practical Sessions/Smart Contracts/cargo_deploy":{"id":"Practical Sessions/Smart Contracts/cargo_deploy","title":"Smart Contract deployment via Rust","description":"Let\'s deploy our smart contract(SC) on the blockchain. We will deploy the adder contract from the previous section.","sidebar":"sidebar"},"Practical Sessions/Smart Contracts/empty":{"id":"Practical Sessions/Smart Contracts/empty","title":"The Empty SC","description":"The smallest smart contract is an empty smart contract with no functionalities. Compiled, it is a binary that is accepted by the blockchain.","sidebar":"sidebar"},"Practical Sessions/Smart Contracts/mxpy_deploy":{"id":"Practical Sessions/Smart Contracts/mxpy_deploy","title":"Smart Contract deployment via Python (mxpy)","description":"Let\'s deploy our smart contract on the blockchain. For this, we will use mxpy tools previously installed.","sidebar":"sidebar"},"Practical Sessions/Smart Contracts/mxpy_sc_call":{"id":"Practical Sessions/Smart Contracts/mxpy_sc_call","title":"Smart Contract call","description":"Now let\'s call our previous adder smart contract.","sidebar":"sidebar"},"Practical Sessions/Smart Contracts/neversea":{"id":"Practical Sessions/Smart Contracts/neversea","title":"Never Sea Festival Smart Contract","description":"You are the NeverSea Festival 2025 organizers and you decide to create the registration via blockchain.","sidebar":"sidebar"},"Practical Sessions/Smart Contracts/prerequisites":{"id":"Practical Sessions/Smart Contracts/prerequisites","title":"Prerequisites","description":"All of these prerequisites were done at the first lab. You can skip this section if you have already done this.","sidebar":"sidebar"},"Practical Sessions/Smart Contracts/rust_interactors":{"id":"Practical Sessions/Smart Contracts/rust_interactors","title":"Creating a Rust interactor","description":"Rust interactors are used to interact with the blockchain via Rust.","sidebar":"sidebar"},"Practical Sessions/Tokens/fungible":{"id":"Practical Sessions/Tokens/fungible","title":"Fungible Tokens","description":"Issuance of fungible ESDT tokens via Web Wallet on MultiversX","sidebar":"sidebar"},"Practical Sessions/Tokens/fungible-non-fungible":{"id":"Practical Sessions/Tokens/fungible-non-fungible","title":"Fungible vs Non-Fungible Tokens","description":"* Fungibility refers to an asset\'s ability to be exchanged for something else of equal value;","sidebar":"sidebar"},"Practical Sessions/Tokens/nft":{"id":"Practical Sessions/Tokens/nft","title":"Non-Fungible Tokens (NFTs)","description":"These NFTs are unique, one-of-a-kind tokens that are built on blockchain technology, allowing for secure ownership and transfer of these assets.","sidebar":"sidebar"},"Practical Sessions/Tokens/standards":{"id":"Practical Sessions/Tokens/standards","title":"Token Standards","description":"A crypto token is a representation of an asset or interest that has been tokenized on an existing cryptocurrency\'s blockchain. Crypto tokens and cryptocurrencies share many similarities, but cryptocurrencies are intended to be used as a medium of exchange, a means of payment, and a measure and store of value.","sidebar":"sidebar"},"Practical Sessions/Wallet/browser_wallet":{"id":"Practical Sessions/Wallet/browser_wallet","title":"Browser Wallet Extension","description":"The MultiversX DeFi Wallet can be installed on Firefox, Chrome, Brave, and other chromium-based browsers. This extension is free and secure, with compelling features that allow you to create a new wallet or import existing wallets, manage multiple wallets on the MultiversX mainnet, and store MultiversX tokens such as EGLD, ESDT, or NFTs on the MultiversX Network with easy accessibility.","sidebar":"sidebar"},"Practical Sessions/Wallet/Cmd line wallet/cmdline_wallet":{"id":"Practical Sessions/Wallet/Cmd line wallet/cmdline_wallet","title":"First Blockchain transaction","description":"Let\'s perform our first ever blockchain transaction.","sidebar":"sidebar"},"Practical Sessions/Wallet/faucet":{"id":"Practical Sessions/Wallet/faucet","title":"Access a wallet","description":"Go to Testnet Wallet and click on \\"PEM\\" (bottom of the screen); click \\"Select a file\\" and locate your wallet new_wallet.pem.","sidebar":"sidebar"},"Practical Sessions/Wallet/Keystore/keystore":{"id":"Practical Sessions/Wallet/Keystore/keystore","title":"Keystore files","description":"The MultiversX keystore is a JSON file that holds a mnemonic (seed phrase), encrypted with a password (as chosen by the user). Thus, the keystore provides users with a reliable and convenient method for managing their hot wallets and protecting their assets.","sidebar":"sidebar"},"Practical Sessions/Wallet/send_tx":{"id":"Practical Sessions/Wallet/send_tx","title":"Send a transaction","description":"Click \\"Send\\" on the right-hand section of the wallet:","sidebar":"sidebar"},"Practical Sessions/Wallet/Wallet/wallet":{"id":"Practical Sessions/Wallet/Wallet/wallet","title":"Setting up a Wallet via Browser","description":"We will use MultiversX Testnet Wallet to participate in the blockchain as a user.","sidebar":"sidebar"},"README":{"id":"README","title":"Blockchain Protocols and Distributed Applications","description":"Welcome to the course on Blockchain Protocols and Distributed Applications.","sidebar":"sidebar"},"resources":{"id":"resources","title":"Resources and Useful Links","description":"List of Resources:","sidebar":"sidebar"}}}')}}]); \ No newline at end of file diff --git a/assets/js/e9cf5841.b66efdba.js b/assets/js/e9cf5841.b66efdba.js new file mode 100644 index 00000000..b15284df --- /dev/null +++ b/assets/js/e9cf5841.b66efdba.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkblockchain_protocols_and_distributed_applications=self.webpackChunkblockchain_protocols_and_distributed_applications||[]).push([[6272],{5680:(t,e,r)=>{r.d(e,{xA:()=>c,yg:()=>g});var n=r(6540);function o(t,e,r){return e in t?Object.defineProperty(t,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):t[e]=r,t}function a(t,e){var r=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),r.push.apply(r,n)}return r}function i(t){for(var e=1;e=0||(o[r]=t[r]);return o}(t,e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,r)&&(o[r]=t[r])}return o}var u=n.createContext({}),l=function(t){var e=n.useContext(u),r=e;return t&&(r="function"==typeof t?t(e):i(i({},e),t)),r},c=function(t){var e=l(t.components);return n.createElement(u.Provider,{value:e},t.children)},p="mdxType",m={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},f=n.forwardRef((function(t,e){var r=t.components,o=t.mdxType,a=t.originalType,u=t.parentName,c=s(t,["components","mdxType","originalType","parentName"]),p=l(r),f=o,g=p["".concat(u,".").concat(f)]||p[f]||m[f]||a;return r?n.createElement(g,i(i({ref:e},c),{},{components:r})):n.createElement(g,i({ref:e},c))}));function g(t,e){var r=arguments,o=e&&e.mdxType;if("string"==typeof t||o){var a=r.length,i=new Array(a);i[0]=f;var s={};for(var u in e)hasOwnProperty.call(e,u)&&(s[u]=e[u]);s.originalType=t,s[p]="string"==typeof t?t:o,i[1]=s;for(var l=2;l{r.r(e),r.d(e,{assets:()=>u,contentTitle:()=>i,default:()=>m,frontMatter:()=>a,metadata:()=>s,toc:()=>l});var n=r(8168),o=(r(6540),r(5680));const a={},i="Tour of Rust",s={unversionedId:"Practical Sessions/Learning Rust/tour-of-rust",id:"Practical Sessions/Learning Rust/tour-of-rust",title:"Tour of Rust",description:"In this section you will learn Rust via Tour of Rust tutorial.",source:"@site/docs/Practical Sessions/Learning Rust/tour-of-rust.md",sourceDirName:"Practical Sessions/Learning Rust",slug:"/Practical Sessions/Learning Rust/tour-of-rust",permalink:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Learning Rust/tour-of-rust",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"sidebar",previous:{title:"Learning Rust and Rust in Smart Contracts",permalink:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Learning Rust/rust"},next:{title:"CryptoZombies",permalink:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Learning Rust/cryptozombies"}},u={},l=[],c={toc:l},p="wrapper";function m(t){let{components:e,...r}=t;return(0,o.yg)(p,(0,n.A)({},c,r,{components:e,mdxType:"MDXLayout"}),(0,o.yg)("h1",{id:"tour-of-rust"},"Tour of Rust"),(0,o.yg)("p",null,"In this section you will learn Rust via ",(0,o.yg)("a",{parentName:"p",href:"https://tourofrust.com/index.html"},"Tour of Rust")," tutorial.\nYou can find this guide in multiple languages including English and Romanian."),(0,o.yg)("p",null,"The following sections are useful for Smart Contract programming:"),(0,o.yg)("ul",null,(0,o.yg)("li",{parentName:"ul"},"Chapter 1 - ",(0,o.yg)("a",{parentName:"li",href:"https://tourofrust.com/chapter_1_en.html"},"The Basics"),";"),(0,o.yg)("li",{parentName:"ul"},"Chapter 2 - ",(0,o.yg)("a",{parentName:"li",href:"https://tourofrust.com/chapter_2_en.html"},"Basic Control Flow"),";"),(0,o.yg)("li",{parentName:"ul"},"Chapter 3 - ",(0,o.yg)("a",{parentName:"li",href:"https://tourofrust.com/chapter_3_en.html"},"Basic Data Structure Types"),";"),(0,o.yg)("li",{parentName:"ul"},"Chapter 4 - ",(0,o.yg)("a",{parentName:"li",href:"https://tourofrust.com/chapter_4_en.html"},"Generic Types"),";"),(0,o.yg)("li",{parentName:"ul"},"Chapter 5 - ",(0,o.yg)("a",{parentName:"li",href:"https://tourofrust.com/chapter_5_en.html"},"Ownership & Borrowing Data"),";"),(0,o.yg)("li",{parentName:"ul"},"Chapter 7 - ",(0,o.yg)("a",{parentName:"li",href:"https://tourofrust.com/chapter_7_en.html"},"Object Oriented Programming")," (Traits).")),(0,o.yg)("p",null,"We recommend going through the whole ",(0,o.yg)("a",{parentName:"p",href:"https://tourofrust.com/index.html"},"Tour of Rust")," tutorial.\nMoreover, to fully understand the Rust Progamming Language, please go through the ",(0,o.yg)("a",{parentName:"p",href:"https://doc.rust-lang.org/book/"},"Rust Programming Language book"),"."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/main.54505205.js b/assets/js/main.54505205.js new file mode 100644 index 00000000..412d822e --- /dev/null +++ b/assets/js/main.54505205.js @@ -0,0 +1,2 @@ +/*! For license information please see main.54505205.js.LICENSE.txt */ +(self.webpackChunkblockchain_protocols_and_distributed_applications=self.webpackChunkblockchain_protocols_and_distributed_applications||[]).push([[8792],{8328:(e,t,n)=>{"use strict";n.d(t,{A:()=>f});var r=n(6540),a=n(8168),o=n(3259),i=n.n(o),l=n(4054);const s={"01497563":[()=>n.e(9218).then(n.bind(n,7866)),"@site/docs/Practical Sessions/Basic Peer-to-Peer Blockchain/transactions.md",7866],"0504e298":[()=>n.e(8964).then(n.bind(n,6058)),"@site/docs/Practical Sessions/Money (DeFi)/swap.md",6058],"053840e8":[()=>n.e(3140).then(n.bind(n,414)),"@site/docs/Practical Sessions/Wallet/Wallet/wallet.md",414],"061587e1":[()=>n.e(2018).then(n.bind(n,6606)),"@site/docs/grading.md",6606],"078b4cd8":[()=>n.e(9793).then(n.bind(n,7926)),"@site/docs/Practical Sessions/Explorer/Consensus Grup/consensus.md",7926],"0de68a20":[()=>n.e(5193).then(n.bind(n,8105)),"@site/docs/Practical Sessions/Basic Peer-to-Peer Blockchain/basic_wallet.md",8105],"0fbda635":[()=>n.e(4394).then(n.bind(n,9178)),"@site/docs/Practical Sessions/Smart Contracts/mxpy_deploy.md",9178],"1128852d":[()=>n.e(2200).then(n.bind(n,983)),"@site/docs/Assignments/assignment1.md",983],"143dbf3b":[()=>n.e(1090).then(n.t.bind(n,8807,19)),"~docs/default/category-blockchain-protocols-and-distributed-applications-sidebar-category-assignments-3f9.json",8807],14403852:[()=>n.e(5020).then(n.bind(n,4365)),"@site/docs/Practical Sessions/Explorer/Time in Blockchain/time.md",4365],"14eb3368":[()=>Promise.all([n.e(1869),n.e(6969)]).then(n.bind(n,4136)),"@theme/DocCategoryGeneratedIndexPage",4136],"1523e34e":[()=>n.e(2421).then(n.bind(n,5438)),"@site/docs/Practical Sessions/Observer/observer.md",5438],17896441:[()=>Promise.all([n.e(1869),n.e(4567),n.e(8401)]).then(n.bind(n,3761)),"@theme/DocItem",3761],"1be78505":[()=>Promise.all([n.e(1869),n.e(8714)]).then(n.bind(n,10)),"@theme/DocPage",10],"1cd07dfb":[()=>n.e(8878).then(n.t.bind(n,5614,19)),"~docs/default/category-blockchain-protocols-and-distributed-applications-sidebar-category-wallet-74a.json",5614],"1f391b9e":[()=>Promise.all([n.e(1869),n.e(4567),n.e(6061)]).then(n.bind(n,7973)),"@theme/MDXPage",7973],"215797bb":[()=>n.e(3316).then(n.bind(n,2010)),"@site/docs/Practical Sessions/Tokens/nft.md",2010],"23374ca6":[()=>n.e(2278).then(n.bind(n,3502)),"@site/docs/README.md",3502],"24730e6e":[()=>n.e(3965).then(n.t.bind(n,181,19)),"~docs/default/category-blockchain-protocols-and-distributed-applications-sidebar-category-learning-rust-694.json",181],"29ad1408":[()=>n.e(9724).then(n.bind(n,9406)),"@site/docs/Practical Sessions/Smart Contracts/cargo_deploy.md",9406],"2df9d47e":[()=>n.e(8906).then(n.t.bind(n,6067,19)),"~docs/default/category-blockchain-protocols-and-distributed-applications-sidebar-category-money-defi-7b4.json",6067],"2ee066bd":[()=>n.e(4009).then(n.bind(n,4516)),"@site/docs/Practical Sessions/Tokens/standards.md",4516],"33c18b39":[()=>n.e(4239).then(n.bind(n,9690)),"@site/docs/Practical Sessions/Money (DeFi)/mint_tokens.md",9690],"393be207":[()=>n.e(4134).then(n.bind(n,2189)),"@site/src/pages/markdown-page.md",2189],"3ac942f0":[()=>n.e(775).then(n.bind(n,7831)),"@site/docs/Practical Sessions/Env Setup/setup.md",7831],"3b260257":[()=>n.e(2830).then(n.bind(n,1023)),"@site/docs/Practical Sessions/Smart Contracts/empty.md",1023],"3f645037":[()=>n.e(6927).then(n.bind(n,4429)),"@site/docs/Practical Sessions/Wallet/browser_wallet.md",4429],"4a9b7d7d":[()=>n.e(9095).then(n.bind(n,410)),"@site/docs/Practical Sessions/Explorer/Blockchain Validators/validators.md",410],"4e4a4c47":[()=>n.e(5047).then(n.bind(n,9534)),"@site/docs/Practical Sessions/Smart Contracts/adder.md",9534],"507276da":[()=>n.e(5637).then(n.t.bind(n,9267,19)),"~docs/default/category-blockchain-protocols-and-distributed-applications-sidebar-category-tokens-9d5.json",9267],"51e4ea00":[()=>n.e(4484).then(n.bind(n,7034)),"@site/docs/Practical Sessions/Basic Peer-to-Peer Blockchain/why_golang.md",7034],"528d1b10":[()=>n.e(7960).then(n.bind(n,3918)),"@site/docs/Practical Sessions/Tokens/fungible.md",3918],"5536eb16":[()=>n.e(8678).then(n.t.bind(n,3885,19)),"~docs/default/category-blockchain-protocols-and-distributed-applications-sidebar-category-smart-contracts-ce1.json",3885],"56a89565":[()=>n.e(7168).then(n.bind(n,7622)),"@site/docs/Practical Sessions/Wallet/send_tx.md",7622],"5712a78f":[()=>n.e(5688).then(n.t.bind(n,6272,19)),"~docs/default/category-blockchain-protocols-and-distributed-applications-sidebar-category-basic-peer-to-peer-blockchain-5ab.json",6272],"5cd13e5c":[()=>n.e(8758).then(n.bind(n,6590)),"@site/docs/Assignments/assignment2.md",6590],"5e99f083":[()=>n.e(4390).then(n.bind(n,9760)),"@site/docs/Practical Sessions/Basic Peer-to-Peer Blockchain/discovery_node.md",9760],"62717f00":[()=>n.e(1932).then(n.bind(n,9411)),"@site/docs/Practical Sessions/Basic Peer-to-Peer Blockchain/terminal.md",9411],"62ff5f97":[()=>n.e(5978).then(n.bind(n,8354)),"@site/docs/Lectures/Introduction.mdx",8354],"695c3a47":[()=>n.e(9143).then(n.bind(n,5110)),"@site/docs/Practical Sessions/Explorer/Blocks/blocks.md",5110],"6cba850a":[()=>n.e(1881).then(n.bind(n,7240)),"@site/docs/Practical Sessions/Learning Rust/rust.md",7240],"6d865e2f":[()=>n.e(5205).then(n.bind(n,693)),"@site/docs/Practical Sessions/Smart Contracts/neversea.md",693],"706697ec":[()=>n.e(9114).then(n.t.bind(n,5590,19)),"~docs/default/category-blockchain-protocols-and-distributed-applications-sidebar-category-env-setup-dac.json",5590],"76ada497":[()=>n.e(4292).then(n.bind(n,6465)),"@site/docs/Practical Sessions/Basic Peer-to-Peer Blockchain/sources.md",6465],"7848bf17":[()=>n.e(762).then(n.t.bind(n,1966,19)),"/build/docusaurus/Blockchain Protocols and Distributed Applications/.docusaurus/docusaurus-plugin-content-docs/default/plugin-route-context-module-100.json",1966],"83258dd0":[()=>n.e(7927).then(n.bind(n,9067)),"@site/docs/Practical Sessions/Basic Peer-to-Peer Blockchain/mining.md",9067],"85df453d":[()=>n.e(9932).then(n.t.bind(n,1517,19)),"~docs/default/category-blockchain-protocols-and-distributed-applications-sidebar-category-observer-c63.json",1517],"85f8441f":[()=>n.e(2893).then(n.t.bind(n,453,19)),"~docs/default/category-blockchain-protocols-and-distributed-applications-sidebar-category-explorer-f3f.json",453],"89c345ad":[()=>n.e(4402).then(n.bind(n,8020)),"@site/docs/Practical Sessions/Learning Rust/cryptozombies.md",8020],"935f2afb":[()=>n.e(8581).then(n.t.bind(n,5610,19)),"~docs/default/version-current-metadata-prop-751.json",5610],"9912e575":[()=>n.e(5758).then(n.bind(n,2271)),"@site/docs/Practical Sessions/Wallet/Cmd line wallet/cmdline_wallet.md",2271],"9da79274":[()=>n.e(196).then(n.bind(n,7099)),"@site/docs/Practical Sessions/Basic Peer-to-Peer Blockchain/what_we_build.md",7099],aebfb1ac:[()=>n.e(5186).then(n.bind(n,6605)),"@site/docs/Practical Sessions/Smart Contracts/rust_interactors.md",6605],b080bbe4:[()=>n.e(6314).then(n.bind(n,8013)),"@site/docs/Practical Sessions/Smart Contracts/prerequisites.md",8013],b396646f:[()=>n.e(5869).then(n.bind(n,7159)),"@site/docs/Practical Sessions/Tokens/fungible-non-fungible.md",7159],bb46bb8c:[()=>n.e(1958).then(n.t.bind(n,3920,19)),"~docs/default/category-blockchain-protocols-and-distributed-applications-sidebar-category-smart-contract-events-5fd.json",3920],bd1b2524:[()=>n.e(7361).then(n.t.bind(n,4061,19)),"/build/docusaurus/Blockchain Protocols and Distributed Applications/.docusaurus/docusaurus-plugin-content-pages/default/plugin-route-context-module-100.json",4061],ccf76c4f:[()=>n.e(371).then(n.bind(n,2205)),"@site/docs/Practical Sessions/Explorer/Blockchain Observers/observers.md",2205],d12b36cf:[()=>n.e(554).then(n.bind(n,3993)),"@site/docs/Practical Sessions/Smart Contract Events/events.md",3993],d92a3c43:[()=>n.e(8864).then(n.bind(n,5855)),"@site/docs/resources.md",5855],dcd0bb0b:[()=>n.e(7202).then(n.bind(n,6729)),"@site/docs/Practical Sessions/Explorer/Block Leader/leader.md",6729],e007c0d7:[()=>n.e(6393).then(n.bind(n,9802)),"@site/docs/Practical Sessions/Smart Contracts/mxpy_sc_call.md",9802],e3ece220:[()=>n.e(3884).then(n.bind(n,4355)),"@site/docs/Practical Sessions/Explorer/Devnet Blockchains/devnet_testnet.md",4355],e75b870c:[()=>n.e(3798).then(n.bind(n,2872)),"@site/docs/Practical Sessions/Wallet/Keystore/keystore.md",2872],e9cf5841:[()=>n.e(6272).then(n.bind(n,1411)),"@site/docs/Practical Sessions/Learning Rust/tour-of-rust.md",1411],eb02a9a6:[()=>n.e(8387).then(n.bind(n,2828)),"@site/docs/Practical Sessions/Explorer/Transactions/transactions.md",2828],ed4d6624:[()=>n.e(5362).then(n.t.bind(n,6144,19)),"~docs/default/category-blockchain-protocols-and-distributed-applications-sidebar-category-lectures-598.json",6144],f09f4349:[()=>n.e(674).then(n.bind(n,6810)),"@site/docs/Practical Sessions/Wallet/faucet.md",6810],f4bc3419:[()=>n.e(4503).then(n.bind(n,3266)),"@site/docs/Assignments/project.md",3266],f57012b0:[()=>n.e(8770).then(n.t.bind(n,4729,19)),"~docs/default/category-blockchain-protocols-and-distributed-applications-sidebar-category-practical-sessions-5c5.json",4729],f6a805cd:[()=>n.e(4620).then(n.bind(n,2760)),"@site/docs/Practical Sessions/Basic Peer-to-Peer Blockchain/p2p_network.md",2760]};function c(e){let{error:t,retry:n,pastDelay:a}=e;return t?r.createElement("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"}},r.createElement("p",null,String(t)),r.createElement("div",null,r.createElement("button",{type:"button",onClick:n},"Retry"))):a?r.createElement("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"}},r.createElement("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb"},r.createElement("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2"},r.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},r.createElement("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),r.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},r.createElement("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),r.createElement("circle",{cx:"22",cy:"22",r:"8"},r.createElement("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"}))))):null}var u=n(6921),d=n(3102);function p(e,t){if("*"===e)return i()({loading:c,loader:()=>n.e(1774).then(n.bind(n,1774)),modules:["@theme/NotFound"],webpack:()=>[1774],render(e,t){const n=e.default;return r.createElement(d.W,{value:{plugin:{name:"native",id:"default"}}},r.createElement(n,t))}});const o=l[`${e}-${t}`],p={},f=[],m=[],h=(0,u.A)(o);return Object.entries(h).forEach((e=>{let[t,n]=e;const r=s[n];r&&(p[t]=r[0],f.push(r[1]),m.push(r[2]))})),i().Map({loading:c,loader:p,modules:f,webpack:()=>m,render(t,n){const i=JSON.parse(JSON.stringify(o));Object.entries(t).forEach((t=>{let[n,r]=t;const a=r.default;if(!a)throw new Error(`The page component at ${e} doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.`);"object"!=typeof a&&"function"!=typeof a||Object.keys(r).filter((e=>"default"!==e)).forEach((e=>{a[e]=r[e]}));let o=i;const l=n.split(".");l.slice(0,-1).forEach((e=>{o=o[e]})),o[l[l.length-1]]=a}));const l=i.__comp;delete i.__comp;const s=i.__context;return delete i.__context,r.createElement(d.W,{value:s},r.createElement(l,(0,a.A)({},i,n)))}})}const f=[{path:"/blockchain-protocols-and-distributed-applications/markdown-page",component:p("/blockchain-protocols-and-distributed-applications/markdown-page","70f"),exact:!0},{path:"/blockchain-protocols-and-distributed-applications/",component:p("/blockchain-protocols-and-distributed-applications/","b2a"),routes:[{path:"/blockchain-protocols-and-distributed-applications/",component:p("/blockchain-protocols-and-distributed-applications/","7eb"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Assignments/",component:p("/blockchain-protocols-and-distributed-applications/Assignments/","170"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Assignments/assignment1",component:p("/blockchain-protocols-and-distributed-applications/Assignments/assignment1","ec6"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Assignments/assignment2",component:p("/blockchain-protocols-and-distributed-applications/Assignments/assignment2","cbe"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Assignments/project",component:p("/blockchain-protocols-and-distributed-applications/Assignments/project","e7b"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/grading",component:p("/blockchain-protocols-and-distributed-applications/grading","acd"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Lectures/",component:p("/blockchain-protocols-and-distributed-applications/Lectures/","fa0"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Lectures/Introduction",component:p("/blockchain-protocols-and-distributed-applications/Lectures/Introduction","b13"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/","da1"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/","e61"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/basic_wallet",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/basic_wallet","9f8"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/discovery_node",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/discovery_node","16e"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/mining",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/mining","b82"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/p2p_network",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/p2p_network","400"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/sources",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/sources","772"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/terminal",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/terminal","66c"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/transactions",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/transactions","6ab"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/what_we_build",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/what_we_build","072"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/why_golang",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/why_golang","0d7"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Env Setup/",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Env Setup/","1ba"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Env Setup/setup",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Env Setup/setup","e8e"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/","3d1"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Block Leader/leader",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Block Leader/leader","78f"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Blockchain Observers/observers",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Blockchain Observers/observers","e1c"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Blockchain Validators/validators",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Blockchain Validators/validators","d22"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Blocks/",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Blocks/","9ca"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Consensus Grup/consensus",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Consensus Grup/consensus","590"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Devnet Blockchains/devnet_testnet",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Devnet Blockchains/devnet_testnet","a93"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Time in Blockchain/time",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Time in Blockchain/time","542"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Transactions/",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Transactions/","34a"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Learning Rust/",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Learning Rust/","2db"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Learning Rust/cryptozombies",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Learning Rust/cryptozombies","cae"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Learning Rust/rust",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Learning Rust/rust","b82"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Learning Rust/tour-of-rust",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Learning Rust/tour-of-rust","267"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Money (DeFi)/",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Money (DeFi)/","589"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Money (DeFi)/mint_tokens",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Money (DeFi)/mint_tokens","d7c"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Money (DeFi)/swap",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Money (DeFi)/swap","3a4"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Observer/",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Observer/","342"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Observer/",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Observer/","c87"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contract Events/",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contract Events/","374"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contract Events/events",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contract Events/events","98d"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/","1ca"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/adder",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/adder","4ce"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/cargo_deploy",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/cargo_deploy","796"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/empty",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/empty","019"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/mxpy_deploy",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/mxpy_deploy","c43"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/mxpy_sc_call",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/mxpy_sc_call","8bd"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/neversea",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/neversea","2b2"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/prerequisites",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/prerequisites","d98"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/rust_interactors",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/rust_interactors","ae4"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Tokens/",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Tokens/","5dd"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Tokens/fungible",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Tokens/fungible","f60"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Tokens/fungible-non-fungible",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Tokens/fungible-non-fungible","f18"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Tokens/nft",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Tokens/nft","ca3"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Tokens/standards",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Tokens/standards","5c7"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Wallet/",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Wallet/","c8d"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Wallet/browser_wallet",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Wallet/browser_wallet","f46"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Wallet/Cmd line wallet/cmdline_wallet",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Wallet/Cmd line wallet/cmdline_wallet","6ef"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Wallet/faucet",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Wallet/faucet","704"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Wallet/Keystore/",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Wallet/Keystore/","2e4"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Wallet/send_tx",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Wallet/send_tx","32c"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Wallet/Wallet/",component:p("/blockchain-protocols-and-distributed-applications/Practical Sessions/Wallet/Wallet/","54b"),exact:!0,sidebar:"sidebar"},{path:"/blockchain-protocols-and-distributed-applications/resources",component:p("/blockchain-protocols-and-distributed-applications/resources","818"),exact:!0,sidebar:"sidebar"}]},{path:"*",component:p("*")}]},6125:(e,t,n)=>{"use strict";n.d(t,{o:()=>a,x:()=>o});var r=n(6540);const a=r.createContext(!1);function o(e){let{children:t}=e;const[n,o]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{o(!0)}),[]),r.createElement(a.Provider,{value:n},t)}},5660:(e,t,n)=>{"use strict";var r=n(6540),a=n(961),o=n(4625),i=n(545),l=n(8193);const s=[n(119),n(6134),n(6294),n(1043)];var c=n(8328),u=n(6347),d=n(2831);function p(e){let{children:t}=e;return r.createElement(r.Fragment,null,t)}var f=n(8168),m=n(5260),h=n(4586),b=n(6025),g=n(6342),v=n(1003),y=n(2131),k=n(4090),w=n(2967),S=n(1463);function E(){const{i18n:{defaultLocale:e,localeConfigs:t}}=(0,h.A)(),n=(0,y.o)();return r.createElement(m.A,null,Object.entries(t).map((e=>{let[t,{htmlLang:a}]=e;return r.createElement("link",{key:t,rel:"alternate",href:n.createUrl({locale:t,fullyQualified:!0}),hrefLang:a})})),r.createElement("link",{rel:"alternate",href:n.createUrl({locale:e,fullyQualified:!0}),hrefLang:"x-default"}))}function x(e){let{permalink:t}=e;const{siteConfig:{url:n}}=(0,h.A)(),a=function(){const{siteConfig:{url:e}}=(0,h.A)(),{pathname:t}=(0,u.zy)();return e+(0,b.A)(t)}(),o=t?`${n}${t}`:a;return r.createElement(m.A,null,r.createElement("meta",{property:"og:url",content:o}),r.createElement("link",{rel:"canonical",href:o}))}function P(){const{i18n:{currentLocale:e}}=(0,h.A)(),{metadata:t,image:n}=(0,g.p)();return r.createElement(r.Fragment,null,r.createElement(m.A,null,r.createElement("meta",{name:"twitter:card",content:"summary_large_image"}),r.createElement("body",{className:k.w})),n&&r.createElement(v.be,{image:n}),r.createElement(x,null),r.createElement(E,null),r.createElement(S.A,{tag:w.Cy,locale:e}),r.createElement(m.A,null,t.map(((e,t)=>r.createElement("meta",(0,f.A)({key:t},e))))))}const _=new Map;function C(e){if(_.has(e.pathname))return{...e,pathname:_.get(e.pathname)};if((0,d.u)(c.A,e.pathname).some((e=>{let{route:t}=e;return!0===t.exact})))return _.set(e.pathname,e.pathname),e;const t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return _.set(e.pathname,t),{...e,pathname:t}}var A=n(6125),T=n(6988);function L(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r{const r=t.default?.[e]??t[e];return r?.(...n)}));return()=>a.forEach((e=>e?.()))}const R=function(e){let{children:t,location:n,previousLocation:a}=e;return(0,r.useLayoutEffect)((()=>{a!==n&&(a&&function(e){const{hash:t}=e;if(t){const e=decodeURIComponent(t.substring(1)),n=document.getElementById(e);n?.scrollIntoView()}else window.scrollTo(0,0)}(n),L("onRouteDidUpdate",{previousLocation:a,location:n}))}),[a,n]),t};function O(e){const t=Array.from(new Set([e,decodeURI(e)])).map((e=>(0,d.u)(c.A,e))).flat();return Promise.all(t.map((e=>e.route.component.preload?.())))}class N extends r.Component{previousLocation;routeUpdateCleanupCb;constructor(e){super(e),this.previousLocation=null,this.routeUpdateCleanupCb=l.A.canUseDOM?L("onRouteUpdate",{previousLocation:null,location:this.props.location}):()=>{},this.state={nextRouteHasLoaded:!0}}shouldComponentUpdate(e,t){if(e.location===this.props.location)return t.nextRouteHasLoaded;const n=e.location;return this.previousLocation=this.props.location,this.setState({nextRouteHasLoaded:!1}),this.routeUpdateCleanupCb=L("onRouteUpdate",{previousLocation:this.previousLocation,location:n}),O(n.pathname).then((()=>{this.routeUpdateCleanupCb(),this.setState({nextRouteHasLoaded:!0})})).catch((e=>{console.warn(e),window.location.reload()})),!1}render(){const{children:e,location:t}=this.props;return r.createElement(R,{previousLocation:this.previousLocation,location:t},r.createElement(u.qh,{location:t,render:()=>e}))}}const D=N,I="docusaurus-base-url-issue-banner-container",B="docusaurus-base-url-issue-banner-suggestion-container",M="__DOCUSAURUS_INSERT_BASEURL_BANNER";function F(e){return`\nwindow['${M}'] = true;\n\ndocument.addEventListener('DOMContentLoaded', maybeInsertBanner);\n\nfunction maybeInsertBanner() {\n var shouldInsert = window['${M}'];\n shouldInsert && insertBanner();\n}\n\nfunction insertBanner() {\n var bannerContainer = document.getElementById('${I}');\n if (!bannerContainer) {\n return;\n }\n var bannerHtml = ${JSON.stringify(function(e){return`\n
\n

Your Docusaurus site did not load properly.

\n

A very common reason is a wrong site baseUrl configuration.

\n

Current configured baseUrl = ${e} ${"/"===e?" (default value)":""}

\n

We suggest trying baseUrl =

\n
\n`}(e)).replace(/{window[M]=!1}),[]),r.createElement(r.Fragment,null,!l.A.canUseDOM&&r.createElement(m.A,null,r.createElement("script",null,F(e))),r.createElement("div",{id:I}))}function z(){const{siteConfig:{baseUrl:e,baseUrlIssueBanner:t}}=(0,h.A)(),{pathname:n}=(0,u.zy)();return t&&n===e?r.createElement(j,null):null}function U(){const{siteConfig:{favicon:e,title:t,noIndex:n},i18n:{currentLocale:a,localeConfigs:o}}=(0,h.A)(),i=(0,b.A)(e),{htmlLang:l,direction:s}=o[a];return r.createElement(m.A,null,r.createElement("html",{lang:l,dir:s}),r.createElement("title",null,t),r.createElement("meta",{property:"og:title",content:t}),r.createElement("meta",{name:"viewport",content:"width=device-width, initial-scale=1.0"}),n&&r.createElement("meta",{name:"robots",content:"noindex, nofollow"}),e&&r.createElement("link",{rel:"icon",href:i}))}var $=n(7489);function G(){const e=(0,d.v)(c.A),t=(0,u.zy)();return r.createElement($.A,null,r.createElement(T.l,null,r.createElement(A.x,null,r.createElement(p,null,r.createElement(U,null),r.createElement(P,null),r.createElement(z,null),r.createElement(D,{location:C(t)},e)))))}var q=n(4054);const H=function(e){try{return document.createElement("link").relList.supports(e)}catch{return!1}}("prefetch")?function(e){return new Promise(((t,n)=>{if("undefined"==typeof document)return void n();const r=document.createElement("link");r.setAttribute("rel","prefetch"),r.setAttribute("href",e),r.onload=()=>t(),r.onerror=()=>n();const a=document.getElementsByTagName("head")[0]??document.getElementsByName("script")[0]?.parentNode;a?.appendChild(r)}))}:function(e){return new Promise(((t,n)=>{const r=new XMLHttpRequest;r.open("GET",e,!0),r.withCredentials=!0,r.onload=()=>{200===r.status?t():n()},r.send(null)}))};var W=n(6921);const V=new Set,K=new Set,Y=()=>navigator.connection?.effectiveType.includes("2g")||navigator.connection?.saveData,Q={prefetch(e){if(!(e=>!Y()&&!K.has(e)&&!V.has(e))(e))return!1;V.add(e);const t=(0,d.u)(c.A,e).flatMap((e=>{return t=e.route.path,Object.entries(q).filter((e=>{let[n]=e;return n.replace(/-[^-]+$/,"")===t})).flatMap((e=>{let[,t]=e;return Object.values((0,W.A)(t))}));var t}));return Promise.all(t.map((e=>{const t=n.gca(e);return t&&!t.includes("undefined")?H(t).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!Y()&&!K.has(e))(e)&&(K.add(e),O(e))},X=Object.freeze(Q);if(l.A.canUseDOM){window.docusaurus=X;const e=a.hydrate;O(window.location.pathname).then((()=>{e(r.createElement(i.vd,null,r.createElement(o.Kd,null,r.createElement(G,null))),document.getElementById("__docusaurus"))}))}},6988:(e,t,n)=>{"use strict";n.d(t,{o:()=>u,l:()=>d});var r=n(6540),a=n(4784);const o=JSON.parse('{"docusaurus-plugin-content-docs":{"default":{"path":"/blockchain-protocols-and-distributed-applications/","versions":[{"name":"current","label":"Next","isLast":true,"path":"/blockchain-protocols-and-distributed-applications/","mainDocId":"README","docs":[{"id":"Assignments/assignment1","path":"/blockchain-protocols-and-distributed-applications/Assignments/assignment1","sidebar":"sidebar"},{"id":"Assignments/assignment2","path":"/blockchain-protocols-and-distributed-applications/Assignments/assignment2","sidebar":"sidebar"},{"id":"Assignments/project","path":"/blockchain-protocols-and-distributed-applications/Assignments/project","sidebar":"sidebar"},{"id":"grading","path":"/blockchain-protocols-and-distributed-applications/grading","sidebar":"sidebar"},{"id":"Lectures/Introduction","path":"/blockchain-protocols-and-distributed-applications/Lectures/Introduction","sidebar":"sidebar"},{"id":"Practical Sessions/Basic Peer-to-Peer Blockchain/basic_wallet","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/basic_wallet","sidebar":"sidebar"},{"id":"Practical Sessions/Basic Peer-to-Peer Blockchain/discovery_node","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/discovery_node","sidebar":"sidebar"},{"id":"Practical Sessions/Basic Peer-to-Peer Blockchain/mining","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/mining","sidebar":"sidebar"},{"id":"Practical Sessions/Basic Peer-to-Peer Blockchain/p2p_network","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/p2p_network","sidebar":"sidebar"},{"id":"Practical Sessions/Basic Peer-to-Peer Blockchain/sources","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/sources","sidebar":"sidebar"},{"id":"Practical Sessions/Basic Peer-to-Peer Blockchain/terminal","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/terminal","sidebar":"sidebar"},{"id":"Practical Sessions/Basic Peer-to-Peer Blockchain/transactions","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/transactions","sidebar":"sidebar"},{"id":"Practical Sessions/Basic Peer-to-Peer Blockchain/what_we_build","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/what_we_build","sidebar":"sidebar"},{"id":"Practical Sessions/Basic Peer-to-Peer Blockchain/why_golang","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/why_golang","sidebar":"sidebar"},{"id":"Practical Sessions/Env Setup/setup","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Env Setup/setup","sidebar":"sidebar"},{"id":"Practical Sessions/Explorer/Block Leader/leader","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Block Leader/leader","sidebar":"sidebar"},{"id":"Practical Sessions/Explorer/Blockchain Observers/observers","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Blockchain Observers/observers","sidebar":"sidebar"},{"id":"Practical Sessions/Explorer/Blockchain Validators/validators","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Blockchain Validators/validators","sidebar":"sidebar"},{"id":"Practical Sessions/Explorer/Blocks/blocks","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Blocks/","sidebar":"sidebar"},{"id":"Practical Sessions/Explorer/Consensus Grup/consensus","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Consensus Grup/consensus","sidebar":"sidebar"},{"id":"Practical Sessions/Explorer/Devnet Blockchains/devnet_testnet","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Devnet Blockchains/devnet_testnet","sidebar":"sidebar"},{"id":"Practical Sessions/Explorer/Time in Blockchain/time","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Time in Blockchain/time","sidebar":"sidebar"},{"id":"Practical Sessions/Explorer/Transactions/transactions","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/Transactions/","sidebar":"sidebar"},{"id":"Practical Sessions/Learning Rust/cryptozombies","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Learning Rust/cryptozombies","sidebar":"sidebar"},{"id":"Practical Sessions/Learning Rust/rust","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Learning Rust/rust","sidebar":"sidebar"},{"id":"Practical Sessions/Learning Rust/tour-of-rust","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Learning Rust/tour-of-rust","sidebar":"sidebar"},{"id":"Practical Sessions/Money (DeFi)/mint_tokens","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Money (DeFi)/mint_tokens","sidebar":"sidebar"},{"id":"Practical Sessions/Money (DeFi)/swap","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Money (DeFi)/swap","sidebar":"sidebar"},{"id":"Practical Sessions/Observer/observer","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Observer/","sidebar":"sidebar"},{"id":"Practical Sessions/Smart Contract Events/events","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contract Events/events","sidebar":"sidebar"},{"id":"Practical Sessions/Smart Contracts/adder","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/adder","sidebar":"sidebar"},{"id":"Practical Sessions/Smart Contracts/cargo_deploy","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/cargo_deploy","sidebar":"sidebar"},{"id":"Practical Sessions/Smart Contracts/empty","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/empty","sidebar":"sidebar"},{"id":"Practical Sessions/Smart Contracts/mxpy_deploy","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/mxpy_deploy","sidebar":"sidebar"},{"id":"Practical Sessions/Smart Contracts/mxpy_sc_call","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/mxpy_sc_call","sidebar":"sidebar"},{"id":"Practical Sessions/Smart Contracts/neversea","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/neversea","sidebar":"sidebar"},{"id":"Practical Sessions/Smart Contracts/prerequisites","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/prerequisites","sidebar":"sidebar"},{"id":"Practical Sessions/Smart Contracts/rust_interactors","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/rust_interactors","sidebar":"sidebar"},{"id":"Practical Sessions/Tokens/fungible","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Tokens/fungible","sidebar":"sidebar"},{"id":"Practical Sessions/Tokens/fungible-non-fungible","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Tokens/fungible-non-fungible","sidebar":"sidebar"},{"id":"Practical Sessions/Tokens/nft","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Tokens/nft","sidebar":"sidebar"},{"id":"Practical Sessions/Tokens/standards","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Tokens/standards","sidebar":"sidebar"},{"id":"Practical Sessions/Wallet/browser_wallet","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Wallet/browser_wallet","sidebar":"sidebar"},{"id":"Practical Sessions/Wallet/Cmd line wallet/cmdline_wallet","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Wallet/Cmd line wallet/cmdline_wallet","sidebar":"sidebar"},{"id":"Practical Sessions/Wallet/faucet","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Wallet/faucet","sidebar":"sidebar"},{"id":"Practical Sessions/Wallet/Keystore/keystore","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Wallet/Keystore/","sidebar":"sidebar"},{"id":"Practical Sessions/Wallet/send_tx","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Wallet/send_tx","sidebar":"sidebar"},{"id":"Practical Sessions/Wallet/Wallet/wallet","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Wallet/Wallet/","sidebar":"sidebar"},{"id":"README","path":"/blockchain-protocols-and-distributed-applications/","sidebar":"sidebar"},{"id":"resources","path":"/blockchain-protocols-and-distributed-applications/resources","sidebar":"sidebar"},{"id":"/Lectures/","path":"/blockchain-protocols-and-distributed-applications/Lectures/","sidebar":"sidebar"},{"id":"/Practical Sessions/","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/","sidebar":"sidebar"},{"id":"/Practical Sessions/Env Setup/","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Env Setup/","sidebar":"sidebar"},{"id":"/Practical Sessions/Wallet/","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Wallet/","sidebar":"sidebar"},{"id":"/Practical Sessions/Explorer/","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Explorer/","sidebar":"sidebar"},{"id":"/Practical Sessions/Tokens/","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Tokens/","sidebar":"sidebar"},{"id":"/Practical Sessions/Smart Contracts/","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/","sidebar":"sidebar"},{"id":"/Practical Sessions/Learning Rust/","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Learning Rust/","sidebar":"sidebar"},{"id":"/Practical Sessions/Observer/","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Observer/","sidebar":"sidebar"},{"id":"/Practical Sessions/Money (DeFi)/","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Money (DeFi)/","sidebar":"sidebar"},{"id":"/Practical Sessions/Basic Peer-to-Peer Blockchain/","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Basic Peer-to-Peer Blockchain/","sidebar":"sidebar"},{"id":"/Practical Sessions/Smart Contract Events/","path":"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contract Events/","sidebar":"sidebar"},{"id":"/Assignments/","path":"/blockchain-protocols-and-distributed-applications/Assignments/","sidebar":"sidebar"}],"draftIds":[],"sidebars":{"sidebar":{"link":{"path":"/blockchain-protocols-and-distributed-applications/","label":"Introduction"}}}}],"breadcrumbs":true}}}'),i=JSON.parse('{"defaultLocale":"en","locales":["en"],"path":"i18n","currentLocale":"en","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en"}}}');var l=n(2654);const s=JSON.parse('{"docusaurusVersion":"2.1.0","siteVersion":"0.0.0","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"2.1.0"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"2.1.0"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"2.1.0"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"2.1.0"}}}'),c={siteConfig:a.A,siteMetadata:s,globalData:o,i18n:i,codeTranslations:l},u=r.createContext(c);function d(e){let{children:t}=e;return r.createElement(u.Provider,{value:c},t)}},7489:(e,t,n)=>{"use strict";n.d(t,{A:()=>u});var r=n(6540),a=n(8193),o=n(5260),i=n(2316);function l(e){let{error:t,tryAgain:n}=e;return r.createElement("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"center",height:"50vh",width:"100%",fontSize:"20px"}},r.createElement("h1",null,"This page crashed."),r.createElement("p",null,t.message),r.createElement("button",{type:"button",onClick:n},"Try again"))}function s(e){let{error:t,tryAgain:n}=e;return r.createElement(u,{fallback:()=>r.createElement(l,{error:t,tryAgain:n})},r.createElement(o.A,null,r.createElement("title",null,"Page Error")),r.createElement(i.A,null,r.createElement(l,{error:t,tryAgain:n})))}const c=e=>r.createElement(s,e);class u extends r.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){a.A.canUseDOM&&this.setState({error:e})}render(){const{children:e}=this.props,{error:t}=this.state;if(t){const e={error:t,tryAgain:()=>this.setState({error:null})};return(this.props.fallback??c)(e)}return e??null}}},8193:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});const r="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,a={canUseDOM:r,canUseEventListeners:r&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&"screen"in window}},5260:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});var r=n(6540),a=n(545);function o(e){return r.createElement(a.mg,e)}},5489:(e,t,n)=>{"use strict";n.d(t,{A:()=>f});var r=n(8168),a=n(6540),o=n(4625),i=n(440),l=n(4586),s=n(6654),c=n(8193);const u=a.createContext({collectLink:()=>{}});var d=n(6025);function p(e,t){let{isNavLink:n,to:p,href:f,activeClassName:m,isActive:h,"data-noBrokenLinkCheck":b,autoAddBaseUrl:g=!0,...v}=e;const{siteConfig:{trailingSlash:y,baseUrl:k}}=(0,l.A)(),{withBaseUrl:w}=(0,d.h)(),S=(0,a.useContext)(u),E=(0,a.useRef)(null);(0,a.useImperativeHandle)(t,(()=>E.current));const x=p||f;const P=(0,s.A)(x),_=x?.replace("pathname://","");let C=void 0!==_?(A=_,g&&(e=>e.startsWith("/"))(A)?w(A):A):void 0;var A;C&&P&&(C=(0,i.applyTrailingSlash)(C,{trailingSlash:y,baseUrl:k}));const T=(0,a.useRef)(!1),L=n?o.k2:o.N_,R=c.A.canUseIntersectionObserver,O=(0,a.useRef)();(0,a.useEffect)((()=>(!R&&P&&null!=C&&window.docusaurus.prefetch(C),()=>{R&&O.current&&O.current.disconnect()})),[O,C,R,P]);const N=C?.startsWith("#")??!1,D=!C||!P||N;return D||b||S.collectLink(C),D?a.createElement("a",(0,r.A)({ref:E,href:C},x&&!P&&{target:"_blank",rel:"noopener noreferrer"},v)):a.createElement(L,(0,r.A)({},v,{onMouseEnter:()=>{T.current||null==C||(window.docusaurus.preload(C),T.current=!0)},innerRef:e=>{E.current=e,R&&e&&P&&(O.current=new window.IntersectionObserver((t=>{t.forEach((t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(O.current.unobserve(e),O.current.disconnect(),null!=C&&window.docusaurus.prefetch(C))}))})),O.current.observe(e))},to:C},n&&{isActive:h,activeClassName:m}))}const f=a.forwardRef(p)},1312:(e,t,n)=>{"use strict";n.d(t,{A:()=>s,T:()=>l});var r=n(6540);function a(e,t){const n=e.split(/(\{\w+\})/).map(((e,n)=>{if(n%2==1){const n=t?.[e.slice(1,-1)];if(void 0!==n)return n}return e}));return n.some((e=>(0,r.isValidElement)(e)))?n.map(((e,t)=>(0,r.isValidElement)(e)?r.cloneElement(e,{key:t}):e)).filter((e=>""!==e)):n.join("")}var o=n(2654);function i(e){let{id:t,message:n}=e;if(void 0===t&&void 0===n)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return o[t??n]??n??t}function l(e,t){let{message:n,id:r}=e;return a(i({message:n,id:r}),t)}function s(e){let{children:t,id:n,values:o}=e;if(t&&"string"!=typeof t)throw console.warn("Illegal children",t),new Error("The Docusaurus component only accept simple string values");const l=i({message:t,id:n});return r.createElement(r.Fragment,null,a(l,o))}},7065:(e,t,n)=>{"use strict";n.d(t,{W:()=>r});const r="default"},6654:(e,t,n)=>{"use strict";function r(e){return/^(?:\w*:|\/\/)/.test(e)}function a(e){return void 0!==e&&!r(e)}n.d(t,{A:()=>a,z:()=>r})},6025:(e,t,n)=>{"use strict";n.d(t,{A:()=>i,h:()=>o});var r=n(4586),a=n(6654);function o(){const{siteConfig:{baseUrl:e,url:t}}=(0,r.A)();return{withBaseUrl:(n,r)=>function(e,t,n,r){let{forcePrependBaseUrl:o=!1,absolute:i=!1}=void 0===r?{}:r;if(!n||n.startsWith("#")||(0,a.z)(n))return n;if(o)return t+n.replace(/^\//,"");if(n===t.replace(/\/$/,""))return t;const l=n.startsWith(t)?n:t+n.replace(/^\//,"");return i?e+l:l}(t,e,n,r)}}function i(e,t){void 0===t&&(t={});const{withBaseUrl:n}=o();return n(e,t)}},4586:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});var r=n(6540),a=n(6988);function o(){return(0,r.useContext)(a.o)}},2303:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});var r=n(6540),a=n(6125);function o(){return(0,r.useContext)(a.o)}},6921:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});const r=e=>"object"==typeof e&&!!e&&Object.keys(e).length>0;function a(e){const t={};return function e(n,a){Object.entries(n).forEach((n=>{let[o,i]=n;const l=a?`${a}.${o}`:o;r(i)?e(i,l):t[l]=i}))}(e),t}},3102:(e,t,n)=>{"use strict";n.d(t,{W:()=>o,o:()=>a});var r=n(6540);const a=r.createContext(null);function o(e){let{children:t,value:n}=e;const o=r.useContext(a),i=(0,r.useMemo)((()=>function(e){let{parent:t,value:n}=e;if(!t){if(!n)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in n))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return n}const r={...t.data,...n?.data};return{plugin:t.plugin,data:r}}({parent:o,value:n})),[o,n]);return r.createElement(a.Provider,{value:i},t)}},4070:(e,t,n)=>{"use strict";n.d(t,{zK:()=>h,vT:()=>p,Gy:()=>u,HW:()=>b,ht:()=>d,r7:()=>m,jh:()=>f});var r=n(6347),a=n(4586),o=n(7065);function i(e,t){void 0===t&&(t={});const n=function(){const{globalData:e}=(0,a.A)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}const l=e=>e.versions.find((e=>e.isLast));function s(e,t){const n=function(e,t){const n=l(e);return[...e.versions.filter((e=>e!==n)),n].find((e=>!!(0,r.B6)(t,{path:e.path,exact:!1,strict:!1})))}(e,t),a=n?.docs.find((e=>!!(0,r.B6)(t,{path:e.path,exact:!0,strict:!1})));return{activeVersion:n,activeDoc:a,alternateDocVersions:a?function(t){const n={};return e.versions.forEach((e=>{e.docs.forEach((r=>{r.id===t&&(n[e.name]=r)}))})),n}(a.id):{}}}const c={},u=()=>i("docusaurus-plugin-content-docs")??c,d=e=>function(e,t,n){void 0===t&&(t=o.W),void 0===n&&(n={});const r=i(e),a=r?.[t];if(!a&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return a}("docusaurus-plugin-content-docs",e,{failfast:!0});function p(e){void 0===e&&(e={});const t=u(),{pathname:n}=(0,r.zy)();return function(e,t,n){void 0===n&&(n={});const a=Object.entries(e).sort(((e,t)=>t[1].path.localeCompare(e[1].path))).find((e=>{let[,n]=e;return!!(0,r.B6)(t,{path:n.path,exact:!1,strict:!1})})),o=a?{pluginId:a[0],pluginData:a[1]}:void 0;if(!o&&n.failfast)throw new Error(`Can't find active docs plugin for "${t}" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(e).map((e=>e.path)).join(", ")}`);return o}(t,n,e)}function f(e){return d(e).versions}function m(e){const t=d(e);return l(t)}function h(e){const t=d(e),{pathname:n}=(0,r.zy)();return s(t,n)}function b(e){const t=d(e),{pathname:n}=(0,r.zy)();return function(e,t){const n=l(e);return{latestDocSuggestion:s(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(t,n)}},6294:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o});var r=n(5947),a=n.n(r);a().configure({showSpinner:!1});const o={onRouteUpdate(e){let{location:t,previousLocation:n}=e;if(n&&t.pathname!==n.pathname){const e=window.setTimeout((()=>{a().start()}),200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){a().done()}}},6134:(e,t,n)=>{"use strict";var r=n(1258),a=n(4784);!function(e){const{themeConfig:{prism:t}}=a.A,{additionalLanguages:r}=t;globalThis.Prism=e,r.forEach((e=>{n(8692)(`./prism-${e}`)})),delete globalThis.Prism}(r.A)},3186:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});var r=n(6540);const a={iconExternalLink:"iconExternalLink_nPIU"};function o(e){let{width:t=13.5,height:n=13.5}=e;return r.createElement("svg",{width:t,height:n,"aria-hidden":"true",viewBox:"0 0 24 24",className:a.iconExternalLink},r.createElement("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"}))}},2316:(e,t,n)=>{"use strict";n.d(t,{A:()=>at});var r=n(6540),a=n(53),o=n(7489),i=n(1003),l=n(7559),s=n(4090),c=n(1312),u=n(6347),d=n(5062);function p(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}const f={skipToContent:"skipToContent_fXgn"};function m(){const{containerRef:e,handleSkip:t}=function(){const e=(0,r.useRef)(null),{action:t}=(0,u.W6)(),n=(0,r.useCallback)((e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.querySelector(`.${l.G.wrapper.main}`);t&&p(t)}),[]);return(0,d.$)((n=>{let{location:r}=n;e.current&&!r.hash&&"PUSH"===t&&p(e.current)})),{containerRef:e,handleSkip:n}}();return r.createElement("div",{ref:e,role:"region","aria-label":(0,c.T)({id:"theme.common.skipToMainContent"})},r.createElement("a",{href:"#",className:f.skipToContent,onClick:t},r.createElement(c.A,{id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation"},"Skip to main content")))}var h=n(6342),b=n(5041),g=n(8168);function v(e){let{width:t=21,height:n=21,color:a="currentColor",strokeWidth:o=1.2,className:i,...l}=e;return r.createElement("svg",(0,g.A)({viewBox:"0 0 15 15",width:t,height:n},l),r.createElement("g",{stroke:a,strokeWidth:o},r.createElement("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})))}const y={closeButton:"closeButton_CVFx"};function k(e){return r.createElement("button",(0,g.A)({type:"button","aria-label":(0,c.T)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"})},e,{className:(0,a.A)("clean-btn close",y.closeButton,e.className)}),r.createElement(v,{width:14,height:14,strokeWidth:3.1}))}const w={content:"content_knG7"};function S(e){const{announcementBar:t}=(0,h.p)(),{content:n}=t;return r.createElement("div",(0,g.A)({},e,{className:(0,a.A)(w.content,e.className),dangerouslySetInnerHTML:{__html:n}}))}const E={announcementBar:"announcementBar_mb4j",announcementBarPlaceholder:"announcementBarPlaceholder_vyr4",announcementBarClose:"announcementBarClose_gvF7",announcementBarContent:"announcementBarContent_xLdY"};function x(){const{announcementBar:e}=(0,h.p)(),{isActive:t,close:n}=(0,b.Mj)();if(!t)return null;const{backgroundColor:a,textColor:o,isCloseable:i}=e;return r.createElement("div",{className:E.announcementBar,style:{backgroundColor:a,color:o},role:"banner"},i&&r.createElement("div",{className:E.announcementBarPlaceholder}),r.createElement(S,{className:E.announcementBarContent}),i&&r.createElement(k,{onClick:n,className:E.announcementBarClose}))}var P=n(9876),_=n(3104);var C=n(9532),A=n(5600);const T=r.createContext(null);function L(e){let{children:t}=e;const n=function(){const e=(0,P.M)(),t=(0,A.YL)(),[n,a]=(0,r.useState)(!1),o=null!==t.component,i=(0,C.ZC)(o);return(0,r.useEffect)((()=>{o&&!i&&a(!0)}),[o,i]),(0,r.useEffect)((()=>{o?e.shown||a(!0):a(!1)}),[e.shown,o]),(0,r.useMemo)((()=>[n,a]),[n])}();return r.createElement(T.Provider,{value:n},t)}function R(e){if(e.component){const t=e.component;return r.createElement(t,e.props)}}function O(){const e=(0,r.useContext)(T);if(!e)throw new C.dV("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,a=(0,r.useCallback)((()=>n(!1)),[n]),o=(0,A.YL)();return(0,r.useMemo)((()=>({shown:t,hide:a,content:R(o)})),[a,o,t])}function N(e){let{header:t,primaryMenu:n,secondaryMenu:o}=e;const{shown:i}=O();return r.createElement("div",{className:"navbar-sidebar"},t,r.createElement("div",{className:(0,a.A)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":i})},r.createElement("div",{className:"navbar-sidebar__item menu"},n),r.createElement("div",{className:"navbar-sidebar__item menu"},o)))}var D=n(5293),I=n(2303);function B(e){return r.createElement("svg",(0,g.A)({viewBox:"0 0 24 24",width:24,height:24},e),r.createElement("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"}))}function M(e){return r.createElement("svg",(0,g.A)({viewBox:"0 0 24 24",width:24,height:24},e),r.createElement("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"}))}const F={toggle:"toggle_vylO",toggleButton:"toggleButton_gllP",darkToggleIcon:"darkToggleIcon_wfgR",lightToggleIcon:"lightToggleIcon_pyhR",toggleButtonDisabled:"toggleButtonDisabled_aARS"};function j(e){let{className:t,value:n,onChange:o}=e;const i=(0,I.A)(),l=(0,c.T)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the navbar color mode toggle"},{mode:"dark"===n?(0,c.T)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,c.T)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return r.createElement("div",{className:(0,a.A)(F.toggle,t)},r.createElement("button",{className:(0,a.A)("clean-btn",F.toggleButton,!i&&F.toggleButtonDisabled),type:"button",onClick:()=>o("dark"===n?"light":"dark"),disabled:!i,title:l,"aria-label":l},r.createElement(B,{className:(0,a.A)(F.toggleIcon,F.lightToggleIcon)}),r.createElement(M,{className:(0,a.A)(F.toggleIcon,F.darkToggleIcon)})))}const z=r.memo(j);function U(e){let{className:t}=e;const n=(0,h.p)().colorMode.disableSwitch,{colorMode:a,setColorMode:o}=(0,D.G)();return n?null:r.createElement(z,{className:t,value:a,onChange:o})}var $=n(3465);function G(){return r.createElement($.A,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function q(){const e=(0,P.M)();return r.createElement("button",{type:"button",className:"clean-btn navbar-sidebar__close",onClick:()=>e.toggle()},r.createElement(v,{color:"var(--ifm-color-emphasis-600)"}))}function H(){return r.createElement("div",{className:"navbar-sidebar__brand"},r.createElement(G,null),r.createElement(U,{className:"margin-right--md"}),r.createElement(q,null))}var W=n(5489),V=n(6025),K=n(6654);function Y(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}var Q=n(3186);function X(e){let{activeBasePath:t,activeBaseRegex:n,to:a,href:o,label:i,html:l,isDropdownLink:s,prependBaseUrlToHref:c,...u}=e;const d=(0,V.A)(a),p=(0,V.A)(t),f=(0,V.A)(o,{forcePrependBaseUrl:!0}),m=i&&o&&!(0,K.A)(o),h=l?{dangerouslySetInnerHTML:{__html:l}}:{children:r.createElement(r.Fragment,null,i,m&&r.createElement(Q.A,s&&{width:12,height:12}))};return o?r.createElement(W.A,(0,g.A)({href:c?f:o},u,h)):r.createElement(W.A,(0,g.A)({to:d,isNavLink:!0},(t||n)&&{isActive:(e,t)=>n?Y(n,t.pathname):t.pathname.startsWith(p)},u,h))}function Z(e){let{className:t,isDropdownItem:n=!1,...o}=e;const i=r.createElement(X,(0,g.A)({className:(0,a.A)(n?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:n},o));return n?r.createElement("li",null,i):i}function J(e){let{className:t,isDropdownItem:n,...o}=e;return r.createElement("li",{className:"menu__list-item"},r.createElement(X,(0,g.A)({className:(0,a.A)("menu__link",t)},o)))}function ee(e){let{mobile:t=!1,position:n,...a}=e;const o=t?J:Z;return r.createElement(o,(0,g.A)({},a,{activeClassName:a.activeClassName??(t?"menu__link--active":"navbar__link--active")}))}var te=n(1422),ne=n(9169),re=n(4586);function ae(e,t){return e.some((e=>function(e,t){return!!(0,ne.ys)(e.to,t)||!!Y(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)))}function oe(e){let{items:t,position:n,className:o,onClick:i,...l}=e;const s=(0,r.useRef)(null),[c,u]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{const e=e=>{s.current&&!s.current.contains(e.target)&&u(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e)}}),[s]),r.createElement("div",{ref:s,className:(0,a.A)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===n,"dropdown--show":c})},r.createElement(X,(0,g.A)({"aria-haspopup":"true","aria-expanded":c,role:"button",href:l.to?void 0:"#",className:(0,a.A)("navbar__link",o)},l,{onClick:l.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),u(!c))}}),l.children??l.label),r.createElement("ul",{className:"dropdown__menu"},t.map(((e,n)=>r.createElement(ye,(0,g.A)({isDropdownItem:!0,onKeyDown:e=>{if(n===t.length-1&&"Tab"===e.key){e.preventDefault(),u(!1);const t=s.current.nextElementSibling;if(t){(t instanceof HTMLAnchorElement?t:t.querySelector("a")).focus()}}},activeClassName:"dropdown__link--active"},e,{key:n}))))))}function ie(e){let{items:t,className:n,position:o,onClick:i,...l}=e;const s=function(){const{siteConfig:{baseUrl:e}}=(0,re.A)(),{pathname:t}=(0,u.zy)();return t.replace(e,"/")}(),c=ae(t,s),{collapsed:d,toggleCollapsed:p,setCollapsed:f}=(0,te.u)({initialState:()=>!c});return(0,r.useEffect)((()=>{c&&f(!c)}),[s,c,f]),r.createElement("li",{className:(0,a.A)("menu__list-item",{"menu__list-item--collapsed":d})},r.createElement(X,(0,g.A)({role:"button",className:(0,a.A)("menu__link menu__link--sublist menu__link--sublist-caret",n)},l,{onClick:e=>{e.preventDefault(),p()}}),l.children??l.label),r.createElement(te.N,{lazy:!0,as:"ul",className:"menu__list",collapsed:d},t.map(((e,t)=>r.createElement(ye,(0,g.A)({mobile:!0,isDropdownItem:!0,onClick:i,activeClassName:"menu__link--active"},e,{key:t}))))))}function le(e){let{mobile:t=!1,...n}=e;const a=t?ie:oe;return r.createElement(a,n)}var se=n(2131);function ce(e){let{width:t=20,height:n=20,...a}=e;return r.createElement("svg",(0,g.A)({viewBox:"0 0 24 24",width:t,height:n,"aria-hidden":!0},a),r.createElement("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"}))}const ue="iconLanguage_nlXk";const de=()=>null,pe={searchBox:"searchBox_ZlJk"};function fe(e){let{children:t,className:n}=e;return r.createElement("div",{className:(0,a.A)(n,pe.searchBox)},t)}var me=n(4070),he=n(1754);var be=n(5597);const ge=e=>e.docs.find((t=>t.id===e.mainDocId));const ve={default:ee,localeDropdown:function(e){let{mobile:t,dropdownItemsBefore:n,dropdownItemsAfter:a,...o}=e;const{i18n:{currentLocale:i,locales:l,localeConfigs:s}}=(0,re.A)(),u=(0,se.o)(),d=[...n,...l.map((e=>{const n=`pathname://${u.createUrl({locale:e,fullyQualified:!1})}`;return{label:s[e].label,lang:s[e].htmlLang,to:n,target:"_self",autoAddBaseUrl:!1,className:e===i?t?"menu__link--active":"dropdown__link--active":""}})),...a],p=t?(0,c.T)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):s[i].label;return r.createElement(le,(0,g.A)({},o,{mobile:t,label:r.createElement(r.Fragment,null,r.createElement(ce,{className:ue}),p),items:d}))},search:function(e){let{mobile:t,className:n}=e;return t?null:r.createElement(fe,{className:n},r.createElement(de,null))},dropdown:le,html:function(e){let{value:t,className:n,mobile:o=!1,isDropdownItem:i=!1}=e;const l=i?"li":"div";return r.createElement(l,{className:(0,a.A)({navbar__item:!o&&!i,"menu__list-item":o},n),dangerouslySetInnerHTML:{__html:t}})},doc:function(e){let{docId:t,label:n,docsPluginId:a,...o}=e;const{activeDoc:i}=(0,me.zK)(a),l=(0,he.QB)(t,a);return null===l?null:r.createElement(ee,(0,g.A)({exact:!0},o,{isActive:()=>i?.path===l.path||!!i?.sidebar&&i.sidebar===l.sidebar,label:n??l.id,to:l.path}))},docSidebar:function(e){let{sidebarId:t,label:n,docsPluginId:a,...o}=e;const{activeDoc:i}=(0,me.zK)(a),l=(0,he.fW)(t,a).link;if(!l)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${t}" doesn't have anything to be linked to.`);return r.createElement(ee,(0,g.A)({exact:!0},o,{isActive:()=>i?.sidebar===t,label:n??l.label,to:l.path}))},docsVersion:function(e){let{label:t,to:n,docsPluginId:a,...o}=e;const i=(0,he.Vd)(a)[0],l=t??i.label,s=n??(e=>e.docs.find((t=>t.id===e.mainDocId)))(i).path;return r.createElement(ee,(0,g.A)({},o,{label:l,to:s}))},docsVersionDropdown:function(e){let{mobile:t,docsPluginId:n,dropdownActiveClassDisabled:a,dropdownItemsBefore:o,dropdownItemsAfter:i,...l}=e;const s=(0,me.zK)(n),u=(0,me.jh)(n),{savePreferredVersionName:d}=(0,be.g1)(n),p=[...o,...u.map((e=>{const t=s.alternateDocVersions[e.name]??ge(e);return{label:e.label,to:t.path,isActive:()=>e===s.activeVersion,onClick:()=>d(e.name)}})),...i],f=(0,he.Vd)(n)[0],m=t&&p.length>1?(0,c.T)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):f.label,h=t&&p.length>1?void 0:ge(f).path;return p.length<=1?r.createElement(ee,(0,g.A)({},l,{mobile:t,label:m,to:h,isActive:a?()=>!1:void 0})):r.createElement(le,(0,g.A)({},l,{mobile:t,label:m,to:h,items:p,isActive:a?()=>!1:void 0}))}};function ye(e){let{type:t,...n}=e;const a=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),o=ve[a];if(!o)throw new Error(`No NavbarItem component found for type "${t}".`);return r.createElement(o,n)}function ke(){const e=(0,P.M)(),t=(0,h.p)().navbar.items;return r.createElement("ul",{className:"menu__list"},t.map(((t,n)=>r.createElement(ye,(0,g.A)({mobile:!0},t,{onClick:()=>e.toggle(),key:n})))))}function we(e){return r.createElement("button",(0,g.A)({},e,{type:"button",className:"clean-btn navbar-sidebar__back"}),r.createElement(c.A,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)"},"\u2190 Back to main menu"))}function Se(){const e=0===(0,h.p)().navbar.items.length,t=O();return r.createElement(r.Fragment,null,!e&&r.createElement(we,{onClick:()=>t.hide()}),t.content)}function Ee(){const e=(0,P.M)();var t;return void 0===(t=e.shown)&&(t=!0),(0,r.useEffect)((()=>(document.body.style.overflow=t?"hidden":"visible",()=>{document.body.style.overflow="visible"})),[t]),e.shouldRender?r.createElement(N,{header:r.createElement(H,null),primaryMenu:r.createElement(ke,null),secondaryMenu:r.createElement(Se,null)}):null}const xe={navbarHideable:"navbarHideable_m1mJ",navbarHidden:"navbarHidden_jGov"};function Pe(e){return r.createElement("div",(0,g.A)({role:"presentation"},e,{className:(0,a.A)("navbar-sidebar__backdrop",e.className)}))}function _e(e){let{children:t}=e;const{navbar:{hideOnScroll:n,style:o}}=(0,h.p)(),i=(0,P.M)(),{navbarRef:l,isNavbarVisible:s}=function(e){const[t,n]=(0,r.useState)(e),a=(0,r.useRef)(!1),o=(0,r.useRef)(0),i=(0,r.useCallback)((e=>{null!==e&&(o.current=e.getBoundingClientRect().height)}),[]);return(0,_.Mq)(((t,r)=>{let{scrollY:i}=t;if(!e)return;if(i=l?n(!1):i+c{if(e)return t.location.hash?(a.current=!0,void n(!1)):void n(!0)})),{navbarRef:i,isNavbarVisible:t}}(n);return r.createElement("nav",{ref:l,className:(0,a.A)("navbar","navbar--fixed-top",n&&[xe.navbarHideable,!s&&xe.navbarHidden],{"navbar--dark":"dark"===o,"navbar--primary":"primary"===o,"navbar-sidebar--show":i.shown})},t,r.createElement(Pe,{onClick:i.toggle}),r.createElement(Ee,null))}const Ce="right";function Ae(e){let{width:t=30,height:n=30,className:a,...o}=e;return r.createElement("svg",(0,g.A)({className:a,width:t,height:n,viewBox:"0 0 30 30","aria-hidden":"true"},o),r.createElement("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"}))}function Te(){const e=(0,P.M)();return r.createElement("button",{onClick:e.toggle,onKeyDown:e.toggle,"aria-label":"Navigation bar toggle",className:"navbar__toggle clean-btn",type:"button",tabIndex:0},r.createElement(Ae,null))}const Le={colorModeToggle:"colorModeToggle_DEke"};function Re(e){let{items:t}=e;return r.createElement(r.Fragment,null,t.map(((e,t)=>r.createElement(ye,(0,g.A)({},e,{key:t})))))}function Oe(e){let{left:t,right:n}=e;return r.createElement("div",{className:"navbar__inner"},r.createElement("div",{className:"navbar__items"},t),r.createElement("div",{className:"navbar__items navbar__items--right"},n))}function Ne(){const e=(0,P.M)(),t=(0,h.p)().navbar.items,[n,a]=function(e){function t(e){return"left"===(e.position??Ce)}return[e.filter(t),e.filter((e=>!t(e)))]}(t),o=t.find((e=>"search"===e.type));return r.createElement(Oe,{left:r.createElement(r.Fragment,null,!e.disabled&&r.createElement(Te,null),r.createElement(G,null),r.createElement(Re,{items:n})),right:r.createElement(r.Fragment,null,r.createElement(Re,{items:a}),r.createElement(U,{className:Le.colorModeToggle}),!o&&r.createElement(fe,null,r.createElement(de,null)))})}function De(){return r.createElement(_e,null,r.createElement(Ne,null))}function Ie(e){let{item:t}=e;const{to:n,href:a,label:o,prependBaseUrlToHref:i,...l}=t,s=(0,V.A)(n),c=(0,V.A)(a,{forcePrependBaseUrl:!0});return r.createElement(W.A,(0,g.A)({className:"footer__link-item"},a?{href:i?c:a}:{to:s},l),o,a&&!(0,K.A)(a)&&r.createElement(Q.A,null))}function Be(e){let{item:t}=e;return t.html?r.createElement("li",{className:"footer__item",dangerouslySetInnerHTML:{__html:t.html}}):r.createElement("li",{key:t.href??t.to,className:"footer__item"},r.createElement(Ie,{item:t}))}function Me(e){let{column:t}=e;return r.createElement("div",{className:"col footer__col"},r.createElement("div",{className:"footer__title"},t.title),r.createElement("ul",{className:"footer__items clean-list"},t.items.map(((e,t)=>r.createElement(Be,{key:t,item:e})))))}function Fe(e){let{columns:t}=e;return r.createElement("div",{className:"row footer__links"},t.map(((e,t)=>r.createElement(Me,{key:t,column:e}))))}function je(){return r.createElement("span",{className:"footer__link-separator"},"\xb7")}function ze(e){let{item:t}=e;return t.html?r.createElement("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:t.html}}):r.createElement(Ie,{item:t})}function Ue(e){let{links:t}=e;return r.createElement("div",{className:"footer__links text--center"},r.createElement("div",{className:"footer__links"},t.map(((e,n)=>r.createElement(r.Fragment,{key:n},r.createElement(ze,{item:e}),t.length!==n+1&&r.createElement(je,null))))))}function $e(e){let{links:t}=e;return function(e){return"title"in e[0]}(t)?r.createElement(Fe,{columns:t}):r.createElement(Ue,{links:t})}var Ge=n(1653);const qe="footerLogoLink_BH7S";function He(e){let{logo:t}=e;const{withBaseUrl:n}=(0,V.h)(),o={light:n(t.src),dark:n(t.srcDark??t.src)};return r.createElement(Ge.A,{className:(0,a.A)("footer__logo",t.className),alt:t.alt,sources:o,width:t.width,height:t.height,style:t.style})}function We(e){let{logo:t}=e;return t.href?r.createElement(W.A,{href:t.href,className:qe,target:t.target},r.createElement(He,{logo:t})):r.createElement(He,{logo:t})}function Ve(e){let{copyright:t}=e;return r.createElement("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:t}})}function Ke(e){let{style:t,links:n,logo:o,copyright:i}=e;return r.createElement("footer",{className:(0,a.A)("footer",{"footer--dark":"dark"===t})},r.createElement("div",{className:"container container-fluid"},n,(o||i)&&r.createElement("div",{className:"footer__bottom text--center"},o&&r.createElement("div",{className:"margin-bottom--sm"},o),i)))}function Ye(){const{footer:e}=(0,h.p)();if(!e)return null;const{copyright:t,links:n,logo:a,style:o}=e;return r.createElement(Ke,{style:o,links:n&&n.length>0&&r.createElement($e,{links:n}),logo:a&&r.createElement(We,{logo:a}),copyright:t&&r.createElement(Ve,{copyright:t})})}const Qe=r.memo(Ye);var Xe=n(9466);const Ze="docusaurus.tab.",Je=r.createContext(void 0);const et=(0,C.fM)([D.a,b.oq,function(e){let{children:t}=e;const n=function(){const[e,t]=(0,r.useState)({}),n=(0,r.useCallback)(((e,t)=>{(0,Xe.W)(`${Ze}${e}`).set(t)}),[]);(0,r.useEffect)((()=>{try{const e={};(0,Xe.E)().forEach((t=>{if(t.startsWith(Ze)){const n=t.substring(15);e[n]=(0,Xe.W)(t).get()}})),t(e)}catch(e){console.error(e)}}),[]);const a=(0,r.useCallback)(((e,r)=>{t((t=>({...t,[e]:r}))),n(e,r)}),[n]);return(0,r.useMemo)((()=>({tabGroupChoices:e,setTabGroupChoices:a})),[e,a])}();return r.createElement(Je.Provider,{value:n},t)},_.Tv,be.VQ,i.Jx,function(e){let{children:t}=e;return r.createElement(A.y_,null,r.createElement(P.e,null,r.createElement(L,null,t)))}]);function tt(e){let{children:t}=e;return r.createElement(et,null,t)}function nt(e){let{error:t,tryAgain:n}=e;return r.createElement("main",{className:"container margin-vert--xl"},r.createElement("div",{className:"row"},r.createElement("div",{className:"col col--6 col--offset-3"},r.createElement("h1",{className:"hero__title"},r.createElement(c.A,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed"},"This page crashed.")),r.createElement("p",null,t.message),r.createElement("div",null,r.createElement("button",{type:"button",onClick:n},r.createElement(c.A,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again when the page crashed"},"Try again"))))))}const rt={mainWrapper:"mainWrapper_z2l0"};function at(e){const{children:t,noFooter:n,wrapperClassName:c,title:u,description:d}=e;return(0,s.J)(),r.createElement(tt,null,r.createElement(i.be,{title:u,description:d}),r.createElement(m,null),r.createElement(x,null),r.createElement(De,null),r.createElement("div",{className:(0,a.A)(l.G.wrapper.main,rt.mainWrapper,c)},r.createElement(o.A,{fallback:e=>r.createElement(nt,e)},t)),!n&&r.createElement(Qe,null))}},3465:(e,t,n)=>{"use strict";n.d(t,{A:()=>d});var r=n(8168),a=n(6540),o=n(5489),i=n(6025),l=n(4586),s=n(6342),c=n(1653);function u(e){let{logo:t,alt:n,imageClassName:r}=e;const o={light:(0,i.A)(t.src),dark:(0,i.A)(t.srcDark||t.src)},l=a.createElement(c.A,{className:t.className,sources:o,height:t.height,width:t.width,alt:n,style:t.style});return r?a.createElement("div",{className:r},l):l}function d(e){const{siteConfig:{title:t}}=(0,l.A)(),{navbar:{title:n,logo:c}}=(0,s.p)(),{imageClassName:d,titleClassName:p,...f}=e,m=(0,i.A)(c?.href||"/"),h=n?"":t,b=c?.alt??h;return a.createElement(o.A,(0,r.A)({to:m},f,c?.target&&{target:c.target}),c&&a.createElement(u,{logo:c,alt:b,imageClassName:d}),null!=n&&a.createElement("b",{className:p},n))}},1463:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});var r=n(6540),a=n(5260);function o(e){let{locale:t,version:n,tag:o}=e;const i=t;return r.createElement(a.A,null,t&&r.createElement("meta",{name:"docusaurus_locale",content:t}),n&&r.createElement("meta",{name:"docusaurus_version",content:n}),o&&r.createElement("meta",{name:"docusaurus_tag",content:o}),i&&r.createElement("meta",{name:"docsearch:language",content:i}),n&&r.createElement("meta",{name:"docsearch:version",content:n}),o&&r.createElement("meta",{name:"docsearch:docusaurus_tag",content:o}))}},1653:(e,t,n)=>{"use strict";n.d(t,{A:()=>c});var r=n(8168),a=n(6540),o=n(53),i=n(2303),l=n(5293);const s={themedImage:"themedImage_ToTc","themedImage--light":"themedImage--light_HNdA","themedImage--dark":"themedImage--dark_i4oU"};function c(e){const t=(0,i.A)(),{colorMode:n}=(0,l.G)(),{sources:c,className:u,alt:d,...p}=e,f=t?"dark"===n?["dark"]:["light"]:["light","dark"];return a.createElement(a.Fragment,null,f.map((e=>a.createElement("img",(0,r.A)({key:e,src:c[e],alt:d,className:(0,o.A)(s.themedImage,s[`themedImage--${e}`],u)},p)))))}},1422:(e,t,n)=>{"use strict";n.d(t,{N:()=>h,u:()=>l});var r=n(8168),a=n(6540),o=n(8193);const i="ease-in-out";function l(e){let{initialState:t}=e;const[n,r]=(0,a.useState)(t??!1),o=(0,a.useCallback)((()=>{r((e=>!e))}),[]);return{collapsed:n,setCollapsed:r,toggleCollapsed:o}}const s={display:"none",overflow:"hidden",height:"0px"},c={display:"block",overflow:"visible",height:"auto"};function u(e,t){const n=t?s:c;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function d(e){let{collapsibleRef:t,collapsed:n,animation:r}=e;const o=(0,a.useRef)(!1);(0,a.useEffect)((()=>{const e=t.current;function a(){const t=e.scrollHeight,n=r?.duration??function(e){const t=e/36;return Math.round(10*(4+15*t**.25+t/5))}(t);return{transition:`height ${n}ms ${r?.easing??i}`,height:`${t}px`}}function l(){const t=a();e.style.transition=t.transition,e.style.height=t.height}if(!o.current)return u(e,n),void(o.current=!0);return e.style.willChange="height",function(){const t=requestAnimationFrame((()=>{n?(l(),requestAnimationFrame((()=>{e.style.height=s.height,e.style.overflow=s.overflow}))):(e.style.display="block",requestAnimationFrame((()=>{l()})))}));return()=>cancelAnimationFrame(t)}()}),[t,n,r])}function p(e){if(!o.A.canUseDOM)return e?s:c}function f(e){let{as:t="div",collapsed:n,children:r,animation:o,onCollapseTransitionEnd:i,className:l,disableSSRStyle:s}=e;const c=(0,a.useRef)(null);return d({collapsibleRef:c,collapsed:n,animation:o}),a.createElement(t,{ref:c,style:s?void 0:p(n),onTransitionEnd:e=>{"height"===e.propertyName&&(u(c.current,n),i?.(n))},className:l},r)}function m(e){let{collapsed:t,...n}=e;const[o,i]=(0,a.useState)(!t),[l,s]=(0,a.useState)(t);return(0,a.useLayoutEffect)((()=>{t||i(!0)}),[t]),(0,a.useLayoutEffect)((()=>{o&&s(t)}),[o,t]),o?a.createElement(f,(0,r.A)({},n,{collapsed:l})):null}function h(e){let{lazy:t,...n}=e;const r=t?m:f;return a.createElement(r,n)}},5041:(e,t,n)=>{"use strict";n.d(t,{Mj:()=>m,oq:()=>f});var r=n(6540),a=n(2303),o=n(9466),i=n(9532),l=n(6342);const s=(0,o.W)("docusaurus.announcement.dismiss"),c=(0,o.W)("docusaurus.announcement.id"),u=()=>"true"===s.get(),d=e=>s.set(String(e)),p=r.createContext(null);function f(e){let{children:t}=e;const n=function(){const{announcementBar:e}=(0,l.p)(),t=(0,a.A)(),[n,o]=(0,r.useState)((()=>!!t&&u()));(0,r.useEffect)((()=>{o(u())}),[]);const i=(0,r.useCallback)((()=>{d(!0),o(!0)}),[]);return(0,r.useEffect)((()=>{if(!e)return;const{id:t}=e;let n=c.get();"annoucement-bar"===n&&(n="announcement-bar");const r=t!==n;c.set(t),r&&d(!1),!r&&u()||o(!1)}),[e]),(0,r.useMemo)((()=>({isActive:!!e&&!n,close:i})),[e,n,i])}();return r.createElement(p.Provider,{value:n},t)}function m(){const e=(0,r.useContext)(p);if(!e)throw new i.dV("AnnouncementBarProvider");return e}},5293:(e,t,n)=>{"use strict";n.d(t,{G:()=>b,a:()=>h});var r=n(6540),a=n(8193),o=n(9532),i=n(9466),l=n(6342);const s=r.createContext(void 0),c="theme",u=(0,i.W)(c),d={light:"light",dark:"dark"},p=e=>e===d.dark?d.dark:d.light,f=e=>a.A.canUseDOM?p(document.documentElement.getAttribute("data-theme")):p(e),m=e=>{u.set(p(e))};function h(e){let{children:t}=e;const n=function(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,l.p)(),[a,o]=(0,r.useState)(f(e));(0,r.useEffect)((()=>{t&&u.del()}),[t]);const i=(0,r.useCallback)((function(t,r){void 0===r&&(r={});const{persist:a=!0}=r;t?(o(t),a&&m(t)):(o(n?window.matchMedia("(prefers-color-scheme: dark)").matches?d.dark:d.light:e),u.del())}),[n,e]);(0,r.useEffect)((()=>{document.documentElement.setAttribute("data-theme",p(a))}),[a]),(0,r.useEffect)((()=>{if(t)return;const e=e=>{if(e.key!==c)return;const t=u.get();null!==t&&i(p(t))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[t,i]);const s=(0,r.useRef)(!1);return(0,r.useEffect)((()=>{if(t&&!n)return;const e=window.matchMedia("(prefers-color-scheme: dark)"),r=()=>{window.matchMedia("print").matches||s.current?s.current=window.matchMedia("print").matches:i(null)};return e.addListener(r),()=>e.removeListener(r)}),[i,t,n]),(0,r.useMemo)((()=>({colorMode:a,setColorMode:i,get isDarkTheme(){return a===d.dark},setLightTheme(){i(d.light)},setDarkTheme(){i(d.dark)}})),[a,i])}();return r.createElement(s.Provider,{value:n},t)}function b(){const e=(0,r.useContext)(s);if(null==e)throw new o.dV("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},5597:(e,t,n)=>{"use strict";n.d(t,{VQ:()=>b,g1:()=>v});var r=n(6540),a=n(4070),o=n(7065),i=n(6342),l=n(1754),s=n(9532),c=n(9466);const u=e=>`docs-preferred-version-${e}`,d={save:(e,t,n)=>{(0,c.W)(u(e),{persistence:t}).set(n)},read:(e,t)=>(0,c.W)(u(e),{persistence:t}).get(),clear:(e,t)=>{(0,c.W)(u(e),{persistence:t}).del()}},p=e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}])));const f=r.createContext(null);function m(){const e=(0,a.Gy)(),t=(0,i.p)().docs.versionPersistence,n=(0,r.useMemo)((()=>Object.keys(e)),[e]),[o,l]=(0,r.useState)((()=>p(n)));(0,r.useEffect)((()=>{l(function(e){let{pluginIds:t,versionPersistence:n,allDocsData:r}=e;function a(e){const t=d.read(e,n);return r[e].versions.some((e=>e.name===t))?{preferredVersionName:t}:(d.clear(e,n),{preferredVersionName:null})}return Object.fromEntries(t.map((e=>[e,a(e)])))}({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]);return[o,(0,r.useMemo)((()=>({savePreferredVersion:function(e,n){d.save(e,t,n),l((t=>({...t,[e]:{preferredVersionName:n}})))}})),[t])]}function h(e){let{children:t}=e;const n=m();return r.createElement(f.Provider,{value:n},t)}function b(e){let{children:t}=e;return l.C5?r.createElement(h,null,t):r.createElement(r.Fragment,null,t)}function g(){const e=(0,r.useContext)(f);if(!e)throw new s.dV("DocsPreferredVersionContextProvider");return e}function v(e){void 0===e&&(e=o.W);const t=(0,a.ht)(e),[n,i]=g(),{preferredVersionName:l}=n[e];return{preferredVersion:t.versions.find((e=>e.name===l))??null,savePreferredVersionName:(0,r.useCallback)((t=>{i.savePreferredVersion(e,t)}),[i,e])}}},6588:(e,t,n)=>{"use strict";n.d(t,{V:()=>l,t:()=>s});var r=n(6540),a=n(9532);const o=Symbol("EmptyContext"),i=r.createContext(o);function l(e){let{children:t,name:n,items:a}=e;const o=(0,r.useMemo)((()=>n&&a?{name:n,items:a}:null),[n,a]);return r.createElement(i.Provider,{value:o},t)}function s(){const e=(0,r.useContext)(i);if(e===o)throw new a.dV("DocsSidebarProvider");return e}},2252:(e,t,n)=>{"use strict";n.d(t,{n:()=>i,r:()=>l});var r=n(6540),a=n(9532);const o=r.createContext(null);function i(e){let{children:t,version:n}=e;return r.createElement(o.Provider,{value:n},t)}function l(){const e=(0,r.useContext)(o);if(null===e)throw new a.dV("DocsVersionProvider");return e}},9876:(e,t,n)=>{"use strict";n.d(t,{e:()=>p,M:()=>f});var r=n(6540),a=n(5600),o=n(4581),i=n(6347),l=n(9532);function s(e){!function(e){const t=(0,i.W6)(),n=(0,l._q)(e);(0,r.useEffect)((()=>t.block(((e,t)=>n(e,t)))),[t,n])}(((t,n)=>{if("POP"===n)return e(t,n)}))}var c=n(6342);const u=r.createContext(void 0);function d(){const e=function(){const e=(0,a.YL)(),{items:t}=(0,c.p)().navbar;return 0===t.length&&!e.component}(),t=(0,o.l)(),n=!e&&"mobile"===t,[i,l]=(0,r.useState)(!1);s((()=>{if(i)return l(!1),!1}));const u=(0,r.useCallback)((()=>{l((e=>!e))}),[]);return(0,r.useEffect)((()=>{"desktop"===t&&l(!1)}),[t]),(0,r.useMemo)((()=>({disabled:e,shouldRender:n,toggle:u,shown:i})),[e,n,u,i])}function p(e){let{children:t}=e;const n=d();return r.createElement(u.Provider,{value:n},t)}function f(){const e=r.useContext(u);if(void 0===e)throw new l.dV("NavbarMobileSidebarProvider");return e}},5600:(e,t,n)=>{"use strict";n.d(t,{GX:()=>s,YL:()=>l,y_:()=>i});var r=n(6540),a=n(9532);const o=r.createContext(null);function i(e){let{children:t}=e;const n=(0,r.useState)({component:null,props:null});return r.createElement(o.Provider,{value:n},t)}function l(){const e=(0,r.useContext)(o);if(!e)throw new a.dV("NavbarSecondaryMenuContentProvider");return e[0]}function s(e){let{component:t,props:n}=e;const i=(0,r.useContext)(o);if(!i)throw new a.dV("NavbarSecondaryMenuContentProvider");const[,l]=i,s=(0,a.Be)(n);return(0,r.useEffect)((()=>{l({component:t,props:s})}),[l,t,s]),(0,r.useEffect)((()=>()=>l({component:null,props:null})),[l]),null}},4090:(e,t,n)=>{"use strict";n.d(t,{w:()=>a,J:()=>o});var r=n(6540);const a="navigation-with-keyboard";function o(){(0,r.useEffect)((()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(a),"mousedown"===e.type&&document.body.classList.remove(a)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(a),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},4581:(e,t,n)=>{"use strict";n.d(t,{l:()=>c});var r=n(6540),a=n(8193);const o={desktop:"desktop",mobile:"mobile",ssr:"ssr"},i=996;function l(){return a.A.canUseDOM?window.innerWidth>i?o.desktop:o.mobile:o.ssr}const s=!1;function c(){const[e,t]=(0,r.useState)((()=>s?"ssr":l()));return(0,r.useEffect)((()=>{function e(){t(l())}const n=s?window.setTimeout(e,1e3):void 0;return window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e),clearTimeout(n)}}),[]),e}},7559:(e,t,n)=>{"use strict";n.d(t,{G:()=>r});const r={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",admonitionType:e=>`theme-admonition-${e}`},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:e=>`theme-doc-sidebar-item-category-level-${e}`,docSidebarItemLinkLevel:e=>`theme-doc-sidebar-item-link-level-${e}`},blog:{}}},1754:(e,t,n)=>{"use strict";n.d(t,{d1:()=>P,_o:()=>m,w8:()=>v,C5:()=>p,$S:()=>h,cC:()=>f,mz:()=>x,Vd:()=>w,QB:()=>E,fW:()=>S,OF:()=>k});var r=n(6540),a=n(6347),o=n(2831),i=n(4070),l=n(5597),s=n(2252),c=n(6588);function u(e){return Array.from(new Set(e))}var d=n(9169);const p=!!i.Gy;function f(e){const t=(0,s.r)();if(!e)return;const n=t.docs[e];if(!n)throw new Error(`no version doc found by id=${e}`);return n}function m(e){if(e.href)return e.href;for(const t of e.items){if("link"===t.type)return t.href;if("category"===t.type){const e=m(t);if(e)return e}}}function h(){const{pathname:e}=(0,a.zy)(),t=(0,c.t)();if(!t)throw new Error("Unexpected: cant find current sidebar in context");const n=y({sidebarItems:t.items,pathname:e,onlyCategories:!0}).slice(-1)[0];if(!n)throw new Error(`${e} is not associated with a category. useCurrentSidebarCategory() should only be used on category index pages.`);return n}const b=(e,t)=>void 0!==e&&(0,d.ys)(e,t),g=(e,t)=>e.some((e=>v(e,t)));function v(e,t){return"link"===e.type?b(e.href,t):"category"===e.type&&(b(e.href,t)||g(e.items,t))}function y(e){let{sidebarItems:t,pathname:n,onlyCategories:r=!1}=e;const a=[];return function e(t){for(const o of t)if("category"===o.type&&((0,d.ys)(o.href,n)||e(o.items))||"link"===o.type&&(0,d.ys)(o.href,n)){return r&&"category"!==o.type||a.unshift(o),!0}return!1}(t),a}function k(){const e=(0,c.t)(),{pathname:t}=(0,a.zy)(),n=(0,i.vT)()?.pluginData.breadcrumbs;return!1!==n&&e?y({sidebarItems:e.items,pathname:t}):null}function w(e){const{activeVersion:t}=(0,i.zK)(e),{preferredVersion:n}=(0,l.g1)(e),a=(0,i.r7)(e);return(0,r.useMemo)((()=>u([t,n,a].filter(Boolean))),[t,n,a])}function S(e,t){const n=w(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.sidebars?Object.entries(e.sidebars):[])),r=t.find((t=>t[0]===e));if(!r)throw new Error(`Can't find any sidebar with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\n Available sidebar ids are:\n - ${Object.keys(t).join("\n- ")}`);return r[1]}),[e,n])}function E(e,t){const n=w(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.docs)),r=t.find((t=>t.id===e));if(!r){if(n.flatMap((e=>e.draftIds)).includes(e))return null;throw new Error(`DocNavbarItem: couldn't find any doc with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\nAvailable doc ids are:\n- ${u(t.map((e=>e.id))).join("\n- ")}`)}return r}),[e,n])}function x(e){let{route:t,versionMetadata:n}=e;const r=(0,a.zy)(),i=t.routes,l=i.find((e=>(0,a.B6)(r.pathname,e)));if(!l)return null;const s=l.sidebar,c=s?n.docsSidebars[s]:void 0;return{docElement:(0,o.v)(i),sidebarName:s,sidebarItems:c}}function P(e){return e.filter((e=>"category"!==e.type||!!m(e)))}},1003:(e,t,n)=>{"use strict";n.d(t,{e3:()=>p,be:()=>u,Jx:()=>f});var r=n(6540),a=n(53),o=n(5260),i=n(3102);function l(){const e=r.useContext(i.o);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}var s=n(6025),c=n(4586);function u(e){let{title:t,description:n,keywords:a,image:i,children:l}=e;const u=function(e){const{siteConfig:t}=(0,c.A)(),{title:n,titleDelimiter:r}=t;return e?.trim().length?`${e.trim()} ${r} ${n}`:n}(t),{withBaseUrl:d}=(0,s.h)(),p=i?d(i,{absolute:!0}):void 0;return r.createElement(o.A,null,t&&r.createElement("title",null,u),t&&r.createElement("meta",{property:"og:title",content:u}),n&&r.createElement("meta",{name:"description",content:n}),n&&r.createElement("meta",{property:"og:description",content:n}),a&&r.createElement("meta",{name:"keywords",content:Array.isArray(a)?a.join(","):a}),p&&r.createElement("meta",{property:"og:image",content:p}),p&&r.createElement("meta",{name:"twitter:image",content:p}),l)}const d=r.createContext(void 0);function p(e){let{className:t,children:n}=e;const i=r.useContext(d),l=(0,a.A)(i,t);return r.createElement(d.Provider,{value:l},r.createElement(o.A,null,r.createElement("html",{className:l})),n)}function f(e){let{children:t}=e;const n=l(),o=`plugin-${n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const i=`plugin-id-${n.plugin.id}`;return r.createElement(p,{className:(0,a.A)(o,i)},t)}},9532:(e,t,n)=>{"use strict";n.d(t,{Be:()=>s,ZC:()=>i,_q:()=>o,dV:()=>l,fM:()=>c});var r=n(6540);const a=n(8193).A.canUseDOM?r.useLayoutEffect:r.useEffect;function o(e){const t=(0,r.useRef)(e);return a((()=>{t.current=e}),[e]),(0,r.useCallback)((function(){return t.current(...arguments)}),[])}function i(e){const t=(0,r.useRef)();return a((()=>{t.current=e})),t.current}class l extends Error{constructor(e,t){super(),this.name="ReactContextError",this.message=`Hook ${this.stack?.split("\n")[1]?.match(/at (?:\w+\.)?(?\w+)/)?.groups.name??""} is called outside the <${e}>. ${t??""}`}}function s(e){const t=Object.entries(e);return t.sort(((e,t)=>e[0].localeCompare(t[0]))),(0,r.useMemo)((()=>e),t.flat())}function c(e){return t=>{let{children:n}=t;return r.createElement(r.Fragment,null,e.reduceRight(((e,t)=>r.createElement(t,null,e)),n))}}},9169:(e,t,n)=>{"use strict";n.d(t,{Dt:()=>l,ys:()=>i});var r=n(6540),a=n(8328),o=n(4586);function i(e,t){const n=e=>(!e||e.endsWith("/")?e:`${e}/`)?.toLowerCase();return n(e)===n(t)}function l(){const{baseUrl:e}=(0,o.A)().siteConfig;return(0,r.useMemo)((()=>function(e){let{baseUrl:t,routes:n}=e;function r(e){return e.path===t&&!0===e.exact}function a(e){return e.path===t&&!e.exact}return function e(t){if(0===t.length)return;return t.find(r)||e(t.filter(a).flatMap((e=>e.routes??[])))}(n)}({routes:a.A,baseUrl:e})),[e])}},3104:(e,t,n)=>{"use strict";n.d(t,{Mq:()=>d,Tv:()=>s,gk:()=>p});var r=n(6540),a=n(8193),o=n(2303),i=n(9532);const l=r.createContext(void 0);function s(e){let{children:t}=e;const n=function(){const e=(0,r.useRef)(!0);return(0,r.useMemo)((()=>({scrollEventsEnabledRef:e,enableScrollEvents:()=>{e.current=!0},disableScrollEvents:()=>{e.current=!1}})),[])}();return r.createElement(l.Provider,{value:n},t)}function c(){const e=(0,r.useContext)(l);if(null==e)throw new i.dV("ScrollControllerProvider");return e}const u=()=>a.A.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function d(e,t){void 0===t&&(t=[]);const{scrollEventsEnabledRef:n}=c(),a=(0,r.useRef)(u()),o=(0,i._q)(e);(0,r.useEffect)((()=>{const e=()=>{if(!n.current)return;const e=u();o(e,a.current),a.current=e},t={passive:!0};return e(),window.addEventListener("scroll",e,t),()=>window.removeEventListener("scroll",e,t)}),[o,n,...t])}function p(){const e=(0,r.useRef)(null),t=(0,o.A)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:n=>{e.current=t?function(e){return window.scrollTo({top:e,behavior:"smooth"}),()=>{}}(n):function(e){let t=null;const n=document.documentElement.scrollTop>e;return function r(){const a=document.documentElement.scrollTop;(n&&a>e||!n&&at&&cancelAnimationFrame(t)}(n)},cancelScroll:()=>e.current?.()}}},2967:(e,t,n)=>{"use strict";n.d(t,{Cy:()=>r,tU:()=>a});n(4586);const r="default";function a(e,t){return`docs-${e}-${t}`}},9466:(e,t,n)=>{"use strict";n.d(t,{E:()=>s,W:()=>l});const r="localStorage";function a(e){if(void 0===e&&(e=r),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,o||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",t),o=!0),null}var t}let o=!1;const i={get:()=>null,set:()=>{},del:()=>{}};function l(e,t){if("undefined"==typeof window)return function(e){function t(){throw new Error(`Illegal storage API usage for storage key "${e}".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.`)}return{get:t,set:t,del:t}}(e);const n=a(t?.persistence);return null===n?i:{get:()=>{try{return n.getItem(e)}catch(t){return console.error(`Docusaurus storage error, can't get key=${e}`,t),null}},set:t=>{try{n.setItem(e,t)}catch(r){console.error(`Docusaurus storage error, can't set ${e}=${t}`,r)}},del:()=>{try{n.removeItem(e)}catch(t){console.error(`Docusaurus storage error, can't delete key=${e}`,t)}}}}function s(e){void 0===e&&(e=r);const t=a(e);if(!t)return[];const n=[];for(let r=0;r{"use strict";n.d(t,{o:()=>o});var r=n(4586),a=n(6347);function o(){const{siteConfig:{baseUrl:e,url:t},i18n:{defaultLocale:n,currentLocale:o}}=(0,r.A)(),{pathname:i}=(0,a.zy)(),l=o===n?e:e.replace(`/${o}/`,"/"),s=i.replace(e,"");return{createUrl:function(e){let{locale:r,fullyQualified:a}=e;return`${a?t:""}${function(e){return e===n?`${l}`:`${l}${e}/`}(r)}${s}`}}}},5062:(e,t,n)=>{"use strict";n.d(t,{$:()=>i});var r=n(6540),a=n(6347),o=n(9532);function i(e){const t=(0,a.zy)(),n=(0,o.ZC)(t),i=(0,o._q)(e);(0,r.useEffect)((()=>{n&&t!==n&&i({location:t,previousLocation:n})}),[i,t,n])}},6342:(e,t,n)=>{"use strict";n.d(t,{p:()=>a});var r=n(4586);function a(){return(0,r.A)().siteConfig.themeConfig}},2983:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){const{trailingSlash:n,baseUrl:r}=t;if(e.startsWith("#"))return e;if(void 0===n)return e;const[a]=e.split(/[#?]/),o="/"===a||a===r?a:(i=a,n?function(e){return e.endsWith("/")?e:`${e}/`}(i):function(e){return e.endsWith("/")?e.slice(0,-1):e}(i));var i;return e.replace(a,o)}},440:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.applyTrailingSlash=t.blogPostContainerID=void 0,t.blogPostContainerID="post-content";var a=n(2983);Object.defineProperty(t,"applyTrailingSlash",{enumerable:!0,get:function(){return r(a).default}})},53:(e,t,n)=>{"use strict";function r(e){var t,n,a="";if("string"==typeof e||"number"==typeof e)a+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;ta});const a=function(){for(var e,t,n=0,a="";n{"use strict";n.d(t,{zR:()=>k,TM:()=>_,yJ:()=>f,sC:()=>A,AO:()=>p});var r=n(8168);function a(e){return"/"===e.charAt(0)}function o(e,t){for(var n=t,r=n+1,a=e.length;r=0;p--){var f=i[p];"."===f?o(i,p):".."===f?(o(i,p),d++):d&&(o(i,p),d--)}if(!c)for(;d--;d)i.unshift("..");!c||""===i[0]||i[0]&&a(i[0])||i.unshift("");var m=i.join("/");return n&&"/"!==m.substr(-1)&&(m+="/"),m};var l=n(1561);function s(e){return"/"===e.charAt(0)?e:"/"+e}function c(e){return"/"===e.charAt(0)?e.substr(1):e}function u(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function d(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function p(e){var t=e.pathname,n=e.search,r=e.hash,a=t||"/";return n&&"?"!==n&&(a+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(a+="#"===r.charAt(0)?r:"#"+r),a}function f(e,t,n,a){var o;"string"==typeof e?(o=function(e){var t=e||"/",n="",r="",a=t.indexOf("#");-1!==a&&(r=t.substr(a),t=t.substr(0,a));var o=t.indexOf("?");return-1!==o&&(n=t.substr(o),t=t.substr(0,o)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),o.state=t):(void 0===(o=(0,r.A)({},e)).pathname&&(o.pathname=""),o.search?"?"!==o.search.charAt(0)&&(o.search="?"+o.search):o.search="",o.hash?"#"!==o.hash.charAt(0)&&(o.hash="#"+o.hash):o.hash="",void 0!==t&&void 0===o.state&&(o.state=t));try{o.pathname=decodeURI(o.pathname)}catch(l){throw l instanceof URIError?new URIError('Pathname "'+o.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):l}return n&&(o.key=n),a?o.pathname?"/"!==o.pathname.charAt(0)&&(o.pathname=i(o.pathname,a.pathname)):o.pathname=a.pathname:o.pathname||(o.pathname="/"),o}function m(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,a){if(null!=e){var o="function"==typeof e?e(t,n):e;"string"==typeof o?"function"==typeof r?r(o,a):a(!0):a(!1!==o)}else a(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;rt?n.splice(t,n.length-t,a):n.push(a),d({action:r,location:a,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",a=f(e,t,h(),k.location);u.confirmTransitionTo(a,r,n,(function(e){e&&(k.entries[k.index]=a,d({action:r,location:a}))}))},go:y,goBack:function(){y(-1)},goForward:function(){y(1)},canGo:function(e){var t=k.index+e;return t>=0&&t{"use strict";var r=n(4363),a={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},o={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},i={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},l={};function s(e){return r.isMemo(e)?i:l[e.$$typeof]||a}l[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},l[r.Memo]=i;var c=Object.defineProperty,u=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,p=Object.getOwnPropertyDescriptor,f=Object.getPrototypeOf,m=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(m){var a=f(n);a&&a!==m&&e(t,a,r)}var i=u(n);d&&(i=i.concat(d(n)));for(var l=s(t),h=s(n),b=0;b{"use strict";e.exports=function(e,t,n,r,a,o,i,l){if(!e){var s;if(void 0===t)s=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var c=[n,r,a,o,i,l],u=0;(s=new Error(t.replace(/%s/g,(function(){return c[u++]})))).name="Invariant Violation"}throw s.framesToPop=1,s}}},4634:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},119:(e,t,n)=>{"use strict";n.r(t)},1043:(e,t,n)=>{"use strict";n.r(t)},5947:function(e,t,n){var r,a;r=function(){var e,t,n={version:"0.2.0"},r=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'
'};function a(e,t,n){return en?n:e}function o(e){return 100*(-1+e)}function i(e,t,n){var a;return(a="translate3d"===r.positionUsing?{transform:"translate3d("+o(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+o(e)+"%,0)"}:{"margin-left":o(e)+"%"}).transition="all "+t+"ms "+n,a}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(r[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=a(e,r.minimum,1),n.status=1===e?null:e;var o=n.render(!t),c=o.querySelector(r.barSelector),u=r.speed,d=r.easing;return o.offsetWidth,l((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),s(c,i(e,u,d)),1===e?(s(o,{transition:"none",opacity:1}),o.offsetWidth,setTimeout((function(){s(o,{transition:"all "+u+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),u)}),u)):setTimeout(t,u)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),r.trickleSpeed)};return r.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*a(Math.random()*t,.1,.95)),t=a(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},e=0,t=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===t&&n.start(),e++,t++,r.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");u(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=r.template;var a,i=t.querySelector(r.barSelector),l=e?"-100":o(n.status||0),c=document.querySelector(r.parent);return s(i,{transition:"all 0 linear",transform:"translate3d("+l+"%,0,0)"}),r.showSpinner||(a=t.querySelector(r.spinnerSelector))&&f(a),c!=document.body&&u(c,"nprogress-custom-parent"),c.appendChild(t),t},n.remove=function(){d(document.documentElement,"nprogress-busy"),d(document.querySelector(r.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&f(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var l=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),s=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function r(t){var n=document.body.style;if(t in n)return t;for(var r,a=e.length,o=t.charAt(0).toUpperCase()+t.slice(1);a--;)if((r=e[a]+o)in n)return r;return t}function a(e){return e=n(e),t[e]||(t[e]=r(e))}function o(e,t,n){t=a(t),e.style[t]=n}return function(e,t){var n,r,a=arguments;if(2==a.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&o(e,n,r);else o(e,a[1],a[2])}}();function c(e,t){return("string"==typeof e?e:p(e)).indexOf(" "+t+" ")>=0}function u(e,t){var n=p(e),r=n+t;c(n,t)||(e.className=r.substring(1))}function d(e,t){var n,r=p(e);c(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function p(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function f(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(a="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=a)},5228:e=>{"use strict";var t=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(a){return!1}}()?Object.assign:function(e,a){for(var o,i,l=function(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}(e),s=1;s{var r=n(4634);e.exports=m,e.exports.parse=o,e.exports.compile=function(e,t){return s(o(e,t),t)},e.exports.tokensToFunction=s,e.exports.tokensToRegExp=f;var a=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function o(e,t){for(var n,r=[],o=0,l=0,s="",c=t&&t.delimiter||"/";null!=(n=a.exec(e));){var d=n[0],p=n[1],f=n.index;if(s+=e.slice(l,f),l=f+d.length,p)s+=p[1];else{var m=e[l],h=n[2],b=n[3],g=n[4],v=n[5],y=n[6],k=n[7];s&&(r.push(s),s="");var w=null!=h&&null!=m&&m!==h,S="+"===y||"*"===y,E="?"===y||"*"===y,x=h||c,P=g||v,_=h||("string"==typeof r[r.length-1]?r[r.length-1]:"");r.push({name:b||o++,prefix:h||"",delimiter:x,optional:E,repeat:S,partial:w,asterisk:!!k,pattern:P?u(P):k?".*":i(x,_)})}}return l-1?"[^"+c(e)+"]+?":c(t)+"|(?:(?!"+c(t)+")[^"+c(e)+"])+?"}function l(e){return encodeURI(e).replace(/[\/?#]/g,(function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()}))}function s(e,t){for(var n=new Array(e.length),a=0;a{"use strict";n.d(t,{A:()=>o});var r=function(){var e=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,n={},r={util:{encode:function e(t){return t instanceof a?new a(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/=d.reach);E+=S.value.length,S=S.next){var x=S.value;if(t.length>e.length)return;if(!(x instanceof a)){var P,_=1;if(v){if(!(P=o(w,E,e,g))||P.index>=e.length)break;var C=P.index,A=P.index+P[0].length,T=E;for(T+=S.value.length;C>=T;)T+=(S=S.next).value.length;if(E=T-=S.value.length,S.value instanceof a)continue;for(var L=S;L!==t.tail&&(Td.reach&&(d.reach=D);var I=S.prev;if(O&&(I=s(t,I,O),E+=O.length),c(t,I,_),S=s(t,I,new a(p,b?r.tokenize(R,b):R,y,R)),N&&s(t,S,N),_>1){var B={cause:p+","+m,reach:D};i(e,t,n,S.prev,E,B),d&&B.reach>d.reach&&(d.reach=B.reach)}}}}}}function l(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function s(e,t,n){var r=t.next,a={value:n,prev:t,next:r};return t.next=a,r.prev=a,e.length++,a}function c(e,t,n){for(var r=t.next,a=0;a"+o.content+""},r}(),a=r;r.default=r,a.languages.markup={comment:{pattern://,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern://i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},a.languages.markup.tag.inside["attr-value"].inside.entity=a.languages.markup.entity,a.languages.markup.doctype.inside["internal-subset"].inside=a.languages.markup,a.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(a.languages.markup.tag,"addInlined",{value:function(e,t){var n={};n["language-"+t]={pattern:/(^$)/i,lookbehind:!0,inside:a.languages[t]},n.cdata=/^$/i;var r={"included-cdata":{pattern://i,inside:n}};r["language-"+t]={pattern:/[\s\S]+/,inside:a.languages[t]};var o={};o[e]={pattern:RegExp(/(<__[^>]*>)(?:))*\]\]>|(?!)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:r},a.languages.insertBefore("markup","cdata",o)}}),Object.defineProperty(a.languages.markup.tag,"addAttribute",{value:function(e,t){a.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[t,"language-"+t],inside:a.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),a.languages.html=a.languages.markup,a.languages.mathml=a.languages.markup,a.languages.svg=a.languages.markup,a.languages.xml=a.languages.extend("markup",{}),a.languages.ssml=a.languages.xml,a.languages.atom=a.languages.xml,a.languages.rss=a.languages.xml,function(e){var t="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",n={pattern:/(^(["']?)\w+\2)[ \t]+\S.*/,lookbehind:!0,alias:"punctuation",inside:null},r={bash:n,environment:{pattern:RegExp("\\$"+t),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--|\+\+|\*\*=?|<<=?|>>=?|&&|\|\||[=!+\-*/%<>^&|]=?|[?~:]/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+t),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|U[0-9a-fA-F]{8}|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{1,2})/};e.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)[\w-]+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b[\w-]+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+t),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+)\s[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:r},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0,inside:{bash:n}},{pattern:/(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/,lookbehind:!0,greedy:!0,inside:r},{pattern:/(^|[^$\\])'[^']*'/,lookbehind:!0,greedy:!0},{pattern:/\$'(?:[^'\\]|\\[\s\S])*'/,greedy:!0,inside:{entity:r.entity}}],environment:{pattern:RegExp("\\$?"+t),alias:"constant"},variable:r.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|apt-cache|apt-get|aptitude|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|docker|docker-compose|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|node|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|podman|podman-compose|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vcpkg|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|alias|bind|break|builtin|caller|cd|command|continue|declare|echo|enable|eval|exec|exit|export|getopts|hash|help|let|local|logout|mapfile|printf|pwd|read|readarray|readonly|return|set|shift|shopt|source|test|times|trap|type|typeset|ulimit|umask|unalias|unset)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:false|true)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|=[=~]?|!=?|<<[<-]?|[&\d]?>>|\d[<>]&?|[<>][&=]?|&[>&]?|\|[&|]?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}},n.inside=e.languages.bash;for(var a=["comment","function-name","for-or-select","assign-left","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],o=r.variable[1].inside,i=0;i]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},a.languages.c=a.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},"class-name":{pattern:/(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,lookbehind:!0},keyword:/\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/,function:/\b[a-z_]\w*(?=\s*\()/i,number:/(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),a.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),a.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},a.languages.c.string],char:a.languages.c.char,comment:a.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:a.languages.c}}}}),a.languages.insertBefore("c","function",{constant:/\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/}),delete a.languages.c.boolean,function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,n=/\b(?!)\w+(?:\s*\.\s*\w+)*\b/.source.replace(//g,(function(){return t.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!)\w+/.source.replace(//g,(function(){return t.source}))),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp(/(\b(?:import|module)\s+)/.source+"(?:"+/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source+"|"+/(?:\s*:\s*)?|:\s*/.source.replace(//g,(function(){return n}))+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(a),function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var n=e.languages.markup;n&&(n.tag.addInlined("style","css"),n.tag.addAttribute("style","css"))}(a),function(e){var t,n=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;e.languages.css.selector={pattern:e.languages.css.selector.pattern,lookbehind:!0,inside:t={"pseudo-element":/:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,"pseudo-class":/:[-\w]+/,class:/\.[-\w]+/,id:/#[-\w]+/,attribute:{pattern:RegExp("\\[(?:[^[\\]\"']|"+n.source+")*\\]"),greedy:!0,inside:{punctuation:/^\[|\]$/,"case-sensitivity":{pattern:/(\s)[si]$/i,lookbehind:!0,alias:"keyword"},namespace:{pattern:/^(\s*)(?:(?!\s)[-*\w\xA0-\uFFFF])*\|(?!=)/,lookbehind:!0,inside:{punctuation:/\|$/}},"attr-name":{pattern:/^(\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+/,lookbehind:!0},"attr-value":[n,{pattern:/(=\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+(?=\s*$)/,lookbehind:!0}],operator:/[|~*^$]?=/}},"n-th":[{pattern:/(\(\s*)[+-]?\d*[\dn](?:\s*[+-]\s*\d+)?(?=\s*\))/,lookbehind:!0,inside:{number:/[\dn]+/,operator:/[+-]/}},{pattern:/(\(\s*)(?:even|odd)(?=\s*\))/i,lookbehind:!0}],combinator:/>|\+|~|\|\|/,punctuation:/[(),]/}},e.languages.css.atrule.inside["selector-function-argument"].inside=t,e.languages.insertBefore("css","property",{variable:{pattern:/(^|[^-\w\xA0-\uFFFF])--(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*/i,lookbehind:!0}});var r={pattern:/(\b\d+)(?:%|[a-z]+(?![\w-]))/,lookbehind:!0},a={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0};e.languages.insertBefore("css","function",{operator:{pattern:/(\s)[+\-*\/](?=\s)/,lookbehind:!0},hexcode:{pattern:/\B#[\da-f]{3,8}\b/i,alias:"color"},color:[{pattern:/(^|[^\w-])(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)(?![\w-])/i,lookbehind:!0},{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:r,number:a,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:r,number:a})}(a),a.languages.javascript=a.languages.extend("clike",{"class-name":[a.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),a.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,a.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:a.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:a.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:a.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:a.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:a.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),a.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:a.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),a.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),a.languages.markup&&(a.languages.markup.tag.addInlined("script","javascript"),a.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),a.languages.js=a.languages.javascript,function(e){var t=/#(?!\{).+/,n={pattern:/#\{[^}]+\}/,alias:"variable"};e.languages.coffeescript=e.languages.extend("javascript",{comment:t,string:[{pattern:/'(?:\\[\s\S]|[^\\'])*'/,greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,greedy:!0,inside:{interpolation:n}}],keyword:/\b(?:and|break|by|catch|class|continue|debugger|delete|do|each|else|extend|extends|false|finally|for|if|in|instanceof|is|isnt|let|loop|namespace|new|no|not|null|of|off|on|or|own|return|super|switch|then|this|throw|true|try|typeof|undefined|unless|until|when|while|window|with|yes|yield)\b/,"class-member":{pattern:/@(?!\d)\w+/,alias:"variable"}}),e.languages.insertBefore("coffeescript","comment",{"multiline-comment":{pattern:/###[\s\S]+?###/,alias:"comment"},"block-regex":{pattern:/\/{3}[\s\S]*?\/{3}/,alias:"regex",inside:{comment:t,interpolation:n}}}),e.languages.insertBefore("coffeescript","string",{"inline-javascript":{pattern:/`(?:\\[\s\S]|[^\\`])*`/,inside:{delimiter:{pattern:/^`|`$/,alias:"punctuation"},script:{pattern:/[\s\S]+/,alias:"language-javascript",inside:e.languages.javascript}}},"multiline-string":[{pattern:/'''[\s\S]*?'''/,greedy:!0,alias:"string"},{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string",inside:{interpolation:n}}]}),e.languages.insertBefore("coffeescript","keyword",{property:/(?!\d)\w+(?=\s*:(?!:))/}),delete e.languages.coffeescript["template-string"],e.languages.coffee=e.languages.coffeescript}(a),function(e){var t=/[*&][^\s[\]{},]+/,n=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,r="(?:"+n.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+n.source+")?)",a=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-])(?:[ \t]*(?:(?![#:])|:))*/.source.replace(//g,(function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source})),o=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function i(e,t){t=(t||"").replace(/m/g,"")+"m";var n=/([:\-,[{]\s*(?:\s<>[ \t]+)?)(?:<>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<>/g,(function(){return r})).replace(/<>/g,(function(){return e}));return RegExp(n,t)}e.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<>/g,(function(){return r}))),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<>[ \t]+)?)<>(?=\s*:\s)/.source.replace(/<>/g,(function(){return r})).replace(/<>/g,(function(){return"(?:"+a+"|"+o+")"}))),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:i(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?(?:[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?))?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),lookbehind:!0,alias:"number"},boolean:{pattern:i(/false|true/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:i(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:i(o),lookbehind:!0,greedy:!0},number:{pattern:i(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source,"i"),lookbehind:!0},tag:n,important:t,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(a),function(e){var t=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;function n(e){return e=e.replace(//g,(function(){return t})),RegExp(/((?:^|[^\\])(?:\\{2})*)/.source+"(?:"+e+")")}var r=/(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source,a=/\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g,(function(){return r})),o=/\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source;e.languages.markdown=e.languages.extend("markup",{}),e.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"front-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:e.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+a+o+"(?:"+a+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+a+o+")(?:"+a+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(r),inside:e.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+a+")"+o+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+a+"$"),inside:{"table-header":{pattern:RegExp(r),alias:"important",inside:e.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:n(/\b__(?:(?!_)|_(?:(?!_))+_)+__\b|\*\*(?:(?!\*)|\*(?:(?!\*))+\*)+\*\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:n(/\b_(?:(?!_)|__(?:(?!_))+__)+_\b|\*(?:(?!\*)|\*\*(?:(?!\*))+\*\*)+\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:n(/(~~?)(?:(?!~))+\2/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},"code-snippet":{pattern:/(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/,lookbehind:!0,greedy:!0,alias:["code","keyword"]},url:{pattern:n(/!?\[(?:(?!\]))+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\]))+\])/.source),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach((function(t){["url","bold","italic","strike","code-snippet"].forEach((function(n){t!==n&&(e.languages.markdown[t].inside.content.inside[n]=e.languages.markdown[n])}))})),e.hooks.add("after-tokenize",(function(e){"markdown"!==e.language&&"md"!==e.language||function e(t){if(t&&"string"!=typeof t)for(var n=0,r=t.length;n",quot:'"'},s=String.fromCodePoint||String.fromCharCode;e.languages.md=e.languages.markdown}(a),a.languages.graphql={comment:/#.*/,description:{pattern:/(?:"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*")(?=\s*[a-z_])/i,greedy:!0,alias:"string",inside:{"language-markdown":{pattern:/(^"(?:"")?)(?!\1)[\s\S]+(?=\1$)/,lookbehind:!0,inside:a.languages.markdown}}},string:{pattern:/"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*"/,greedy:!0},number:/(?:\B-|\b)\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,boolean:/\b(?:false|true)\b/,variable:/\$[a-z_]\w*/i,directive:{pattern:/@[a-z_]\w*/i,alias:"function"},"attr-name":{pattern:/\b[a-z_]\w*(?=\s*(?:\((?:[^()"]|"(?:\\.|[^\\"\r\n])*")*\))?:)/i,greedy:!0},"atom-input":{pattern:/\b[A-Z]\w*Input\b/,alias:"class-name"},scalar:/\b(?:Boolean|Float|ID|Int|String)\b/,constant:/\b[A-Z][A-Z_\d]*\b/,"class-name":{pattern:/(\b(?:enum|implements|interface|on|scalar|type|union)\s+|&\s*|:\s*|\[)[A-Z_]\w*/,lookbehind:!0},fragment:{pattern:/(\bfragment\s+|\.{3}\s*(?!on\b))[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-mutation":{pattern:/(\bmutation\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-query":{pattern:/(\bquery\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},keyword:/\b(?:directive|enum|extend|fragment|implements|input|interface|mutation|on|query|repeatable|scalar|schema|subscription|type|union)\b/,operator:/[!=|&]|\.{3}/,"property-query":/\w+(?=\s*\()/,object:/\w+(?=\s*\{)/,punctuation:/[!(){}\[\]:=,]/,property:/\w+/},a.hooks.add("after-tokenize",(function(e){if("graphql"===e.language)for(var t=e.tokens.filter((function(e){return"string"!=typeof e&&"comment"!==e.type&&"scalar"!==e.type})),n=0;n0)){var l=p(/^\{$/,/^\}$/);if(-1===l)continue;for(var s=n;s=0&&f(c,"variable-input")}}}}function u(e){return t[n+e]}function d(e,t){t=t||0;for(var n=0;n?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/},function(e){var t=e.languages.javascript["template-string"],n=t.pattern.source,r=t.inside.interpolation,a=r.inside["interpolation-punctuation"],o=r.pattern.source;function i(t,r){if(e.languages[t])return{pattern:RegExp("((?:"+r+")\\s*)"+n),lookbehind:!0,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},"embedded-code":{pattern:/[\s\S]+/,alias:t}}}}function l(e,t){return"___"+t.toUpperCase()+"_"+e+"___"}function s(t,n,r){var a={code:t,grammar:n,language:r};return e.hooks.run("before-tokenize",a),a.tokens=e.tokenize(a.code,a.grammar),e.hooks.run("after-tokenize",a),a.tokens}function c(t){var n={};n["interpolation-punctuation"]=a;var o=e.tokenize(t,n);if(3===o.length){var i=[1,1];i.push.apply(i,s(o[1],e.languages.javascript,"javascript")),o.splice.apply(o,i)}return new e.Token("interpolation",o,r.alias,t)}function u(t,n,r){var a=e.tokenize(t,{interpolation:{pattern:RegExp(o),lookbehind:!0}}),i=0,u={},d=s(a.map((function(e){if("string"==typeof e)return e;for(var n,a=e.content;-1!==t.indexOf(n=l(i++,r)););return u[n]=a,n})).join(""),n,r),p=Object.keys(u);return i=0,function e(t){for(var n=0;n=p.length)return;var r=t[n];if("string"==typeof r||"string"==typeof r.content){var a=p[i],o="string"==typeof r?r:r.content,l=o.indexOf(a);if(-1!==l){++i;var s=o.substring(0,l),d=c(u[a]),f=o.substring(l+a.length),m=[];if(s&&m.push(s),m.push(d),f){var h=[f];e(h),m.push.apply(m,h)}"string"==typeof r?(t.splice.apply(t,[n,1].concat(m)),n+=m.length-1):r.content=m}}else{var b=r.content;Array.isArray(b)?e(b):e([b])}}}(d),new e.Token(r,d,"language-"+r,t)}e.languages.javascript["template-string"]=[i("css",/\b(?:styled(?:\([^)]*\))?(?:\s*\.\s*\w+(?:\([^)]*\))*)*|css(?:\s*\.\s*(?:global|resolve))?|createGlobalStyle|keyframes)/.source),i("html",/\bhtml|\.\s*(?:inner|outer)HTML\s*\+?=/.source),i("svg",/\bsvg/.source),i("markdown",/\b(?:markdown|md)/.source),i("graphql",/\b(?:gql|graphql(?:\s*\.\s*experimental)?)/.source),i("sql",/\bsql/.source),t].filter(Boolean);var d={javascript:!0,js:!0,typescript:!0,ts:!0,jsx:!0,tsx:!0};function p(e){return"string"==typeof e?e:Array.isArray(e)?e.map(p).join(""):p(e.content)}e.hooks.add("after-tokenize",(function(t){t.language in d&&function t(n){for(var r=0,a=n.length;r]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:Array|Function|Promise|any|boolean|console|never|number|string|symbol|unknown)\b/}),e.languages.typescript.keyword.push(/\b(?:abstract|declare|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,/\btype\b(?=\s*(?:[\{*]|$))/),delete e.languages.typescript.parameter,delete e.languages.typescript["literal-property"];var t=e.languages.extend("typescript",{});delete t["class-name"],e.languages.typescript["class-name"].inside=t,e.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:t}}}}),e.languages.ts=e.languages.typescript}(a),function(e){function t(e,t){return RegExp(e.replace(//g,(function(){return/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/.source})),t)}e.languages.insertBefore("javascript","function-variable",{"method-variable":{pattern:RegExp("(\\.\\s*)"+e.languages.javascript["function-variable"].pattern.source),lookbehind:!0,alias:["function-variable","method","function","property-access"]}}),e.languages.insertBefore("javascript","function",{method:{pattern:RegExp("(\\.\\s*)"+e.languages.javascript.function.source),lookbehind:!0,alias:["function","property-access"]}}),e.languages.insertBefore("javascript","constant",{"known-class-name":[{pattern:/\b(?:(?:Float(?:32|64)|(?:Int|Uint)(?:8|16|32)|Uint8Clamped)?Array|ArrayBuffer|BigInt|Boolean|DataView|Date|Error|Function|Intl|JSON|(?:Weak)?(?:Map|Set)|Math|Number|Object|Promise|Proxy|Reflect|RegExp|String|Symbol|WebAssembly)\b/,alias:"class-name"},{pattern:/\b(?:[A-Z]\w*)Error\b/,alias:"class-name"}]}),e.languages.insertBefore("javascript","keyword",{imports:{pattern:t(/(\bimport\b\s*)(?:(?:\s*,\s*(?:\*\s*as\s+|\{[^{}]*\}))?|\*\s*as\s+|\{[^{}]*\})(?=\s*\bfrom\b)/.source),lookbehind:!0,inside:e.languages.javascript},exports:{pattern:t(/(\bexport\b\s*)(?:\*(?:\s*as\s+)?(?=\s*\bfrom\b)|\{[^{}]*\})/.source),lookbehind:!0,inside:e.languages.javascript}}),e.languages.javascript.keyword.unshift({pattern:/\b(?:as|default|export|from|import)\b/,alias:"module"},{pattern:/\b(?:await|break|catch|continue|do|else|finally|for|if|return|switch|throw|try|while|yield)\b/,alias:"control-flow"},{pattern:/\bnull\b/,alias:["null","nil"]},{pattern:/\bundefined\b/,alias:"nil"}),e.languages.insertBefore("javascript","operator",{spread:{pattern:/\.{3}/,alias:"operator"},arrow:{pattern:/=>/,alias:"operator"}}),e.languages.insertBefore("javascript","punctuation",{"property-access":{pattern:t(/(\.\s*)#?/.source),lookbehind:!0},"maybe-class-name":{pattern:/(^|[^$\w\xA0-\uFFFF])[A-Z][$\w\xA0-\uFFFF]+/,lookbehind:!0},dom:{pattern:/\b(?:document|(?:local|session)Storage|location|navigator|performance|window)\b/,alias:"variable"},console:{pattern:/\bconsole(?=\s*\.)/,alias:"class-name"}});for(var n=["function","function-variable","method","method-variable","property-access"],r=0;r*\.{3}(?:[^{}]|)*\})/.source;function o(e,t){return e=e.replace(//g,(function(){return n})).replace(//g,(function(){return r})).replace(//g,(function(){return a})),RegExp(e,t)}a=o(a).source,e.languages.jsx=e.languages.extend("markup",t),e.languages.jsx.tag.pattern=o(/<\/?(?:[\w.:-]+(?:+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s{'"/>=]+|))?|))**\/?)?>/.source),e.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,e.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,e.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,e.languages.jsx.tag.inside.comment=t.comment,e.languages.insertBefore("inside","attr-name",{spread:{pattern:o(//.source),inside:e.languages.jsx}},e.languages.jsx.tag),e.languages.insertBefore("inside","special-attr",{script:{pattern:o(/=/.source),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:e.languages.jsx}}},e.languages.jsx.tag);var i=function(e){return e?"string"==typeof e?e:"string"==typeof e.content?e.content:e.content.map(i).join(""):""},l=function(t){for(var n=[],r=0;r0&&n[n.length-1].tagName===i(a.content[0].content[1])&&n.pop():"/>"===a.content[a.content.length-1].content||n.push({tagName:i(a.content[0].content[1]),openedBraces:0}):n.length>0&&"punctuation"===a.type&&"{"===a.content?n[n.length-1].openedBraces++:n.length>0&&n[n.length-1].openedBraces>0&&"punctuation"===a.type&&"}"===a.content?n[n.length-1].openedBraces--:o=!0),(o||"string"==typeof a)&&n.length>0&&0===n[n.length-1].openedBraces){var s=i(a);r0&&("string"==typeof t[r-1]||"plain-text"===t[r-1].type)&&(s=i(t[r-1])+s,t.splice(r-1,1),r--),t[r]=new e.Token("plain-text",s,null,s)}a.content&&"string"!=typeof a.content&&l(a.content)}};e.hooks.add("after-tokenize",(function(e){"jsx"!==e.language&&"tsx"!==e.language||l(e.tokens)}))}(a),function(e){e.languages.diff={coord:[/^(?:\*{3}|-{3}|\+{3}).*$/m,/^@@.*@@$/m,/^\d.*$/m]};var t={"deleted-sign":"-","deleted-arrow":"<","inserted-sign":"+","inserted-arrow":">",unchanged:" ",diff:"!"};Object.keys(t).forEach((function(n){var r=t[n],a=[];/^\w+$/.test(n)||a.push(/\w+/.exec(n)[0]),"diff"===n&&a.push("bold"),e.languages.diff[n]={pattern:RegExp("^(?:["+r+"].*(?:\r\n?|\n|(?![\\s\\S])))+","m"),alias:a,inside:{line:{pattern:/(.)(?=[\s\S]).*(?:\r\n?|\n)?/,lookbehind:!0},prefix:{pattern:/[\s\S]/,alias:/\w+/.exec(n)[0]}}}})),Object.defineProperty(e.languages.diff,"PREFIXES",{value:t})}(a),a.languages.git={comment:/^#.*/m,deleted:/^[-\u2013].*/m,inserted:/^\+.*/m,string:/("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,command:{pattern:/^.*\$ git .*$/m,inside:{parameter:/\s--?\w+/}},coord:/^@@.*@@$/m,"commit-sha1":/^commit \w{40}$/m},a.languages.go=a.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/,lookbehind:!0,greedy:!0},keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,boolean:/\b(?:_|false|iota|nil|true)\b/,number:[/\b0(?:b[01_]+|o[0-7_]+)i?\b/i,/\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,/(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i],operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/}),a.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete a.languages.go["class-name"],function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,a,o){if(n.language===r){var i=n.tokenStack=[];n.code=n.code.replace(a,(function(e){if("function"==typeof o&&!o(e))return e;for(var a,l=i.length;-1!==n.code.indexOf(a=t(r,l));)++l;return i[l]=e,a})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var a=0,o=Object.keys(n.tokenStack);!function i(l){for(var s=0;s=o.length);s++){var c=l[s];if("string"==typeof c||c.content&&"string"==typeof c.content){var u=o[a],d=n.tokenStack[u],p="string"==typeof c?c:c.content,f=t(r,u),m=p.indexOf(f);if(m>-1){++a;var h=p.substring(0,m),b=new e.Token(r,e.tokenize(d,n.grammar),"language-"+r,d),g=p.substring(m+f.length),v=[];h&&v.push.apply(v,i([h])),v.push(b),g&&v.push.apply(v,i([g])),"string"==typeof c?l.splice.apply(l,[s,1].concat(v)):c.content=v}}else c.content&&i(c.content)}return l}(n.tokens)}}}})}(a),function(e){e.languages.handlebars={comment:/\{\{![\s\S]*?\}\}/,delimiter:{pattern:/^\{\{\{?|\}\}\}?$/,alias:"punctuation"},string:/(["'])(?:\\.|(?!\1)[^\\\r\n])*\1/,number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee][+-]?\d+)?/,boolean:/\b(?:false|true)\b/,block:{pattern:/^(\s*(?:~\s*)?)[#\/]\S+?(?=\s*(?:~\s*)?$|\s)/,lookbehind:!0,alias:"keyword"},brackets:{pattern:/\[[^\]]+\]/,inside:{punctuation:/\[|\]/,variable:/[\s\S]+/}},punctuation:/[!"#%&':()*+,.\/;<=>@\[\\\]^`{|}~]/,variable:/[^!"#%&'()*+,\/;<=>@\[\\\]^`{|}~\s]+/},e.hooks.add("before-tokenize",(function(t){e.languages["markup-templating"].buildPlaceholders(t,"handlebars",/\{\{\{[\s\S]+?\}\}\}|\{\{[\s\S]+?\}\}/g)})),e.hooks.add("after-tokenize",(function(t){e.languages["markup-templating"].tokenizePlaceholders(t,"handlebars")})),e.languages.hbs=e.languages.handlebars}(a),a.languages.json={property:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,lookbehind:!0,greedy:!0},string:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,lookbehind:!0,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},a.languages.webmanifest=a.languages.json,a.languages.less=a.languages.extend("css",{comment:[/\/\*[\s\S]*?\*\//,{pattern:/(^|[^\\])\/\/.*/,lookbehind:!0}],atrule:{pattern:/@[\w-](?:\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{punctuation:/[:()]/}},selector:{pattern:/(?:@\{[\w-]+\}|[^{};\s@])(?:@\{[\w-]+\}|\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};@\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{variable:/@+[\w-]+/}},property:/(?:@\{[\w-]+\}|[\w-])+(?:\+_?)?(?=\s*:)/,operator:/[+\-*\/]/}),a.languages.insertBefore("less","property",{variable:[{pattern:/@[\w-]+\s*:/,inside:{punctuation:/:/}},/@@?[\w-]+/],"mixin-usage":{pattern:/([{;]\s*)[.#](?!\d)[\w-].*?(?=[(;])/,lookbehind:!0,alias:"function"}}),a.languages.makefile={comment:{pattern:/(^|[^\\])#(?:\\(?:\r\n|[\s\S])|[^\\\r\n])*/,lookbehind:!0},string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"builtin-target":{pattern:/\.[A-Z][^:#=\s]+(?=\s*:(?!=))/,alias:"builtin"},target:{pattern:/^(?:[^:=\s]|[ \t]+(?![\s:]))+(?=\s*:(?!=))/m,alias:"symbol",inside:{variable:/\$+(?:(?!\$)[^(){}:#=\s]+|(?=[({]))/}},variable:/\$+(?:(?!\$)[^(){}:#=\s]+|\([@*%<^+?][DF]\)|(?=[({]))/,keyword:/-include\b|\b(?:define|else|endef|endif|export|ifn?def|ifn?eq|include|override|private|sinclude|undefine|unexport|vpath)\b/,function:{pattern:/(\()(?:abspath|addsuffix|and|basename|call|dir|error|eval|file|filter(?:-out)?|findstring|firstword|flavor|foreach|guile|if|info|join|lastword|load|notdir|or|origin|patsubst|realpath|shell|sort|strip|subst|suffix|value|warning|wildcard|word(?:list|s)?)(?=[ \t])/,lookbehind:!0},operator:/(?:::|[?:+!])?=|[|@]/,punctuation:/[:;(){}]/},a.languages.objectivec=a.languages.extend("c",{string:{pattern:/@?"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},keyword:/\b(?:asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|in|inline|int|long|register|return|self|short|signed|sizeof|static|struct|super|switch|typedef|typeof|union|unsigned|void|volatile|while)\b|(?:@interface|@end|@implementation|@protocol|@class|@public|@protected|@private|@property|@try|@catch|@finally|@throw|@synthesize|@dynamic|@selector)\b/,operator:/-[->]?|\+\+?|!=?|<>?=?|==?|&&?|\|\|?|[~^%?*\/@]/}),delete a.languages.objectivec["class-name"],a.languages.objc=a.languages.objectivec,a.languages.ocaml={comment:{pattern:/\(\*[\s\S]*?\*\)/,greedy:!0},char:{pattern:/'(?:[^\\\r\n']|\\(?:.|[ox]?[0-9a-f]{1,3}))'/i,greedy:!0},string:[{pattern:/"(?:\\(?:[\s\S]|\r\n)|[^\\\r\n"])*"/,greedy:!0},{pattern:/\{([a-z_]*)\|[\s\S]*?\|\1\}/,greedy:!0}],number:[/\b(?:0b[01][01_]*|0o[0-7][0-7_]*)\b/i,/\b0x[a-f0-9][a-f0-9_]*(?:\.[a-f0-9_]*)?(?:p[+-]?\d[\d_]*)?(?!\w)/i,/\b\d[\d_]*(?:\.[\d_]*)?(?:e[+-]?\d[\d_]*)?(?!\w)/i],directive:{pattern:/\B#\w+/,alias:"property"},label:{pattern:/\B~\w+/,alias:"property"},"type-variable":{pattern:/\B'\w+/,alias:"function"},variant:{pattern:/`\w+/,alias:"symbol"},keyword:/\b(?:as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|match|method|module|mutable|new|nonrec|object|of|open|private|rec|sig|struct|then|to|try|type|val|value|virtual|when|where|while|with)\b/,boolean:/\b(?:false|true)\b/,"operator-like-punctuation":{pattern:/\[[<>|]|[>|]\]|\{<|>\}/,alias:"punctuation"},operator:/\.[.~]|:[=>]|[=<>@^|&+\-*\/$%!?~][!$%&*+\-.\/:<=>?@^|~]*|\b(?:and|asr|land|lor|lsl|lsr|lxor|mod|or)\b/,punctuation:/;;|::|[(){}\[\].,:;#]|\b_\b/},a.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},a.languages.python["string-interpolation"].inside.interpolation.inside.rest=a.languages.python,a.languages.py=a.languages.python,a.languages.reason=a.languages.extend("clike",{string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^\\\r\n"])*"/,greedy:!0},"class-name":/\b[A-Z]\w*/,keyword:/\b(?:and|as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|method|module|mutable|new|nonrec|object|of|open|or|private|rec|sig|struct|switch|then|to|try|type|val|virtual|when|while|with)\b/,operator:/\.{3}|:[:=]|\|>|->|=(?:==?|>)?|<=?|>=?|[|^?'#!~`]|[+\-*\/]\.?|\b(?:asr|land|lor|lsl|lsr|lxor|mod)\b/}),a.languages.insertBefore("reason","class-name",{char:{pattern:/'(?:\\x[\da-f]{2}|\\o[0-3][0-7][0-7]|\\\d{3}|\\.|[^'\\\r\n])'/,greedy:!0},constructor:/\b[A-Z]\w*\b(?!\s*\.)/,label:{pattern:/\b[a-z]\w*(?=::)/,alias:"symbol"}}),delete a.languages.reason.function,function(e){e.languages.sass=e.languages.extend("css",{comment:{pattern:/^([ \t]*)\/[\/*].*(?:(?:\r?\n|\r)\1[ \t].+)*/m,lookbehind:!0,greedy:!0}}),e.languages.insertBefore("sass","atrule",{"atrule-line":{pattern:/^(?:[ \t]*)[@+=].+/m,greedy:!0,inside:{atrule:/(?:@[\w-]+|[+=])/}}}),delete e.languages.sass.atrule;var t=/\$[-\w]+|#\{\$[-\w]+\}/,n=[/[+*\/%]|[=!]=|<=?|>=?|\b(?:and|not|or)\b/,{pattern:/(\s)-(?=\s)/,lookbehind:!0}];e.languages.insertBefore("sass","property",{"variable-line":{pattern:/^[ \t]*\$.+/m,greedy:!0,inside:{punctuation:/:/,variable:t,operator:n}},"property-line":{pattern:/^[ \t]*(?:[^:\s]+ *:.*|:[^:\s].*)/m,greedy:!0,inside:{property:[/[^:\s]+(?=\s*:)/,{pattern:/(:)[^:\s]+/,lookbehind:!0}],punctuation:/:/,variable:t,operator:n,important:e.languages.sass.important}}}),delete e.languages.sass.property,delete e.languages.sass.important,e.languages.insertBefore("sass","punctuation",{selector:{pattern:/^([ \t]*)\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*(?:,(?:\r?\n|\r)\1[ \t]+\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*)*/m,lookbehind:!0,greedy:!0}})}(a),a.languages.scss=a.languages.extend("css",{comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},atrule:{pattern:/@[\w-](?:\([^()]+\)|[^()\s]|\s+(?!\s))*?(?=\s+[{;])/,inside:{rule:/@[\w-]+/}},url:/(?:[-a-z]+-)?url(?=\()/i,selector:{pattern:/(?=\S)[^@;{}()]?(?:[^@;{}()\s]|\s+(?!\s)|#\{\$[-\w]+\})+(?=\s*\{(?:\}|\s|[^}][^:{}]*[:{][^}]))/,inside:{parent:{pattern:/&/,alias:"important"},placeholder:/%[-\w]+/,variable:/\$[-\w]+|#\{\$[-\w]+\}/}},property:{pattern:/(?:[-\w]|\$[-\w]|#\{\$[-\w]+\})+(?=\s*:)/,inside:{variable:/\$[-\w]+|#\{\$[-\w]+\}/}}}),a.languages.insertBefore("scss","atrule",{keyword:[/@(?:content|debug|each|else(?: if)?|extend|for|forward|function|if|import|include|mixin|return|use|warn|while)\b/i,{pattern:/( )(?:from|through)(?= )/,lookbehind:!0}]}),a.languages.insertBefore("scss","important",{variable:/\$[-\w]+|#\{\$[-\w]+\}/}),a.languages.insertBefore("scss","function",{"module-modifier":{pattern:/\b(?:as|hide|show|with)\b/i,alias:"keyword"},placeholder:{pattern:/%[-\w]+/,alias:"selector"},statement:{pattern:/\B!(?:default|optional)\b/i,alias:"keyword"},boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"},operator:{pattern:/(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|not|or)(?=\s)/,lookbehind:!0}}),a.languages.scss.atrule.inside.rest=a.languages.scss,function(e){var t={pattern:/(\b\d+)(?:%|[a-z]+)/,lookbehind:!0},n={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0},r={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},url:{pattern:/\burl\((["']?).*?\1\)/i,greedy:!0},string:{pattern:/("|')(?:(?!\1)[^\\\r\n]|\\(?:\r\n|[\s\S]))*\1/,greedy:!0},interpolation:null,func:null,important:/\B!(?:important|optional)\b/i,keyword:{pattern:/(^|\s+)(?:(?:else|for|if|return|unless)(?=\s|$)|@[\w-]+)/,lookbehind:!0},hexcode:/#[\da-f]{3,6}/i,color:[/\b(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)\b/i,{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:t,number:n,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:t,boolean:/\b(?:false|true)\b/,operator:[/~|[+!\/%<>?=]=?|[-:]=|\*[*=]?|\.{2,3}|&&|\|\||\B-\B|\b(?:and|in|is(?: a| defined| not|nt)?|not|or)\b/],number:n,punctuation:/[{}()\[\];:,]/};r.interpolation={pattern:/\{[^\r\n}:]+\}/,alias:"variable",inside:{delimiter:{pattern:/^\{|\}$/,alias:"punctuation"},rest:r}},r.func={pattern:/[\w-]+\([^)]*\).*/,inside:{function:/^[^(]+/,rest:r}},e.languages.stylus={"atrule-declaration":{pattern:/(^[ \t]*)@.+/m,lookbehind:!0,inside:{atrule:/^@[\w-]+/,rest:r}},"variable-declaration":{pattern:/(^[ \t]*)[\w$-]+\s*.?=[ \t]*(?:\{[^{}]*\}|\S.*|$)/m,lookbehind:!0,inside:{variable:/^\S+/,rest:r}},statement:{pattern:/(^[ \t]*)(?:else|for|if|return|unless)[ \t].+/m,lookbehind:!0,inside:{keyword:/^\S+/,rest:r}},"property-declaration":{pattern:/((?:^|\{)([ \t]*))(?:[\w-]|\{[^}\r\n]+\})+(?:\s*:\s*|[ \t]+)(?!\s)[^{\r\n]*(?:;|[^{\r\n,]$(?!(?:\r?\n|\r)(?:\{|\2[ \t])))/m,lookbehind:!0,inside:{property:{pattern:/^[^\s:]+/,inside:{interpolation:r.interpolation}},rest:r}},selector:{pattern:/(^[ \t]*)(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)(?:(?:\r?\n|\r)(?:\1(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)))*(?:,$|\{|(?=(?:\r?\n|\r)(?:\{|\1[ \t])))/m,lookbehind:!0,inside:{interpolation:r.interpolation,comment:r.comment,punctuation:/[{},]/}},func:r.func,string:r.string,comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0,greedy:!0},interpolation:r.interpolation,punctuation:/[{}()\[\];:.]/}}(a),function(e){var t=e.util.clone(e.languages.typescript);e.languages.tsx=e.languages.extend("jsx",t),delete e.languages.tsx.parameter,delete e.languages.tsx["literal-property"];var n=e.languages.tsx.tag;n.pattern=RegExp(/(^|[^\w$]|(?=<\/))/.source+"(?:"+n.pattern.source+")",n.pattern.flags),n.lookbehind=!0}(a),a.languages.wasm={comment:[/\(;[\s\S]*?;\)/,{pattern:/;;.*/,greedy:!0}],string:{pattern:/"(?:\\[\s\S]|[^"\\])*"/,greedy:!0},keyword:[{pattern:/\b(?:align|offset)=/,inside:{operator:/=/}},{pattern:/\b(?:(?:f32|f64|i32|i64)(?:\.(?:abs|add|and|ceil|clz|const|convert_[su]\/i(?:32|64)|copysign|ctz|demote\/f64|div(?:_[su])?|eqz?|extend_[su]\/i32|floor|ge(?:_[su])?|gt(?:_[su])?|le(?:_[su])?|load(?:(?:8|16|32)_[su])?|lt(?:_[su])?|max|min|mul|neg?|nearest|or|popcnt|promote\/f32|reinterpret\/[fi](?:32|64)|rem_[su]|rot[lr]|shl|shr_[su]|sqrt|store(?:8|16|32)?|sub|trunc(?:_[su]\/f(?:32|64))?|wrap\/i64|xor))?|memory\.(?:grow|size))\b/,inside:{punctuation:/\./}},/\b(?:anyfunc|block|br(?:_if|_table)?|call(?:_indirect)?|data|drop|elem|else|end|export|func|get_(?:global|local)|global|if|import|local|loop|memory|module|mut|nop|offset|param|result|return|select|set_(?:global|local)|start|table|tee_local|then|type|unreachable)\b/],variable:/\$[\w!#$%&'*+\-./:<=>?@\\^`|~]+/,number:/[+-]?\b(?:\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:[eE][+-]?\d(?:_?\d)*)?|0x[\da-fA-F](?:_?[\da-fA-F])*(?:\.[\da-fA-F](?:_?[\da-fA-D])*)?(?:[pP][+-]?\d(?:_?\d)*)?)\b|\binf\b|\bnan(?::0x[\da-fA-F](?:_?[\da-fA-D])*)?\b/,punctuation:/[()]/};const o=a},6969:e=>{e.exports&&(e.exports={core:{meta:{path:"components/prism-core.js",option:"mandatory"},core:"Core"},themes:{meta:{path:"themes/{id}.css",link:"index.html?theme={id}",exclusive:!0},prism:{title:"Default",option:"default"},"prism-dark":"Dark","prism-funky":"Funky","prism-okaidia":{title:"Okaidia",owner:"ocodia"},"prism-twilight":{title:"Twilight",owner:"remybach"},"prism-coy":{title:"Coy",owner:"tshedor"},"prism-solarizedlight":{title:"Solarized Light",owner:"hectormatos2011 "},"prism-tomorrow":{title:"Tomorrow Night",owner:"Rosey"}},languages:{meta:{path:"components/prism-{id}",noCSS:!0,examplesPath:"examples/prism-{id}",addCheckAll:!0},markup:{title:"Markup",alias:["html","xml","svg","mathml","ssml","atom","rss"],aliasTitles:{html:"HTML",xml:"XML",svg:"SVG",mathml:"MathML",ssml:"SSML",atom:"Atom",rss:"RSS"},option:"default"},css:{title:"CSS",option:"default",modify:"markup"},clike:{title:"C-like",option:"default"},javascript:{title:"JavaScript",require:"clike",modify:"markup",optional:"regex",alias:"js",option:"default"},abap:{title:"ABAP",owner:"dellagustin"},abnf:{title:"ABNF",owner:"RunDevelopment"},actionscript:{title:"ActionScript",require:"javascript",modify:"markup",owner:"Golmote"},ada:{title:"Ada",owner:"Lucretia"},agda:{title:"Agda",owner:"xy-ren"},al:{title:"AL",owner:"RunDevelopment"},antlr4:{title:"ANTLR4",alias:"g4",owner:"RunDevelopment"},apacheconf:{title:"Apache Configuration",owner:"GuiTeK"},apex:{title:"Apex",require:["clike","sql"],owner:"RunDevelopment"},apl:{title:"APL",owner:"ngn"},applescript:{title:"AppleScript",owner:"Golmote"},aql:{title:"AQL",owner:"RunDevelopment"},arduino:{title:"Arduino",require:"cpp",alias:"ino",owner:"dkern"},arff:{title:"ARFF",owner:"Golmote"},armasm:{title:"ARM Assembly",alias:"arm-asm",owner:"RunDevelopment"},arturo:{title:"Arturo",alias:"art",optional:["bash","css","javascript","markup","markdown","sql"],owner:"drkameleon"},asciidoc:{alias:"adoc",title:"AsciiDoc",owner:"Golmote"},aspnet:{title:"ASP.NET (C#)",require:["markup","csharp"],owner:"nauzilus"},asm6502:{title:"6502 Assembly",owner:"kzurawel"},asmatmel:{title:"Atmel AVR Assembly",owner:"cerkit"},autohotkey:{title:"AutoHotkey",owner:"aviaryan"},autoit:{title:"AutoIt",owner:"Golmote"},avisynth:{title:"AviSynth",alias:"avs",owner:"Zinfidel"},"avro-idl":{title:"Avro IDL",alias:"avdl",owner:"RunDevelopment"},awk:{title:"AWK",alias:"gawk",aliasTitles:{gawk:"GAWK"},owner:"RunDevelopment"},bash:{title:"Bash",alias:["sh","shell"],aliasTitles:{sh:"Shell",shell:"Shell"},owner:"zeitgeist87"},basic:{title:"BASIC",owner:"Golmote"},batch:{title:"Batch",owner:"Golmote"},bbcode:{title:"BBcode",alias:"shortcode",aliasTitles:{shortcode:"Shortcode"},owner:"RunDevelopment"},bbj:{title:"BBj",owner:"hyyan"},bicep:{title:"Bicep",owner:"johnnyreilly"},birb:{title:"Birb",require:"clike",owner:"Calamity210"},bison:{title:"Bison",require:"c",owner:"Golmote"},bnf:{title:"BNF",alias:"rbnf",aliasTitles:{rbnf:"RBNF"},owner:"RunDevelopment"},bqn:{title:"BQN",owner:"yewscion"},brainfuck:{title:"Brainfuck",owner:"Golmote"},brightscript:{title:"BrightScript",owner:"RunDevelopment"},bro:{title:"Bro",owner:"wayward710"},bsl:{title:"BSL (1C:Enterprise)",alias:"oscript",aliasTitles:{oscript:"OneScript"},owner:"Diversus23"},c:{title:"C",require:"clike",owner:"zeitgeist87"},csharp:{title:"C#",require:"clike",alias:["cs","dotnet"],owner:"mvalipour"},cpp:{title:"C++",require:"c",owner:"zeitgeist87"},cfscript:{title:"CFScript",require:"clike",alias:"cfc",owner:"mjclemente"},chaiscript:{title:"ChaiScript",require:["clike","cpp"],owner:"RunDevelopment"},cil:{title:"CIL",owner:"sbrl"},cilkc:{title:"Cilk/C",require:"c",alias:"cilk-c",owner:"OpenCilk"},cilkcpp:{title:"Cilk/C++",require:"cpp",alias:["cilk-cpp","cilk"],owner:"OpenCilk"},clojure:{title:"Clojure",owner:"troglotit"},cmake:{title:"CMake",owner:"mjrogozinski"},cobol:{title:"COBOL",owner:"RunDevelopment"},coffeescript:{title:"CoffeeScript",require:"javascript",alias:"coffee",owner:"R-osey"},concurnas:{title:"Concurnas",alias:"conc",owner:"jasontatton"},csp:{title:"Content-Security-Policy",owner:"ScottHelme"},cooklang:{title:"Cooklang",owner:"ahue"},coq:{title:"Coq",owner:"RunDevelopment"},crystal:{title:"Crystal",require:"ruby",owner:"MakeNowJust"},"css-extras":{title:"CSS Extras",require:"css",modify:"css",owner:"milesj"},csv:{title:"CSV",owner:"RunDevelopment"},cue:{title:"CUE",owner:"RunDevelopment"},cypher:{title:"Cypher",owner:"RunDevelopment"},d:{title:"D",require:"clike",owner:"Golmote"},dart:{title:"Dart",require:"clike",owner:"Golmote"},dataweave:{title:"DataWeave",owner:"machaval"},dax:{title:"DAX",owner:"peterbud"},dhall:{title:"Dhall",owner:"RunDevelopment"},diff:{title:"Diff",owner:"uranusjr"},django:{title:"Django/Jinja2",require:"markup-templating",alias:"jinja2",owner:"romanvm"},"dns-zone-file":{title:"DNS zone file",owner:"RunDevelopment",alias:"dns-zone"},docker:{title:"Docker",alias:"dockerfile",owner:"JustinBeckwith"},dot:{title:"DOT (Graphviz)",alias:"gv",optional:"markup",owner:"RunDevelopment"},ebnf:{title:"EBNF",owner:"RunDevelopment"},editorconfig:{title:"EditorConfig",owner:"osipxd"},eiffel:{title:"Eiffel",owner:"Conaclos"},ejs:{title:"EJS",require:["javascript","markup-templating"],owner:"RunDevelopment",alias:"eta",aliasTitles:{eta:"Eta"}},elixir:{title:"Elixir",owner:"Golmote"},elm:{title:"Elm",owner:"zwilias"},etlua:{title:"Embedded Lua templating",require:["lua","markup-templating"],owner:"RunDevelopment"},erb:{title:"ERB",require:["ruby","markup-templating"],owner:"Golmote"},erlang:{title:"Erlang",owner:"Golmote"},"excel-formula":{title:"Excel Formula",alias:["xlsx","xls"],owner:"RunDevelopment"},fsharp:{title:"F#",require:"clike",owner:"simonreynolds7"},factor:{title:"Factor",owner:"catb0t"},false:{title:"False",owner:"edukisto"},"firestore-security-rules":{title:"Firestore security rules",require:"clike",owner:"RunDevelopment"},flow:{title:"Flow",require:"javascript",owner:"Golmote"},fortran:{title:"Fortran",owner:"Golmote"},ftl:{title:"FreeMarker Template Language",require:"markup-templating",owner:"RunDevelopment"},gml:{title:"GameMaker Language",alias:"gamemakerlanguage",require:"clike",owner:"LiarOnce"},gap:{title:"GAP (CAS)",owner:"RunDevelopment"},gcode:{title:"G-code",owner:"RunDevelopment"},gdscript:{title:"GDScript",owner:"RunDevelopment"},gedcom:{title:"GEDCOM",owner:"Golmote"},gettext:{title:"gettext",alias:"po",owner:"RunDevelopment"},gherkin:{title:"Gherkin",owner:"hason"},git:{title:"Git",owner:"lgiraudel"},glsl:{title:"GLSL",require:"c",owner:"Golmote"},gn:{title:"GN",alias:"gni",owner:"RunDevelopment"},"linker-script":{title:"GNU Linker Script",alias:"ld",owner:"RunDevelopment"},go:{title:"Go",require:"clike",owner:"arnehormann"},"go-module":{title:"Go module",alias:"go-mod",owner:"RunDevelopment"},gradle:{title:"Gradle",require:"clike",owner:"zeabdelkhalek-badido18"},graphql:{title:"GraphQL",optional:"markdown",owner:"Golmote"},groovy:{title:"Groovy",require:"clike",owner:"robfletcher"},haml:{title:"Haml",require:"ruby",optional:["css","css-extras","coffeescript","erb","javascript","less","markdown","scss","textile"],owner:"Golmote"},handlebars:{title:"Handlebars",require:"markup-templating",alias:["hbs","mustache"],aliasTitles:{mustache:"Mustache"},owner:"Golmote"},haskell:{title:"Haskell",alias:"hs",owner:"bholst"},haxe:{title:"Haxe",require:"clike",optional:"regex",owner:"Golmote"},hcl:{title:"HCL",owner:"outsideris"},hlsl:{title:"HLSL",require:"c",owner:"RunDevelopment"},hoon:{title:"Hoon",owner:"matildepark"},http:{title:"HTTP",optional:["csp","css","hpkp","hsts","javascript","json","markup","uri"],owner:"danielgtaylor"},hpkp:{title:"HTTP Public-Key-Pins",owner:"ScottHelme"},hsts:{title:"HTTP Strict-Transport-Security",owner:"ScottHelme"},ichigojam:{title:"IchigoJam",owner:"BlueCocoa"},icon:{title:"Icon",owner:"Golmote"},"icu-message-format":{title:"ICU Message Format",owner:"RunDevelopment"},idris:{title:"Idris",alias:"idr",owner:"KeenS",require:"haskell"},ignore:{title:".ignore",owner:"osipxd",alias:["gitignore","hgignore","npmignore"],aliasTitles:{gitignore:".gitignore",hgignore:".hgignore",npmignore:".npmignore"}},inform7:{title:"Inform 7",owner:"Golmote"},ini:{title:"Ini",owner:"aviaryan"},io:{title:"Io",owner:"AlesTsurko"},j:{title:"J",owner:"Golmote"},java:{title:"Java",require:"clike",owner:"sherblot"},javadoc:{title:"JavaDoc",require:["markup","java","javadoclike"],modify:"java",optional:"scala",owner:"RunDevelopment"},javadoclike:{title:"JavaDoc-like",modify:["java","javascript","php"],owner:"RunDevelopment"},javastacktrace:{title:"Java stack trace",owner:"RunDevelopment"},jexl:{title:"Jexl",owner:"czosel"},jolie:{title:"Jolie",require:"clike",owner:"thesave"},jq:{title:"JQ",owner:"RunDevelopment"},jsdoc:{title:"JSDoc",require:["javascript","javadoclike","typescript"],modify:"javascript",optional:["actionscript","coffeescript"],owner:"RunDevelopment"},"js-extras":{title:"JS Extras",require:"javascript",modify:"javascript",optional:["actionscript","coffeescript","flow","n4js","typescript"],owner:"RunDevelopment"},json:{title:"JSON",alias:"webmanifest",aliasTitles:{webmanifest:"Web App Manifest"},owner:"CupOfTea696"},json5:{title:"JSON5",require:"json",owner:"RunDevelopment"},jsonp:{title:"JSONP",require:"json",owner:"RunDevelopment"},jsstacktrace:{title:"JS stack trace",owner:"sbrl"},"js-templates":{title:"JS Templates",require:"javascript",modify:"javascript",optional:["css","css-extras","graphql","markdown","markup","sql"],owner:"RunDevelopment"},julia:{title:"Julia",owner:"cdagnino"},keepalived:{title:"Keepalived Configure",owner:"dev-itsheng"},keyman:{title:"Keyman",owner:"mcdurdin"},kotlin:{title:"Kotlin",alias:["kt","kts"],aliasTitles:{kts:"Kotlin Script"},require:"clike",owner:"Golmote"},kumir:{title:"KuMir (\u041a\u0443\u041c\u0438\u0440)",alias:"kum",owner:"edukisto"},kusto:{title:"Kusto",owner:"RunDevelopment"},latex:{title:"LaTeX",alias:["tex","context"],aliasTitles:{tex:"TeX",context:"ConTeXt"},owner:"japborst"},latte:{title:"Latte",require:["clike","markup-templating","php"],owner:"nette"},less:{title:"Less",require:"css",optional:"css-extras",owner:"Golmote"},lilypond:{title:"LilyPond",require:"scheme",alias:"ly",owner:"RunDevelopment"},liquid:{title:"Liquid",require:"markup-templating",owner:"cinhtau"},lisp:{title:"Lisp",alias:["emacs","elisp","emacs-lisp"],owner:"JuanCaicedo"},livescript:{title:"LiveScript",owner:"Golmote"},llvm:{title:"LLVM IR",owner:"porglezomp"},log:{title:"Log file",optional:"javastacktrace",owner:"RunDevelopment"},lolcode:{title:"LOLCODE",owner:"Golmote"},lua:{title:"Lua",owner:"Golmote"},magma:{title:"Magma (CAS)",owner:"RunDevelopment"},makefile:{title:"Makefile",owner:"Golmote"},markdown:{title:"Markdown",require:"markup",optional:"yaml",alias:"md",owner:"Golmote"},"markup-templating":{title:"Markup templating",require:"markup",owner:"Golmote"},mata:{title:"Mata",owner:"RunDevelopment"},matlab:{title:"MATLAB",owner:"Golmote"},maxscript:{title:"MAXScript",owner:"RunDevelopment"},mel:{title:"MEL",owner:"Golmote"},mermaid:{title:"Mermaid",owner:"RunDevelopment"},metafont:{title:"METAFONT",owner:"LaeriExNihilo"},mizar:{title:"Mizar",owner:"Golmote"},mongodb:{title:"MongoDB",owner:"airs0urce",require:"javascript"},monkey:{title:"Monkey",owner:"Golmote"},moonscript:{title:"MoonScript",alias:"moon",owner:"RunDevelopment"},n1ql:{title:"N1QL",owner:"TMWilds"},n4js:{title:"N4JS",require:"javascript",optional:"jsdoc",alias:"n4jsd",owner:"bsmith-n4"},"nand2tetris-hdl":{title:"Nand To Tetris HDL",owner:"stephanmax"},naniscript:{title:"Naninovel Script",owner:"Elringus",alias:"nani"},nasm:{title:"NASM",owner:"rbmj"},neon:{title:"NEON",owner:"nette"},nevod:{title:"Nevod",owner:"nezaboodka"},nginx:{title:"nginx",owner:"volado"},nim:{title:"Nim",owner:"Golmote"},nix:{title:"Nix",owner:"Golmote"},nsis:{title:"NSIS",owner:"idleberg"},objectivec:{title:"Objective-C",require:"c",alias:"objc",owner:"uranusjr"},ocaml:{title:"OCaml",owner:"Golmote"},odin:{title:"Odin",owner:"edukisto"},opencl:{title:"OpenCL",require:"c",modify:["c","cpp"],owner:"Milania1"},openqasm:{title:"OpenQasm",alias:"qasm",owner:"RunDevelopment"},oz:{title:"Oz",owner:"Golmote"},parigp:{title:"PARI/GP",owner:"Golmote"},parser:{title:"Parser",require:"markup",owner:"Golmote"},pascal:{title:"Pascal",alias:"objectpascal",aliasTitles:{objectpascal:"Object Pascal"},owner:"Golmote"},pascaligo:{title:"Pascaligo",owner:"DefinitelyNotAGoat"},psl:{title:"PATROL Scripting Language",owner:"bertysentry"},pcaxis:{title:"PC-Axis",alias:"px",owner:"RunDevelopment"},peoplecode:{title:"PeopleCode",alias:"pcode",owner:"RunDevelopment"},perl:{title:"Perl",owner:"Golmote"},php:{title:"PHP",require:"markup-templating",owner:"milesj"},phpdoc:{title:"PHPDoc",require:["php","javadoclike"],modify:"php",owner:"RunDevelopment"},"php-extras":{title:"PHP Extras",require:"php",modify:"php",owner:"milesj"},"plant-uml":{title:"PlantUML",alias:"plantuml",owner:"RunDevelopment"},plsql:{title:"PL/SQL",require:"sql",owner:"Golmote"},powerquery:{title:"PowerQuery",alias:["pq","mscript"],owner:"peterbud"},powershell:{title:"PowerShell",owner:"nauzilus"},processing:{title:"Processing",require:"clike",owner:"Golmote"},prolog:{title:"Prolog",owner:"Golmote"},promql:{title:"PromQL",owner:"arendjr"},properties:{title:".properties",owner:"Golmote"},protobuf:{title:"Protocol Buffers",require:"clike",owner:"just-boris"},pug:{title:"Pug",require:["markup","javascript"],optional:["coffeescript","ejs","handlebars","less","livescript","markdown","scss","stylus","twig"],owner:"Golmote"},puppet:{title:"Puppet",owner:"Golmote"},pure:{title:"Pure",optional:["c","cpp","fortran"],owner:"Golmote"},purebasic:{title:"PureBasic",require:"clike",alias:"pbfasm",owner:"HeX0R101"},purescript:{title:"PureScript",require:"haskell",alias:"purs",owner:"sriharshachilakapati"},python:{title:"Python",alias:"py",owner:"multipetros"},qsharp:{title:"Q#",require:"clike",alias:"qs",owner:"fedonman"},q:{title:"Q (kdb+ database)",owner:"Golmote"},qml:{title:"QML",require:"javascript",owner:"RunDevelopment"},qore:{title:"Qore",require:"clike",owner:"temnroegg"},r:{title:"R",owner:"Golmote"},racket:{title:"Racket",require:"scheme",alias:"rkt",owner:"RunDevelopment"},cshtml:{title:"Razor C#",alias:"razor",require:["markup","csharp"],optional:["css","css-extras","javascript","js-extras"],owner:"RunDevelopment"},jsx:{title:"React JSX",require:["markup","javascript"],optional:["jsdoc","js-extras","js-templates"],owner:"vkbansal"},tsx:{title:"React TSX",require:["jsx","typescript"]},reason:{title:"Reason",require:"clike",owner:"Golmote"},regex:{title:"Regex",owner:"RunDevelopment"},rego:{title:"Rego",owner:"JordanSh"},renpy:{title:"Ren'py",alias:"rpy",owner:"HyuchiaDiego"},rescript:{title:"ReScript",alias:"res",owner:"vmarcosp"},rest:{title:"reST (reStructuredText)",owner:"Golmote"},rip:{title:"Rip",owner:"ravinggenius"},roboconf:{title:"Roboconf",owner:"Golmote"},robotframework:{title:"Robot Framework",alias:"robot",owner:"RunDevelopment"},ruby:{title:"Ruby",require:"clike",alias:"rb",owner:"samflores"},rust:{title:"Rust",owner:"Golmote"},sas:{title:"SAS",optional:["groovy","lua","sql"],owner:"Golmote"},sass:{title:"Sass (Sass)",require:"css",optional:"css-extras",owner:"Golmote"},scss:{title:"Sass (SCSS)",require:"css",optional:"css-extras",owner:"MoOx"},scala:{title:"Scala",require:"java",owner:"jozic"},scheme:{title:"Scheme",owner:"bacchus123"},"shell-session":{title:"Shell session",require:"bash",alias:["sh-session","shellsession"],owner:"RunDevelopment"},smali:{title:"Smali",owner:"RunDevelopment"},smalltalk:{title:"Smalltalk",owner:"Golmote"},smarty:{title:"Smarty",require:"markup-templating",optional:"php",owner:"Golmote"},sml:{title:"SML",alias:"smlnj",aliasTitles:{smlnj:"SML/NJ"},owner:"RunDevelopment"},solidity:{title:"Solidity (Ethereum)",alias:"sol",require:"clike",owner:"glachaud"},"solution-file":{title:"Solution file",alias:"sln",owner:"RunDevelopment"},soy:{title:"Soy (Closure Template)",require:"markup-templating",owner:"Golmote"},sparql:{title:"SPARQL",require:"turtle",owner:"Triply-Dev",alias:"rq"},"splunk-spl":{title:"Splunk SPL",owner:"RunDevelopment"},sqf:{title:"SQF: Status Quo Function (Arma 3)",require:"clike",owner:"RunDevelopment"},sql:{title:"SQL",owner:"multipetros"},squirrel:{title:"Squirrel",require:"clike",owner:"RunDevelopment"},stan:{title:"Stan",owner:"RunDevelopment"},stata:{title:"Stata Ado",require:["mata","java","python"],owner:"RunDevelopment"},iecst:{title:"Structured Text (IEC 61131-3)",owner:"serhioromano"},stylus:{title:"Stylus",owner:"vkbansal"},supercollider:{title:"SuperCollider",alias:"sclang",owner:"RunDevelopment"},swift:{title:"Swift",owner:"chrischares"},systemd:{title:"Systemd configuration file",owner:"RunDevelopment"},"t4-templating":{title:"T4 templating",owner:"RunDevelopment"},"t4-cs":{title:"T4 Text Templates (C#)",require:["t4-templating","csharp"],alias:"t4",owner:"RunDevelopment"},"t4-vb":{title:"T4 Text Templates (VB)",require:["t4-templating","vbnet"],owner:"RunDevelopment"},tap:{title:"TAP",owner:"isaacs",require:"yaml"},tcl:{title:"Tcl",owner:"PeterChaplin"},tt2:{title:"Template Toolkit 2",require:["clike","markup-templating"],owner:"gflohr"},textile:{title:"Textile",require:"markup",optional:"css",owner:"Golmote"},toml:{title:"TOML",owner:"RunDevelopment"},tremor:{title:"Tremor",alias:["trickle","troy"],owner:"darach",aliasTitles:{trickle:"trickle",troy:"troy"}},turtle:{title:"Turtle",alias:"trig",aliasTitles:{trig:"TriG"},owner:"jakubklimek"},twig:{title:"Twig",require:"markup-templating",owner:"brandonkelly"},typescript:{title:"TypeScript",require:"javascript",optional:"js-templates",alias:"ts",owner:"vkbansal"},typoscript:{title:"TypoScript",alias:"tsconfig",aliasTitles:{tsconfig:"TSConfig"},owner:"dkern"},unrealscript:{title:"UnrealScript",alias:["uscript","uc"],owner:"RunDevelopment"},uorazor:{title:"UO Razor Script",owner:"jaseowns"},uri:{title:"URI",alias:"url",aliasTitles:{url:"URL"},owner:"RunDevelopment"},v:{title:"V",require:"clike",owner:"taggon"},vala:{title:"Vala",require:"clike",optional:"regex",owner:"TemplarVolk"},vbnet:{title:"VB.Net",require:"basic",owner:"Bigsby"},velocity:{title:"Velocity",require:"markup",owner:"Golmote"},verilog:{title:"Verilog",owner:"a-rey"},vhdl:{title:"VHDL",owner:"a-rey"},vim:{title:"vim",owner:"westonganger"},"visual-basic":{title:"Visual Basic",alias:["vb","vba"],aliasTitles:{vba:"VBA"},owner:"Golmote"},warpscript:{title:"WarpScript",owner:"RunDevelopment"},wasm:{title:"WebAssembly",owner:"Golmote"},"web-idl":{title:"Web IDL",alias:"webidl",owner:"RunDevelopment"},wgsl:{title:"WGSL",owner:"Dr4gonthree"},wiki:{title:"Wiki markup",require:"markup",owner:"Golmote"},wolfram:{title:"Wolfram language",alias:["mathematica","nb","wl"],aliasTitles:{mathematica:"Mathematica",nb:"Mathematica Notebook"},owner:"msollami"},wren:{title:"Wren",owner:"clsource"},xeora:{title:"Xeora",require:"markup",alias:"xeoracube",aliasTitles:{xeoracube:"XeoraCube"},owner:"freakmaxi"},"xml-doc":{title:"XML doc (.net)",require:"markup",modify:["csharp","fsharp","vbnet"],owner:"RunDevelopment"},xojo:{title:"Xojo (REALbasic)",owner:"Golmote"},xquery:{title:"XQuery",require:"markup",owner:"Golmote"},yaml:{title:"YAML",alias:"yml",owner:"hason"},yang:{title:"YANG",owner:"RunDevelopment"},zig:{title:"Zig",owner:"RunDevelopment"}},plugins:{meta:{path:"plugins/{id}/prism-{id}",link:"plugins/{id}/"},"line-highlight":{title:"Line Highlight",description:"Highlights specific lines and/or line ranges."},"line-numbers":{title:"Line Numbers",description:"Line number at the beginning of code lines.",owner:"kuba-kubula"},"show-invisibles":{title:"Show Invisibles",description:"Show hidden characters such as tabs and line breaks.",optional:["autolinker","data-uri-highlight"]},autolinker:{title:"Autolinker",description:"Converts URLs and emails in code to clickable links. Parses Markdown links in comments."},wpd:{title:"WebPlatform Docs",description:'Makes tokens link to WebPlatform.org documentation. The links open in a new tab.'},"custom-class":{title:"Custom Class",description:"This plugin allows you to prefix Prism's default classes (.comment can become .namespace--comment) or replace them with your defined ones (like .editor__comment). You can even add new classes.",owner:"dvkndn",noCSS:!0},"file-highlight":{title:"File Highlight",description:"Fetch external files and highlight them with Prism. Used on the Prism website itself.",noCSS:!0},"show-language":{title:"Show Language",description:"Display the highlighted language in code blocks (inline code does not show the label).",owner:"nauzilus",noCSS:!0,require:"toolbar"},"jsonp-highlight":{title:"JSONP Highlight",description:"Fetch content with JSONP and highlight some interesting content (e.g. GitHub/Gists or Bitbucket API).",noCSS:!0,owner:"nauzilus"},"highlight-keywords":{title:"Highlight Keywords",description:"Adds special CSS classes for each keyword for fine-grained highlighting.",owner:"vkbansal",noCSS:!0},"remove-initial-line-feed":{title:"Remove initial line feed",description:"Removes the initial line feed in code blocks.",owner:"Golmote",noCSS:!0},"inline-color":{title:"Inline color",description:"Adds a small inline preview for colors in style sheets.",require:"css-extras",owner:"RunDevelopment"},previewers:{title:"Previewers",description:"Previewers for angles, colors, gradients, easing and time.",require:"css-extras",owner:"Golmote"},autoloader:{title:"Autoloader",description:"Automatically loads the needed languages to highlight the code blocks.",owner:"Golmote",noCSS:!0},"keep-markup":{title:"Keep Markup",description:"Prevents custom markup from being dropped out during highlighting.",owner:"Golmote",optional:"normalize-whitespace",noCSS:!0},"command-line":{title:"Command Line",description:"Display a command line with a prompt and, optionally, the output/response from the commands.",owner:"chriswells0"},"unescaped-markup":{title:"Unescaped Markup",description:"Write markup without having to escape anything."},"normalize-whitespace":{title:"Normalize Whitespace",description:"Supports multiple operations to normalize whitespace in code blocks.",owner:"zeitgeist87",optional:"unescaped-markup",noCSS:!0},"data-uri-highlight":{title:"Data-URI Highlight",description:"Highlights data-URI contents.",owner:"Golmote",noCSS:!0},toolbar:{title:"Toolbar",description:"Attach a toolbar for plugins to easily register buttons on the top of a code block.",owner:"mAAdhaTTah"},"copy-to-clipboard":{title:"Copy to Clipboard Button",description:"Add a button that copies the code block to the clipboard when clicked.",owner:"mAAdhaTTah",require:"toolbar",noCSS:!0},"download-button":{title:"Download Button",description:"A button in the toolbar of a code block adding a convenient way to download a code file.",owner:"Golmote",require:"toolbar",noCSS:!0},"match-braces":{title:"Match braces",description:"Highlights matching braces.",owner:"RunDevelopment"},"diff-highlight":{title:"Diff Highlight",description:"Highlights the code inside diff blocks.",owner:"RunDevelopment",require:"diff"},"filter-highlight-all":{title:"Filter highlightAll",description:"Filters the elements the highlightAll and highlightAllUnder methods actually highlight.",owner:"RunDevelopment",noCSS:!0},treeview:{title:"Treeview",description:"A language with special styles to highlight file system tree structures.",owner:"Golmote"}}})},8722:(e,t,n)=>{const r=n(6969),a=n(8380),o=new Set;function i(e){void 0===e?e=Object.keys(r.languages).filter((e=>"meta"!=e)):Array.isArray(e)||(e=[e]);const t=[...o,...Object.keys(Prism.languages)];a(r,e,t).load((e=>{if(!(e in r.languages))return void(i.silent||console.warn("Language does not exist: "+e));const t="./prism-"+e;delete n.c[n(3157).resolve(t)],delete Prism.languages[e],n(3157)(t),o.add(e)}))}i.silent=!1,e.exports=i},8692:(e,t,n)=>{var r={"./":8722};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=8692},3157:(e,t,n)=>{var r={"./":8722};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=3157},8380:e=>{"use strict";var t=function(){var e=function(){};function t(e,t){Array.isArray(e)?e.forEach(t):null!=e&&t(e,0)}function n(e){for(var t={},n=0,r=e.length;n "));var l={},s=e[r];if(s){function c(t){if(!(t in e))throw new Error(r+" depends on an unknown component "+t);if(!(t in l))for(var i in a(t,o),l[t]=!0,n[t])l[i]=!0}t(s.require,c),t(s.optional,c),t(s.modify,c)}n[r]=l,o.pop()}}return function(e){var t=n[e];return t||(a(e,r),t=n[e]),t}}function a(e){for(var t in e)return!0;return!1}return function(o,i,l){var s=function(e){var t={};for(var n in e){var r=e[n];for(var a in r)if("meta"!=a){var o=r[a];t[a]="string"==typeof o?{title:o}:o}}return t}(o),c=function(e){var n;return function(r){if(r in e)return r;if(!n)for(var a in n={},e){var o=e[a];t(o&&o.alias,(function(t){if(t in n)throw new Error(t+" cannot be alias for both "+a+" and "+n[t]);if(t in e)throw new Error(t+" cannot be alias of "+a+" because it is a component.");n[t]=a}))}return n[r]||r}}(s);i=i.map(c),l=(l||[]).map(c);var u=n(i),d=n(l);i.forEach((function e(n){var r=s[n];t(r&&r.require,(function(t){t in d||(u[t]=!0,e(t))}))}));for(var p,f=r(s),m=u;a(m);){for(var h in p={},m){var b=s[h];t(b&&b.modify,(function(e){e in d&&(p[e]=!0)}))}for(var g in d)if(!(g in u))for(var v in f(g))if(v in u){p[g]=!0;break}for(var y in m=p)u[y]=!0}var k={getIds:function(){var e=[];return k.load((function(t){e.push(t)})),e},load:function(t,n){return function(t,n,r,a){var o=a?a.series:void 0,i=a?a.parallel:e,l={},s={};function c(e){if(e in l)return l[e];s[e]=!0;var a,u=[];for(var d in t(e))d in n&&u.push(d);if(0===u.length)a=r(e);else{var p=i(u.map((function(e){var t=c(e);return delete s[e],t})));o?a=o(p,(function(){return r(e)})):r(e)}return l[e]=a}for(var u in n)c(u);var d=[];for(var p in s)d.push(l[p]);return i(d)}(f,u,t,n)}};return k}}();e.exports=t},2694:(e,t,n)=>{"use strict";var r=n(6925);function a(){}function o(){}o.resetWarningCache=a,e.exports=function(){function e(e,t,n,a,o,i){if(i!==r){var l=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw l.name="Invariant Violation",l}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:o,resetWarningCache:a};return n.PropTypes=n,n}},5556:(e,t,n)=>{e.exports=n(2694)()},6925:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},2551:(e,t,n)=>{"use strict";var r=n(6540),a=n(5228),o=n(9982);function i(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n
- - + + \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml index 170da18c..595861b0 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -1 +1 @@ -http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/markdown-pageweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Assignments/weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Assignments/assignment1weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Assignments/assignment2weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Assignments/projectweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/gradingweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Lectures/weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Lectures/Introductionweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Basic%20Peer-to-Peer%20Blockchain/weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Basic%20Peer-to-Peer%20Blockchain/basic_walletweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Basic%20Peer-to-Peer%20Blockchain/discovery_nodeweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Basic%20Peer-to-Peer%20Blockchain/miningweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Basic%20Peer-to-Peer%20Blockchain/p2p_networkweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Basic%20Peer-to-Peer%20Blockchain/sourcesweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Basic%20Peer-to-Peer%20Blockchain/terminalweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Basic%20Peer-to-Peer%20Blockchain/transactionsweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Basic%20Peer-to-Peer%20Blockchain/what_we_buildweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Basic%20Peer-to-Peer%20Blockchain/why_golangweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Env%20Setup/weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Env%20Setup/setupweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Explorer/weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Explorer/Block%20Leader/leaderweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Explorer/Blockchain%20Observers/observersweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Explorer/Blockchain%20Validators/validatorsweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Explorer/Blocks/weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Explorer/Consensus%20Grup/consensusweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Explorer/Devnet%20Blockchains/devnet_testnetweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Explorer/Time%20in%20Blockchain/timeweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Explorer/Transactions/weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Money%20(DeFi)/weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Money%20(DeFi)/mint_tokensweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Money%20(DeFi)/swapweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Observer/weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Observer/weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Smart%20Contract%20Events/weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Smart%20Contract%20Events/eventsweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Smart%20Contracts/weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Smart%20Contracts/adderweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Smart%20Contracts/cargo_deployweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Smart%20Contracts/emptyweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Smart%20Contracts/mxpy_deployweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Smart%20Contracts/mxpy_sc_callweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Smart%20Contracts/neverseaweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Smart%20Contracts/prerequisitesweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Smart%20Contracts/rust_interactorsweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Tokens/weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Tokens/fungibleweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Tokens/fungible-non-fungibleweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Tokens/nftweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Tokens/standardsweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Wallet/weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Wallet/browser_walletweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Wallet/Cmd%20line%20wallet/cmdline_walletweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Wallet/faucetweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Wallet/Keystore/weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Wallet/send_txweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Wallet/Wallet/weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/resourcesweekly0.5 \ No newline at end of file +http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/markdown-pageweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Assignments/weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Assignments/assignment1weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Assignments/assignment2weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Assignments/projectweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/gradingweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Lectures/weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Lectures/Introductionweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Basic%20Peer-to-Peer%20Blockchain/weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Basic%20Peer-to-Peer%20Blockchain/basic_walletweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Basic%20Peer-to-Peer%20Blockchain/discovery_nodeweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Basic%20Peer-to-Peer%20Blockchain/miningweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Basic%20Peer-to-Peer%20Blockchain/p2p_networkweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Basic%20Peer-to-Peer%20Blockchain/sourcesweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Basic%20Peer-to-Peer%20Blockchain/terminalweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Basic%20Peer-to-Peer%20Blockchain/transactionsweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Basic%20Peer-to-Peer%20Blockchain/what_we_buildweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Basic%20Peer-to-Peer%20Blockchain/why_golangweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Env%20Setup/weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Env%20Setup/setupweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Explorer/weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Explorer/Block%20Leader/leaderweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Explorer/Blockchain%20Observers/observersweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Explorer/Blockchain%20Validators/validatorsweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Explorer/Blocks/weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Explorer/Consensus%20Grup/consensusweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Explorer/Devnet%20Blockchains/devnet_testnetweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Explorer/Time%20in%20Blockchain/timeweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Explorer/Transactions/weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Learning%20Rust/weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Learning%20Rust/cryptozombiesweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Learning%20Rust/rustweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Learning%20Rust/tour-of-rustweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Money%20(DeFi)/weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Money%20(DeFi)/mint_tokensweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Money%20(DeFi)/swapweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Observer/weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Observer/weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Smart%20Contract%20Events/weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Smart%20Contract%20Events/eventsweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Smart%20Contracts/weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Smart%20Contracts/adderweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Smart%20Contracts/cargo_deployweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Smart%20Contracts/emptyweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Smart%20Contracts/mxpy_deployweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Smart%20Contracts/mxpy_sc_callweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Smart%20Contracts/neverseaweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Smart%20Contracts/prerequisitesweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Smart%20Contracts/rust_interactorsweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Tokens/weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Tokens/fungibleweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Tokens/fungible-non-fungibleweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Tokens/nftweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Tokens/standardsweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Wallet/weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Wallet/browser_walletweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Wallet/Cmd%20line%20wallet/cmdline_walletweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Wallet/faucetweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Wallet/Keystore/weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Wallet/send_txweekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/Practical%20Sessions/Wallet/Wallet/weekly0.5http://costincarabas.github.io/blockchain-protocols-and-distributed-applications/resourcesweekly0.5 \ No newline at end of file